Simple window class in a DLL is crashing

hi..
I am a beginner in windows programing using win API. I had created a very simple project that has a windows class with its needed constructor. This project creates a DLL. Then i created another project that call this DLL in order to initiate, create and show the window. But the application is crashing. It is giving a null pointer execption. Please help :)
Below is the code of both projects:

This is the code of the project of DLL:

file BsolWindow.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include "windows.h"

namespace BsolControls {
	class BsolWindows {		
		private:
			HINSTANCE	hInst;
			WNDCLASSEX	BsolWndCls;
			HWND		hWnd;
		public:
			__declspec(dllexport) BsolWindows (LPCWSTR ClassName, LPCWSTR WndTitle);
			__declspec(dllexport) BsolWindows (HINSTANCE hIns, LPCWSTR ClassName, LPCWSTR WndTitle);
			__declspec(dllexport) void BsolSetInstance(HINSTANCE Inst);
			__declspec(dllexport) void BsolSetClassName(LPCWSTR ClassName);
			__declspec(dllexport) void BsolSetWndProc(WNDPROC WndProcName);
			__declspec(dllexport) void BsolWndShow(void);			
	};
}


file BsolWindows.cpp:

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
#include "BsolWindows.h"
#include <stdio.h>
#include <tchar.h>

namespace BsolControls {

	BsolWindows::BsolWindows(LPCWSTR ClassName, LPCWSTR WndTitle) {
		
		hInst = NULL;
		BsolWndCls.cbClsExtra = 0;
		BsolWndCls.cbSize = sizeof(WNDCLASSEX);
		BsolWndCls.cbWndExtra = 0;
		BsolWndCls.hbrBackground = (HBRUSH)(COLOR_WINDOW);
		BsolWndCls.hCursor = LoadCursor(NULL, IDC_ARROW);
		BsolWndCls.hIcon = LoadIcon(NULL, IDI_APPLICATION);
		BsolWndCls.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
		BsolWndCls.hInstance = this->hInst;
		BsolWndCls.lpfnWndProc = NULL; //BsolWndProc;
		BsolWndCls.lpszClassName = ClassName;
		BsolWndCls.lpszMenuName = NULL;
		BsolWndCls.style = NULL;

		if(!RegisterClassEx(&BsolWndCls)) {
			MessageBoxA(NULL, "Grrr!\nCould not register window class!", "ERROR", MB_OK | MB_ICONERROR);
		}
		MessageBoxA(NULL, "Before creating window!", "Note", MB_OK | MB_ICONERROR);

		hWnd = CreateWindowEx(WS_EX_APPWINDOW, ClassName, WndTitle, WS_OVERLAPPEDWINDOW, 0, 0, 300, 400, NULL, NULL, hInst, NULL);
		
		if(hWnd == NULL) {
			MessageBoxA(NULL, "Could not create Window! :(", "ERROR", MB_OK | MB_ICONERROR);
		}
	}

	void BsolWindows::BsolSetInstance(HINSTANCE Inst) {
		this->hInst = Inst;
		this->BsolWndCls.hInstance = this->hInst;
	}

	void BsolWindows::BsolSetClassName(LPCWSTR ClassName) {
		this->BsolWndCls.lpszClassName = ClassName;
	}

	void BsolWindows::BsolSetWndProc(WNDPROC WndProcName) {
		this->BsolWndCls.lpfnWndProc = WndProcName;
	}

	void BsolWindows::BsolWndShow() {
		ShowWindow(hWnd, SW_SHOW);
	}
}


The below code belongs to the project that calls the above DLL code

file BSolutionsApps.cpp:

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
#include "BsolWindows.h"
#include <stdio.h>
#include <tchar.h>

LRESULT CALLBACK BsolWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);

using namespace BsolControls;

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{

	MSG Msg;
	BsolWindows MainWnd = BsolWindows::BsolWindows (TEXT("MainWnd"), TEXT("BSolutions: Main Window"));
	MainWnd.BsolSetInstance(hInst);
	MainWnd.BsolSetWndProc(BsolWndProc);
	
	MainWnd.BsolWndShow();
	
	while(GetMessage(&Msg, NULL, 0, 0))
	{
		TranslateMessage(&Msg);
		DispatchMessage(&Msg);
	}
	return Msg.wParam;

}

LRESULT CALLBACK BsolWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
   switch(message)
   {
   
      case WM_CLOSE:
      
         	DestroyWindow(hWnd);
         
      break;
      
      case WM_DESTROY:
      
         	PostQuitMessage(0);
      break;
      default:
         return DefWindowProc(hWnd, message, wParam, lParam);
   }
   return 0;
}


I'm hopping that someone will help
Thx in advance
Ahmad
anyone can help ??!!!!!
any idea of my problem ?
Sorry, I only had a second to take a quick look at your code, but you are doing quite a lot of things strangely. What you are attempting to do is create a 'custom control'. With custom controls, one registers a class in the dll, and the WndProc for the registered class is also in the dll. You generally will do a LoadLibrary() on the dll, unless you link to it statically. If there are no exports an object of the registered class can be instantiated in the host simply with a CreateWindow() call (provided the class is registered, of course). The CreateWindow() call needs to be in the host - not the dll. The host app acts as a 'container' of the object of the class registered in the dll.I have a tutorial on all this here...

http://www.jose.it-berater.org/smfforum/index.php?topic=2907.0

Later, if I have time, I'll look at what you did in more detail and get back with you.
Last edited on
I had checked out your code and it is intresting.. thanks for help. However, I had found a very simple tutorial that creates a DLL in project1 using microsoft visual studio and then creates a simple application in project2 that uses the DLL. Project2 accessed the DLL without loading it. It was just referenced in project2 properties.
I tried to do the same on my code but it didn't work..
Is there any clue of using your code in visual studio?

below is the link of the tutorial from msdn:
http://msdn.microsoft.com/en-us/library/ms235636(v=VS.90).aspx

Thanks in advance
Ahmad
I feel guilty I didn't put more work into examining your code ahbazzi. I did copy it all and set up the files for an examination of it and compilation; I just didn't continue and let it slide.

To tell the truth, I'm actually somewhat 'put off' with everyone's continual attempts to wrap Windows Apis in C++ OOP syntax. The C Api is very object oriented. Most C++ coders don't seem to recognize it as such however.

I really ought to convert that PowerBASIC code in my link you studied to C++. The only thing that might not work is that in that PowerBASIC code one can easily Register the Window Class through the DLL_PROCESS_ATTACH message that comes into the Dll when it is loaded, whereas I just found out very recently that there *can* be proiblems with that in C++. You might look at this code I just posted today for meesa...

http://www.cplusplus.com/forum/windows/44149/

In that code I create a very simple edit control in a Dll which is used by a host app. There, I had to export an 'Initialize()' function from the Dll which registers the class an object of which is instantiated in the host. The host must first call the Initialize function exported from the Dll. Linking can be either implicit through an export lib, or explicit (the way I did it in the example for meesa) using LoadLibrary() / GetProcAddress().

I do promise to look at your code I originally copied (sorry I let it slide!), and I'll get it working for you, but it may not be until Monday or Tuesday.
Also, the easiest way to get client/server setups involving Dlls working in Visual Studio is through implicit linking where you tell the Visual Studio IDE that one project is a 'dependency' of another. An *.exp and a *.lib file are created through the compilation process of the dll, and in the project properties of the host you have to tell the linker to link against that specific lib file. That way, exported functions in the Dll won't throw linker errors when you call them from the host.

The somewhat unusual circumstance of that PowerBASIC custom control I gave you a link to is that there were NO exported functions. The class for the custom control was registered in the dll, but since a dll is mapped into the process of the host, the host can make a CreateWindow() call on the class registered in the dll without there being any exported functions. That is somewhat atypical though. In the example I made for meesa, there is an exported function (Initialize()).
Last edited on
Just started looking at your code close. The very first thing I noted is that you are attempting to create a window with a CreateWindow() call before you are assigning the address of the Window Procedure. This is a SEVERE error!

When a CreateWindow() or CreateWindowEx() call is made, and before it returns, several messages, among them the WM_CREATE message, will be sent to the Window Procedure registered for the class. In your case Windows will be calling a NULL pointer - therefore your crash.

I personally would not wrap Windows creation machinery in C++ class syntax.
Freddie..
I would like to thank you very much.. your last update had resolved the problem for me.. When I assigned a window procedure before calling CreateWindow(), the code gave desired results..
Beside, I was interested with your customized edit control code that was beneficial for me as well..

I'll contact you soon when I have a new quest :)
Topic archived. No new replies allowed.