[SOLVED] DirectX9 and GDI Dialog Box

Started by
4 comments, last by amarhys 17 years ago
Hello, I am working on a Direct3D game (a myst-like game) and my game engine embeds a game editor. This game editor allows to create the game database (for example it helps to create a new click zone and to affect an action to this new click zone). It is a collection of different tools based on GDI dialog boxes (animation editor, inventory object editor, sound editor ....). All these tools can be launched when playing the game entering a special edition mode (in this mode, Direct3D graphics are still rendered and GDI dialog boxes are displayed on top of them). In one of my GDI dialog boxes (animation editor), I want to display a basic animation (sequence of bitmap managed by a multimedia timer) using StretchDiBits GDI function. When I do that, regular refreshing of the GDI dialog box (result of regular <invalidateRect> of the zone of the Dialog Box where the animation is played) causes all the screen to be redrawn after having been full discarded in black (instead of only the refresh zone of the dialog box) => it creates an awful flickering. Is there something to do to avoid that ? Thank you in advance for your answer and sorry for my poor English (I am French) Cheers Amarhys [Edited by - amarhys on April 19, 2007 9:20:26 AM]
Advertisement
1. Does IDirect3DDevice9::SetDialogBoxMode make any difference?

2. If this is a windowed mode application, how are you handling WM_PAINT messages recieved by the window that Direct3D uses? If it contains any calls to D3D, check the window handle to make sure that you only handle paint messages for it for the D3D window and not for other windows (such as the dialog box).

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

Thanks for your answer S1CA.

1. No, IDirect3DDevice9::SetDialogBoxMode does not change anything.

2. WM_PAINT message of the main window (D3D window) does nothing, it only enables 3D rendering (indeed, I noticed that I cannot render D3D graphics until the main windows enters WM_PAINT a first time) :

BOOL renderOK = FALSE;.........case WM_PAINT:    // Wait for first PAINT    if (!renderOK) {        renderOK = TRUE;    }			    break;



All D3D rendering is done outside the message loop :

while (gameStatus == GAME_OK){	// Handle messages	if (PeekMessage (&msg,NULL,0,0,PM_REMOVE))        {            TranslateMessage (&msg);            DispatchMessage (&msg);        }		        // Render Display	if (renderOK) 	    updateAndRender();}


Regards
Amarhys
Are you passing a handle to your window in the InvalidateRect function? If you pass NULL as the handle, it will invalidate every window currently open.
Yes, I am passing the handle to the dialog box which displays the animation to InvalidateRect function.

Some part of code which manages the dialog box

......#define ANIM_POS_X		320#define ANIM_POS_Y		20#define ANIM_WIDTH		240#define ANIM_HEIGHT		240MMRESULT animTimer;int nbAnimFrame;int curAnimFrame;......//-----------------------------------//   Animation timer//-----------------------------------void CALLBACK AnimTimerProc(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2){    HWND hDlg = (HWND)dw1;    // Get next frame    if (curAnimFrame < nbAnimFrame-1)        curAnimFrame = curAnimFrame+1;    else        curAnimFrame = 0;    // Update display    RECT rt = { ANIM_POS_X, ANIM_POS_Y, ANIM_POS_X+ANIM_WIDTH, ANIM_POS_Y+ANIM_HEIGHT };    InvalidateRect(hDlg, &rt, false);}......//--------------------------------------//// Message handler for Dialog Box////--------------------------------------LRESULT CALLBACK EdtAnim(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam){    ...    ...    PAINTSTRUCT ps;    HDC hdc;    ...    ...    switch (message)    {        //---------------------------        //    Init        //---------------------------        case WM_INITDIALOG:            ..            ..            nbAnimFrame  = 10;            curAnimFrame = 0;            ..            ..            return TRUE;           //---------------------------        //    Command parsing        //---------------------------        case WM_COMMAND:            ..            ..            //-------------------------            //     Play anim button            //-------------------------            if (LOWORD(wParam) == IDC_EANIM_PLAYANIM) {                                // Set anim timer		animTimer = timeSetEvent(200, 5, AnimTimerProc,(DWORD)hDlg, TIME_PERIODIC);            }            break;        //--------------------------        //    Paint        //--------------------------        case WM_PAINT:            hdc = BeginPaint(hDlg, &ps);	    StretchDiBits( .....);            EndPaint(hDlg, &ps);            break;    }        return FALSE;}


Cheers
Amarhys
I found the error, in fact the handle I am passing to InvalidateRect is not correct.

I should retrieve it from dwUser and not from dw1 in my timer callback.

Thanks to all of you for your help.

Cheers
Amarhys

This topic is closed to new replies.

Advertisement