關於 WS_TABSTOP,我一直沒搞明白,為何加了 WS_TABSTOP ,當按下 Tab 鍵時,窗口中的控件還是不能自動的切換焦點。
為何 SetFocus(hwnd); 后,雖然按鈕已獲得焦點,但焦點的虛線框不顯示。
關於 BS_DEFPUSHBUTTON,為何加了,在窗體上按下【回車】什么反應都沒有。
過去幾年,我一直都是通過編寫 WM_KEYDOWN 代碼來實現 WS_TABSTOP 和 BS_DEFPUSHBUTTON,今天無意發現一篇文章上有這樣的寫法:
while (GetMessage(&msg, NULL, 0, 0)) { 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);
