WM GETDLGCODE

WM_GETDLGCODE，是Windows作業系統內建的一種標準Windows消息。如果使用Windows API函數IsDialogMessage來過濾Windows消息，作業系統在下述情形會發送一條WM_GETDLGCODE消息給對話框或窗體內的控制項：

- 確定控制項是否會處理特定類型輸入。
- 確定編輯框控制項（edit control）的內容是否被選中，如果使用者按了TAB鍵使得這個編輯框控制項收到了輸入焦點（input focus）。
- 確定按鈕（button）類型。

## 參數

WM_GETDLGCODE消息的參數的含義：

- wParam：按鍵輸入的虛擬鍵碼（virtual key）。
- lParam：MSG數據結構的指針或者為NULL（如果系統執行一個查詢）。

## 返回碼

每個預定義控制項的窗口過程對WM_GETDLGCODE消息返回1個或多個下述值，可用布爾OR運算符組合：

返回碼｜解釋

DLGC_BUTTON｜Control is a button (of any kind).

DLGC_DEFPUSHBUTTON｜Control is a default push button.

DLGC_HASSETSEL｜Windows will send an EM_SETSEL message to the control to select its contents.

DLGC_RADIOBUTTON｜Control is an option (radio) button.

DLGC_STATIC｜Control is a static control.

DLGC_UNDEFPUSHBUTTON｜Control is a push button but not the default push button.

DLGC_WANTALLKEYS｜Control processes all keyboard input.

DLGC_WANTARROWS｜Control processes arrow keys.

DLGC_WANTCHARS｜Control processes WM_CHAR messages.

DLGC_WANTMESSAGE｜Control processes the message in the MSG structure that lParam points to.

DLGC_WANTTAB｜Control processes the TAB key.

上述返回值也可用於使用者定義控制項或者子類化（subclassing）的預定義控制項。子類化一個預定義控制項，應該先調用預定義控制項的窗口過程，然後修改返回碼的必要的位元。

## 範例

如果控制項處理WM_GETDLGCODE消息時返回某個DLGC_WANT位元組，控制項將處理指定的消息類型而Windows將對該類型的消息不會做任何默認處理。

例如，下拉列表控制項（list box）處理WM_GETDLGCODE消息返回碼包含了DLGC_WANTARROWS位，指示下拉列表控制項將會處理方向鍵。如果下拉列表控制項有輸入焦點且使用者按下了「向下方向鍵」, Windows發送WM_GETDLGCODE消息給下拉列表控制項。由於返回值包含了DLGC_WANTARROWS值， Windows允許下拉列表控制項處理方向鍵且作業系統不會做任何處理。如果返回值不包含DLGC_WANTARROWS值， Windows將繼續處理方向鍵並且把輸入焦點轉移為下一個控制項。

另一個例子，編輯框控制項返回值包含DLGC_WANTCHARS碼而按鈕控制項返回值則不包含。因此如果一個按鈕控制項有輸入焦點且使用者按下了一個有效的控制項助記符（mnemonic character，顯示為控制項標籤中的加了底劃線的字母）, Windows將設置輸入焦點到該控制項上。如果一個編輯框控制項有輸入焦點且使用者輸入了一個助記符， Windows不會把輸入焦點改到別的控制項因為編輯框控制項會自行處理WM_CHAR消息。

一個控制項處理WM_GETDLGCODE 消息時，如果返回值包含了DLGC_WANTMESSAGE碼，表明應用程式不希望系統默認處理lParam參數中包含的消息。這些消息可以是WM_KEYDOWN, WM_SYSCHAR, WM_CHAR.

下述代碼示例，對檢查框控制項（check box）子類化，處理WM_GETDLGCODE消息，當使用者按下"X"鍵則選中檢查框，如果按下"O"鍵則清除檢查框。

```cpp
   case WM_GETDLGCODE:
      // Call the check box window procedure first
      lRet = CallWindowProc(lpCheckProc, hWnd, wMessage, wParam,
                            lParam);

      // If lParam points to an MSG structure
      if (lParam)
      {
         lpmsg = (LPMSG)lParam;
         if (lpmsg->message == WM_CHAR)
         {
            if (lpmsg->wParam == 'x' || lpmsg->wParam == 'X')
            {
               // Select the check box when user presses "X"
               SendMessage(hWnd, BM_SETCHECK, TRUE, 0);
               lRet |= DLGC_WANTMESSAGE;
            }
            else if (lpmsg->wParam == 'o' || lpmsg->wParam == 'O')
            {
               // Clear the check box when user presses "O"
               SendMessage(hWnd, BM_SETCHECK, FALSE, 0);
               lRet |= DLGC_WANTMESSAGE;
            }
         }
      }
      return lRet;
```

上述代碼使得Windows對X, x, O, o字符的WM_CHAR消息不會做進一步處理，因為WM_GETDLGCODE返回值包含了DLGC_WANTMESSAGE碼。上例中，控制項返回值也可以用DLGC_WANTCHARS代替DLGC_WANTMESSAGE。

下例代碼子類化編輯框控制項，禁止其通過Tab鍵獲得輸入焦點時默認地全部選中編輯框內的文本。

```cpp
     // In the subclass procedure
   case WM_GETDLGCODE:
      // Call the original edit control window procedure
      lRet = CallWindowProc(lpEditProc, hWnd, wMessage, wParam,
                            lParam);

      // Clear the DLGC_HASSETSEL bit from the return value
      lRet &= ~DLGC_HASSETSEL;

      return lRet;
```