0
votes

I made a custom Splitter control in pure Windows API. It's made of 4 controls: the main container, the splitter and the 2 panes.

Now I needed to hook into the windows procedure in order to find out when one of its child controls was moving or resizing, so I used SetWindowsHookEx. I get the WM_SIZE messages in my hook procedure just fine, but no WM_MOVE messages are ever caught from my Splitter's child windows.

I tried adding a child window to a Groupbox (which I know isn't the way they're supposed to be used) just to see if the WM_MOVE messages were caught by the hook procedure, and they were.

So what am I missing here? What do I need to add to my Splitter window procedure so those WM_MOVEs get sent? Or was my error somewhere else?

PS: SetWindowPos does work on those child windows, it's just not catching WM_MOVE.

EDIT: As requested, here is the full code of the Splitter window class: http://pastebin.com/Lgvb0Vfv

Here is the part of the code that matters:

LRESULT WINAPI AnchorProc(int nCode, WPARAM wParam, LPARAM lParam) {
    CWPRETSTRUCT* theMessage = (CWPRETSTRUCT*)lParam;

    if (theMessage->message == WM_MOVE) printf ("!");
}    

Sometime after the main window's WM_CREATE:

SetWindowsHookEx(WH_CALLWNDPROCRET,AnchorProc,NULL,GetCurrentThreadId());

// groupbox

HWND gb = CreateWindowEx(0,"button",NULL,BS_GROUPBOX|WS_CHILD,0,0,200,200,hwndMain,0,hInst,NULL);
HWND but = CreateWindowEx(0,"button",NULL,BS_PUSHBUTTON|WS_CHILD,0,0,40,40,gb,0,hInst,NULL);

// custom control

HWND split = CreateWindowEx(0,"FSplitterClass",NULL,WS_CHILD,200,0,200,200,hwndMain,0,hInst,NULL);
HWND pane1 = (HWND)SendMessage(split,WM_SPGETPANE,0,0);
HWND but1 = CreateWindowEx(0,"button",NULL,BS_PUSHBUTTON|WS_CHILD,0,0,40,40,pane1,0,hInst,NULL);

SetWindowPos(but, NULL, 1,1,0,0,SWP_NOSIZE|SWP_NOZORDER); // triggers WM_MOVE
SetWindowPos(but1, NULL, 1,1,0,0,SWP_NOSIZE|SWP_NOZORDER); // doesn't
1
Er, why don't you write your own window proc? - David Heffernan
@Hans, there are many reasons why you would want to know when a control is moving. In my case, I am implementing Anchors. - stelonix

1 Answers

5
votes
  1. A windows hook is overkill here. Subclassing is much more efficient.
  2. WM_MOVE is generated only if the window procedure passes the WM_WINDOWPOSCHANGED message to DefWindowProc. If you cannot guarantee that, then you are not guaranteed a WM_MOVE message. Listen for WM_WINDOWPOSCHANGED.