Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

How to hide modal dialog?

Posted on 2001-08-31
7
Medium Priority
?
3,210 Views
Last Modified: 2013-11-20
Hi, I have a simple task. I want to display a modal dialog invisibly. User will not be able to see/click on the OK/Cancel button. And some events will call EndDialog so the app will not hang.
My question is, how do I display the modal invisibly when I say DoModal()?
Do I do something in OnInitDialog()?
Thanks.
0
Comment
Question by:hoooi
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
7 Comments
 
LVL 8

Expert Comment

by:VinExpert
ID: 6447144
Hi,

In the OnInitDialog, u set the timer for that dialog just before that function returns TRUE as
SetTimer(100, 1, NULL);

Then using classwizard, map the WM_TIMER message to that dialog, and modify the function as

void CMyDlg::OnTimer(UINT nIDEvent)
{
     ShowWindow(SW_HIDE);
     KillTimer(100);
     CDialog::OnTimer(nIDEvent);
}

Try it out.
VinExpert
0
 
LVL 8

Expert Comment

by:VinExpert
ID: 6447154
Hi,

I forgot to mention something.
By hiding a modal dialog box, there is every possiblity that, ur app looks like hanging till the hidden dialog closes unless u have popped up this dialog in a seperate thread. May be U would like to create the dialog and launch it as modeless and then hide it???
Check it out.

VinExpert
0
 

Expert Comment

by:Parkson
ID: 6447182
You can make modal dialog invisible. Just put:

 ShowWindow(FALSE);

in the OnPaint() handler.  But because it's modal dialog, you can't do anything except on this hidden dialog.  The question is what events do you want to call EndDialog?  Don't forget the dialog is invisible.  How can you trigger those events on the dialog that you won't be able to touch?
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 

Author Comment

by:hoooi
ID: 6447217
I call ShowWindow(SW_HIDE) inside OnInitDialog, it failed.
I use ShowWindow(SW_HIDE) instead of DoModal to display the dialog, it failed and because of the first assert error of m_hWnd. I guess that's because I didn't call Create.
May I ask why I should use a timer and can't do it in OnInitDialog?
When I can hide it, I also use SetTimer and OnTimer to perform some operation first, and when the condition is right, then only I EndDialog(IDOK). Actually EndDialog failed on assert error too...
The reason I want this is because I want to hang the app for a while and do something before it continues.
Thanks.
0
 
LVL 1

Expert Comment

by:ua1zcl
ID: 6447926

/*
Found some decision of problem, not the best way ...

In MyDlg class definition added:
afx_msg void OnSomeCommand();
virtual BOOL OnInitDialog();

// in message queue inserted OnSomeCommand():
BEGIN_MESSAGE_MAP(MyDlg, CDialog)
     //{{AFX_MSG_MAP(MyDlg)
          // NOTE: the ClassWizard will add message map macros here
     //}}AFX_MSG_MAP
     //ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
     ON_COMMAND(777,OnSomeCommand)
END_MESSAGE_MAP()
*/

#define USE_TMP_WNDPROC
HWND hwDlg;
DLGPROC pDlgOriginalProc;
DWORD dwStyle;
RECT rc;

int CALLBACK MyDlgTmpProc(HWND hwDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
 if( uMsg==WM_SHOWWINDOW)
 {
     ::PostMessage(hwDlg,WM_COMMAND,0xFFFFFFFF,0);
 }
 if( uMsg==WM_COMMAND)
 {
     SetWindowLong(hwDlg,GWL_WNDPROC,(LONG)pDlgOriginalProc);
     ::ShowWindow(hwDlg,SW_HIDE);
 }
 return DefDlgProc(hwDlg,uMsg,wParam,lParam);
}
BOOL MyDlg::OnInitDialog()
{
 // Becuse i don't know how to get HWND (at all, at a moment )
 // here is used asm trick
 // for intel PC, Release not Debug version,
 // Debug work differently and will be error
 // because there is some spam on stack
   _asm{
           mov eax,[ebp+0Ch]
           mov  hwDlg,eax
          // int 3
     }
#ifdef USE_TMP_WNDPROC
// Dialog disapears, keyboard focus losed
  pDlgOriginalProc=
     (DLGPROC)::GetWindowLong(hwDlg,GWL_WNDPROC);
  SetWindowLong(hwDlg,GWL_WNDPROC,(LONG)MyDlgTmpProc);

#else
//  need to test this: , works also
  ::GetWindowRect(hwDlg,&rc);
  ::MoveWindow(hwDlg,rc.left,rc.top,0,0,1);


#endif
 return 1;
}

void MyDlg::OnSomeCommand()
{
      // To restore rect later:
   ::MoveWindow(hwDlg,rc.left,rc.top,rc.right-rc.left,rc.bottom-rc.top,1);
}
//////////////////////////////////////////////////////////////////////

Alex, ua1zcl
0
 

Expert Comment

by:ianwhite
ID: 6465564
Its actually possible to override DoModal, and just not display it at all. Here's a snip from one of my apps, look for the //IANW comments for the juciy bits, the rest is copied straight from the MFC libraries.
NOTE, if they every change the implementation,you'd have to recopy but it works great.

int CProtectionDlg::DoModal()
{
     // can be constructed with a resource template or InitModalIndirect
     ASSERT(m_lpszTemplateName != NULL || m_hDialogTemplate != NULL ||
          m_lpDialogTemplate != NULL);

     // load resource as necessary
     LPCDLGTEMPLATE lpDialogTemplate = m_lpDialogTemplate;
     HGLOBAL hDialogTemplate = m_hDialogTemplate;
     HINSTANCE hInst = AfxGetResourceHandle();
     if (m_lpszTemplateName != NULL)
     {
          hInst = AfxFindResourceHandle(m_lpszTemplateName, RT_DIALOG);
          HRSRC hResource = ::FindResource(hInst, m_lpszTemplateName, RT_DIALOG);
          hDialogTemplate = LoadResource(hInst, hResource);
     }
     if (hDialogTemplate != NULL)
          lpDialogTemplate = (LPCDLGTEMPLATE)LockResource(hDialogTemplate);

     // return -1 in case of failure to load the dialog template resource
     if (lpDialogTemplate == NULL)
          return -1;

     // disable parent (before creating dialog)
     HWND hWndParent = PreModal();
     AfxUnhookWindowCreate();
     CWnd* pParentWnd = CWnd::FromHandle(hWndParent);
     BOOL bEnableParent = FALSE;
     if (hWndParent != NULL && ::IsWindowEnabled(hWndParent))
     {
          ::EnableWindow(hWndParent, FALSE);
          bEnableParent = TRUE;
     }

     TRY
     {
          // create modeless dialog
          AfxHookWindowCreate(this);
          if (CreateDlgIndirect(lpDialogTemplate, CWnd::FromHandle(hWndParent), hInst))
          {
               if (m_nFlags & WF_CONTINUEMODAL)
               {
                    // enter modal loop
               // IANW : FIX TO KEEP DIALOG QUIET
                    DWORD dwFlags=0;
                    if(m_bDoSilently!=TRUE)
                         dwFlags = MLF_SHOWONIDLE;
               // IANW FIX END
                    if (GetStyle() & DS_NOIDLEMSG)
                         dwFlags |= MLF_NOIDLEMSG;
                    VERIFY(RunModalLoop(dwFlags) == m_nModalResult);
               }

               // hide the window before enabling the parent, etc.
               if (m_hWnd != NULL)
                    SetWindowPos(NULL, 0, 0, 0, 0, SWP_HIDEWINDOW|
                         SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER);
          }
     }
     CATCH_ALL(e)
     {
          DELETE_EXCEPTION(e);
          m_nModalResult = -1;
     }
     END_CATCH_ALL

     if (bEnableParent)
          ::EnableWindow(hWndParent, TRUE);
     if (hWndParent != NULL && ::GetActiveWindow() == m_hWnd)
          ::SetActiveWindow(hWndParent);

     // destroy modal window
     DestroyWindow();
     PostModal();

     // unlock/free resources as necessary
     if (m_lpszTemplateName != NULL || m_hDialogTemplate != NULL)
          UnlockResource(hDialogTemplate);
     if (m_lpszTemplateName != NULL)
          FreeResource(hDialogTemplate);

     return m_nModalResult;
}




basically don't do the dwFlags = MLF_SHOWONIDLE; if you wan't the dialog to stay hidden.

HOWEVER! I'll ask like the others did, why modal+hidden? if you want the app to freeze while its doing something, better to pop a window with a progress bar, or at least a "please wait" window, and then in your main window set a timer. (I assume in a different thread?) the timer can check the thread state, and when finished call a destroy on the "please wait" window..
0
 
LVL 8

Accepted Solution

by:
VinExpert earned 150 total points
ID: 6473189
Hi,

>May I ask why I should use a timer and can't do it in OnInitDialog?

I just placed the code in OnTimer, so that dialog window will be created by that time and hence ShowWindow(...) will be successfull in its job.

Yes, I too have faced prob will EndDialog(...). According to MSDN, EndDialog(...) takes some time to close the dialog. I had tried to solve that by placing some delay after calling the EndDialog(...) function!!!

But, Finally, I wrote two public functions for the dialog class which will call CDialog's OnOK() and OnCancel() functions. And I called these functions instead of EndDialog(...) call. I did not had time to dig into it. May be U can alo try this out.

VinExpert
0

Featured Post

[Webinar] Lessons on Recovering from Petya

Skyport is working hard to help customers recover from recent attacks, like the Petya worm. This work has brought to light some important lessons. New malware attacks like this can take down your entire environment. Learn from others mistakes on how to prevent Petya like worms.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction: The undo support, implementing a stack. Continuing from the eigth article about sudoku.   We need a mechanism to keep track of the digits entered so as to implement an undo mechanism.  This should be a ‘Last In First Out’ collec…
In this post we will learn different types of Android Layout and some basics of an Android App.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
This tutorial will teach you the special effect of super speed similar to the fictional character Wally West aka "The Flash" After Shake : http://www.videocopilot.net/presets/after_shake/ All lightning effects with instructions : http://www.mediaf…

650 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question