win api - 如何为树视图实现单独的事件过程
Posted
技术标签:
【中文标题】win api - 如何为树视图实现单独的事件过程【英文标题】:win api - how to implement a separate events procedure for tree view 【发布时间】:2020-01-07 15:01:37 【问题描述】:我已经使用 WNDCLASSEXW 创建了一个带有事件过程集的主窗口 (CreateWindowEx):
wcex.lpfnWndProc = WndProc;
。
接下来我创建了一个用作树视图的子窗口:
HWND hwndTRV = CreateWindowEx(
WS_EX_CLIENTEDGE,
WC_TREEVIEW,
TEXT("Tree View"),
WS_VISIBLE | WS_CHILD | WS_BORDER | TVS_HASLINES | TVS_EDITLABELS,
0,
0,
rcClient.right,
rcClient.bottom,
hwndParent,
NULL,
hInstance,
NULL);
我想在单独的函数中处理特定于树视图的事件。我使用以下代码:
SetWindowLongPtr(hwndTRV, GWLP_WNDPROC, (LONG_PTR)TRVProc);
我应该如何实现 TRVProc ?这是一个示例代码,TVN_BEGINLABELEDIT 和 TVN_ENDLABELEDIT 事件在 TRVProc 中不可见:
LRESULT CALLBACK TRVProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
switch (message)
case WM_NOTIFY:
LPNMHDR l = (LPNMHDR)lParam;
switch (l->code)
case TVN_BEGINLABELEDIT:
return 0;
case TVN_ENDLABELEDIT:
return 1;
return CallWindowProc(WndProc, hWnd, message, wParam, lParam);
消息循环看起来是这样的:
while (GetMessage(&msg, nullptr, 0, 0))
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
TranslateMessage(&msg);
DispatchMessage(&msg);
【问题讨论】:
阅读这些通知消息的文档。它说的第一件事是它们被发送到树视图的父控件。所以你需要在父窗口的窗口过程中处理这些通知。 另外,在极少数情况下,您确实需要子类化 TreeView 本身来处理内部消息,您应该使用SetWindowSubclass()
而不是 SetWindowLongPtr(GWLP_WNDPROC)
如果您没有子类化,您能否在主窗口的WndProc
中收到TVN_BEGINLABELEDIT
?如果可以,请展示一个迷你、完整且可重现的示例,以便我尝试重现此问题。
嗨,Irbis,如果对此问题仍有任何问题,请随时告诉我。
【参考方案1】:
可以根据文档为树视图实现单独的事件过程:
使用
GWLP_WNDPROC
索引调用SetWindowLongPtr
会创建一个 用于创建窗口的窗口类的子类。一个应用程序 必须将任何未被新窗口过程处理的消息传递给 通过调用CallWindowProc
上一个窗口过程。这允许 应用程序创建一系列窗口过程。
您想替换 父窗口 (hwndParent
) 的默认窗口过程而不是树视图窗口 (hwndTRV
)。所以相关的代码行会是这样的:
SetWindowLongPtr(hwndParent, GWLP_WNDPROC, (LONG_PTR)TRVProc);
此外,要接收TVN_BEGINLABELEDIT
和TVN_ENDLABELEDIT
通知代码,您可能需要先添加一些项目到树视图。然后,当您编辑项目的标签时,TRVProc
将收到上述通知代码。添加项目的例子可以参考this官方文档。
【讨论】:
以上是关于win api - 如何为树视图实现单独的事件过程的主要内容,如果未能解决你的问题,请参考以下文章
如何为两个单独的 CreateProcess() API 调用打开单独的命令提示符控制台