Skip to content

Commit

Permalink
Add correct std::function support for EventHook and WindowClass
Browse files Browse the repository at this point in the history
Remove redundant folder in start menu in installer
Some other minor improvements
  • Loading branch information
sylveon committed Jun 24, 2018
1 parent acba7ae commit 9fe80ad
Show file tree
Hide file tree
Showing 17 changed files with 103 additions and 85 deletions.
2 changes: 1 addition & 1 deletion DesktopInstaller/deps/isxdl/isxdl.iss
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Source: "DesktopInstaller\deps\isxdl\isxdl.dll"; Flags: dontcopy
procedure isxdl_AddFile(URL, Filename: PAnsiChar);
external 'isxdl_AddFile@files:isxdl.dll stdcall';
function isxdl_DownloadFiles(hWnd: Integer): Integer;
function isxdl_DownloadFiles(hWnd: HWND): Integer;
external 'isxdl_DownloadFiles@files:isxdl.dll stdcall';
function isxdl_SetOption(Option, Value: PAnsiChar): Integer;
Expand Down
2 changes: 1 addition & 1 deletion DesktopInstaller/deps/products.pas
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ function NextButtonClick(CurPageID: Integer): boolean;

if CurPageID = wpReady then begin
if downloadMessage <> '' then begin
if isxdl_DownloadFiles(StrToInt(ExpandConstant('{wizardhwnd}'))) = 0 then
if isxdl_DownloadFiles(WizardForm.Handle) = 0 then
Result := false;
end;
end;
Expand Down
7 changes: 2 additions & 5 deletions DesktopInstaller/main.iss
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@
#define AppVersion GetFileVersion('..\Release\' + AppName + '.exe')

[Setup]
AllowNoIcons=yes
AllowRootDirectory=yes
AppCopyright=Copyright © 2018 {#AppPublisher}
AppendDefaultDirName=no
AppendDefaultGroupName=no
AppMutex={#AppMutex}
AppName={#AppName}
AppPublisher={#AppPublisher}
Expand All @@ -17,8 +15,8 @@ AppReadmeFile=https://github.com/{#AppName}/{#AppName}/blob/master/Readme.md
AppSupportURL=https://github.com/{#AppName}/{#AppName}/issues/new
AppVersion={#AppVersion}
DefaultDirName={code:GetDefaultDirName}
DefaultGroupName={#AppName}
DisableWelcomePage=no
DisableProgramGroupPage=yes
LicenseFile=LICENSE.md
MinVersion=10
OutputBaseFilename={#AppName}-setup
Expand All @@ -38,8 +36,7 @@ Source: "Release\*"; Excludes: "*.pdb, *.lib, *.exp"; DestDir: "{app}"; Flags: i
Root: HKCU; Subkey: "SOFTWARE\Microsoft\Windows\CurrentVersion\Run"; ValueName: {#AppName}; Flags: dontcreatekey uninsdeletevalue

[Icons]
Name: "{group}\{#AppName}"; Filename: "{app}\{#AppName}.exe"; WorkingDir: "{app}"
Name: "{group}\{cm:UninstallProgram,{#AppName}}"; Filename: "{uninstallexe}"; WorkingDir: "{app}"
Name: "{commonprograms}\{#AppName}"; Filename: "{app}\{#AppName}.exe"; WorkingDir: "{app}"

[Run]
Filename: "{app}\{#AppName}.exe"; Description: "{cm:LaunchProgram,{#AppName}}"; Flags: nowait postinstall
Expand Down
2 changes: 1 addition & 1 deletion TranslucentTB/blacklist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ void Blacklist::ClearCache()
}
}

void Blacklist::HandleWinEvent(HWINEVENTHOOK, const DWORD event, const HWND window, LONG, LONG, DWORD, DWORD)
void Blacklist::HandleWinEvent(const DWORD event, const Window &window, ...)
{
if (event == EVENT_OBJECT_DESTROY || event == EVENT_OBJECT_NAMECHANGE)
{
Expand Down
2 changes: 1 addition & 1 deletion TranslucentTB/blacklist.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class Blacklist {
static std::unordered_map<Window, bool> m_Cache;

static EventHook m_Hook;
static void CALLBACK HandleWinEvent(HWINEVENTHOOK, const DWORD event, const HWND window, LONG, LONG, DWORD, DWORD);
static void HandleWinEvent(const DWORD event, const Window &window, ...);

static void AddToVector(std::wstring line, std::vector<std::wstring> &vector, const wchar_t &delimiter = L',');
static bool OutputMatchToLog(const Window &window, const bool &isMatch);
Expand Down
23 changes: 20 additions & 3 deletions TranslucentTB/eventhook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,26 @@

#include "ttblog.hpp"

EventHook::EventHook(const DWORD &min, const DWORD &max, WINEVENTPROC callback, const DWORD &flags, const HMODULE &hMod, const DWORD &idProcess, const DWORD &idThread)
// As function because static initialization order.
std::unordered_map<HWINEVENTHOOK, EventHook::callback_t> &EventHook::GetMap()
{
m_Handle = SetWinEventHook(min, max, hMod, callback, idProcess, idThread, flags);
if (!m_Handle)
static std::unordered_map<HWINEVENTHOOK, callback_t> map;
return map;
}

void CALLBACK EventHook::RawHookCallback(HWINEVENTHOOK hook, DWORD event, HWND window, LONG idObject, LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime)
{
GetMap()[hook](event, window, idObject, idChild, dwEventThread, dwmsEventTime);
}

EventHook::EventHook(const DWORD &min, const DWORD &max, const callback_t &callback, const DWORD &flags, const HMODULE &hMod, const DWORD &idProcess, const DWORD &idThread)
{
m_Handle = SetWinEventHook(min, max, hMod, RawHookCallback, idProcess, idThread, flags);
if (m_Handle)
{
GetMap()[m_Handle] = callback;
}
else
{
Log::OutputMessage(L"Failed to create a Windows event hook.");
}
Expand All @@ -15,6 +31,7 @@ EventHook::~EventHook()
{
if (m_Handle)
{
GetMap().erase(m_Handle);
if (!UnhookWinEvent(m_Handle))
{
Log::OutputMessage(L"Failed to delete a Windows event hook.");
Expand Down
9 changes: 8 additions & 1 deletion TranslucentTB/eventhook.hpp
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
#pragma once
#include "arch.h"
#include <functional>
#include <unordered_map>
#include <windef.h>
#include <WinUser.h>

#include "window.hpp"

class EventHook {

private:
using callback_t = std::function<void(DWORD, const Window &, LONG, LONG, DWORD, DWORD)>;
HWINEVENTHOOK m_Handle;
static std::unordered_map<HWINEVENTHOOK, callback_t> &GetMap();
static void CALLBACK RawHookCallback(HWINEVENTHOOK hook, DWORD event, HWND window, LONG idObject, LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime);

public:
inline EventHook(const HWINEVENTHOOK &handle) : m_Handle(handle) { }
EventHook(const DWORD &min, const DWORD &max, WINEVENTPROC callback, const DWORD &flags, const HMODULE &hMod = NULL, const DWORD &idProcess = 0, const DWORD &idThread = 0);
EventHook(const DWORD &min, const DWORD &max, const callback_t &callback, const DWORD &flags, const HMODULE &hMod = NULL, const DWORD &idProcess = 0, const DWORD &idThread = 0);

inline EventHook(const EventHook &) = delete;
inline EventHook &operator =(const EventHook &) = delete;
Expand Down
15 changes: 9 additions & 6 deletions TranslucentTB/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -420,11 +420,6 @@ BOOL CALLBACK EnumWindowsProcess(const HWND hWnd, LPARAM)
return true;
}

void CALLBACK HandleAeroPeekEvent(HWINEVENTHOOK, const DWORD event, HWND, LONG, LONG, DWORD, DWORD)
{
run.peek_active = event == 0x21;
}

void SetTaskbarBlur()
{
static uint8_t counter = 10;
Expand Down Expand Up @@ -683,7 +678,15 @@ int WINAPI wWinMain(const HINSTANCE hInstance, HINSTANCE, wchar_t *, int)
RefreshHandles();

// Undoc'd, allows to detect when Aero Peek starts and stops
EventHook peek_hook(0x21, 0x22, HandleAeroPeekEvent, WINEVENT_OUTOFCONTEXT);
EventHook peek_hook(
0x21,
0x22,
[](const DWORD event, ...)
{
run.peek_active = event == 0x21;
},
WINEVENT_OUTOFCONTEXT
);

// Register our start menu detection sink
ClassicComPtr<IAppVisibility> app_visibility(CLSID_AppVisibility);
Expand Down
64 changes: 15 additions & 49 deletions TranslucentTB/messagewindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,64 +4,30 @@
#include "ttberror.hpp"
#include "util.hpp"

LRESULT MessageWindow::WindowProcedure(HWND hWnd, unsigned int uMsg, WPARAM wParam, LPARAM lParam)
LRESULT MessageWindow::WindowProcedure(const Window &window, unsigned int uMsg, WPARAM wParam, LPARAM lParam)
{
MessageWindow *pThis;

if (uMsg == WM_NCCREATE)
{
const CREATESTRUCT *const lpcs = reinterpret_cast<const CREATESTRUCT *>(lParam);
pThis = static_cast<MessageWindow *>(lpcs->lpCreateParams);

pThis->set_ptr(hWnd);
}
else
{
pThis = get_ptr(hWnd);
}

if (pThis)
const auto &callbackVector = m_CallbackMap[uMsg];
if (callbackVector.size() > 0)
{
MessageWindow &window = *pThis;
const auto &callbackVector = window.m_CallbackMap[uMsg];
if (callbackVector.size() > 0)
long result = 0;
for (const auto &callbackPair : callbackVector)
{
long result = 0;
for (const auto &callbackPair : callbackVector)
{
result = (std::max)(callbackPair.second(wParam, lParam), result);
}
return result;
result = (std::max)(callbackPair.second(wParam, lParam), result);
}
return result;
}

return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

void MessageWindow::set_ptr(const HWND &hwnd)
{
SetLastError(0);
if (!SetWindowLongPtr(hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this)) && GetLastError() != 0)
{
LastErrorHandle(Error::Level::Fatal, L"Failed to set window pointer!");
}
}

MessageWindow *MessageWindow::get_ptr(const HWND &hwnd)
{
SetLastError(0);
MessageWindow *window = reinterpret_cast<MessageWindow *>(GetWindowLongPtr(hwnd, GWLP_USERDATA));

if (!window && GetLastError() != 0)
{
LastErrorHandle(Error::Level::Fatal, L"Failed to get window pointer!");
}

return window;
return DefWindowProc(window, uMsg, wParam, lParam);
}

MessageWindow::MessageWindow(const std::wstring &className, const std::wstring &windowName, const HINSTANCE &hInstance, const wchar_t *iconResource) :
m_WindowClass(WindowProcedure, className, iconResource, 0, hInstance)
m_WindowClass(
std::bind(&MessageWindow::WindowProcedure, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4),
className,
iconResource,
0,
hInstance
)
{
m_WindowHandle = Window::Create(0, m_WindowClass, windowName, 0, 0, 0, 0, 0, Window::NullWindow, 0, hInstance, this);

Expand Down
4 changes: 1 addition & 3 deletions TranslucentTB/messagewindow.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@ class MessageWindow : public Window {
std::unordered_map<unsigned int, std::vector<std::pair<unsigned short, m_CallbackFunction>>> m_CallbackMap;
WindowClass m_WindowClass;

static LRESULT CALLBACK WindowProcedure(HWND hWnd, unsigned int uMsg, WPARAM wParam, LPARAM lParam);
void set_ptr(const HWND &hwnd);
static MessageWindow *get_ptr(const HWND &hwnd);
LRESULT WindowProcedure(const Window &window, unsigned int uMsg, WPARAM wParam, LPARAM lParam);

public:
MessageWindow(const std::wstring &className, const std::wstring &windowName, const HINSTANCE &hInstance = GetModuleHandle(NULL), const wchar_t *iconResource = MAKEINTRESOURCE(MAINICON));
Expand Down
5 changes: 4 additions & 1 deletion TranslucentTB/ttberror.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,10 @@ bool Error::Handle(const HRESULT &error, const Level &level, const wchar_t *cons
case Level::Fatal:
Log::OutputMessage(err.str());
MessageBox(NULL, boxbuffer.str().c_str(), NAME L" - Fatal error", MB_ICONERROR | MB_OK | MB_SETFOREGROUND | MB_TOPMOST);
std::terminate();
RaiseFailFastException(NULL, NULL, FAIL_FAST_GENERATE_EXCEPTION_ADDRESS); // Calling abort() will generate a dialog box,
// but we already have our own. Raising a fail-fast
// exception skips it but also allows WER to do its
// job.
break;
default:
throw std::invalid_argument("level was not one of known values");
Expand Down
2 changes: 1 addition & 1 deletion TranslucentTB/ttblog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ inline std::pair<HRESULT, std::wstring> Log::InitStream()
return std::make_pair(hr, L"Failed to combine log folder location and log file name!");
}

HANDLE file = CreateFile(log_file, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
HANDLE file = CreateFile(log_file, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if (file == INVALID_HANDLE_VALUE)
{
return std::make_pair(HRESULT_FROM_WIN32(GetLastError()), L"Failed to create and open log file!");
Expand Down
2 changes: 1 addition & 1 deletion TranslucentTB/win32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ std::wstring win32::CharToWchar(const char *str)
const size_t strLength = std::char_traits<char>::length(str);
std::wstring strW;
strW.resize(strLength);
int count = MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, str, strLength, strW.data(), strLength + 1);
int count = MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED | MB_ERR_INVALID_CHARS, str, strLength, strW.data(), strLength);
if (count)
{
strW.resize(count);
Expand Down
10 changes: 5 additions & 5 deletions TranslucentTB/window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,24 @@

#include "classiccomptr.hpp"
#include "common.hpp"
#include "eventhook.hpp"
#include "ttberror.hpp"

std::unordered_map<Window, std::wstring> Window::m_ClassNames;
std::unordered_map<Window, std::wstring> Window::m_Filenames;
std::unordered_map<Window, std::wstring> Window::m_Titles;
EventHook Window::m_Hook(EVENT_OBJECT_DESTROY, EVENT_OBJECT_NAMECHANGE, Window::HandleWinEvent, WINEVENT_OUTOFCONTEXT);

void Window::HandleWinEvent(HWINEVENTHOOK, const DWORD event, const HWND window, LONG, LONG, DWORD, DWORD)
void Window::HandleWinEvent(const DWORD event, const Window &window, ...)
{
const Window eventWindow(window);
switch (event)
{
case EVENT_OBJECT_DESTROY:
m_ClassNames.erase(eventWindow);
m_Filenames.erase(eventWindow);
m_ClassNames.erase(window);
m_Filenames.erase(window);
[[fallthrough]];
case EVENT_OBJECT_NAMECHANGE:
m_Titles.erase(eventWindow);
m_Titles.erase(window);
break;
}
}
Expand Down
5 changes: 3 additions & 2 deletions TranslucentTB/window.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@
#include <string>
#include <unordered_map>

#include "eventhook.hpp"
#include "windowclass.hpp"

class EventHook; // Forward declare to avoid circular deps

class Window {

private:
static std::unordered_map<Window, std::wstring> m_ClassNames;
static std::unordered_map<Window, std::wstring> m_Filenames;
static std::unordered_map<Window, std::wstring> m_Titles;
static EventHook m_Hook;
static void CALLBACK HandleWinEvent(HWINEVENTHOOK, const DWORD event, const HWND window, LONG, LONG, DWORD, DWORD);
static void HandleWinEvent(const DWORD event, const Window &window, ...);

protected:
HWND m_WindowHandle;
Expand Down
25 changes: 22 additions & 3 deletions TranslucentTB/windowclass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,26 @@
#include <winerror.h>

#include "ttberror.hpp"
#include "window.hpp"

WindowClass::WindowClass(WNDPROC callback, const std::wstring &className, const wchar_t *iconResource, const unsigned int &style, const HINSTANCE &hInstance, const HBRUSH &brush, const HCURSOR &cursor) :
std::unordered_map<ATOM, WindowClass::callback_t> WindowClass::m_CallbackMap;

LRESULT WindowClass::RawWindowProcedure(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
ATOM atom = static_cast<ATOM>(GetClassLongPtr(hwnd, GCW_ATOM));
if (!atom)
{
LastErrorHandle(Error::Level::Fatal, L"Failed to get class atom!");
}

return m_CallbackMap[atom](hwnd, msg, wParam, lParam);
}

WindowClass::WindowClass(const callback_t &callback, const std::wstring &className, const wchar_t *iconResource, const unsigned int &style, const HINSTANCE &hInstance, const HBRUSH &brush, const HCURSOR &cursor) :
m_ClassStruct {
sizeof(m_ClassStruct),
style,
callback,
RawWindowProcedure,
0,
0,
hInstance,
Expand All @@ -25,14 +39,19 @@ WindowClass::WindowClass(WNDPROC callback, const std::wstring &className, const
ErrorHandle(LoadIconMetric(hInstance, iconResource, LIM_SMALL, &m_ClassStruct.hIconSm), Error::Level::Log, L"Failed to load small window class icon.");

m_Atom = RegisterClassEx(&m_ClassStruct);
if (!m_Atom)
if (m_Atom)
{
m_CallbackMap[m_Atom] = callback;
}
else
{
LastErrorHandle(Error::Level::Fatal, L"Failed to register window class!");
}
}

WindowClass::~WindowClass()
{
m_CallbackMap.erase(m_Atom);
if (!UnregisterClass(atom(), m_ClassStruct.hInstance))
{
LastErrorHandle(Error::Level::Log, L"Failed to unregister window class.");
Expand Down
Loading

0 comments on commit 9fe80ad

Please sign in to comment.