摘要

以 Windows 為基礎的應用程式通常會顯示資料輸入對話方塊,以向使用者要求資訊。 這些對話方塊可能包含數個編輯控制項,以及兩個命令(推入)按鈕,標示為 [確定] 和 [取消]。 [資料輸入] 對話方塊的範例就是要求使用者輸入個人資訊,例如社會保險號碼、位址、身分識別(ID)號碼、日期/時間等。 這些專案中的每一個都是在編輯控制項中輸入。根據預設,會在對話方塊中使用 TAB 鍵,以將焦點移到 [編輯] 控制項之間。 但作為常見的使用者介面,您也可以使用 ENTER (RETURN)鍵在編輯控制項之間移動(例如,使用者輸入一條資訊之後,按下 ENTER 就會將焦點移到下一個欄位)。有幾種方式可讓您使用 ENTER 鍵在 [編輯] 控制項之間移動。 其中一個方法是在編輯控制項和按鈕的對話方塊中使用 WM_COMMAND 及隨附的通知訊息。 另一種方法是針對編輯控制項進行子類分類。 第三個涉及使用 App Studio 和課程嚮導,並建立新的對話方塊成員函數。

其他相關資訊

方法 I:(WM_COMMAND)

這個方法是以對話方塊的下列行為為基礎(對話方塊管理員),以及 Windows 中的焦點處理。如果對話方塊或其中一個控制項目前有輸入焦點,則按 ENTER 鍵會導致 Windows 傳送 WM_COMMAND 訊息,並將 idItem (wParam)參數設定為預設命令按鈕的識別碼。 如果對話方塊沒有預設的命令按鈕,則 idItem 參數預設會設定為 IDOK。當應用程式收到 idItem 設定為預設命令按鈕識別碼的 WM_COMMAND 訊息時,焦點會保持在按下 ENTER 鍵前擁有焦點的控制項。 在此點呼叫 GetFocus ()會傳回在按下 ENTER 鍵前,擁有焦點的控制項控制碼。 應用程式可以檢查這個控制控制碼,並判斷它是否屬於對話方塊中的任何編輯控制項。 如果有的話,使用者是在其中一個編輯控制項中輸入資料,然後在執行此動作之後,按下 ENTER。 此時,應用程式可以將 WM_NEXTDLGCTL 的訊息傳送到對話方塊,以將焦點移至下一個控制項。不過,如果焦點是使用其中一個命令按鈕([取消] 或 [確定]),則 GetFocus ()會傳回一個按鈕控制項控點,這時,點即可關閉對話方塊。 此邏輯的偽程式碼類似下列在應用程式的對話方塊程式中:

     case WM_COMMAND:     if(wParam=IDOFDEFBUTTON || IDOK) {          // User has hit the ENTER key.          hwndTest = GetFocus() ;          retVal = TesthWnd(hWndTest) ;          //Where retVal is a boolean variable that indicates whether        //the hwndTest is the handle of one of the edit controls.          if(hwndTest) {         //Focus is with an edit control, so do not close the dialog.            //Move focus to the next control in the dialog.         PostMessage(hDlg, WM_NEXTDLGCTL, 0, 0L) ;         return TRUE ;          }          else {            //Focus is with the default button, so close the dialog.            EndDialog(hDlg, TRUE) ;            return FALSE ;          }        }     break ;

Method II

這個方法涉及在對話方塊中將 [編輯] 控制項為子類/superclassing。 只要編輯控制項是 [細分] 或 [superclassed],無論對話方塊是否有預設的命令按鈕,所有的鍵盤輸入都會傳送到目前擁有輸入焦點的編輯控制項的子類/超類程式。 應用程式可以將鑰匙鍵(或 char)訊息補漏白,尋找 ENTER 鍵,並據此進行處理。 下列是尋找 ENTER 鍵的範例子類程式:

   //*-------------------------------------------------------------------   //| Title:   //|     SubClassProc   //|   //| Parameters:   //|     hWnd            - Handle to the message's destination window   //|     wMessage        - Message number of the current message   //|     wParam          - Additional info associated with the message   //|     lParam          - Additional info associated with the message   //|   //| Purpose:   //|     This is the window procedure used to subclass the edit control.   //*---------------------------------------------------------------------   long FAR PASCAL SubProc(HWND hWnd, WORD wMessage,WORD wParam,LONG                           lParam)   {       switch (wMessage)        {             case WM_GETDLGCODE:               return (DLGC_WANTALLKEYS |                       CallWindowProc(lpOldProc, hWnd, wMessage,                                      wParam, lParam));             case WM_CHAR:             //Process this message to avoid message beeps.            if ((wParam == VK_RETURN) || (wParam == VK_TAB))              return 0;               else              return (CallWindowProc(lpOldProc, hWnd,                                        wMessage, wParam, lParam));          case WM_KEYDOWN:               if ((wParam == VK_RETURN) || (wParam == VK_TAB)) {                 PostMessage (ghDlg, WM_NEXTDLGCTL, 0, 0L);                 return FALSE;               }            return (CallWindowProc(lpOldProc, hWnd, wMessage,                                      wParam, lParam));            break ;          default:               break;        } /* end switch */ 

方法 3

這個方法涉及使用 App Studio 及 ClassWizard 並建立新的對話方塊成員函數。這個方法可讓使用者按 ENTER 鍵,並將焦點移到下一個編輯控制項。 如果焦點目前在對話方塊中的最後一個編輯控制項上,則焦點會移至第一個編輯控制項。首先,使用 App Studio 變更對話方塊 [確定] 按鈕的識別碼。 App Studio 的預設行為是將 [確定] 按鈕設為 [識別碼 IDOK]。 [確定] 按鈕的識別碼應該變更為其他值,例如 [IDC_OK]。 此外,您也可以變更 [確定] 按鈕的屬性,使其不是預設的按鍵。接著,使用 ClassWizard 建立新的對話方塊成員 funciton。 將新的成員函數命名為 OnClickedOK。 此函數應與來自 IDC_OK 控制項的 BN_CLICKED 訊息相關聯。完成這項操作後,請撰寫 OnClickedOK 函數的主體。 您應該將您通常會放入 OnOK 函數中的程式碼放入新的 OnClickedOK 函數中,包括類別的 OnOK 函數。在對話方塊的標頭檔中新增下列原型:

   protected:      virtual void OnOK();

在對話方塊中新增 OnOK 函數,程式碼如下所示:

   void CMyDialog::OnOK()   {        CWnd* pwndCtrl = GetFocus();        CWnd* pwndCtrlNext = pwndCtrl;        int ctrl_ID = pwndCtrl->GetDlgCtrlID();        switch (ctrl_ID) {            case IDC_EDIT1:                pwndCtrlNext = GetDlgItem(IDC_EDIT2);                break;            case IDC_EDIT2:                pwndCtrlNext = GetDlgItem(IDC_EDIT3);                break;            case IDC_EDIT3:                pwndCtrlNext = GetDlgItem(IDC_EDIT4);                break;            case IDC_EDIT4:                pwndCtrlNext = GetDlgItem(IDC_EDIT1);                break;            case IDOK:                CDialog::OnOK();                break;            default:                break;        }        pwndCtrlNext->SetFocus();   }

Need more help?

Want more options?

探索訂閱權益、瀏覽訓練課程、瞭解如何保護您的裝置等等。

社群可協助您詢問並回答問題、提供意見反應,以及聆聽來自具有豐富知識的專家意見。