kirennian 0 Light Poster

I'll start by saying that I've solved the problem I had, I'm just trying to gain an understanding of exactly what caused it in the first place. Please note I'm cutting out as much middle-man code as I possibly can for understanding purposes.

My program is currently setup so that program creation begins in the class 'Main'. I call the usual suspect,

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)

within the .cpp file to start the program. The header and rest of the class is part of the established class 'Main' and as a result, when attempting to call any method within the 'Main' class from the WinMain method, I use a static pointer:

'static Main* g_main'

The only relevant code in this initial WinMain method is the initialization and looping of the 'Main' program cycle.

The problem came about from attempting to create a msgProc for newly created windows which are created in a completely different classes of the program. The resulting msgProcs are established as:

//Beginning of system message handling.  Merely process pointers to this class here via the HWNDs USERDATA chunk of data.
static LRESULT CALLBACK Main::staticMsgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

//Processes all messages relating to the display window, received from the system.
LRESULT Main::msgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

The staticMsgProc merely points to the actual msgProc where all of the code is completed. It is worthy of note that both of these methods are part of the 'Main' class yet due to their nature, when attempting to access any part of the system, I have to use the class pointer to access any members, using the g_main-> prefix (hence the use of two methods aiming toward a single solution). That is why the 'Main' class is in the same class .cpp and .h files as the WinMain method, despite the WinMain method not being a directly linked part of the class. Bleh, that's a mouthful...


The problem arose when attempting to invalidate and restore my system using these msgProcs. Deeper in the bowls of the system, I have a method which modifies a RECT structure to either 0, 0, 0, 0 or 23, 0, 4, 0 and these are the only values which I've put at any time to set the RECT struct. They are set via this method.

//Read the windows positioning.
RECT clientRect;
RECT windowRect;
GetClientRect(displayHandles.at(0).wndHandle, &clientRect);
GetWindowRect(displayHandles.at(0).wndHandle, &windowRect);

//If the displays are to be set as fullscreen.
if(fullScreen == true){
	wndBounds.top = 0;		//Sets north windowBounds.
	wndBounds.left = 0;	//Sets west windowBounds.
	wndBounds.right = 0;	//Sets east windowBounds.
	wndBounds.bottom = 0;	//Sets south windowBounds.
}

//Else the displays are to be windowed.
else{
	wndBounds.top = windowRect.bottom - windowRect.top - clientRect.bottom - GetSystemMetrics(SM_CYFRAME);	//Sets north windowBounds.
	wndBounds.left = GetSystemMetrics(SM_CXFRAME);							//Sets west windowBounds.
	wndBounds.right = 0;										//Sets east windowBounds.
	wndBounds.bottom = 0;										//Sets south windowBounds.
}

After having completed restoration, I set a value (boolean paused) in the 'Main' class to false which has no direct baring on this RECT; in fact, all it does is stops or continues the program loop AFTER I've completed restoration and checked that the values have been set correctly. When setting the code as the following, the program functions 100% accurately, having checked via breakpoints the output of the RECT between these two lines.

g_main->setPaused(false);
break;

If however I forget the g_main pointer, setting the pause value still works correctly yet the RECT, deep and unrelated lower down in the system, completely falls apart.

paused = false;
break;

Setting a breakpoint on the 'paused = false;' line, the RECT value in an unrelated class is 23, 0, 4, 0. When setting the breakpoint on the 'break;' line however, the RECT value has set itself to 0, 0, 4, 0.

Not only is this value not really a possibility in a windowed application, it's been set in between two lines of code which should be executing in sequence and thus a dilemma is born. I realize that not using the pointer was the mistake and the code works fine after rectifying the mistake but I just don't understand how on earth this happened.


Other information:
1)The first line of code in the program is:

CoInitializeEx(NULL, COINIT_MULTITHREADED);

I do not however, have any other multi threading code in place and this is just there to allow XAudio2 to function correctly.

2)The 'setPaused' method contains a single line of code:

//sets a new value for the 'paused' boolean.
void Main::setPaused(bool newPaused){
	paused = newPaused;
}

3)The invalidation and restoration methods are executed 100% accurately prior to these two lines of code messing with this RECT value.

4)The rest of my invalidation and restoration methods work perfectly. This is the only value which is throwing up a random result through the entire program which includes several other uses of other RECT structs.

5)The above code is the ONLY method which can access the RECT which is throwing up errors. It is a private variable so no other classes can access it, even if I wanted them to.

6)Nowherelse in the program were the invalidation and restoration methods called for validation purposes. Even if multithreading was somehow sending multiple messages at once, the only way that inval/rest could be called a second time is if two threads called the very same msgProc message (WM_EXITSIZEMOVE) at the same time and executed somehow while each other were both simultaneously accessing the methods functions... the debug window shows no such signs...


I'm perplexed. On one hand I'm happy to have solved the issue but on the other, I don't like simply throwing out an issue without first completely understanding how it arose in the first place.

Any pointers would be most appreciated...if anymore information is required, please please, just ask. :)

Thanks,

Mark.