**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"键则清除检查框。

```
 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键获得输入焦点时默认地全部选中编辑框内的文本。

```
 // 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;

```

参考文献
----

1. ↑ .  [2017-03-09]. （原始内容存档于2017-05-06）.
2. ↑ .  [2017-03-09]. （原始内容存档于2017-05-17）.