Jump to content
  • Advertisement
Sign in to follow this  
Coldon

WIN32: Dialog Help - using a dialog as a wait message

This topic is 3626 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm building an image processing toolkit in win32 (learning win32 as I'm building it unfortunately) and one operation takes forever to complete, so i want to display a title-less dialog that says "please wait" and lock the parent window (disable moving and focus). my dialog:
IDD_WAIT DIALOGEX 0, 0, 147, 38
style DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_SYSMENU
EXstyle WS_EX_TOPMOST
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
    LTEXT           "Decomposing Image - Please Wait",IDC_STATIC,20,15,114,8
END

and am displaying it as follows:
[/
case ID_FILE_CREATEDPTFROMIMAGE :	
				{
					//get filename
					char filename[MAX_PATH] = "";
					getImageFilename(hWnd, filename);
					
					//load image
					if ( imgHandler.loadImage(filename) )
					{					
						//create wait message
						HWND hDlg = CreateDialog( hInst, MAKEINTRESOURCE(IDD_WAIT), hWnd, waitDialogProc );
						ShowWindow(hDlg, SW_SHOW);

						//center dialog
						RECT rect, rectP;
						int width, height;      
						int screenwidth, screenheight;
						int x, y;

						GetWindowRect(hDlg, &rect);
						GetWindowRect(hWnd, &rectP);
					        
						width  = rect.right  - rect.left;
						height = rect.bottom - rect.top;

						x = ((rectP.right-rectP.left) -  width) / 2 + rectP.left;
						y = ((rectP.bottom-rectP.top) - height) / 2 + rectP.top;

						screenwidth  = GetSystemMetrics(SM_CXSCREEN);
						screenheight = GetSystemMetrics(SM_CYSCREEN);
					    
						//make sure that the dialog box never moves outside of
						//the screen
						if(x < 0) x = 0;
						if(y < 0) y = 0;
						if(x + width  > screenwidth)  x = screenwidth  - width;
						if(y + height > screenheight) y = screenheight - height;

						MoveWindow(hDlg, x, y, width, height, FALSE);

						//create FPT object and decompose
						FPT fpt(imgHandler.getImg(), imgHandler.getWidth(), imgHandler.getHeight() );
						fpt.decompose();

						//close wait message
						DestroyWindow(hDlg);

						//updateControls();
					}
					else MessageBox(hWnd, "Invalid Image File!", "Image Load Error", MB_ICONERROR);				
				}
				break;

now i'm having two problems, the first is that the dialog appears but the text doesnt?!?! and i have no idea why... secondly how do i go about "locking" the parent so that the user cant do anything till the process finishes?

Share this post


Link to post
Share on other sites
Advertisement
The dialog text probably isn't appearing because you're creating a modeless dialog, but never ticking it, so messages aren't pumped to it, so the dialog isn't ever redrawn.

As for "locking" the parent window, I don't know if this is possible aside from using a modal dialog instead (DialogBox() instead of CreateDialog()).

However, doing that means that your image processing would have be done in a thread, which I'd recommend anyway - you're effectively trying to do multithreading in a single thread, which obviously won't work [smile]

Share this post


Link to post
Share on other sites
i was considering using a modal just this morning, and running the decomposing function in the dialog effectively locking the main window till the dialog completes.

I've only played around with the basics of threading in windows but I'll take a look at that.

Share this post


Link to post
Share on other sites
Quote:
Original post by Coldon
i was considering using a modal just this morning, and running the decomposing function in the dialog effectively locking the main window till the dialog completes.

I've only played around with the basics of threading in windows but I'll take a look at that.
So long as the main thread isn't touching the data, it should be very straightforwards. Give this a try (Not tested or even compiled):

// Struct to pass to the thread proc. If you only need one parameter, you don't need the struct obviously
struct ThreadParams
{
ImageHandler* pImgHandler;
};

// Your worker thread:
DWORD WINAPI WorkerThreadProc(LPVOID lpParameter)
{
// Get params
ThreadParams* pParams = (ThreadParams*)lpParameter;

// Do work
FPT fpt(pParams->pImgHandler->getImg(), pParams->pImgHandler->getWidth(), pParams->pImgHandler->getHeight());
fpt.decompose();

// Done
return 0;
}

// Spawn a thread...
DWORD dwID;
ThreadParams params;
params.pImgHandler = &imgHandler;
HANDLE hThread = CreateThread(NULL, 0, WorkerThreadProc, &params, 0, &dwID);
if(!hThread)
{
// Error creating thread
}

// Show wait dialog (modal, won't return till dialog is ended)
DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_WAIT), hWnd, waitDialogProc, (LPARAM)hThread);

// Done, cleanup handle
CloseHandle(hThread);




// In your dialog proc:
static HANDLE s_hThread = NULL;
case WM_INITDIALOG:
{
// Store parameter passed in
s_hThread = (HANDLE)lParam;

// Start a timer to make sure this dialog is "ticked" every 100ms
SetTimer(hDlg, 1, 100, NULL);
}
break;

case WM_DESTROY:
{
s_hThread = NULL;
KillTimer(hDlg, 1);
}
break;

case WM_TIMER:
{
// Has thread finished?
if(WaitForSingleObject(hThread, 0) == WAIT_OBJECT_0)
{
// Yup, end dialog
EndDialog(hDlg, 0);
}
}
break;




That should do it (It's a little more complex than I thought...). Basically, you create a thread, then pass that handle to the dialog box. The dialog box starts a timer, and every 100ms it checks if the thread has exited. If it has, then it ends the dialog and returns control to the main application, where you cleanup the handle.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!