C++ winapi中的WS_TABSTOP在子窗口的编辑控件上

C++ winapi中的WS_TABSTOP在子窗口的编辑控件上,c++,windows,winapi,tabstop,C++,Windows,Winapi,Tabstop,在我的WinAPI应用程序中,我在子窗口中有一系列编辑控件。我希望用户能够通过按tab键向前移动和按住shift键向后移动来在它们之间移动,但我似乎不知道如何在子窗口中使用WS\u TABSTOP。我想要做的是,当用户单击tab键时,随后的编辑控件被选中。但是,当我单击下面代码窗口中的选项卡时,光标就消失了 以下是一个最小的可复制示例: //libraries #pragma comment ("lib", "Comctl32.lib") #pra

在我的WinAPI应用程序中,我在子窗口中有一系列编辑控件。我希望用户能够通过按tab键向前移动和按住shift键向后移动来在它们之间移动,但我似乎不知道如何在子窗口中使用
WS\u TABSTOP
。我想要做的是,当用户单击tab键时,随后的编辑控件被选中。但是,当我单击下面代码窗口中的选项卡时,光标就消失了

以下是一个最小的可复制示例:

    //libraries
#pragma comment ("lib", "Comctl32.lib")
#pragma comment ("lib", "d2d1.lib")


#define WIN32_LEAN_AND_MEAN             // Exclude rarely-used stuff from Windows headers
// Windows Header Files
#include <windows.h>
#include <CommCtrl.h>
// C RunTime Header Files

#include <vector>
#include <string>


#define IDS_APP_TITLE           103
#define IDI_PRACTICE            107
#define IDI_SMALL               108
#define IDC_PRACTICE            109

#define MAX_LOADSTRING          100

// Global Variables:
HINSTANCE hInst;                                // current instance
WCHAR szTitle[MAX_LOADSTRING];                  // The title bar text
WCHAR szWindowClass[MAX_LOADSTRING];            // the main window class name

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK WndProcChild(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

ATOM MyRegisterClass(HINSTANCE hInstance);

HWND childHWND;

HWND InitInstance(HINSTANCE hInstance, int nCmdShow);

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
    _In_opt_ HINSTANCE hPrevInstance,
    _In_ LPWSTR    lpCmdLine,
    _In_ int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);
    // Initialize global strings
    LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadStringW(hInstance, IDC_PRACTICE, szWindowClass, MAX_LOADSTRING);
    MyRegisterClass(hInstance);

    SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);

    // Perform application initialization:
    HWND hWnd = InitInstance(hInstance, nCmdShow);
    if(!hWnd)
    {
        return FALSE;
    }
    HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_PRACTICE));
    MSG msg;
    // Main message loop:
    while (GetMessage(&msg, nullptr, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            if (!IsDialogMessage(hWnd, &msg))
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        }
    }
    return (int)msg.wParam;
}


LRESULT CALLBACK WndProcChild(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_CREATE:
    {
        HWND edit1 = CreateWindow(WC_EDIT, L"", WS_CHILD | WS_BORDER | WS_VISIBLE | WS_TABSTOP, 100, 100, 100, 100, hWnd, (HMENU)1, hInst, NULL);
        HWND edit2 = CreateWindow(WC_EDIT, L"", WS_CHILD | WS_BORDER | WS_VISIBLE | WS_TABSTOP, 300, 100, 100, 100, hWnd, (HMENU)2, hInst, NULL);
        break;
    }
    }
    return DefWindowProc(hWnd, message, wParam, lParam);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;

}

ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEXW wcex;
    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = WndProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInstance;
    wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_PRACTICE));
    wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)(GetStockObject(WHITE_BRUSH));
    wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_PRACTICE);
    wcex.lpszClassName = L"Parent";
    wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));


    //Child wnd class
    WNDCLASSEXW wcexChild;
    wcexChild.cbSize = sizeof(WNDCLASSEX);
    wcexChild.style = CS_HREDRAW | CS_VREDRAW;
    wcexChild.lpfnWndProc = WndProcChild;
    wcexChild.cbClsExtra = 0;
    wcexChild.cbWndExtra = 0;
    wcexChild.hInstance = hInstance;
    wcexChild.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_PRACTICE));
    wcexChild.hCursor = LoadCursor(nullptr, IDC_ARROW);
    wcexChild.hbrBackground = (HBRUSH)(GetStockObject(WHITE_BRUSH));
    wcexChild.lpszMenuName = MAKEINTRESOURCEW(IDC_PRACTICE);
    wcexChild.lpszClassName = L"Child";
    wcexChild.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
    return RegisterClassExW(&wcexChild) && RegisterClassExW(&wcex);
}


HWND InitInstance(HINSTANCE hInstance, int nCmdShow)
{
    hInst = hInstance; // Store instance handle in our global variable
    HWND hWnd = CreateWindowW(L"Parent", L"PARENT", WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, nullptr, nullptr, hInstance, nullptr);

    childHWND = CreateWindowW(L"Child", L"", WS_CHILD | WS_VISIBLE | WS_EX_CONTROLPARENT,
        0, 0, 700, 700, hWnd, nullptr, hInstance, nullptr);

    if (!hWnd)
    {
        return NULL;
    }
    ShowWindow(childHWND, nCmdShow);
    UpdateWindow(childHWND);

    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);
    return hWnd;
}
//库
#pragma注释(“lib”、“Comctl32.lib”)
#pragma注释(“lib”、“d2d1.lib”)
#定义WIN32_LEAN_和_MEAN//从Windows标题中排除很少使用的内容
//Windows头文件
#包括
#包括
//C运行时头文件
#包括
#包括
#定义ID\u应用程序\u标题103
#定义IDI_实践107
#定义IDI_小108
#定义IDC_实践109
#定义最大加载字符串100
//全局变量:
HINSTANCE hInst;//当前实例
WCHAR szTitle[MAX_LOADSTRING];//标题栏文本
WCHAR szWindowClass[最大加载字符串];//主窗口类名称
LRESULT回调WndProc(HWND HWND,UINT消息,WPARAM WPARAM,LPARAM LPARAM);
LRESULT回调WndProcChild(HWND-HWND,UINT消息,WPARAM-WPARAM,LPARAM-LPARAM);
ATOM MyRegisterClass(HINSTANCE HINSTANCE);
孩子们;
HWND InitInstance(HINSTANCE-HINSTANCE,int-nCmdShow);
国际货币基金组织,
_在当前情况下,
_在LPWSTR lpCmdLine中,
_In_uuint(nCmdShow)
{
未引用的_参数(HPPreInstance);
未引用的_参数(lpCmdLine);
//初始化全局字符串
LoadStringW(hInstance、IDS\U APP\U TITLE、szTitle、MAX\U LOADSTRING);
LoadStringW(hInstance、IDC_PRACTICE、szWindowClass、MAX_LOADSTRING);
MyRegisterClass(hInstance);
SetProcessDPIawarenesContext(DPI\U感知\U上下文每\U监视器\U感知\U V2);
//执行应用程序初始化:
HWND HWND=InitInstance(hInstance,nCmdShow);
如果(!hWnd)
{
返回FALSE;
}
HACCEL hAccelTable=装载加速器(hInstance,MAKEINTRESOURCE(IDC_实践));
味精;
//主消息循环:
while(GetMessage(&msg,nullptr,0,0))
{
if(!TranslateAccelerator(msg.hwnd、hAccelTable和msg))
{
如果(!IsDialogMessage(hWnd和msg))
{
翻译信息(&msg);
发送消息(&msg);
}
}
}
返回(int)msg.wParam;
}
LRESULT回调WNDPROCCILD(HWND HWND,UINT消息,WPARAM WPARAM,LPARAM LPARAM)
{
开关(信息)
{
案例WM_创建:
{
HWND edit1=CreateWindow(WC_EDIT,L“”,WS_CHILD | WS|u BORDER | WS|u VISIBLE | WS|u TABSTOP,100100100100,HWND,(menu)1,hInst,NULL);
HWND edit2=CreateWindow(WC_EDIT,L“”,WS_CHILD | WS|u BORDER | WS|u VISIBLE | WS|u TABSTOP,300100100100100,HWND,(HMENU)2,hInst,NULL);
打破
}
}
返回DefWindowProc(hWnd、message、wParam、lParam);
}
LRESULT回调WndProc(HWND HWND,UINT消息,WPARAM WPARAM,LPARAM LPARAM)
{
开关(信息)
{
案例WM_销毁:
PostQuitMessage(0);
打破
违约:
返回DefWindowProc(hWnd、message、wParam、lParam);
}
返回0;
}
ATOM MyRegisterClass(HINSTANCE HINSTANCE)
{
WNDCLASSEXW wcex;
wcex.cbSize=sizeof(WNDCLASSEX);
wcex.style=CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc=WndProc;
wcex.cbClsExtra=0;
wcex.cbWndExtra=0;
wcex.hInstance=hInstance;
wcex.hIcon=LoadIcon(hInstance,MAKEINTRESOURCE(IDI_实践));
wcex.hCursor=LoadCursor(nullptr,IDC_箭头);
wcex.hbrBackground=(HBRUSH)(GetStockObject(WHITE_BRUSH));
wcex.lpszMenuName=MAKEINTRESOURCEW(IDC_实践);
wcex.lpszClassName=L“父级”;
wcex.hIconSm=LoadIcon(wcex.hInstance,MAKEINTRESOURCE(IDI_SMALL));
//小班
WNDCLASSXW wcexChild;
wcexChild.cbSize=sizeof(WNDCLASSEX);
wcexChild.style=CS|HREDRAW | CS|VREDRAW;
wcexChild.lpfnWndProc=WndProcChild;
wcexChild.cbClsExtra=0;
wcexChild.cbWndExtra=0;
wcexChild.hInstance=hInstance;
wcexChild.hIcon=LoadIcon(hInstance,MAKEINTRESOURCE(IDI_实践));
wcexChild.hCursor=LoadCursor(nullptr,IDC_箭头);
wcexChild.hbrBackground=(HBRUSH)(GetStockObject(WHITE_BRUSH));
wcexChild.lpszMenuName=MAKEINTRESOURCEW(IDC_实践);
wcexChild.lpszClassName=L“Child”;
wcexChild.hIconSm=LoadIcon(wcex.hInstance,MAKEINTRESOURCE(IDI_SMALL));
返回RegisterClassExW(&wcexChild)和RegisterClassExW(&wcex);
}
HWND InitInstance(HINSTANCE HINSTANCE,int-nCmdShow)
{
hInst=hInstance;//将实例句柄存储在全局变量中
HWND HWND=CreateWindowW(L“父”,L“父”,WS_重叠窗口,
CW_usefault、CW_usefault、CW_usefault、CW_usefault、nullptr、nullptr、hInstance、nullptr);
childHWND=CreateWindowW(L“Child”,L“”,WS|u Child | WS|u VISIBLE | WS|u EX|u CONTROLPARENT,
0、0、700、700、hWnd、nullptr、hInstance、nullptr);
如果(!hWnd)
{
返回NULL;
}
ShowWindow(儿童乐园、nCmdShow);
更新窗口(childHWND);
显示窗口(hWnd、nCmdShow);
更新窗口(hWnd);
返回hWnd;
}

这里的问题是,
如果(!IsDialogMessage(hWnd,&msg))
在错误的窗口中被调用

如果(!IsDialogMessage(childHWND,&msg))使选项卡导航正常工作,则用
替换该行

从文件中:

尽管IsDialogMessage功能适用于非模态对话框,您可以将其用于包含控件的任何窗口,使窗口能够提供与对话框中相同的键盘选择

在发布的代码中,“包含c的窗口”