Strange behaviour of CreateWindowEx within hiearchy causes VTable corruption?

Hi all,
I am working on an object-oriented wrapper class hierarchy for the Win32 GUI API.
I have been experiencing strange behavior after I implemented mix-in classes providing window text wrapper functions.

This is what my hierarchy looks like now:

[Base class : Window] --virtual--> UserWindow --------------> Frame (Inherits HasText and Window) --> MainFrame
+-----------virtual--> HasText (mix in class)------^

Window defines a static Base_WndProc procedure which process WM_NCCREATE and sets the window's user data to the classes this pointer. It then does this->WndProc, where this->WndProc is a virtual WndProc function which takes a this pointer.
The this pointer is sent to Base_WndProc by means of the lpCreateParams member of the CREATESTRUCT structure.

This worked fine, until I changed Frame to inherit UserWindow and HasText. Then, the vtable of the MainFrame object seemed to have been corrupted or something. Base_WndProc is called correctly, and then retrieves the correct this pointer.

The problem occurs here :

1
2
3
4
CREATESTRUCT* cs=(CREATESTRUCT*)lParam;
Window* pWindow=(Window*)cs->lpCreateParams;
SetWindowLongPtr(hWnd, GWL_USERDATA, (LONG)pWindow);
return pWindow->WndProc(hWnd, uMsg, wParam, lParam);  // Dereferencing of NULL pointer occurs (vtable entry = 0) 


In my WinMain, the calling code:
1
2
3
4
5
6
7
8
9
	MainFrame frm;
	frm.WndProc(NULL, NULL, NULL, NULL); // succeeds in calling MainFrame::WndProc
	Window* pw=(Window*)&frm;
	CREATESTRUCT cs;
	cs.lpCreateParams=(void*)pw;
	Window::Base_WndProc(NULL, WM_NCCREATE, NULL, (LPARAM)&cs); // succeeds in calling MainFrame::WndProc
	frm.Register();
	frm.Create(320, 200); // CreateWindowProc fails to call MainFrame::WndProc.
	frm.Show(SW_SHOWDEFAULT);


This debugging information might help : http://pastebin.com/h3NzqPiP

And the source is here :
https://github.com/zsteve/hard86/tree/master/src/interface/win32/generic/src
This problem involves window, userwindow, frame, main.cpp/h
I'm going to go ahead and state the obvious, I didn't compile this. But let's be honest here, you didn't really expect anyone to did you?

But based on your description and what I would call a fair look at your code, it looks like you have what's called a "diamond problem" with your base classes "Create()" function: http://www.cprogramming.com/tutorial/virtual_inheritance.html
 
frm.WndProc(NULL, NULL, NULL, NULL);


Please tell me you aren't trying to call the Window Procedure yourself?

@freddie1 : I'm attempting to call frm::WndProc to see if the virtual call works (it does). Attempting to call Window::Base_WndProc with WM_NCCREATE and cs.lpCreateParams=&frm for the same reason. Both succeed.

The only problem is within Base_WndProc, as aforementioned:
1
2
3
4
CREATESTRUCT* cs=(CREATESTRUCT*)lParam;
Window* pWindow=(Window*)cs->lpCreateParams;
SetWindowLongPtr(hWnd, GWL_USERDATA, (LONG)pWindow);
return pWindow->WndProc(hWnd, uMsg, wParam, lParam);  // Dereferencing of NULL pointer occurs (vtable entry = 0) 


I really don't understand how the virtual call succeeds when called from WinMain but fails when called from Base_WndProc.
@ OP: I told you why, did you bother to read the site I linked to? Your program isn't failing on the call to WndProc, it's failing on your call to "Create()" because it is ambiguous. Rename the function to something unique and see what happens. Or you could read the article.
Topic archived. No new replies allowed.