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_BEGINLABELEDITTVN_ENDLABELEDIT 通知代码,您可能需要先添加一些项目到树视图。然后,当您编辑项目的标签时,TRVProc 将收到上述通知代码。添加项目的例子可以参考this官方文档。

【讨论】:

以上是关于win api - 如何为树视图实现单独的事件过程的主要内容,如果未能解决你的问题,请参考以下文章

如何为两个单独的 CreateProcess() API 调用打开单独的命令提示符控制台

如何为 jQuery 列表视图中的特定链接创建点击事件。

如何为 recyclerView 上的两个不同事件设置监听器?

如何为 LOB 应用程序中的多个视图设计 REST API

如何为自定义控件创建事件

我将如何为读写操作实现单独的数据库?