WM_NCCREATE not called as first message in custom Framework's WndProc function

12 hours ago 1
ARTICLE AD BOX

I'm implementing a custom Win32 C++ framework which encapsulates all the Win32 plumbing in a class called Framework. To satisfy the Win32 C endpoints, some core methods are static. The following 3 static methods will support the myRegisterClass / initInstance / mainWndProcsequence expected by winMain.

static ATOM myRegisterClass(HINSTANCE hInstance); static BOOL initInstance(HINSTANCE hInstance, Framework* framework); static LRESULT CALLBACK mainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

The static function myRegisterClass specifies mainWndProc as

ATOM Framework::myRegisterClass(HINSTANCE hInstance) { WNDCLASSEXW wcex; ZeroMemory(&wcex, sizeof(wcex)); wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = Framework::mainWndProc; ... //etc.

In order to pass custom data to mainWndProc, the initInstance method (called from a non-static winMain entry point) takes as a param the current Framework object's pointer (it's invoked with this from the non-static winMain entry point), and will pass it to mainWndProc.

BOOL Framework::initInstance(HINSTANCE hInstance, Framework* framework) { HWND hWnd = CreateWindow(..., hInstance, framework/* Last param has user data */);

And finally mainWndProc needs to obtain the custom Framework data in WM_NCCREATE and set it as SetWindowLongPtr. The framework object contains all the details needed for encapsulated message processing.

PROBLEM: The WM_NCCREATE is never called. The first message that I get is 36. So I bypass the WM_NCCREATE and don't receive my passedFramework, it's NULL in the else.

LRESULT CALLBACK Framework::mainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { Framework* passedFramework = nullptr; if (message == WM_NCCREATE) { // NEVER CALLED // Extract pointer from CREATESTRUCT CREATESTRUCT* pCreate = reinterpret_cast<CREATESTRUCT*>(lParam); passedFramework = reinterpret_cast<Framework*>(pCreate->lpCreateParams); // Store it in the window's user data SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(passedFramework)); // **NOTE: ALSO TRIED THIS, NO DIFFERENCE (it's something related to DefWindowProc() // return DefWindowProc(hWnd, message, wParam, lParam); // Must return TRUE to continue } else { // Retrieve the pointer for all subsequent messages passedFramework = reinterpret_cast<Framework*>(GetWindowLongPtr(hWnd, GWLP_USERDATA)); } // End of WM_NCCREATE If, continuing with regular checks // ----------------------------------------------------- switch (message) { case WM_CREATE: createMainWindowControls(); break; case WM_COMMAND: //etc. default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }
Read Entire Article