检测按钮按Tab键

时间:2014-01-02 12:08:46

标签: winapi visual-c++ event-handling

我正在使用WinAPI创建GUI实用程序。我有两个标签,每个标签都有一些按钮。我正在使用此功能创建按钮:

CreateWindowEx(NULL,"button", "Clear", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
          150, 175, 100, 25, tab_window_2, (HMENU) CLEAR_DATA, instance_handle, NULL);

在Windows proc功能中,我不知道如何检测按下上面的按钮的时间。我还尝试在CLEAR_DATA开关构造中处理WM_COMMAND,如下所示。

switch ( message ) {  
    case WM_COMMAND:{
        switch(LOWORD(wparam)) {

            case CLEAR_DATA : break
    }
}

如何检测和处理被按下的按钮?

我正在创建tab_window_2标签,如下所示:

class frame_window {  
    private:
        LPCSTR window_class_name;  
        HINSTANCE instance_handle;  
        HCURSOR cursor_arrow;  
        HWND window_handle;
        HWND tab_handle;
        HWND tab_window_1;
        HWND tab_window_2;
        HWND current_tab_window;
        RECT client_rectangle;   
    public:
        frame_window(LPCSTR window_class_identity) : window_class_name(window_class_identity) {  
            INITCOMMONCONTROLSEX common_controls; 
            common_controls.dwSize = sizeof(INITCOMMONCONTROLSEX); 
            common_controls.dwICC = ICC_BAR_CLASSES; 
            InitCommonControlsEx(&common_controls); 
            int screen_width = GetSystemMetrics(SM_CXFULLSCREEN);  
            int screen_height = GetSystemMetrics(SM_CYFULLSCREEN);  
            instance_handle = GetModuleHandle(NULL);  

            WNDCLASS window_class = { CS_OWNDC, main_window_proc, 0, 0,    
                                      instance_handle, NULL,    
                                      NULL, NULL, NULL,    
                                      window_class_name };   

            //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++   
            // Create a standard frame window   
            //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++   

            RegisterClass(&window_class);   
            window_handle = CreateWindowEx(WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE,    
                                           window_class_name,    
                                           "IR Remote and Barcode Demo",   
                                           WS_OVERLAPPEDWINDOW | 
                                           WS_CLIPCHILDREN | WS_CLIPSIBLINGS,   
                                           100, 100, screen_width-1600,    
                                           screen_height-490, NULL, NULL,   
                                           instance_handle, NULL);


           //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
            // Get the size of the client rectangle for the window we have just created
            //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
            RECT client_rect; 
            GetClientRect(window_handle, &client_rect); 

            //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
            // Create the tab control window.
            //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

            tab_handle = CreateWindowEx(NULL, WC_TABCONTROL, NULL,
                                        WS_CHILD | WS_VISIBLE,
                                        10, 10, client_rect.right-client_rect.left-20,
                                        client_rect.bottom-client_rect.top-10,
                                        window_handle, NULL, 
                                        instance_handle, NULL);

            // Create three tabs.
            TCITEM tab_info;
            memset(&tab_info, 0, sizeof(tab_info));
            tab_info.mask = TCIF_TEXT;
            tab_info.pszText = "tab#1";
            tab_info.cchTextMax = 5;
            SendMessage(tab_handle, TCM_INSERTITEM, 0, (LPARAM)&tab_info);
            tab_info.pszText = "tab#2";
            SendMessage(tab_handle, TCM_INSERTITEM, 1, (LPARAM)&tab_info);

            RECT tab_rectangle;
            GetClientRect(tab_handle, &tab_rectangle);
            SendMessage(tab_handle, TCM_ADJUSTRECT, FALSE, (LPARAM)&tab_rectangle);

            // Create the tab view windows
            tab_window_1 = CreateWindowEx(NULL, "STATIC", "  ",
                                          WS_CHILD | WS_VISIBLE|SS_OWNERDRAW,
                                          tab_rectangle.left+10, tab_rectangle.top+10, 
                                          tab_rectangle.right-tab_rectangle.left,
                                          tab_rectangle.bottom -tab_rectangle.top,
                                          tab_handle, (HMENU)1, 
                                          instance_handle, NULL);

            SetParent(tab_window_1, window_handle);
            current_tab_window = tab_window_1;
            tab_window_2 = CreateWindowEx(NULL, "STATIC", " ",
                                          WS_CHILD|SS_OWNERDRAW,
                                          tab_rectangle.left+10, tab_rectangle.top+10, 
                                          tab_rectangle.right-tab_rectangle.left,
                                          tab_rectangle.bottom -tab_rectangle.top,
                                          tab_handle, (HMENU)2, 
                                          instance_handle, NULL);


          CreateWindowEx(NULL,"button", "Clear", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
              150, 175, 100, 25, tab_window_2, (HMENU) CLEAR_DATA, instance_handle, NULL);

            SetParent(tab_window_2, window_handle);

            SetCursor(LoadCursor(NULL, IDC_ARROW)); 
            SetWindowLongPtr(window_handle, GWL_USERDATA, (LONG)this);  
            ShowWindow(window_handle, SW_SHOW);   
            UpdateWindow(window_handle); 
        }  
        ~frame_window() {  
            UnregisterClass(window_class_name, instance_handle);   
        }  

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++   
// Windows main entry point   
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++   

int WINAPI wWinMain(HINSTANCE instance_handle, HINSTANCE, LPWSTR, INT) {  
    frame_window main_window("my base window");  
    main_window.run();  
    return 0;   
}

2 个答案:

答案 0 :(得分:0)

用于处理来自按钮的事件的WM_COMMAND必须位于其父窗口的窗口过程中。您的代码会将tab_window_2显示为CLEAR_DATA按钮的父级。

WM_COMMAND代码移到右侧窗口Proc(或Dialog Proc)中。

编辑:我认为您不明白Tab Control的工作原理。 如果您希望每个选项卡视图包含多个虚拟静态控件,则应使用无模式和无边框DialogBox,Tab控件的子项,并根据TCN_SELCHANGE通知显示/隐藏它们。

如果您不需要对话框功能,可以创建常规子窗口(使用RegisterClass / CreateWindow),然后将控件添加为子窗口。

在任何一种情况下,显示/隐藏代码都必须对TCN_SELCHANGE做出反应。

使用常规子窗口或使用对话框,净效果是相同的:您将有一个Window Procedure或Dialog Procadure,其中WM_COMMAND将处理用户操作。

不要与SetParent一起玩。但是,如果你绝对想要它,那么使用:

HWND hWndPushClear = CreateWindowEx(NULL,"button", "Clear", [...]
SetParent( hWndPushClear, window_handle );

然而,您可能会遇到奇怪的 Paint / Focus问题。

编辑:不幸的是,似乎没有好的Tab Control教程。 我建议您更新实际的源代码。作为起点,请执行以下操作:

  1. CreateWindowEx替换为CreateDialog tab_window_1结束tab_window_2(只有一个对话框必须可见)
  2. 取消所有SetParent来电

答案 1 :(得分:0)

您的CreateWindowEx()WM_COMMAND代码似乎正确无误。 所以,

  1. 检查CreateWindowEx()的返回值是否为NULLNULL表示无法创建控件。
  2. 检查父级HWND是否有效。在您的代码中,它是tab_window_2
  3. 此外,如果您不想使用任何WS_EX_XXX样式,则可以使用CreateWindow()

    此代码只是示例。

    LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
    {
    switch(iMessage) {
    case WM_CREATE:
        CreateWindow("button","Clear",WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
            20,20,100,25,hWnd,(HMENU)0,g_hInst,NULL);
        return 0;
    case WM_COMMAND:
        switch(LOWORD(wParam))
        {
        case 0:
            MessageBox(hWnd,"Clear Button Clicked","Button",MB_OK);
            break;
        }
        return 0;
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return(DefWindowProc(hWnd,iMessage,wParam,lParam));
    

    }