I have an EDIT control which I try to subclass and when I do so the entire window is empty:
// Global variables
HINSTANCE hInst;
WNDPROC oldEditWndProc;
INT_PTR CALLBACK EditWndProc(HWND, UINT, WPARAM, LPARAM);
// Messages handler of the parent window
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
HDC hDC;
HWND myedit;
switch (message)
{
case WM_CREATE:
// Create the EDIT control
myedit= CreateWindowEx(
WS_EX_CLIENTEDGE|WS_EX_CONTROLPARENT,
L"EDIT",
L"",
WS_CHILD|WS_VISIBLE|WS_TABSTOP|ES_LEFT,
20, 120,
160, 20,
hWnd,
NULL,
hInst,
NULL
);
oldEditWndProc = (WNDPROC)GetWindowLongPtr (myedit, GWLP_WNDPROC);
// This is the line where problems begin
SetWindowLongPtr (myedit, GWLP_WNDPROC, (LONG_PTR)EditWndProc);
break;
case WM_PAINT:
hDC = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// EDIT control own handler
INT_PTR CALLBACK EditWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
case WM_GETDLGCODE:
return DLGC_WANTTAB;
break;
}
return (INT_PTR)FALSE;
}
I just can't figure out why the entire window is empty when calling SetWindowLongPtr
By "empty" you mean it's not showing on screen?
If yes, it's because when you subclass a Window, all it's messages will be sent to the new MessageProc, which doesn't have all the functions to properly show it in it's defaultProc function (such as WM_PAINT, or even a button click).
So you need something like this:
//store the old window proc somewhere
WNDPROC oldWindowProc = (WNDPROC)SetWindowLong(subWindowHandle, GWL_WNDPROC, long(NewMessageProc));
//and in the message proc
switch(uMsg)
{
//your "case"s here
default:
{
CallWindowProc(oldWindowProc, windowHandle, uMsg, wParam, lParam);
}
}
This will call the proper WM_PAINT and other messages to the messageProc that is responsible for drawing and clicking and other functions (the DefWindowProc() of the subclassed window).
Alternatively you can also just implement the WM_PAINT in your NewMessageProc for all your subclassed windows, but without calling their DefWindowProc you'll need to do for every event they might receive (mousemove, mouse clicks, button clicks, everything), so using their original DefWindowProc is easier.