Home > Software design >  In WIndows API, under what "event" do I put child control creation or why aren't my c
In WIndows API, under what "event" do I put child control creation or why aren't my c

Time:11-04

It's been years since I last worked with Windows API and I'm trying my hand at it again. I have a simple Window (with title "Test"). I put in the Window message handler under WM_CREATE, 2 CreateWindow calls to create a static and an edit control. I'm pretty sure the coordinates are decent (not overlapping or off the window rectangle). Am I putting the calls under the wrong event? It's just a simple window - not MDI or SDI or anything like that. Here is my code for the entire program. I hope it's sufficient to figure out what I'm doing wrong. I'm using Eclipse CDT with Cygwin's G compiler to build it....:

#include <windows.h>

BOOL InitApplication(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE hinstance, int nCmdShow);
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

BOOL InitApplication(HINSTANCE hInstance)
{
    WNDCLASS wc;

    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = MainWndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName = "";
    wc.lpszClassName = "MainWindow";

    return(RegisterClass(&wc));
}

BOOL InitInstance(HINSTANCE hinstance, int nCmdShow)
{
    HINSTANCE hCurInstance = hinstance;
    HWND hWnd = CreateWindow("MainWindow", "Test", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, (HWND)(NULL), (HMENU)(NULL), hCurInstance, (LPVOID)(NULL));

    if(!hWnd)
        return(FALSE);

    // Show the window and send a WM_PAINT message to the window
        // procedure.

        ShowWindow(hWnd, nCmdShow);
        UpdateWindow(hWnd);

        return(TRUE);
}

LRESULT CALLBACK MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
        {
        case WM_CREATE:
            CreateWindow("WC_STATIC", "&Test: ", SS_LEFT | WS_VISIBLE | WS_CHILD, 10, 10, 50, 20, hWnd, NULL, (HINSTANCE)(GetWindowLongPtr(hWnd, GWLP_HINSTANCE)), (LPVOID)(NULL));
            CreateWindow("WC_EDIT", "", WS_BORDER | WS_TABSTOP | WS_VISIBLE | WS_CHILD | ES_LEFT, 60, 10, 50, 20, hWnd, NULL, (HINSTANCE)(GetWindowLongPtr(hWnd, GWLP_HINSTANCE)), (LPVOID)(NULL));
            return(0);
        default:
            return(DefWindowProcA(hWnd, uMsg, wParam, lParam));
        }
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmd, int nCmdShow)
{
    BOOL fGotMessage;
    MSG msg;

    if(!InitApplication(hInstance))
            return(FALSE);

    if(!InitInstance(hInstance, nCmdShow))
            return(FALSE);

    while(((fGotMessage = GetMessage(&msg, (HWND) NULL, 0, 0)) != 0) && (fGotMessage != -1))
        {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
        }

    return(msg.wParam);
}

CodePudding user response:

You are using the wrong class names for the child controls, and not checking the result of those CreateWindow() calls for failures. Had you done so, you would have noticed that CreateWindow() was returning NULL, and GetLastError() was reporting ERROR_CANNOT_FIND_WND_CLASS (1407).

You need to replace "WC_STATIC" with "Static", and replace "WC_EDIT" with "Edit". Or, you can use the pre-defined WC_STATIC and WC_EDIT constants that are defined in commctrl.h.


On a side note: your GetMessage() loop can be simplified to just:

while (GetMessage(&msg, (HWND) NULL, 0, 0))

See: When will GetMessage return -1?

  • Related