|
|
Look up WM_USER in the help text. This is a #defined constant in the Windows header files that is always equal to the highest Windows message ID. Thus, you can safely define your own IDs starting at WM_USER + 1.
Beware, however, that some Windows common controls use IDs above WM_USER, so what I have done use WM_USER + 1000, + 1001, + 1002, etc., and I have not had any problems.
Scott
|
|
|
|
|
Hi. I am trying to create a pop up loading message. Something like the MessageBox function would do, but no buttons will be visible or enabled until done loading. The app is dialog based. Loading/Done loading will be controled in the main window, and the pop up will be a modal simply to prevent any action from the user in the main window until done loading. Is this possible? Thanks in advance.
|
|
|
|
|
one way is to use a modeless dialog.
::EnableWindow(hwndMain, FALSE);
...create/show modeless status dialog...
...do loading
...destroy modeless status dialog...
::EnableWindow(hwndMain, TRUE);
|
|
|
|
|
I created a new dialog in the resource editor, called IDD_LOADING, and created a new class for it called CLoading.
To create it, I have this code in the main dialog.
EnableWindow(FALSE);
CLoading *pLoadingDlg = new CLoading;
pLoadingDlg->Create(IDD_LOADING,this);
How do I destroy it? Something like this?
CLoading::DestroyWindow();
EnableWindow(TRUE);
|
|
|
|
|
This is what I'd do:
pLoadingDlg->DestroyWindow();
delete pLoadingDlg;
pLoadingDlg = 0;
EnableWindow(TRUE);
|
|
|
|
|
So after implementing the create and destroy loading window, it didn't show up. So I added the line
pLoadingDlg->ShowWindow(SW_SHOW);
Now the window shows up, but when done loading, and the window is destroyed, the focus doesn't return to the main window. How can I fix that? I tried usins popup and overlap style, and it has the same problem. Using the child style, the loading window doesn't even show up.
-- modified at 18:56 Monday 27th November, 2006
|
|
|
|
|
acerunner316 wrote: after implementing the create and destroy loading window, it didn't show up
For the dalog resource: Style should be Child. Set the Visible property to TRUE.
acerunner316 wrote: when done loading, and the window is destroyed, the focus doesn't return to the main window
Try this:
HWND hwndOldForeground = ::GetForegroundWindow();
EnableWindow(FALSE);
CLoading *pLoadingDlg = new CLoading;
pLoadingDlg->Create(IDD_LOADING,this);
...
...
pLoadingDlg->DestroyWindow();
delete pLoadingDlg;
pLoadingDlg = 0;
EnableWindow(TRUE);
if (hwndOldForeground)
{
::SetForegroundWindow(hwndOldForeground);
hwndOldForeground = 0;
}
|
|
|
|
|
Setting the style to child does not work. The popup window does not show up at all. The Visible property is already checked.
The code to SetForeground code does not work. I also tried SetFocus(), but that didn't work either. Any other clever ideas?
|
|
|
|
|
hmmm I tested the code before I posted it.
Are you using the correct parent window when creating the dialog window?
|
|
|
|
|
How do i know if i'm using the correct parent window?
When created the "loading..." dialog window, i just inserted a new dialog in the resource editor. And then opened class wizard to generate a new class for the new dialog. And the rest of the code, you pretty much know already.
|
|
|
|
|
You are passing "this" as the parent. I don't know what class you are creating the dialog in.
For example, if it is a CFrameWnd derived then you may need to pass the client window as the
parent.
pLoadingDlg->Create(IDD_LOADING,this);
By the way, as Scott mentioned, child windows do get disabled when you disable the parent.
This doesn't affect the visiblility of any windows. I disabled the main window in my example to
prevent the user from doing anything until the operation completes, which is the Microsoft
recommended method. Of course, you can do what you want with the UI as you need to.
This does work
Here's the dialog resource I tested with:
IDD_STATUS DIALOGEX 0, 0, 186, 25<br />
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_CHILD | WS_VISIBLE<br />
EXSTYLE WS_EX_STATICEDGE<br />
FONT 8, "MS Shell Dlg", 400, 0, 0x1<br />
BEGIN<br />
CTEXT "Test Status",IDC_STATIC,15,7,156,12<br />
END
|
|
|
|
|
this is what i have:
pLoadingDlg->Create(IDD_LOADING,this);
IDD_LOADING is configured as Style: child, Border: dialog frame, title bar, visible, tool window.
Is this correct? The Loading dialog still doesn't show up. But the main window is disabled as expected. I can't click anything during the loading time.
|
|
|
|
|
acerunner316 wrote: IDD_LOADING is configured as Style: child, Border: dialog frame, title bar, visible, tool window.
OK for reference, I tested with the same except no title bar and no toolwindow.
What I'm wondering is in this line
pLoadingDlg->Create(IDD_LOADING,this);
What class "this" points to? Where are you calling this from and what class is the window
derived from?
|
|
|
|
|
this is called in a function belonging to the main dialog's class.
|
|
|
|
|
acerunner316 wrote: this is called in a function belonging to the main dialog's class.
and called from what function?
|
|
|
|
|
Called from yet another function belonging to the same class. I only have one class because everything have been in one dialog box until now.
|
|
|
|
|
acerunner316 wrote: Called from yet another function belonging to the same class.
OK, my point is, as long as you're not creating it in the class' WM_CREATE handler or OnInitDialog()
override it should show.
Are you creating the dialog, doing the processing, and destroying the dialog all in one function?
If so, then you could try this:
...
pLoadingDlg->Create(IDD_LOADING,this);
Invalidate(FALSE);
UpdateWindow();
....do processing
...destroy dialog as usual
|
|
|
|
|
Yes i am creating, processing and destroying all in one function. But on different calls of the function. Therefore, the pointer to CLoading has to be static.
I've tried your new node, it works! But the dialog box is created in the upper left corner of the main dialog box. How can I position it so that it pops up in the center like with the popup and overlap styles?
|
|
|
|
|
acerunner316 wrote: How can I position it so that it pops up in the center like with the popup and overlap styles?
Center of the main dialog?
You could set the Center style to TRUE or move the dialog yourself:
pLoadingDlg->Create(IDD_LOADING,this);
CRect MainDialogRect, LoadDialogRect;
GetClientRect(&MainDialogRect);
pLoadingDlg->GetWindowRect(&LoadDialogRect);
pLoadingDlg->MoveWindow((MainDialogRect.Width() - LoadDialogRect.Width()) / 2,
(MainDialogRect.Height() - LoadDialogRect.Height()) / 2,
LoadDialogRect.Width(), LoadDialogRect.Height());
*EDIT* Fixed the MoveWindow call heh :laugh:
-- modified at 21:55 Monday 27th November, 2006
|
|
|
|
|
The center style seems to center the child dialog relative to the screen and not to the main window.
The code you provided positioned the child dialog where I wanted, except for one problem. The controls in the main dialog appear to overlap the "loading" dialog. I know that controls are considered child windows as well. So how to I make the "loading" dialog on top of the other child dialogs?
|
|
|
|
|
Instead of MoveWindow...
pLoadingDlg->SetWindowPos(wndTop, (MainDialogRect.Width() - LoadDialogRect.Width()) / 2, (MainDialogRect.Height() - LoadDialogRect.Height()) / 2, LoadDialogRect.Width(), LoadDialogRect.Height(), SWP_NOSIZE | SWP_SHOWWINDOW);
Maybe?
|
|
|
|
|
Setting the style to "Child" does not work because, when you disable a window, Windows will automatically disable its child windows as well.
When you used SetFocus, did you do it as follows:
HWND hwndSaveFocus = GetFocus() ;
... (display dialog and delete when done) ...
SetFocus(hwndsaveFocus) ;
Scott
|
|
|
|
|
hwndSaveFocus = GetFocus();
that gives me the error:
error C2440: '=' : cannot convert from 'class CWnd *' to 'struct HWND__ *
|
|
|
|
|
OK, hang on, let me check the API documentaiton....be right back
|
|
|
|