WNDCLASSEX没有采用WNDPROC参数

时间:2016-05-06 16:10:46

标签: c++ winapi

尝试在这里学习一些WinAPI,并且在将WNDPROC传递给我的wcex.lpfnWndProc时遇到了麻烦,但是我在调​​用MyWinClass时遇到了错误(WNDPROC,LPCWSTR,HINSTANCE);

错误发生在此代码部分底部的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;
}

2 个答案:

答案 0 :(得分:3)

问题不在于你的窗口程序。这是availableID。您的构造函数定义为className,a.k.a,LPCWSTR。但wchar_t const*className的数组,而不是char的数组。您可以通过将其声明为:

来修复错误
wchar_t

但是,您的代码存在大量其他问题,我现在不会介绍。

答案 1 :(得分:2)

您正在以错误的方式混合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;
}