Home > Software engineering >  WIn32API - Subclassing a window, my first attempt
WIn32API - Subclassing a window, my first attempt

Time:10-07

I've been trying to create a child window by subclassing the parent window procedure. I've encountered some really weird behavior that I cannot figure out.

After the CreateWindow() call is made, the code stops executing and immediately jumps to the top of the code-block (which is a WM_CREATE message) and executes everything over again in an infinite loop.

I've never done this before, so I don't know what I'm doing wrong. Here's the code.

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;

Here's the subclass window procedure:

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);
}

The code stops and repeats at:

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

CodePudding user response:

Disclaimer: Everything in this answer is assumption, because we can not see all code.

I hope in this line:

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

szEditorName is not same class name as your parent window. If yes, why you are surprised about infinite loop?

You create parent szEditorName window, in WM_CREATE create child windows, but last window have same class as the parent, so same window procedure, so EditorProc is called again and again and again......

  • Related