WNDCLASSEX未采用WNDPROC参数

WNDCLASSEX not taking WNDPROC parameter

本文关键字:WNDPROC 参数 WNDCLASSEX      更新时间:2023-10-16

试图在这里学习一些WinAPI,但在向我的wcex传递WNDPROC时遇到了问题;

错误出现在此代码部分底部的WinMain函数中。

我正在学习的来源是1998年,但它是最直观的(对我个人来说),它一直在用扩展版本WNDCLASSEX、CreateWindowEx等取代旧版本,如WNDCLASS

#include <Windows.h>
#include <string>
using namespace std;
LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
class MyWinClass
{
public:
    MyWinClass(WNDPROC winProc, LPCWSTR className, HINSTANCE hInst);
    void Register()
    {
        ::RegisterClassEx(&wcex);
    }
private:
    WNDCLASSEX wcex;
};
MyWinClass::MyWinClass(WNDPROC winProc, LPCWSTR className, HINSTANCE hInst)
{
    wcex.style = 0;
    wcex.lpfnWndProc = winProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInst;
    wcex.hIcon = 0;
    wcex.hCursor = LoadCursor(0, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wcex.lpszMenuName = 0;
    wcex.lpszClassName = className;
}
class CreateMyWindow
{
public:
    CreateMyWindow() : _hwnd(0){}
    CreateMyWindow(char const * caption, char const * className, HINSTANCE hInstance);
    void ShowWindow(int cmdShow)
    {
        ::ShowWindow(_hwnd, cmdShow);
        ::UpdateWindow(_hwnd);
    }
protected:
    HWND _hwnd;
};
CreateMyWindow::CreateMyWindow(char const * caption, char const * className, HINSTANCE hInstance)
{
    _hwnd = ::CreateWindowEx(
        (DWORD)className,
        (LPCWSTR)caption,
        WS_OVERLAPPED,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        0,
        0,
        NULL,
        hInstance,
        0);
}

//MyWindow Procedure that is called by windows
LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, char * cmdParam, int cmdShow)
{
    char className[] = "Winnie";
    MyWinClass myWinClass(WindowProcedure, className, hInst);
    /*Error: no Instance of constructor "MYWinClass::MYWinClass" mat  the argument list argument types are:(LRESULT _stdcall(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) char[7], HINSTANCE)
//MyWinClass myWinClass(WindowProcedure...) us underlined with above error, and I do not know why it is seeing WNDPROC as an HWND.*/
    myWinClass.Register();
    CreateMyWindow myWndClass("MyWindowClass", className, hInst);
    myWndClass.ShowWindow(cmdShow);
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}

问题不在于您的窗口过程。它与className有关。您的构造函数被定义为接受LPCWSTR,也就是wchar_t const*。但classNamechar的数组,而不是wchar_t的数组。您可以通过将这个错误声明为:来修复它

wchar_t className[] = L"Winnie";

然而,您的代码中还有许多其他问题,我现在不会深入讨论。

您以不正确的方式混合了ANSI和Unicode数据,并且某些类型转换是错误的。试试类似的东西:

#include <Windows.h>
LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
class MyWinClass
{
public:
    MyWinClass(WNDPROC winProc, LPCTSTR className, HINSTANCE hInst);
    void Register()
    {
        ::RegisterClassEx(&wcex);
    }
private:
    WNDCLASSEX wcex;
};
MyWinClass::MyWinClass(WNDPROC winProc, LPCTSTR className, HINSTANCE hInst)
{
    wcex.style = 0;
    wcex.lpfnWndProc = winProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInst;
    wcex.hIcon = 0;
    wcex.hCursor = LoadCursor(0, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wcex.lpszMenuName = 0;
    wcex.lpszClassName = className;
}
class CreateMyWindow
{
public:
    CreateMyWindow() : _hwnd(0){}
    CreateMyWindow(LPCTSTR caption, LPCTSTR className, HINSTANCE hInstance);
    void ShowWindow(int cmdShow)
    {
        ::ShowWindow(_hwnd, cmdShow);
        ::UpdateWindow(_hwnd);
    }
protected:
    HWND _hwnd;
};
CreateMyWindow::CreateMyWindow(LPCTSTR caption, LPCTSTR className, HINSTANCE hInstance)
{
    _hwnd = ::CreateWindowEx(
        0,
        className,
        caption,
        WS_OVERLAPPED,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        NULL,
        NULL,
        hInstance,
        NULL);
}

//MyWindow Procedure that is called by windows
LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, char * cmdParam, int cmdShow)
{
    TCHAR className[] = TEXT("Winnie");
    MyWinClass myWinClass(WindowProcedure, className, hInst);
    myWinClass.Register();
    CreateMyWindow myWndClass(TEXT("MyWindowClass"), className, hInst);
    myWndClass.ShowWindow(cmdShow);
    MSG msg;
    while (::GetMessage(&msg, NULL, 0, 0))
    {
        ::TranslateMessage(&msg);
        ::DispatchMessage(&msg);
    }
    return msg.wParam;
}

或者:

#include <Windows.h>
LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
class MyWinClass
{
public:
    MyWinClass(WNDPROC winProc, LPCWSTR className, HINSTANCE hInst);
    void Register()
    {
        ::RegisterClassExW(&wcex);
    }
private:
    WNDCLASSEXW wcex;
};
MyWinClass::MyWinClass(WNDPROC winProc, LPCWSTR className, HINSTANCE hInst)
{
    wcex.style = 0;
    wcex.lpfnWndProc = winProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInst;
    wcex.hIcon = 0;
    wcex.hCursor = LoadCursor(0, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wcex.lpszMenuName = 0;
    wcex.lpszClassName = className;
}
class CreateMyWindow
{
public:
    CreateMyWindow() : _hwnd(0){}
    CreateMyWindow(LPCWSTR caption, LPCWSTR className, HINSTANCE hInstance);
    void ShowWindow(int cmdShow)
    {
        ::ShowWindow(_hwnd, cmdShow);
        ::UpdateWindow(_hwnd);
    }
protected:
    HWND _hwnd;
};
CreateMyWindow::CreateMyWindow(LPCWSTR caption, LPCWSTR className, HINSTANCE hInstance)
{
    _hwnd = ::CreateWindowExW(
        0,
        className,
        caption,
        WS_OVERLAPPED,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        NULL,
        NULL,
        hInstance,
        NULL);
}

//MyWindow Procedure that is called by windows
LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, char * cmdParam, int cmdShow)
{
    WCHAR className[] = L"Winnie";
    MyWinClass myWinClass(WindowProcedure, className, hInst);
    myWinClass.Register();
    CreateMyWindow myWndClass(L"MyWindowClass", className, hInst);
    myWndClass.ShowWindow(cmdShow);
    MSG msg;
    while (::GetMessage(&msg, NULL, 0, 0))
    {
        ::TranslateMessage(&msg);
        ::DispatchMessage(&msg);
    }
    return msg.wParam;
}