WS_TABSTOP 与 BS_DEFPUSHBUTTON 第一次使有

关于 WS_TABSTOP,我一直没搞明白,为何加了 WS_TABSTOP ,当按下 Tab 键时,窗口中的控件还是不能自动的切换焦点。

为何 SetFocus(hwnd); 后,虽然按钮已获得焦点,但焦点的虚线框不显示。

关于 BS_DEFPUSHBUTTON,为何加了,在窗体上按下【回车】什么反应都没有。

过去几年,我一直都是通过编写 WM_KEYDOWN 代码来实现 WS_TABSTOP 和 BS_DEFPUSHBUTTON,今天无意发现一篇文章上有这样的写法: 

while (GetMessage(&msg, NULL, 00)) 
{
        if (!IsDialogMessage(hWnd, &msg))
        {
            TranslateMessage(&msg);

            DispatchMessage(&msg);            
        }
}

 

关于 IsDialogMessage() 介绍:https://docs.microsoft.com/zh-cn/windows/desktop/api/winuser/nf-winuser-isdialogmessagea

 

 

通过下面几段代码,就可实现在窗口上按 Tab 键自动切换焦点, 同时也能实现 【默认按钮】效果:

CreateWindowEx(WS_EX_CLIENTEDGE, "edit", "",
                                      WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL | ES_NUMBER | WS_TABSTOP,
                                      221,   // xpos
                                      101,  // ypos
                                      60, //width
                                      22, //height
                                      hwnd_dialog_four_squares, (HMENU) NULL,   hThisInst,   NULL);

CreateWindowEx(0, "button", "确定",
                                WS_CHILD | WS_VISIBLE |  BS_DEFPUSHBUTTON | WS_TABSTOP, // | WS_DISABLED
                                66, // xpos
                                151, // ypos
                                75, //width
                                25, //height
                                hwnd_dialog_four_squares, (HMENU) IDOK, hThisInst,  NULL);  /** IDOK: 表示这个按钮是当前窗口中的默认按钮, 按下 【回车键】 触发 **/


CreateWindowEx(0, "button", "取消",
                                    WS_CHILD | WS_VISIBLE | WS_TABSTOP,  // | WS_DISABLED
                                    165, // xpos
                                    151, // ypos
                                    75, //width
                                    25, //height
                                    hwnd_dialog_four_squares, (HMENU) IDCANCEL, hThisInst,  NULL);  /** IDCANCEL: 表示这个按钮是当前窗口中的【取消按钮】, 按下 【ESC】 触发 **/

 

dialog_init(hwnd_parent_frame, lpData);

SendMessage(hwnd_b_cancel, BM_SETSTYLE, BS_PUSHBUTTON, TRUE); //如果上一次用户点了【取消】按钮,再次显示窗口的时候,这个【取消】按钮会有边框, 重置一下状态
SendMessage(hwnd_b_ok, BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE); //设置【默认按钮】样式

 

while (GetMessage(&msg, NULL, 0, 0)) 
{
        /*

        提示: IsDialogMessage() + WS_TABSTOP 就可以让窗口上每一个带 WS_TABSTOP 样式的控件自动获取焦点

        ------------------------------------------------------------------------------------------------------------------------

        IsDialogMessage() 资料: https://docs.microsoft.com/zh-cn/windows/desktop/api/winuser/nf-winuser-isdialogmessagea

        尽管 IsDialogMessage 函数适用于无模式对话框,但您可以将其用于包含控件的任何窗口,从而使窗口能够提供与对话框中使用的相同的键盘选择。

        当 IsDialogMessage 处理消息时,它会检查键盘消息并将其转换为相应对话框的选择。例如,按下TAB键时,选择下一个控件或一组控件,按下DOWN ARROW键,选择组中的下一个控件。

        由于 IsDialogMessage 函数执行所有必要的消息转换和分派,因此不能将 IsDialogMessage 处理的消息传递给 TranslateMessage 或 DispatchMessage 函数。

        */
        if(IsDialogMessage(hWnd, &msg))
        {
             // 由对话管理器自动处理

             /** Tab 键自动切换焦点, BS_DEFPUSHBUTTON (默认按钮) 等工作在这里自动完成。 **/
        }
        else
        {
            TranslateMessage(&msg);

            DispatchMessage(&msg);
        }
}

 

如果窗口中有多个嵌套子窗口,在 Tab 键切换焦点的时候,需要给子窗口的父窗口设置为:WS_EX_CONTROLPARENT,相关资料:https://stackoverrun.com/cn/q/338463

 

CreateWindowEx(WS_EX_CONTROLPARENT, "static", "",
                                      WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL | WS_TABSTOP,
                                      221,   // xpos
                                      101,  // ypos
                                      60, //width
                                      22, //height
                                      hwnd_dialog_four_squares, (HMENU) NULL,   hThisInst,   NULL);

 

 

名品推荐:阿季 狼马 牧之逸

转载于:https://www.cnblogs.com/personnel/p/9416393.html

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这个问题需要更多的上下文和细节才能回答。以下是一个简单的示例,在Windows下使用C语言和WinAPI编写一个具有两个按钮的程序,一个按钮将打开另一个程序。 ```c #include <windows.h> #define ID_BUTTON_ONE 1 #define ID_BUTTON_TWO 2 LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { // Register the window class. const char CLASS_NAME[] = "Sample Window Class"; WNDCLASS wc = {0}; wc.lpfnWndProc = WindowProc; wc.hInstance = hInstance; wc.lpszClassName = CLASS_NAME; RegisterClass(&wc); // Create the window. HWND hwnd = CreateWindowEx( 0, // Optional window styles. CLASS_NAME, // Window class "Button Sample", // Window text WS_OVERLAPPEDWINDOW, // Window style // Size and position CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, // Parent window NULL, // Menu hInstance, // Instance handle NULL // Additional application data ); if (hwnd == NULL) { return 0; } // Create the first button. HWND hwndButton1 = CreateWindow( "BUTTON", // Button class "Open Another Program", // Button text WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, // Button style 10, // X position 10, // Y position 200, // Width 50, // Height hwnd, // Parent window (HMENU)ID_BUTTON_ONE, // Button identifier hInstance, // Instance handle NULL // No additional parameters ); // Create the second button. HWND hwndButton2 = CreateWindow( "BUTTON", // Button class "Exit", // Button text WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, // Button style 10, // X position 70, // Y position 200, // Width 50, // Height hwnd, // Parent window (HMENU)ID_BUTTON_TWO, // Button identifier hInstance, // Instance handle NULL // No additional parameters ); // Run the message loop. MSG msg = {0}; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return 0; } LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_COMMAND: { switch (LOWORD(wParam)) { case ID_BUTTON_ONE: // Run the other program. ShellExecute(NULL, "open", "C:\\path\\to\\program.exe", NULL, NULL, SW_SHOWNORMAL); break; case ID_BUTTON_TWO: // Exit the program. DestroyWindow(hwnd); break; } break; } case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, uMsg, wParam, lParam); } return 0; } ``` 这个示例中,我们创建了两个按钮。第一个按钮将打开另一个程序,第二个按钮将退出程序。当用户单击按钮时,将发送 `WM_COMMAND` 消息,我们可以捕获这个消息并根据按钮的ID执行相应的操作。在这个示例中,我们使用 `ShellExecute` 函数来打开另一个程序。 请注意,这只是一个简单的示例,仅用于展示如何创建具有按钮的窗口,并捕获按钮单击事件。实际上,实现程序之间的跳转需要更多的逻辑和代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值