我有一个带有编辑控件和自定义按钮的主窗口。当编辑控件具有焦点并按Tab键时,按钮控件会获得焦点,但它永远不会收到WM_UPDATEUISTATE
?我在主窗口的消息循环中使用IsDialogMessage()
。关于为什么会发生这种情况的任何想法?
修改:为什么自定义按钮控件无法接收WM_UPDATEUISTATE
?
修改:IsDialogMessage()
在此示例中未发送WM_UPDATEUISTATE
或WM_CHANGUISTATE
#include <windows.h>
#include <tchar.h>
HINSTANCE g_hInst;
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static HWND hBtn1, hBtn2;
switch(msg)
{
case WM_CREATE:
hBtn1 = CreateWindowEx(0, TEXT("Button"), TEXT("Button 1"), WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
4, 4, 100, 40, hwnd, 0, g_hInst, 0);
if(!hBtn1) return -1;
hBtn2 = CreateWindowEx(0, TEXT("Button"), TEXT("Button 2"), WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
114, 4, 100, 40, hwnd, 0, g_hInst, 0);
if(!hBtn1) return -1;
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
const TCHAR szClassName[] = TEXT("Main////");
WNDCLASSEX wc;
HWND hwnd;
MSG msg;
SecureZeroMemory(&wc, sizeof(WNDCLASSEX));
wc.cbSize = sizeof(WNDCLASSEX);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.hCursor = LoadCursor(0, IDC_ARROW);
wc.hIcon = LoadIcon(0, IDI_APPLICATION);;
wc.hInstance = hInstance;
wc.lpfnWndProc = WndProc;
wc.lpszClassName = szClassName;
if(!RegisterClassEx(&wc)) return 0;
g_hInst = hInstance;
hwnd = CreateWindowEx(0, szClassName, TEXT("Main"), WS_OVERLAPPEDWINDOW, 140, 140, 440, 240, 0, 0, hInstance, 0);
if(!hwnd) return 0;
ShowWindow(hwnd, nCmdShow);
while(GetMessage(&msg, 0, 0, 0) > 0)
{
if(!IsDialogMessage(hwnd, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int)msg.wParam;
}
我在主窗口使用spy ++,在按Tab键时使用了2个按钮,我在任何地方都看不到WM_UPDATEUISTATE
和WM_CHANGEUISTATE
,但是标准按钮控件绘制了焦点rect 。标准按钮如何知道何时绘制焦点矩形?
答案 0 :(得分:0)
具有焦点的窗口应显示其焦点指示器。为此,控件应注意WM_SETFOCUS和WM_KILLFOCUS。当具有焦点时,行为良好的控件将通过向自身发送WM_QUERYUISTATE来检查UI状态,并且,如果UI状态设置了UISF_HIDEFOCUS标志,则该控件将不会绘制焦点指示器。
WM_CHANGEUISTATE和WM_UPDATEUISTATE负责控制窗口树(包括控件)是否应该显示键盘“提示”和焦点指示器 。例如,如果未显示提示,而您单击ALT键,则这些消息将更新树中窗口的UI状态,以便它们开始显示提示。这些消息不用于从一个控件中隐藏焦点指示符,并在用户通过这些控件TAB时将其显示在下一个控件中。之所以会产生这种效果,是因为控件要注意焦点更改消息。
通常来说,自定义控件应监视焦点更改消息,并让DefWindowProc处理UI状态消息。
Raymond Chen拥有一系列有关UI状态以及这些消息如何传播的博客文章。
当我最近再次尝试解决所有这些问题时,我发现这些功能很有帮助。有关该主题的官方文档的当前状态在某些地方还有些模糊和含糊。
注意:即使在Microsoft的官方文档和某些API名称中,术语“助记符”,“加速键”和“热键”也已模糊在一起。当我说“键盘提示”时,我主要是指助记符(有时称为“快捷键”或“访问键”)。这些是控件标签和菜单项中带下划线的字符,使用户知道ALT+<character>
将选择带标签的项。