WNDCLASSEX未采用WNDPROC参数
WNDCLASSEX not taking WNDPROC parameter
试图在这里学习一些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*
。但className
是char
的数组,而不是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;
}
相关文章:
- 如何反转整数参数包
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 如何使用默认参数等选择模板专业化
- 模板参数替换失败,并且未完成隐式转换
- 具有默认模板参数的多态类的模板推导失败
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 函数调用中参数的顺序重要吗
- 部分定义/别名模板模板参数
- 模板-模板参数推导:三个不同的编译器三种不同的行为
- 使用不带参数的函数访问结构元素
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 如何在OMNET++中指定与命令行参数组合的输出文件名
- 如何使用Luacneneneba API正确读取字符串和表参数
- 在派生函数中指定void*参数
- 视图中的参数推导失败:take_while
- static_assert在宏中,但也可以扩展到可以用作函数参数的东西
- 使用指向成员的指针将成员函数作为参数传递
- WNDCLASSEX未采用WNDPROC参数
- 如何从 WndProc 的参数中检索消息发送对象?