[SOLVED]Conflicting Window Focuses

Started by
2 comments, last by TLAK1001 16 years, 3 months ago
I'm finishing up my first video game and am in the process of adding menus. I have a start menu and a game over menu. Each one is a separate dialog box contained within its own state for the game's finite state machine. In windowed mode, everything runs fine, but in full screen, I can only get one menu or the other to show itself at runtime. The other window is not displayed. However, the windows always have focus. I can manipulate the dialogs using the keyboard. Furthermore, if I alt-tab away and then back, there is the dialog box in the corner of my desktop at my development resolution, not the game's resolution! Menu State:

//=============================================================================
// Menu State
//=============================================================================
//------------------------------------------------------------------------
// Menu Dialog Box Callback
//------------------------------------------------------------------------
BOOL CALLBACK MenuDialogProc( HWND hWndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
	switch( uMsg )
	{
	case WM_INITDIALOG:
		//Load the high scores and print them to the dialog
		BringWindowToTop( hWndDlg );
		ShowWindow( hWndDlg, SW_SHOW );
		SetWindowPos( hWndDlg, HWND_TOPMOST, 0, 0, 200, 220, SWP_NOMOVE | SWP_NOSIZE );
		return TRUE;

	case WM_COMMAND:
		switch( wParam )
		{
		case IDOK:
			EndDialog( hWndDlg, 0 );
			g_game->ChangeState( STATE_GAME ); //Start Apache!
			return TRUE;

		case IDCANCEL:
			EndDialog( hWndDlg, 0 );
			PostQuitMessage( 0 ); //Exit the program
			return TRUE;
		}
		break;
	}
	return FALSE;
}

//------------------------------------------------------------------------
// Render the dialog
//------------------------------------------------------------------------
void MenuState::Render()
{
	DialogBox( g_game->GetSetup()->instance, MAKEINTRESOURCE(IDD_MENU), 
		g_game->GetWindow(), MenuDialogProc );
}


Game State:
[source lang = "cpp"]
//=============================================================================
// Game State
//=============================================================================
//------------------------------------------------------------------------
// Load
//------------------------------------------------------------------------
void GameState::Load()
{
	//First, prepare the rendering system
	SetWindowPos( g_game->GetWindow(), HWND_TOP, 0, 0, 
		g_game->GetSetup()->width, g_game->GetSetup()->height, SWP_NOMOVE | SWP_NOSIZE );
	ShowCursor( false );

	m_objMgr = g_game->GetObjectManager();
	m_spriteMgr = g_game->GetSpriteManager();

	m_objMgr->Add( OT_PLAYEROBJECT, m_spriteMgr );
	m_objMgr->Add( OT_CURSOROBJECT, m_spriteMgr );

	//Prepare the game's data
	m_score = 0;

	m_counter = 0.0f;
	m_threshold = 5.0f;
	m_level = 0;

	//Now, let's load the users list of background music
	m_trackList = new LinkedList<Sound>();
	Script* list = new Script( "TrackList.txt", "Assets/" );
	char path[MAX_PATH], title[MAX_PATH];
	int counter = 0;
	Sound* curSound;

	do
	{
		sprintf( title, "song%d", counter++ );
		if( list->GetStringData( title ) == NULL )
			break;
		sprintf( path, "%s", list->GetStringData( title ) );

		curSound = new Sound( path, "" );
		if( curSound != NULL )
			m_trackList->Add( curSound );
	} while( true ); //until path is null and the loop breaks

	m_sound = m_trackList->GetFirst();
	m_sound->GetSegment()->AddNotificationType( GUID_NOTIFICATION_SEGMENT );
	m_sound->Play( false, DMUS_SEGF_AUTOTRANSITION );
}

//------------------------------------------------------------------------
// Close
//------------------------------------------------------------------------
void GameState::Close()
{
	//Don't delete objMgr or spriteMgr - they are part of g_game!
	m_sound->Stop();
	SAFE_DELETE( m_sound );

	m_objMgr->Purge();
	m_spriteMgr->Purge();

	ShowCursor( true ); //Give the user the cursor for dialog boxes
	//ShowWindow( g_game->GetWindow(), SW_BOTTOM );
	SetWindowPos( g_game->GetWindow(), HWND_BOTTOM, 0, 0, 
		g_game->GetSetup()->width, g_game->GetSetup()->height, SWP_NOMOVE | SWP_NOSIZE );
}

//-->Remaining functions deleted for clarity<--


Game Over dialog:
[source lang = "cpp"]
//=============================================================================
// Game Over State
//=============================================================================
//------------------------------------------------------------------------
// Dialog Box Callback
//------------------------------------------------------------------------
BOOL CALLBACK GameOverDialogProc( HWND hWndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
	switch( uMsg )
	{
	case WM_INITDIALOG:
		//Print the users score to 'IDC_SCORE'
		SetWindowPos( hWndDlg, HWND_TOPMOST, 0, 0, 200, 220, SWP_NOMOVE | SWP_NOSIZE );
		BringWindowToTop( hWndDlg );
		ShowWindow( hWndDlg, SW_SHOW );
		return TRUE;

	case WM_COMMAND:
		switch( wParam )
		{
		case IDOK:
			EndDialog( hWndDlg, 0 );
			//Update high scores
			g_game->ChangeState( STATE_MENU );
			return TRUE;

		case IDCANCEL:
			EndDialog( hWndDlg, 0 );
			g_game->ChangeState( STATE_MENU );
			return TRUE;
		}
		break;
	}
	return FALSE;
}

//------------------------------------------------------------------------
// Render the dialog
//------------------------------------------------------------------------
void GameOverState::Render()
{
	DialogBox( g_game->GetSetup()->instance, MAKEINTRESOURCE(IDD_GAMEOVER), 
		g_game->GetWindow(), GameOverDialogProc );
}


By randomly shuffling SetWindowPos, BringWindowToTop, and ShowWindow I can alter which dialog is shown and which one is hidden, as well as at what resolution, but I can't find a corrolation. WTF is going on?!?!?! Thank you in advance, Tlak [Edited by - TLAK1001 on January 9, 2008 10:44:04 AM]
Advertisement
I believe the issue is that you're trying to take over the Window Manager's job: dont try to dictate what window should be on the top and what should be on the bottom, the Window Manager will do that for you.

When you call DialogBox() that dialog is automatically brought to the foreground. You dont need to call BringWindowToTop(), ShowWindow(), or SetWindowPos(). Likewise, you dont need to call SetWindowPos() or ShowWindow() to send any other window to the background.
Fullscreen (DirectX i reckon) doesn't play well with GDI (which is used for dialogs/controls/windows). Reason is the acceleration; GDI doesn't know about double buffering.

There is a function in the Direct3d device (version 7, and onward from 9), SetDialogBoxMode. Call this while you want to display standard Windows dialogs.

If you're using DX8 you're out of luck AFAIK.

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

Thank you

This topic is closed to new replies.

Advertisement