Using WndProc as a member function of a class

A few things here: someone hinted to me that I should use a wrapper function so I have WndProcWrapper, a "select" function (creates the window), and a WndProc function. Below is my code. Everything looks like it would work perfectly except in my select function, I cannot declare wc.lpfnWndProc = WndProcWrapper; because a value of type "LRESULT(*)()" cannot be assigned to an entity of type "WNDPROC". I'm not all that knowledgeable on winapi stuff (I plan on using Qt after this project though). Is there an easy fix for this problem?
Header declarations:
1
2
static LRESULT WndProcWrapper();
void columnSelect(std::vector<std::string>&);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
LRESULT wndproc::WndProcWrapper()
{
	wndproc *pThis; 
	vector<string> vec;
	pThis->select(vec);
}
void wndproc::select(vector<string>& return)
{
	HINSTANCE hInstance = GetModuleHandle(NULL);
	WNDCLASSW wc = { 0 };
	MSG  msg;

	wc.lpszClassName = L"Selection1";
	wc.hInstance = hInstance;
	wc.hbrBackground = CreateSolidBrush(RGB(0, 0, 255));
	wc.lpfnWndProc = WndProcWrapper;
	wc.hCursor = LoadCursor(0, IDC_ARROW);
	wc.style = CS_DBLCLKS;

	RegisterClassW(&wc);
	CreateWindowW(wc.lpszClassName, L"Selection",
		WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_SYSMENU,
		CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, hInstance, &return);

	while (GetMessage(&msg, NULL, 0, 0)) {

		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
}
LRESULT CALLBACK wndproc::WndProc(HWND hwnd, UINT msg,
	WPARAM wParam, LPARAM lParam) {
	bool checked = true;
	
	HWND text, button, selection1;
	switch (msg) {

	case WM_CREATE: {
		text = CreateWindow("STATIC", "Please select options from below:", WS_VISIBLE | WS_CHILD, 20, 20, 300, 25, hwnd, NULL, NULL, NULL);
		button = CreateWindow("BUTTON", "Submit", WS_VISIBLE | WS_CHILD | WS_BORDER, 500, 500, 80, 25, hwnd, (HMENU)0, NULL, NULL);
		selection1 = CreateWindow("button", "Scan?", WS_VISIBLE | WS_CHILD | BS_CHECKBOX | WS_OVERLAPPED, 500, 460, 350, 20, hwnd, (HMENU)1001, NULL, NULL);
		CheckDlgButton(hwnd, 1001, BST_CHECKED);
		LPCREATESTRUCT lpcs = reinterpret_cast<LPCREATESTRUCT>(lParam);
		vector<string> *strings = reinterpret_cast<vector<string>*>(lpcs->lpCreateParams);
		int j = 40;
		
		checkVectorSize = strings->size();
		for (int i = 1; i != strings->size() + 1; i++)
		{
			CreateWindowA("button", (*strings)[i - 1].c_str(),
				WS_VISIBLE | WS_CHILD | BS_CHECKBOX | WS_OVERLAPPED,
				20, j, 185, 35, hwnd, (HMENU)i,
				NULL, NULL);
			CheckDlgButton(hwnd, 0, BST_UNCHECKED);

			j = j + 30;
		}

		break;
	}
	case WM_COMMAND: {
		int i = wParam;
		if (i == 0)
		{
			for (int j = 0; j != checkVectorSize; j++)
			{
				if (IsDlgButtonChecked(hwnd, j + 1) == true)
				{
					check.push_back(j);//check is a member variable
				}
			}
			if (IsDlgButtonChecked(hwnd, 1001) == true)
			{
				scan = true; //scan is a boolean member variable
			}
			else
			{
				scan = false;
			}
			PostMessage(hwnd, WM_CLOSE, 0, 0);
			break;
		}
		checked = IsDlgButtonChecked(hwnd, i);
		if (checked) {

			CheckDlgButton(hwnd, i, BST_UNCHECKED);
		}
		else {
			CheckDlgButton(hwnd, i, BST_CHECKED);
		}
		break;
	}
	case WM_DESTROY: {

		PostQuitMessage(0);
		break;
	}
	}
	return DefWindowProcW(hwnd, msg, wParam, lParam);
}
Last edited on
A WindowProc must use the CALLBACK calling convention (CALLBACK is a #define for stdcall).

1
2
3
4
5
//declaration:
static LRESULT CALLBACK WndProcWrapper();

//definition:
LRESULT CALLBACK wndproc::WndProcWrapper(){


Also, note that your definition of wndproc::WndProcWrapper() is illegal. pThis is invalid at line 5.
Last edited on
Thank you, I didn't think of that. Should I also leave the CALLBACK in the actual WndProc function?
Also, I don't see why pThis is invalid at line 5.
I still have an error at line 16: '=': cannot convert from 'LRESULT (__stdcall *)(void)' to 'WNDPROC' . I know you get this error when WndProc isn't static or a global function but I used a wrapper function specifically to avoid making it static or global.
Last edited on
Oops. Should have checked the actual signature. WindowProc takes four arguments: https://msdn.microsoft.com/en-us/library/windows/desktop/ms633573(v=vs.85).aspx

Also, I don't see why pThis is invalid at line 5.
You're not giving the pointer any value.
Yes it takes four arguments but I'm not sure what you're suggesting haha. Regarding the pointer, wont it simply be initialized at line 3 and call the wndproc::wndproc default constructor? I'm confused as to what "value" it needs.
I suggest reading a tutorial on pointers. A pointer to a class is not the same thing as an object of that class. There is no class constructor to call.
http://www.cplusplus.com/doc/tutorial/pointers/

Line 3: You declare pThis as an uninitialized pointer.
Line 5: You dereference this uninitialized pointer. This is undefined behavior (most likely will crash).
(I'm not sure what you actually want to do there, but we're just letting you know what you have now is wrong.)

This code example has a different implementation of WndProcWrapper (no idea if it applies to what you're doing):
https://github.com/gkv311/sview/blob/master/StOutPageFlip/StQuadBufferCheck.cpp
Last edited on
I understand. I thought that when I declared a pointer, such as int* i, it would automatically create an int and point to it.
I think that code is a little bit too advanced for me. I don't know why this wrapper thing is so difficult. I figured my "select" method would call the wrapper method and the wrapper would simply pass the four parameters to WndProc but I must not be going about this the right way. I think I'll just give up and find some other way, this is too frustrating.
I think I'll just give up and find some other way, this is too frustrating.
Good idea. Learn first how to write Windows code in the traditional(functional way). Once you have learned this you should be able to write it in OO way.

To learn the basics:
http://www.winprog.org/tutorial/
http://www.functionx.com/win32/index.htm
Topic archived. No new replies allowed.