Skip to content

Instantly share code, notes, and snippets.

@lnicola
Created June 24, 2014 10:36
Show Gist options
  • Save lnicola/abc44198290534120764 to your computer and use it in GitHub Desktop.
Save lnicola/abc44198290534120764 to your computer and use it in GitHub Desktop.
LeaF garbage can
#define fatal(msg, ...) do \
{ \
char message[512]; \
wsprintf(message, msg, __VA_ARGS__); \
MessageBox(NULL, message, "Fatal error", MB_OK); \
DebugBreak(); \
ExitProcess(-1); \
} while(false)
#define assert(cond) do \
{ \
if (!(cond)) \
fatal("Assertion \"%s\" failed on line %d of \"%s\"", #cond, __LINE__, __FILE__); \
} while(false)
WindowBase * WindowBase::CreateHiddenWindow()
{
static WNDCLASS wndClass = {0, &DefWindowProcA, 0, 0, Application::hInstance, NULL, NULL, NULL, NULL, "HiddenWindow" };
RegisterClass(&wndClass);
return new WindowBase(NULL, CreateWindowEx(WS_EX_NOPARENTNOTIFY, "HiddenWindow", "HiddenWindow", DS_NOIDLEMSG, 0, 0, 0, 0, NULL, NULL, Application::hInstance, NULL));
}
WindowBase * WindowBase::GetHiddenWindow()
{
static WindowBase *window = CreateHiddenWindow();
return window;
}
#ifdef STATIC_CONSTRUCTORS
typedef void (__cdecl *_PVFV)();
#pragma section(".CRT$XCA", long, read)
#pragma section(".CRT$XCZ", long, read)
__declspec(allocate(".CRT$XCA")) _PVFV __xc_a[] = { NULL };
__declspec(allocate(".CRT$XCZ")) _PVFV __xc_z[] = { NULL };
Vector<_PVFV> *DestructorList;
extern "C" int __cdecl atexit(_PVFV func)
{
DestructorList->Append(func);
return 0;
}
#endif
#ifdef STATIC_CONSTRUCTORS
DestructorList = new Vector<_PVFV>();
for (_PVFV *pfbegin = __xc_a + 1; pfbegin < __xc_z; pfbegin++)
if (*pfbegin)
(**pfbegin)();
DestructorList->Trim();
#endif
#ifdef STATIC_CONSTRUCTORS
for (int i = DestructorList->Length - 1; i >= 0; i--)
(*(*DestructorList)[i])();
// delete DestructorList;
#endif
#define DECLARE_MSG_MAP() virtual INT_PTR HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) override
#define CALL_HANDLER(handler, ...) do { chainMessage = handler(__VA_ARGS__); handled = TRUE; } while(false)
#define CHAIN_MSG_MAP() return chainMessage ? __super::HandleMessage(uMsg, wParam, lParam) : 0 || handled
#define BEGIN_MSG_MAP(class) INT_PTR class::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) \
{ \
INT_PTR handled = FALSE; \
bool chainMessage = true; \
\
switch (uMsg) \
{
#define ON_WM_INITDIALOG(handler) case WM_INITDIALOG: CALL_HANDLER(handler); break
#define ON_WM_WINDOWPOSCHANGED(handler) case WM_WINDOWPOSCHANGED: CALL_HANDLER(handler, reinterpret_cast<WINDOWPOS *>(lParam)); break
#define ON_WM_CLOSE(handler) case WM_CLOSE: CALL_HANDLER(handler); break
#define ON_WM_DESTROY(handler) case WM_DESTROY: CALL_HANDLER(handler); break
#define ON_WM_COMMAND(id, handler) case WM_COMMAND: if (wParam == id) CALL_HANDLER(handler); break
#define END_MSG_MAP() } \
CHAIN_MSG_MAP(); \
}
void Application::AddInstancePointer(Window *Instance)
{
CreateWindowData wndData = { Instance, GetCurrentThreadId() };
instancePointerList.Append(wndData);
}
Window * Application::ExtractInstancePointer()
{
DWORD ThreadId;
ThreadId = GetCurrentThreadId();
instancePointerList.Lock();
for (int i = 0; ; i++)
if (instancePointerList[i].ThreadId == ThreadId)
{
Window *pThis = instancePointerList[i].pThis;
instancePointerList.FastDelete(i);
instancePointerList.Unlock();
return pThis;
}
assert(false);
}
void Dialog::AddInstancePointer()
{
Application::AddInstancePointer(this);
}
pThis = static_cast<Dialog *> (Application::ExtractInstancePointer());
Synchronized<Vector<CreateWindowData>> Application::instancePointerList;
struct CreateWindowData sealed
{
Window *pThis;
DWORD ThreadId;
};
pThis->hWnd = hWnd;
pThis->thunk.Init(reinterpret_cast<LONG_PTR> (&DialogFunc), reinterpret_cast<LONG_PTR> (pThis));
DLGPROC dlgProc = reinterpret_cast<DLGPROC> (&pThis->thunk.mov);
BOOL Dialog::DialogFunc(Dialog *dialog, UINT uMsg, WPARAM wParam, LPARAM lParam)
#pragma pack(push, 1)
struct DialogProcThunk
{
DWORD mov;
LONG_PTR pThis;
BYTE jmp;
LONG_PTR relproc;
void Init(LONG_PTR WndProc, LONG_PTR Instance);
};
#pragma pack(pop)
DialogProcThunk thunk;
void Dialog::DialogProcThunk::Init(LONG_PTR WndProc, LONG_PTR Instance)
{
mov = 0x042444c7;
pThis = Instance;
jmp = 0xe9;
relproc = WndProc - reinterpret_cast<LONG_PTR> (&mov) - sizeof(DialogProcThunk);
}
/*
LRESULT __stdcall ListView::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
ListView *pThis = reinterpret_cast<ListView *>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
INT_PTR ret;
if (!(ret = pThis->HandleMessage(uMsg, wParam, lParam)))
return CallWindowProc(pThis->oldProc, hWnd, uMsg, wParam, lParam);
return ret;
}
LRESULT __stdcall ListView::CreateWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
ListView *pThis = reinterpret_cast<ListView *>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
if (pThis != NULL)
SetWindowLongPtr(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG>(&WndProc));
INT_PTR ret;
if (pThis == NULL || !(ret = pThis->HandleMessage(uMsg, wParam, lParam)))
return CallWindowProc(pThis->oldProc, hWnd, uMsg, wParam, lParam);
return ret;
}
*/
// oldProc = reinterpret_cast<WNDPROC>(GetWindowLongPtr(hWnd, GWLP_WNDPROC));
// SetWindowLongPtr(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(&CreateWndProc));
//SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));
// WNDPROC oldProc;
//static LRESULT __stdcall WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
//static LRESULT __stdcall CreateWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
template<typename T> class UserControl : public Window<T>
{
static LRESULT __stdcall WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
T *pThis = reinterpret_cast<T *>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
INT_PTR ret;
if (!(ret = pThis->HandleMessage(uMsg, wParam, lParam)))
ret = DefWindowProc(hWnd, uMsg, wParam, lParam);
return ret;
}
protected:
static LRESULT __stdcall CreateWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
T *pThis = reinterpret_cast<T *>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
if (pThis != NULL)
SetWindowLongPtr(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG>(&WndProc));
INT_PTR ret;
if (pThis == NULL || !(ret = pThis->HandleMessage(uMsg, wParam, lParam)))
ret = DefWindowProc(hWnd, uMsg, wParam, lParam);
return ret;
}
public:
UserControl(WindowBase *Parent, int Name) : Window<T>(Parent, Name) { }
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment