WinAPI无法创建按钮

时间:2018-10-16 16:13:07

标签: c++ winapi

我的问题:我正在尝试在窗口上创建一个按钮。听起来很简单,但没有出现该按钮。窗口已创建,但按钮的CreateWindow函数返回1407:找不到窗口类。我还在创建第二个窗口,但是您可以忽略它。无法弄清楚出什么问题了。请帮助!代码:

#include "windows.h"
#include "CanvasWndProc.h"
#include "resource.h"

#define IDB_LINE 1001

// Main window handle
HWND hMainWindow;
// Canvas window
HWND hCanvasWindow;
// Line button
HWND hButtonLine;

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case(WM_CREATE):

        hButtonLine = CreateWindowEx(0,"ButtonLineClass", "Line", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
            10, 10, 100, 100, hWnd, (HMENU)IDB_LINE, GetModuleHandle(0), NULL);

        break;
    case (WM_DESTROY):

        DestroyWindow(hCanvasWindow);
        DestroyWindow(hButtonLine);
        PostQuitMessage(0);

        break;
    default:
        return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    // MainWindow class
    WNDCLASSEX wc;
    wc.cbSize        = sizeof(wc);
    wc.style         = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc   = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hbrBackground = CreateSolidBrush(RGB(255, 168, 0));
    wc.hInstance     = hInstance;
    wc.lpszClassName = "MainWindowClass";
    wc.lpszMenuName  = NULL;
    wc.hIcon         = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MAINICON));
    wc.hIconSm       = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MAINICON));
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);



    // CanvasWindow class
    WNDCLASSEX wcCanvas;
    wcCanvas.cbSize        = sizeof(wcCanvas);
    wcCanvas.style         = CS_HREDRAW | CS_VREDRAW;
    wcCanvas.lpfnWndProc   = WndProcCanvas;
    wcCanvas.cbClsExtra    = 0;
    wcCanvas.cbWndExtra    = 0;
    wcCanvas.hbrBackground = CreateSolidBrush(RGB(255, 255, 255));
    wcCanvas.hInstance     = hInstance;
    wcCanvas.lpszClassName = "CanvasWindowClass";
    wcCanvas.lpszMenuName  = NULL;
    wcCanvas.hIcon         = LoadIcon(NULL, IDI_WINLOGO);
    wcCanvas.hIconSm       = LoadIcon(NULL, IDI_WINLOGO);
    wcCanvas.hCursor       = LoadCursor(NULL, IDC_ARROW);



    // Register classes
    if (!RegisterClassEx(&wc)) 
    {
        MessageBox(NULL, "It was not possible to register a class!", "Error", MB_OK);
        return NULL;
    }
    if (!RegisterClassEx(&wcCanvas))
    {
        MessageBox(NULL, "It was not possible to register a canvas class!", "Error", MB_OK);
        return NULL;
    }



    // Create and show main window
    hMainWindow = CreateWindowEx(NULL,"MainWindowClass", "VPainter", WS_CLIPCHILDREN | WS_VISIBLE | 
        WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX | WS_OVERLAPPED | WS_SYSMENU, 
        CW_USEDEFAULT, NULL,CW_USEDEFAULT, NULL, NULL, NULL, hInstance, NULL);
    if (!hMainWindow)
    {
        MessageBox(NULL, "It was not possible to create a window!", "Error", MB_OK);
        return NULL;
    }
    ShowWindow(hMainWindow, nCmdShow);
    UpdateWindow(hMainWindow);
    SendMessage(hMainWindow, WM_SYSCOMMAND, SC_MAXIMIZE, 0);



    // Create and show canvas window
    RECT MainWindowSize;
    GetClientRect(hMainWindow, &MainWindowSize);
    hCanvasWindow = CreateWindowEx(NULL, "CanvasWindowClass", NULL, WS_VISIBLE | WS_CHILD,
        MainWindowSize.right - (MainWindowSize.right*0.8), MainWindowSize.bottom - (MainWindowSize.bottom*0.9),
        MainWindowSize.right - (MainWindowSize.right*0.2), MainWindowSize.bottom - (MainWindowSize.bottom*0.1), hMainWindow,
        NULL, hInstance, NULL);
    if (!hCanvasWindow)
    {
        MessageBox(NULL, "It was not possible to create a canvas window!", "Error", MB_OK);
        return NULL;
    }
    ShowWindow(hCanvasWindow, nCmdShow);
    UpdateWindow(hCanvasWindow);

    // MSC loop
    MSG message;
    while (GetMessage(&message, NULL, 0, 0))
    {
        DispatchMessage(&message);
    }

    return message.wParam;
}

1 个答案:

答案 0 :(得分:2)

CreateWindowEx(0, "ButtonLineClass", ...

要创建标准按钮,请使用类名"BUTTON"WC_BUTTON。如果您有自己的自定义类"ButtonLineClass",则它需要自己的类注册和窗口过程。

旁注WndProc应该始终返回一个值。您可以将return DefWindowProc放在过程的末尾。

对于子窗口和子控件,不必调用DestroyWindow。请尝试以下操作:

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg) 
    {
    case WM_CREATE:
        hButtonLine = CreateWindowEx(0, WC_BUTTON, "Line", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
            10, 10, 100, 100, hWnd, (HMENU)IDB_LINE, GetModuleHandle(0), NULL);
        return 0;
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}