Full Screen Dialogs - Question Mark Crash

Started by
7 comments, last by S1CA 17 years, 8 months ago
Running full screen mode - my open file dialog works fine, except some users have reported that when they click on the helper (that little question mark beside the close button), the program crashes. I've looked, but I can't seem to find a way to disable it. I'm wondering if there's a better semi-standard way to deal with file opening dialogs(or any dialogs) under directx in full screen mode?
Advertisement
Which window messages (WM_*) are you handling, and how?

Also, under what conditions do you call DefWindowProc()?

It sounds like the crash could be down to a problem with the way you're handling or forwarding a message such as WM_SYSCOMMAND.

Could you post your handling for WM_SYSCOMMAND, WM_PAINT and the place where you call DefWindowProc()?


If you get a wParam of SC_CONTEXTHELP when you get a WM_SYSCOMMAND, try returning 0 to tell Windows you've handled the message and it should't do any more processing (such as displaying tooltips or bringing up system help).

Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

Thanks for responding. :)
I tried adding return 0 for SC_CONTEXTHELP, although I'm not sure if what I'm doing is correct. (Now the program exits [unless in windowed mode]) I noticed recently though that the app has no problem with the help thingy when in windowed mode, but when you click on something in full screen, it doesn't really crash but the computer returns to windows and you can't re-enter the app (Although it's still taking input).

I also tried using:
CommDlg_OpenSave_HideControl(g_hwnd, pshHelp);
I've read everything I could find about this, but I still can't figure out how to use it. :(


// D E F A U L T W I N D O W P R O C
LRESULT CALLBACK default_window_proc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
{
switch(msg) {
case WM_SYSCOMMAND: if (wparam==SC_CONTEXTHELP) return 0; //(ADDED)
case WM_CLOSE: g_exit_game=true; PostQuitMessage(0); return 0;
case WM_DESTROY: g_exit_game=true; PostQuitMessage(0); return 0;}
return (DefWindowProc(hwnd,msg,wparam,lparam));
}

.....


#define INPUT_MSG if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {if (msg.message == WM_QUIT) break;TranslateMessage(&msg);DispatchMessage(&msg);}
....

MAIN {
BEGIN_MEMORY_LEAK_CHECK
INIT_WINDOW
INIT_D3D_SIMPLE
INIT_DIRECT_INPUT
// S E T T I N G S :
SET_D3D(D3DRS_LIGHTING, FALSE)
SET_D3D(D3DRS_ZENABLE, FALSE)
....
while(!g_exit_game) {
INPUT_MSG
....
if KEYPRESS(L) {
g_gpu->SetDialogBoxMode(TRUE);
ShowCursor(TRUE);

OPENFILENAME ofn;
char szFileName[MAX_PATH] = "";
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = g_hwnd;
ofn.lpstrFilter = (LPCTSTR)L"3D studio (*.3ds)\0*.3ds\0All Files (*.*)\0*.*\0";
ofn.lpstrFile = (LPTSTR)szFileName;
ofn.nMaxFile = MAX_PATH;
ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
ofn.lpstrDefExt = L"3ds";

//???
//GetDlgItem(g_hwnd,0x000C08B0);//000C08B0);
//ShowWindow(GetDlgItem(g_hwnd,0x000C08B0),SW_HIDE);
//CommDlg_OpenSave_HideControl(g_hwnd, //pshHelp);

if(GetOpenFileName(&ofn)) {
//process the file
.....
}

Keyz.ClearBuffer();
ShowCursor(FALSE);
g_gpu->SetDialogBoxMode(FALSE);
}
if KEYPRESS(ESCAPE) PostMessage(g_hwnd, WM_DESTROY, 0, 0); //Temporary
//track and clip direct input mouse
....
//graphics stuff
....
}
CLEANUP
END_D3D
END_WINDOW
....
DISPLAY_MEMORY_LEAKS
} END
Does your application handle lost devices?

If it's not actually crashing, but your window is minimizing and/or refusing to render any more Direct3D output after the dialog box has been on screen, that's a common symptom of the Direct3D device being lost.

Also, do you process any more window messages other than the ones you've posted?


I just transplanted the message handling and dialog box code from above into a test application, and everything behaves as I'd expect it to - dragging the dialog leaves trails due to not updating on WM_PAINT, closing the dialog works ok, clicking the help icon then clicking around the dialog works ok, clicking the help icon then clicking around the main window works ok...

Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

I'm currently not handling WM_PAINT - I didn't even try moving the dialog before -- thanks for the heads up. My defwinproc is in startup.cpp, so if I add a prototype for render(in main.cpp) and call Render() for WM_PAINT, that should work I'm guessing.

I didn't previously handle LostDevice.
Weird thing is, that is what the problem seems to be, but it seems unable to restore the lost device.
I get this from TestCooperativeLevel:
D3DERR_DEVICENOTRESET
Then I try to reset (default error message as "unable to reset device") and even though reset fails, it does not return any of these three errors: D3DERR_DEVICELOST, D3DERR_DRIVERINTERNALERROR, D3DERR_OUTOFVIDEOMEMORY
Weird.. I did check to make sure everthing was released before and restored after successful reset.
Basically here's what I did:

  INPUT_MSG //handles windows messages//Respond to Direct Input (mouse, keyboard)//....   if KEYPRESS(L) {       g_gpu->SetDialogBoxMode(TRUE);       ShowCursor(TRUE);	       //.... open file stuff       ShowCursor(FALSE); Keyz.ClearBuffer();       g_gpu->SetDialogBoxMode(FALSE);   }   if(DeviceLost) {       Sleep( 100 );       if(FAILED(ghr=g_gpu->TestCooperativeLevel())) {           if(ghr==D3DERR_DEVICELOST) goto skip_graphics;	   if(ghr==D3DERR_DEVICENOTRESET) {	       SAFE_RELEASE(g_font);	       SAFE_RELEASE_ALL_TEXTURES;	       SAFE_RELEASE(g_sprite);	       ghr=g_gpu->Reset(&d3dpp);	       if(FAILED(ghr)) {	           PROBLEM(L"Unable to reset device")		   switch (ghr) {		   case D3DERR_DEVICELOST:                       PROBLEM(L"(Reset FAIL) D3DERR_DEVICELOST"); break;		   case D3DERR_DRIVERINTERNALERROR:                       PROBLEM(L"(Reset FAIL) D3DERR_DRIVERINTERNALERROR");                       break;		   case D3DERR_OUTOFVIDEOMEMORY:                       PROBLEM(L"(Reset FAIL) E_OUTOFVIDEOMEMORY"); break;			   }		   goto skip_graphics;		}		MAKE_SPRITE(g_sprite);		LOAD_ALL_TEXTURES;                D3DXCreateFontIndirect(g_gpu,&FontDesc,&g_font);	    }   	    PROBLEM(L"Unhandled lost device error"); goto skip_graphics;		}        DeviceLost = false;    }    g_gpu->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,0),1.0f,0);    g_gpu->BeginScene();    // .................... bla bla bla .....................    g_sprite->End();    g_gpu->EndScene();    ghr=g_gpu->Present(NULL,NULL,NULL,NULL);    if(ghr==D3DERR_DEVICELOST) DeviceLost = true;skip_graphics:


(It only says: "Unable to reset device")
My guess is it's D3DERR_INVALIDCALL, which you usually get if you don't release all D3DPOOL_DEFAULT resources before resetting the device (And call OnLostDevice() for all D3DX objects that have that member function).

If you install the debug runtimes, you'll be given more helpful information, such as the objects still allocated (if that is the problem).
Yep. That was it. D3DERR_INVALIDCALL.
I forgot that the startup module was setting up a zbuffer and I wasn't releasing it. Thanks guys. :)
I'm now using debug runtimes like you suggested. Strangely I still sortof lose program focus when I click around with the help icon. The help dialog shows up over top of Visual Studio, I click on my running app and exit the dialog and everything now goes back to normal. So at least the program will still run ok once the dialog is closed. :)
I'm thinking my d3d present parameters might have something to do with the problem. I'll check into this.. I'm also going to try writing a hook for a customized open/save and use CommDlg_OpenSave_HideControl(g_hwnd, ?????); to hide the ? help control. Although I've looked around and I don't think pshHelp is the control for this - I think that only works on the help button if the flag for it is enabled. I'll look around and see if I can find the correct control ID. I've also heard you can get it's window(?) and disable it somehow?
Anyway, thanks very much for the help! (^-^)
How does a device get lost?
Quote:Original post by ELFanatic
How does a device get lost?


If another application or Windows needs to use your graphics card or some of the resources on the card (such as video memory), then you can 'lose' your control over the device.

Fullscreen Direct3D applications generally have exclusive control over the graphics card. However if the user of the PC presses Alt-Tab to switch processes or Windows-L to switch active user (fast user switching on XP), then your application can lose its exclusive control over the device.

When your application has regained control after a lost device, you need to destroy and re-create all non-managed pool resources since the thing that caused the lost device may have used the memory that those were previously in.

Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

This topic is closed to new replies.

Advertisement