Solved

Dialog Window Disappears

Posted on 2001-08-03
18
382 Views
Last Modified: 2013-11-20
I have an SDI application with a FormView base class. I Create the Dialog in OnInitialUpdate() and Hide it until it is ready to be used as follows.

  pRTGMaintenanceDlg = new CRTGMaintenanceDlg();
  pRTGMaintenanceDlg->Create(IDD_RTGMAINTENANCE,NULL);
  pRTGMaintenanceDlg->ShowWindow(SW_HIDE);


I use an OnCommand function to display the Dialog.

// On Command Function to Display Maintenance Dialog.
void CDisplay2View::OnRngtrackerpopupMaintenance()
{
  // TODO: Add your command handler code here
   pRTGMaintenanceDlg->ShowWindow(SW_SHOW);
   CRect oSize;
   pRTGMaintenanceDlg->GetWindowRect(&oSize);
   pRTGMaintenanceDlg->SetWindowPos(NULL,640,585,oSize.Width(),oSize.Height(),SWP_NOZORDER);
}

I have two problems.
1.The first is how do I lock the Dialog Window in place so that the user cannot move it.
2. My second problem is if the Dialog Window is currently displayed and I minimize the application and then maximize it, the Dialog Window is no longer displayed. How do I keep the Dialog Window displayed on a minimized-maximize operation.
I'm already using OnActivateView to re-paint the Display.

// Windows Message that is called to Re-Activate (Paint) the Display after a Screen Saver or other Window has been Displayed.
void CDisplay2View::OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView)
{
     // TODO: Add your specialized code here and/or call the base class
     Invalidate(TRUE);
     UpdateWindow();

     CFormView::OnActivateView(bActivate, pActivateView, pDeactiveView);
}





0
Comment
Question by:hugoitt
  • 6
  • 6
  • 5
  • +1
18 Comments
 
LVL 2

Accepted Solution

by:
Lockias earned 100 total points
ID: 6350336
1.  Handle the WM_WINDOWPOSCHANGING message.  This gives you a pointer to a rect that holds where the user (or anything) is trying to move\size the window.  You can change the values (keep them fixed numbers based on where you want the window) to override where the window was going to be move\sized.

2.  Handle WM_SHOWWINDOW.  This will tell you when your a window is being shown as result of coming out of being minimized (and other things).  You can then call ShowWindow(SW_SHOW) on your dialog thing again.

~Lockias
0
 

Author Comment

by:hugoitt
ID: 6351786
Lockias, thks for the response.

Let's address question two. In my Dialog.cpp I added a windows message handler for WM_SHOWWINDOW as follows:

void CAnyDialog::OnShowWindow(BOOL bShow, UINT nStatus)
{
   CDialog::OnShowWindow(bShow, nStatus)

    // TODO: Add your specialized code here and/or call the base class

       if (nStatus == SW_PARENTOPENING && bShow == TRUE)
            pRTGMaintenanceDlg->ShowWindow(SW_SHOW);
}

This works well in bringing up the dialog window if the main application window is minimized then maximized. The
problem is I have other dialog boxes that can be displayed. If one of the other dialog boxes are displayed and the minimize-maximize is initiated, it will bring up the pRTGMaintenanceDlg as well even though it wasn't displayed at the time. It seems like I will have to set flags to tell me if the current dialog was displayed before I show it, but I was thinking there was a cleaner way of doing this.

anyone?


0
 
LVL 2

Expert Comment

by:Lockias
ID: 6351929
Well, from how I *think* that you have things setup, you should be able to do this:

void CAnyDialog::OnShowWindow(BOOL bShow, UINT nStatus)
{
  CDialog::OnShowWindow(bShow, nStatus)

   // TODO: Add your specialized code here and/or call the base class

      if (nStatus == SW_PARENTOPENING && bShow == TRUE)
      {
         if (pRTGMaintenanceDlg->IsWindowVisible())
           pRTGMaintenanceDlg->ShowWindow(SW_SHOW);
      }
}

The IsWindowVisible() should return true if the WS_VISIBLE flag is set.  This should be set if the dialog was shown before its parent was hidden.  If I am remembering this wrong and it doesn't work that way then setting a flag of your own would probably be the best solution.

~Lockias

0
 

Author Comment

by:hugoitt
ID: 6352056
Lockias, thks for the response.

Let's address question two. In my Dialog.cpp I added a windows message handler for WM_SHOWWINDOW as follows:

void CAnyDialog::OnShowWindow(BOOL bShow, UINT nStatus)
{
   CDialog::OnShowWindow(bShow, nStatus)

    // TODO: Add your specialized code here and/or call the base class

       if (nStatus == SW_PARENTOPENING && bShow == TRUE)
            pRTGMaintenanceDlg->ShowWindow(SW_SHOW);
}

This works well in bringing up the dialog window if the main application window is minimized then maximized. The
problem is I have other dialog boxes that can be displayed. If one of the other dialog boxes are displayed and the minimize-maximize is initiated, it will bring up the pRTGMaintenanceDlg as well even though it wasn't displayed at the time. It seems like I will have to set flags to tell me if the current dialog was displayed before I show it, but I was thinking there was a cleaner way of doing this.

anyone?


0
 
LVL 49

Expert Comment

by:DanRollins
ID: 6352439
>>I have two problems.
>>1.The first is how do I lock the Dialog Window in place
>>so that the user cannot move it.

Don't do this.  It is wrong at many levels.  You must allow a user to reposition windows at any time. If you break this very basic GUI rule, it means that you have no understanding of Windows programming.  You will look like an amateur.

>>2. ... How do I keep the Dialog Window displayed on a minimized-maximize operation.

The modeless dlg closes because it is a parent of the main window.  When you create the modeless dlg, set it's parent to the Desktop:

  pRTGMaintenanceDlg= new CRTGMaintenanceDlg();
  pRTGMaintenanceDlg->Create( CRTGMaintenanceDlg::IDD, GetDesktopWindow() );

That way, it will not need to follow the app window.

-- Dan
0
 

Author Comment

by:hugoitt
ID: 6354140
Dan,

thanks for the response. What I'm looking to do is if there was a dialog box displayed in the main application window when the application was minimized, i want the dialog box to be re-displayed when the application is maximized. Currently, the dialog box disappears when I maximize the application. Your suggestion leaves the dialog box displayed when the application is minimized which is a feature I do not want.

In reponse to question one, I see your point, however the user of this application will not be using the "computer" for anything but his assigned task.The design calls for the user to be able to use one of three applications. He will be performing repetitive tasks, and making quick decisions on short notice, the user has to know that a control is available to him at the same location every time he needs it. If the user moves the window he would be covering other controls that could cause him to miss information critical to his assignment. Mistakes do happen, and were trying to prevent the application from working in a way that could jeapordize his assigned task.

thanks again
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 6357133
>>i want the dialog box to be re-displayed when the application is maximized.

Q1: That is the default behavior, so I did not address it.  You must be doing something strange in order for your program to *not* display all child modeless dialogs when the parent window gets maximized.

Q2: I agree that there may be a place for fixed-location windows on a one-task, dedicated PC.  I still recommend against it.  Howeverh ere is a simple way to handle it.


class CAboutDlg : public CDialog
{
public:
    CAboutDlg();
    afx_msg void OnWindowPosChanged( WINDOWPOS* lpwndpos );
...


BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
     //{{AFX_MSG_MAP(CAboutDlg)
     ON_WM_WINDOWPOSCHANGED()
     //}}AFX_MSG_MAP
END_MESSAGE_MAP()

void CAboutDlg::OnWindowPosChanged( WINDOWPOS* lpwndpos )
{
    SetWindowPos(0, 100,100, 0,0, SWP_NOSIZE  );
   // CDialog::OnWindowPosChanged( lpwndpos );
}


-- Dan
0
 
LVL 9

Expert Comment

by:Pacman
ID: 6358919
I agree with DanRollins.
It really does break any GUI design rules if you forbid dragging of a window having a caption.

A window with a caption should be able to be dragged. Therefore it has a caption. If you don't want the user to drag the window then don't display a caption.
0
 
LVL 2

Expert Comment

by:Lockias
ID: 6359896
Dan,
  I already stated that one could use WM_WINDOWPOSCHANGING.  Further more the code you provide will enter an infinite loop.  The OnwindowPosChanged will fire the SetWindowPos, which will fire the OnWindowPosChanged, which will...
This is why there is a changING version of this message.

~Lockias
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

by:hugoitt
ID: 6360158
Ok, I need to move on. I've decided to go with the following.
Question One - Since the consensus is I would be breaking GUI design rules if I disallowed moving of the dialog window, I will remove the caption from the dialog box, thus
not allowing the user that option, thanks Pacman, Dan.

Question Two - I will set flags to tell me which dialog boxes are currently displayed and use the windows message handler WM_SHOWWINDOW to show them in a maximize operation.

void CAnyDialog::OnShowWindow(BOOL bShow, UINT nStatus)
{
 CDialog::OnShowWindow(bShow, nStatus)

  // TODO: Add your specialized code here and/or call the base class

     if (nStatus == SW_PARENTOPENING && bShow == TRUE)
     {
        if (iRTGMaintenanceDlgFlag == TRUE)
          pRTGMaintenanceDlg->ShowWindow(SW_SHOW);
     }
}

thanks Lockias

I appreciate everyone's input.

0
 
LVL 49

Expert Comment

by:DanRollins
ID: 6360703
Lockias,
>>I already stated that one could use WM_WINDOWPOSCHANGING.

WM_WINDOWPOSCHANGED is the better message to handle.  WM_WINDOWPOSCHANGING will cause unwanted recursion.

>> Further more the code you provide will enter an infinite loop.  The OnwindowPosChanged will fire the SetWindowPos, which will fire the OnWindowPosChanged,
which will...

I also thought that might happen, so I tested the code.  That is something that you didn't bother to do.  Had you done so, you would know that it works perfectly.
-=-=-=-=-=-=-=-=-=-=

hugoitt,
I'm glad you used my suggestion to allow the window to move.

There is no need *at all* to use the code you posted to make the child dialog appear when its parent is maximized.  Your code simply enforces what happens automatically.  I'm guessing that it is just undoing some mistake that you made elsewhere in your program.

-- Dan
0
 
LVL 2

Expert Comment

by:Lockias
ID: 6360756
I did test it.  You must have not tested it correctly.  You say that WM_WINDOWPOSCHANGING will cause recursion.  That can only be if you do not know how to use it.
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 6360894
Lockias,
>>You must have not tested it correctly.  

OK, you made me redo the test.  As usual, my work was sound and my test -- and my code -- was correct.  There is no infinite recursion.  You can drag the modeless dialog box around, but it always returns to 100,100.

Now, perhaps you will take a moment to verify that your testing procedure was correct.  The code I showed was cut and pasted from a functional program.  Use it and see. I'll wait here for your appology.

-- Dan
0
 
LVL 2

Expert Comment

by:Lockias
ID: 6361075
I have learned something new!  SetWindowPos always fires a WM_WINDOWPOSCHANGING message.  However, if the values relevant to the flags do not different than the current ones, WM_WINDOWPOSCHANGED never gets sent.  They built in recursion protection!

However, Dan, please try out my code and see which you think is more appealing to the user:

class CAboutDlg : public CDialog
{
public:
   CAboutDlg();
   afx_msg void OnWindowPosChanging( WINDOWPOS* lpwndpos );
...


BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
    //{{AFX_MSG_MAP(CAboutDlg)
    ON_WM_WINDOWPOSCHANGING()
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

void CAboutDlg::OnWindowPosChanging( WINDOWPOS* lpwndpos )
{  
   if (!(lpwndpos->flags & SWP_NOMOVE))
   {
      lpwndpos->x = 100;
      lpwndpos->y = 100;
   }

   CDialog::OnWindowPosChanging(lpwndpos);
}




0
 
LVL 2

Expert Comment

by:Lockias
ID: 6361076
BTW: Sorry!
0
 

Author Comment

by:hugoitt
ID: 6362053
Dan,
thanks for your persistence. You made me go back and look at my code again.

Dan
I'm guessing that it is just undoing
some mistake that you made elsewhere in your program.

I didn't override the OnCancel member function which by default calls EndDialog. EndDialog makes the dialog box invisible but does not destroy it.

The first time after my application first comes up, I bring up the dialog box - I can minimize and maximize and the dialog window comes up like it should.

As soon as I close it, bring it back up, and minimize-maximize, the dialog window is gone.

I'm still not clear as to why this is happening but I beleive I can fix it by overriding the OnCancel Member function and Hiding the window when I decide to close it.

Below is the way I'am currently using OnCancel to hide the Dialog window.

void CRTGMaintenanceDlg::OnCancel()
{
  pRTGMaintenanceDlg->ShowWindow(SW_HIDE);
  CDialog::OnCancel();
}

Just a refresher, I create all dialog Windows on Startup and then Show and Hide them as I use them.
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 6362254
Hi Lockias,
I'll assume that your code prevents movement altogether, which would undoubtedly be better than my kludgy-looking snap-back technique.  I quit looking for a better technique when hugoitt accepted your answer.

hugoitt,
You might be able to just...

void CRTGMaintenanceDlg::OnCancel(){
 pRTGMaintenanceDlg->ShowWindow(SW_HIDE);
// CDialog::OnCancel();
}

...to prevent any undesured side-effects of the base-class handler.  After all, the only goal is to hide the window, and your override does that.

-- Dan
0
 

Author Comment

by:hugoitt
ID: 6362677
thanks Dan,

That's exactly what I did and it works great.
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Introduction: Dialogs (1) modal - maintaining the database. Continuing from the ninth article about sudoku.   You might have heard of modal and modeless dialogs.  Here with this Sudoku application will we use one of each type: a modal dialog …
If you use Adobe Reader X it is possible you can't open OLE PDF documents in the standard. The reason is the 'save box mode' in adobe reader X. Many people think the protected Mode of adobe reader x is only to stop the write access. But this fe…
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.
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…

762 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

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now