WIn32API - 子类化 window,我的第一次尝试

WIn32API - Subclassing a window, my first attempt

我一直在尝试通过子类化父 window 过程来创建子 window。我遇到了一些我无法理解的非常奇怪的行为。

CreateWindow() 调用后,代码停止执行并立即跳转到代码块的顶部(这是一条 WM_CREATE 消息)并无限地重新执行所有内容循环。

我以前从来没有这样做过,所以我不知道我做错了什么。这是代码。

LRESULT CALLBACK EditorProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    PAINTSTRUCT ps;
    HDC hdc;
    RECT rect; 
    HWND RichEdit;
    HWND Toolbar;
    HWND ListboxType, ListboxArch;
    HWND hwndBuildButton;
    HWND Labels;

    hdc = GetDC(hwnd);

    GetClientRect(hwnd, &rect);

    switch (message)
    {
    case WM_CREATE:
        LoadLibrary(TEXT ("Msftedit.dll"));
    
        //Create Child Windows

        RichEdit = CreateWindow(MSFTEDIT_CLASS, TEXT("EDITOR"), WS_CHILD | ES_MULTILINE | WS_VISIBLE | WS_BORDER,
            0, 0, 0, 0, hwnd, RichEditorID, GetModuleHandle(NULL), NULL);
        
        Toolbar = CreateWindow(TOOLBARCLASSNAME, NULL, WS_CHILD | TBSTYLE_FLAT, 0, 0, 0, 0, hwnd,
            ToolBarID, GetModuleHandle(NULL), NULL);
        
        ListboxType = CreateWindow(WC_LISTBOX, NULL, WS_CHILD| WS_VISIBLE, 0, 0, 0, 0, Toolbar, ChildID1 + 2,
            GetModuleHandle(NULL), NULL);
        
        ListboxArch = CreateWindow(WC_LISTBOX, NULL, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, Toolbar, ChildID1 + 3,
            GetModuleHandle(NULL), NULL);
        
        hwndBuildButton = CreateWindow(WC_BUTTON, L"Build", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 0, 0, 0, 0, Toolbar, ChildID1 + 4,
            GetModuleHandle(NULL), NULL);

        Labels = CreateWindow(szEditorName,NULL, WS_CHILD, 0, 0, 0, 0, hwnd, ChildID1 + 5,
            GetModuleHandle(NULL), NULL);
        
        OriginalProc = SetWindowLong(Labels, GWL_WNDPROC, LabelProc);

        EnumChildWindows(hwnd, EditorChildProc, (LPARAM)&rect);
        
        return 0;

这是子类 window 过程:

LRESULT CALLBACK LabelProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{   
    HDC hdc;
    PAINTSTRUCT ps;
    TCHAR ArchLabel[] = (L"Architecture:");
    TCHAR BuildLabel[] = (L"Build Type:");
    hdc = GetDC(hwnd);

    switch (message)
    {
    case WM_PAINT:
        hdc = BeginPaint(hwnd, &ps);

        SetTextAlign(hdc, TA_TOP);
        TextOut(hdc, 50, 50, ArchLabel, ARRAYSIZE(ArchLabel));
        TextOut(hdc, 100, 50, BuildLabel, ARRAYSIZE(BuildLabel));
        EndPaint(hwnd, &ps);
        return TRUE;
    }

    ReleaseDC(hwnd, hdc);
    
    return CallWindowProcA(OriginalProc, hwnd, message, wParam, lParam);
}

代码在以下位置停止并重复:

Labels = CreateWindow(szEditorName,NULL, WS_CHILD, 0, 0, 0, 0, hwnd, ChildID1 + 5,
    GetModuleHandle(NULL), NULL);

免责声明:此答案中的所有内容都是假设,因为我们看不到所有代码。

我希望在这一行:

Labels = CreateWindow(szEditorName,NULL, WS_CHILD, 0, 0, 0, 0, hwnd, ChildID1 + 5,
        GetModuleHandle(NULL), NULL);

szEditorName 与您的 parent window 名称不同 class。 如果是,为什么你对无限循环感到惊讶?

你创建parent szEditorName window,在WM_CREATE创建child windows,但是最后 window 与 parent 有相同的 class,所以相同的 window 过程,所以 EditorProc 被一次又一次地调用......