简体   繁体   English

来自TrackBar的WM_VSCROLL / WM_HSCROLL消息不会发送到子类MessageHandler。 为什么?

[英]WM_VSCROLL / WM_HSCROLL message from TrackBar is not sent to the subclassed MessageHandler. Why?

I have a crazy issue. 我有一个疯狂的问题。 I subclassed buttons, richedits, checkboxes,.. and all seems working fine. 我将按钮,richedits,复选框等子类化,并且一切似乎都正常。 But after I subclassed a trackbar I'm having some trouble now. 但是在我将一个轨道栏子类化后,我现在遇到了一些麻烦。 The problem is that my subclassed messagehandler don't receive the WM_VSCROLL / WM_HSCROLL messages. 问题是我的子类消息处理程序没有收到WM_VSCROLL / WM_HSCROLL消息。 They are still sent to the parent's messagehandler. 它们仍然被发送给父母的消息处理程序。 WM_PAINT message and some others are successfully sent to the subclassed messagehanlder. WM_PAINT消息和其他一些消息成功发送到子类消息列表。 Someone knows what I'm doing wrong? 有人知道我做错了什么吗? …And maybe knows how to solve this problem? ......也许知道如何解决这个问题? I created a clean project with the following needed code: 我使用以下所需代码创建了一个干净的项目:

#include <windows.h>
#include <CommCtrl.h>
#pragma comment(lib,"comctl32.lib")

//Prototyps
HWND CreateMainWindow(HINSTANCE hInstance);
LRESULT CALLBACK MessageHandler(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
LRESULT CALLBACK SubMessageHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
WNDPROC oldWndProc;
HWND hWnd = 0;
HWND hTrackBar = 0;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){        
    WNDCLASSEXA wndClass = {sizeof(WNDCLASSEX), CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW, MessageHandler, 0,0, hInstance, LoadIcon(NULL, IDI_WINLOGO),
                            LoadCursor(NULL, IDC_ARROW),(HBRUSH)GetStockObject(WHITE_BRUSH), NULL, "WindowClass", LoadIcon(NULL, IDI_WINLOGO)};
    RegisterClassExA(&wndClass);
    //Creat MainWindow
    hWnd = CreateWindowExA(NULL, "WindowClass", "Test Windows", WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPCHILDREN,             
                            100, 100, 400, 300, NULL, NULL, hInstance, NULL);              
    //Creat Trackbar
    INITCOMMONCONTROLSEX initCtrlEx;
    initCtrlEx.dwSize = sizeof(INITCOMMONCONTROLSEX);
    initCtrlEx.dwICC = ICC_BAR_CLASSES;
    if (InitCommonControlsEx(&initCtrlEx)){
        hTrackBar = CreateWindowExA(NULL,TRACKBAR_CLASSA, "TrackBar_Test",  WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS | TBS_AUTOTICKS | 
                                    TBS_ENABLESELRANGE | TBS_VERT | TBS_BOTH, 10, 10, 50, 200, hWnd, NULL, hInstance, NULL); 
        oldWndProc = (WNDPROC)SetWindowLongPtrA(hTrackBar, GWLP_WNDPROC, (LONG_PTR)SubMessageHandler);  //Subclassing messagehandler
    }
    //Message loop
    MSG msg;
    while (GetMessageA(&msg, NULL, 0, 0))   {   
        TranslateMessage(&msg);
        DispatchMessageA(&msg);
    }
    return 0;
}

LRESULT CALLBACK SubMessageHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){
    switch (msg){
        case WM_VSCROLL: //callback is subclassed but WM_VSCROLL is not send. why?
            MessageBoxA(hWnd, "WM_VSCROLL sent (to SubMessageHandler)", "Test", MB_OK);
            break;
    }
    if (oldWndProc != 0)
        return CallWindowProcA(oldWndProc, hwnd, msg, wParam, lParam);
    else
        return DefWindowProcA(hwnd, msg, wParam, lParam);
}

LRESULT CALLBACK MessageHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){
    switch (msg){       
        case WM_VSCROLL:  //Why the hell is the Trackbar WM_VSCROLL still sent here to the parent callback!?!?
            MessageBoxA(hWnd, "WM_VSCROLL sent (to Parent)", "Test", MB_OK);
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
            break;
    }   
    return DefWindowProcA(hwnd, msg, wParam, lParam);
}

From the MSDN documentation on Trackbar controls : Trackbar控件上的MSDN文档

A trackbar notifies its parent window of user actions by sending the parent a WM_HSCROLL or WM_VSCROLL message. 跟踪栏通过向父组件发送WM_HSCROLL或WM_VSCROLL消息来通知其父窗口用户操作。

The Trackbar's contract is to notify the parent window with WM_HSCROLL / WM_VSCROLL . Trackbar的合同是通过WM_HSCROLL / WM_VSCROLL通知父窗口。 The Trackbar control generates and sends those messages; Trackbar控件生成并发送这些消息; it does not receive them. 它没有收到它们。

Also note that the Default Trackbar Message Processing section does not list WM_HSCROLL / WM_VSCROLL (but does list WM_LBUTTONDOWN , WM_MOUSEMOVE , WM_LBUTTONUP , WM_KEYDOWN , WM_KEYUP , which are the raw messages it would need to handle to handle interaction). 另请注意, 默认轨道栏消息处理部分未列出WM_HSCROLL / WM_VSCROLL (但列出了WM_LBUTTONDOWNWM_MOUSEMOVEWM_LBUTTONUPWM_KEYDOWNWM_KEYUP ,它们是处理交互所需处理的原始消息)。

As for what to do about it, it probably depends on exactly what you want to do. 至于该怎么做,它可能取决于你想要做什么。 You could try subclassing and intercepting all of the user input messages, but that seems like a lot of work and is potentially brittle. 您可以尝试子类化和拦截所有用户输入消息,但这似乎很多工作并且可能很脆弱。 My recommendation would be to have the parent window explicitly reflect WM_HSCROLL / WM_VSCROLL back to your custom Trackbar control. 我的建议是让父窗口明确地将WM_HSCROLL / WM_VSCROLL反映回您的自定义Trackbar控件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM