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

Started by
2 comments, last by Evil Steve 15 years, 9 months ago
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?

"In theory, theory and practice are the same. In Practice, they never are."
My Technical Blog : http://www.takinginitiative.net/

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]
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.

"In theory, theory and practice are the same. In Practice, they never are."
My Technical Blog : http://www.takinginitiative.net/

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 obviouslystruct 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 handleCloseHandle(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.

This topic is closed to new replies.

Advertisement