我有一个窗口,里面有10个子编辑控件。我想通过按Tab键从一个编辑控件移动到另一个编辑控件 - 我该怎么做?
我的意思是,即使我能找出是否按下了tab键,我如何找到要关注的下一个编辑控件?我希望自己不必跟踪编辑控件,因为我已将它们添加到父窗口中。
PS:“下一步”是指我创建编辑控件的顺序......
编辑:我使用普通的C在Win32上。
编辑2:示例
#include
#define NAME "test"
LRESULT CALLBACK WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
HWND edit1, edit2;
switch (msg)
{
case WM_CREATE:
edit1 = CreateWindow("edit", "", WS_CHILD|WS_VISIBLE, 0, 0, 200, 50, hWnd, NULL, NULL, NULL);
edit2 = CreateWindow("edit", "", WS_CHILD|WS_VISIBLE, 250, 0, 200, 50, hWnd, NULL, NULL, NULL);
return 0;
case WM_CLOSE:
DestroyWindow(hWnd);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASS wc;
wc.style = 0;
wc.lpfnWndProc = WinProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
wc.lpszMenuName = NAME;
wc.lpszClassName = NAME;
RegisterClass(&wc);
HWND win;
win = CreateWindow(NAME, "test", WS_OVERLAPPEDWINDOW, 0, 0, 500, 500, NULL, NULL, hInstance, NULL);
ShowWindow(win, nCmdShow);
UpdateWindow(win);
MSG msg;
while(GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
答案 0 :(得分:3)
对话管理器为你做了很多这样的事情,所以如果你没有充分的理由创建自己的窗口类,你可以考虑改为创建一个对话框。
如果你仍然想要自己动手,你必须拦截 WM_CHAR 并寻找 VK_TAB 和 VK_SHIFT | VK_TAB 即可。对话管理器使用称为“z-order”的东西作为Tab键顺序(http://msdn.microsoft.com/en-us/library/ms632599%28VS.85%29.aspx#zorder)。
FWIW,我的建议是不要低估在尝试在Windows中重新创建现有设施时所承担的负担。对于你所知道的每一种行为,通常至少有你不知道的行为。例如,您的应用程序将如何在基于笔的设备上运行?可访问性扩展如何?屏幕阅读器能够正确处理吗?所有这些东西都已经被烘焙到对话管理器中了。
我不确定我是否跟着......我想 对话框只是一个浮动的窗口 在“常规”(?)之上。是吗 应用程序可能使用的 只是一个对话,而不是正确的 CreateWindow的()?
对话框可以是主应用程序窗口的模态或无模式子项,但它们也可以 主应用程序窗口。这通常称为基于对话框的应用程序。
如果你想要一个基于对话框的应用程序(也就是一个带有对话框作为主窗口的应用程序),你可以这样做:
int WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow )
{
MSG msg;
HWND hDlg = CreateDialog(hInst, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DialogProc);
if (hDlg != NULL)
{
ShowWindow(hDlg, SW_SHOWNORMAL);
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return 0;
}
完整示例可能在此处列出的时间太长,但如果您使用Google for CreateDialog,则应该找到一些示例。
......是否有可能 在对话框中添加其他窗口? 即使使用自定义窗口程序? (换句话说,在对话中,我不是 仅限于默认值 控件,如编辑和静态?)
是的,您可以在对话框中创建自定义控件。在.rc文件的DIALOG部分中,您可以包含以下内容:
CONTROL "",IDC_MYCUSTOM,"MyCtrlClassName",WS_TABSTOP,10,20,30,40
您还可以创建一个新控件并将其动态添加到对话框中(我将以Google为例)。
另外,如果我想自己动手,那怎么样 我能找出下一个控件是什么吗? 我真的不认为会有 比基本桌面更多的用例
如果您想按Tab键顺序浏览对话框中的控件,请使用GetNextDlgTabItem()
:http://msdn.microsoft.com/en-us/library/ms645495%28VS.85%29.aspx
如果你自己动手,那么你可能想要EnumChildWindows()
函数:http://msdn.microsoft.com/en-us/library/ms633494%28VS.85%29.aspx
这可能也很有用:http://msdn.microsoft.com/en-us/library/bb775501%28VS.85%29.aspx
答案 1 :(得分:0)
此类处理可以轻松添加到应用程序中: - 在消息循环中添加对IsDialogMessage()
的调用 - 所有控件都必须具有WS_TABSTOP
样式。
父窗口可能必须是对话框类,因为对话框窗口类存储状态,允许它(例如)在激活丢失和恢复时将焦点恢复到正确的控件。