Reputation: 57
trying to learn some WinAPI here and running into trouble passing a WNDPROC to my wcex.lpfnWndProc, it's all fine in the decleration but I get an error when I call MyWinClass(WNDPROC, LPCWSTR, HINSTANCE);
The error is in the WinMain function at the bottom of this code section.
The source I am learning from is dated 1998, but it has been the most intuitive(For me personaly), it have been replacing older versions such as WNDCLASS with the extended versions WNDCLASSEX, CreateWindowEx etc...
#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;
}
Upvotes: 0
Views: 1122
Reputation: 595329
You are mixing ANSI and Unicode data in incorrect ways, and some of your type-casts are wrong. Try something more like this instead:
#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;
}
Or:
#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;
}
Upvotes: 2
Reputation: 103693
The issue is not your window procedure. It is with className
. Your constructor is defined to take LPCWSTR
, a.k.a, wchar_t const*
. But className
is an array of char
, not an array of wchar_t
. You can fix this error by declaring it as:
wchar_t className[] = L"Winnie";
However, you have a myriad of of other problems with your code that I won't go into at this time.
Upvotes: 3