// Handles window messages. LRESULT CALLBACK DemoApp::WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { LRESULT result = 0; if (message == WM_CREATE) { LPCREATESTRUCT pcs = (LPCREATESTRUCT)lParam; DemoApp *pDemoApp = (DemoApp *)pcs->lpCreateParams; ::SetWindowLongPtrW( hwnd, GWLP_USERDATA, PtrToUlong(pDemoApp) ); result = 1; } else { DemoApp *pDemoApp = reinterpret_cast<DemoApp *>(static_cast<LONG_PTR>( ::GetWindowLongPtrW( hwnd, GWLP_USERDATA ))); bool wasHandled = false; if (pDemoApp) { switch (message) { case WM_SIZE: { UINT width = LOWORD(lParam); UINT height = HIWORD(lParam); pDemoApp->OnResize(width, height); } result = 0; wasHandled = true; break; case WM_DISPLAYCHANGE: { InvalidateRect(hwnd, NULL, FALSE); } result = 0; wasHandled = true; break; case WM_PAINT: { pDemoApp->OnRender(); ValidateRect(hwnd, NULL); } result = 0; wasHandled = true; break; case WM_DESTROY: { PostQuitMessage(0); } result = 1; wasHandled = true; break; } } if (!wasHandled) { result = DefWindowProc(hwnd, message, wParam, lParam); } } return result; }
I am studying the example code found here:
Creating a Simple Direct2D Application (Windows)
My first question is in regards to the block:
if (message == WM_CREATE) { LPCREATESTRUCT pcs = (LPCREATESTRUCT)lParam; DemoApp *pDemoApp = (DemoApp *)pcs->lpCreateParams; ::SetWindowLongPtrW( hwnd, GWLP_USERDATA, PtrToUlong(pDemoApp) ); result = 1; }
If I understand correctly if the message is WM_CREATE "lParam" is used to create a "*pDemoApp" that appears to be loaded with members that belong to "DemoApp *app" that was created in WinMain. Then "*pDemoApp" is used to set user data. I think I understand that much but I am a little unclear why this is being done.
DemoApp *pDemoApp = reinterpret_cast<DemoApp *>(static_cast<LONG_PTR>( ::GetWindowLongPtrW( hwnd, GWLP_USERDATA )));
The block above if I understand correctly is used to get user data from the window. Again it is a little unclear to me why this has to be done in this way. It is also not fully clear to me what exactly user data is or why the set and get methods have to make use of a pointer.
I'm hoping to get some further explanation of the internals of the code and why it is the way that it is.
Thanks for any help on this...