【问题标题】:Custom controls and windows messages自定义控件和窗口消息
【发布时间】:2011-10-30 20:59:30
【问题描述】:

我在纯 Windows API 中制作了一个自定义拆分器控件。它由 4 个控件组成:主容器、拆分器和 2 个窗格。

现在我需要挂钩到 windows 过程,以便找出其中一个子控件何时移动或调整大小,因此我使用了 SetWindowsHookEx。我的钩子程序中的 WM_SIZE 消息很好,但没有从我的拆分器的子窗口中捕获任何 WM_MOVE 消息。

我尝试将子窗口添加到 Groupbox(我知道这不是它们应该使用的方式),只是为了查看钩子过程是否捕获了 WM_MOVE 消息,他们是。

那么我在这里错过了什么?我需要在拆分器窗口过程中添加什么以便发送那些 WM_MOVE?还是我的错误在其他地方?

PS:SetWindowPos 确实适用于那些子窗口,只是没有捕捉到 WM_MOVE

编辑:根据要求,这里是拆分器窗口类的完整代码:http://pastebin.com/Lgvb0Vfv

下面是重要的代码部分:

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

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

在主窗口的 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

【问题讨论】:

  • 呃,你为什么不写你自己的window proc?
  • @Hans,您想知道控件何时移动的原因有很多。就我而言,我正在实施 Anchors。

标签: c windows winapi hook


【解决方案1】:
  1. windows 钩子在这里是多余的。子类化效率更高。
  2. WM_MOVE 仅生成 if the window procedure passes the WM_WINDOWPOSCHANGED message to DefWindowProc。如果你不能保证,那么你不能保证 WM_MOVE 消息。监听 WM_WINDOWPOSCHANGED。

【讨论】:

  • 按钮控件在作为 groupbox 的子项时生成 WM_MOVE,但在作为我的自定义容器控件的子项时不会生成 WM_MOVE(它只是将鼠标输入转发到父窗口过程并在所有其他,如您在代码中所见)。虽然我只是将其子类化,但我想知道我的自定义控件有什么问题。是什么根本不同使得它的孩子不发送 WM_MOVE 消息?
  • 你确定它真的移动了吗?一个窗口是相对于它的父窗口定位的,所以如果相对位置没有改变,它就不会被认为已经移动了。另外,我认为如果您仔细观察,您会发现该按钮严格来说不是 groupbox 的 a.child。它可能只是 z 顺序中较低的兄弟。
  • 是的。此外,groupbox 是父级,您可以在上面的 CreateWindowEx 调用中看到它。无论哪种方式,我现在都在进行子类化,并将这些问题留到其他时间。
猜你喜欢
  • 1970-01-01
  • 2013-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多