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);

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM