Created
June 24, 2014 10:36
-
-
Save lnicola/abc44198290534120764 to your computer and use it in GitHub Desktop.
LeaF garbage can
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #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