Code Review: Windows API Wrapper Class Problem

I am learning Windows API. My project is an attempt to wrap Windows API in a System class for future DirectX development. When I run my code, I get the error, "Unhandled Execption at 0x763AD298 (user32.dll) in Project1.exe: 0xC0000005: Access violation reading location 0xCCCCCCC." at RegisterClassEx function in the System.cpp file.

Thank you in advance for you time helping me resolve my coding error.


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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
 /**************/
/*  System.h  */
/**************/

#pragma once
#include <Windows.h>

class System
{
public:
	System(HINSTANCE);  
	~System(void);
	bool InitilizeWindow(bool);										//Initialize , register, show, and update the class
	static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);	//Message Processing
	WPARAM Run();													//Windows Application Loop

public:
	HINSTANCE hInstance;
	HWND hwnd;
	MSG msg;
	WNDCLASSEX wcex;
	LPCSTR  className;
	RECT rc;
};



/**************/
/*  System.cpp  */
/**************/

#include "System.h"
#include <Windows.h>



System::System(HINSTANCE instance)
{
	hwnd = 0;
	hInstance = instance;
	LPCSTR className = "D3D Application";
}

bool System::InitilizeWindow(bool b3dApplication) {
	
	//Set Class
	wcex.cbSize = sizeof(WNDCLASSEX);
	wcex.cbClsExtra = 0;
	wcex.cbWndExtra = 0;
	wcex.hbrBackground = (HBRUSH) GetStockObject(LTGRAY_BRUSH);
	wcex.hCursor = LoadCursor(hInstance, IDC_ARROW);
	wcex.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
	wcex.hIconSm = LoadIcon(hInstance, IDI_APPLICATION);
	wcex.hInstance = hInstance;
	wcex.lpfnWndProc = WndProc;
	wcex.lpszClassName = className;
	wcex.style = CS_HREDRAW | CS_VREDRAW;
	
	//Register Windows Class
	//Error Unhandled Execption at 0x763AD298 (user32.dll) in Project1.exe: 0xC0000005: Access violation reading location 0xCCCCCCC.
	if(!RegisterClassEx(&wcex)) { return false; }

	//Create Window
	hwnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, className, "D3DApplication", WS_BORDER, CW_USEDEFAULT, CW_USEDEFAULT, 
		640, 480,
		NULL, NULL, hInstance, 0);

	if(!hwnd) { return false; }

	//Show Window and Update Window
	ShowWindow(hwnd, SW_SHOW);
	UpdateWindow(hwnd);

	return true;
}

LRESULT CALLBACK System::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {

	switch(msg){
	case WM_CLOSE:
		DestroyWindow(hwnd);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hwnd, msg, wParam, lParam);
	}
	return 0;
}

WPARAM System::Run(){
	while(GetMessage(&msg, hwnd, 0, 0 ) != 0) {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return msg.wParam;
}

System::~System(void)
{
}



/**************/
/* Main.cpp  */
/**************/

#include <Windows.h>
#include "System.h"


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);

	System EngineWindow(hInstance);

	if(!EngineWindow.InitilizeWindow(false)) { return -1; }



	return static_cast<int> (EngineWindow.Run()); //static_cast<int>( msg.wParam );
}

Last edited on
You should finish initializing members of wcex (there's no reason for it to be a class member) before calling registerclassex.

And, it's spelled initialize.
Cire, thanks for your response.

I fixed my misspelling, finished initializing wcex member functions, and moved the WNDCLASSEX wcex System object from class to function internal object inside System::InitializeWindow.

I am still receiving the same error. I tested the code by stripping it from a class into a normal windows program and it worked perfectly. I have a hunch that the error is because of my class structure.

Here is my source code again with changes. (I annotated your changes in the comments)


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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/**************/
/*  System.h  */
/**************/

#pragma once
#include <Windows.h>

class System
{
public:
	System(HINSTANCE);  
	~System(void);
	bool InitializeWindow();   //Initialize , register, show, and update the class
	static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);	//Message Processing
	WPARAM Run();    //Windows Application Loop

private:
	//WNDCLASSEX wcex;     //Cplusplus User Cire's Correction: Removed from Class member to InitializeWindow Function
	HINSTANCE hInstance;
	HWND hwnd;
	MSG msg;
	LPCSTR  className;
	RECT rc;
};


/**************/
/*  System.cpp  */
/**************/

#include "System.h"
#include <Windows.h>



System::System(HINSTANCE instance)
{
	hwnd = 0;
	hInstance = instance;
	LPCSTR className = "D3D Application";
}

bool System::InitializeWindow() {
	
	WNDCLASSEX wcex;		//Cplusplus User Cire's Correction: Moved WNDCLASSEX object from private class object to function internal

	//Set Class
	wcex.cbSize = sizeof(WNDCLASSEX);
	wcex.cbClsExtra = 0;
	wcex.cbWndExtra = 0;
	wcex.hbrBackground = (HBRUSH) GetStockObject(LTGRAY_BRUSH);
	wcex.hCursor = LoadCursor(hInstance, IDC_ARROW);
	wcex.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
	wcex.hIconSm = LoadIcon(hInstance, IDI_APPLICATION);
	wcex.hInstance = hInstance;
	wcex.lpfnWndProc = WndProc;
	wcex.lpszClassName = className;
	wcex.lpszMenuName = NULL;                       //Cplusplus User Cire's Correction: Initialized missing wcex lpszMenuName
	wcex.style = CS_HREDRAW | CS_VREDRAW;

	//Register Windows Class
	//Error Unhandled Execption at 0x763AD298 (user32.dll) in Project1.exe: 0xC0000005: Access violation reading location 0xCCCCCCC.
	if(!RegisterClassEx(&wcex)) { return false; }
	
	//Create Window
	hwnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, className, "D3DApplication", WS_BORDER, CW_USEDEFAULT, CW_USEDEFAULT, 
		640, 480,
		NULL, NULL, hInstance, 0);

	if(!hwnd) { return false; }

	//Show Window and Update Window
	ShowWindow(hwnd, SW_SHOW);
	UpdateWindow(hwnd);

	return true;
}

LRESULT CALLBACK System::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {

	switch(msg){
	case WM_CLOSE:
		DestroyWindow(hwnd);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hwnd, msg, wParam, lParam);
	}
	return 0;
}

WPARAM System::Run(){
	while(GetMessage(&msg, hwnd, 0, 0 ) != 0) {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return msg.wParam;
}

System::~System(void)
{
}

/**************/
/* Main.cpp  */
/**************/

#include <Windows.h>
#include "System.h"


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);

	System EngineWindow(hInstance);

	if(!EngineWindow.InitializeWindow()) { return -1; }



	return static_cast<int> (EngineWindow.Run()); //static_cast<int>( msg.wParam );
}
Last edited on
Further researching the problem, I have identified the issue is variable LPSTR className.

I assigned className as type LPSTR, which is incorrect according to my complier and I am not sure what type is acceptable.

Can anyone please provide me with a solution to the described problem? I would accept a resource that describes the differences between char*, string*, LPSTR, LPCSTR, LPCESTR,...ect and how to implemented these types in windows API.
In:

1
2
3
4
5
6
System::System(HINSTANCE instance)
{
	hwnd = 0;
	hInstance = instance;
	LPCSTR className = "D3D Application";
}


You set a local variable className which hides the data member className to "D3D Application." The actual data member className is a wild pointer that points somewhere random in memory.

Great catch.

I implemented LPCSTR className as a private class member variable, therefore I removed the LPCSTR from the System::System(HINSTANCE instance).

The System::System(HINSTANCE instance) portion of the code now reads as follows,

1
2
3
4
5
6
System::System(HINSTANCE instance)
{
	hwnd = 0;
	hInstance = instance;
	className = "D3D Application";
}


Works as intended.
Thanks


Topic archived. No new replies allowed.