Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

Nonmodal dialog cancel itself without any user input

Posted on 2006-03-20
12
Medium Priority
?
290 Views
Last Modified: 2013-11-20
I have a nonmodal dialog that opens a couple of files.  If the files don't exist, I want the dialog to tell the user, then close itself.  I can get right to the point of closing itself, and then I am stumped.  Whatever I do, generates an error message.    In other words, I want something like if(!file)OnCancel().  I tried going back to the function that created the dialog, doing something like if(!pDlg->file)..., but I still get an error.  I believe it is because the dialog has not finished being created, so attempting to destroy it is premature.  Anyway, I am tempted to try a timer, but I hope that someone here has a better answer.  Perhaps I should send a message from the calling function as in if(!pDlg->file)send a close message.  It would certainly help if I better understood the process of dialog and window creation.

BTW, I know that I can open the files before creating the dialog, but that will create other problems, and I still won't understand this issue.

Anyway, thanks in advance, Rick
0
Comment
Question by:rickatseasoft
12 Comments
 
LVL 48

Expert Comment

by:AlexFM
ID: 16234202
Please show your code. Where is "if(!file)OnCancel()" fragment is placed?
0
 
LVL 45

Expert Comment

by:AndyAinscow
ID: 16234252
non-modal dialog - OnCancel (and OnOK) is usually used for modal dialogs.
Try this instead.
if(!file)
  PostMessage(WM_CLOSE, 0, 0);
0
 
LVL 12

Expert Comment

by:rajeev_devin
ID: 16234253
Can't you something like this.

if(!file) {
   CDialog::OnCancel();
}
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 45

Expert Comment

by:AndyAinscow
ID: 16234639
rajeev_devin
excerpt from help
When you implement a modeless dialog box, always override the OnCancel member function and call DestroyWindow from within it. Don't call the base class CDialog::OnCancel, because it calls EndDialog, which will make the dialog box invisible but will not destroy it.

That is why you can't do something like this....
0
 

Author Comment

by:rickatseasoft
ID: 16239368
I was pretty sleep deprived last night.  In re-reading my question, and doing some additional debugging, I can see that not only was I not explicit enough, but my problem is elsewhere.  Sorry about that.  Anyway, we use a MDI interface to manage the dialogs.  Each one is created with minor deviations from

void CDlgView::EmployerEntry()
{
            CRect cr;
            CArun31eDlg *pDlg;
            GetDocument()->SetTitle("Employer Entry/Edit");
            pDlg=new CArun31eDlg(this);
            cr=CalculateSize(pDlg);
            m_pParentFrame->MoveWindow(cr,TRUE);
            m_pDialog=pDlg;
            if(!pDlg->f05e)pDlg->ForceCancel();   //force cancel is a public function within the dialog that calls OnCancel();
}


the instantiation of the class is only modified by the addition of

m_pParent=pParent;
if(Create(........)){
ShowWindow(SW_SHOW);
}

BTW: the file is opened in the precreate window, but I have also tried in the instantiation


void CArun31eDlg::OnCancel()
{
      // TODO: Add extra cleanup here
      if(f05e)close(f05e);      
      CDialog::OnCancel();
      ((CDlgView*)m_pParent)->GetDocument()->OnCloseDocument();

}

void CDlgDoc::OnCloseDocument()
{
      // TODO: Add your specialized code here and/or call the base class
      CView *cv;
      POSITION pos=GetFirstViewPosition();
      while(pos){
            cv=GetNextView(pos);
            ((CDlgView*)cv)->Destroy();
      }
      CDocument::OnCloseDocument();
}

void CDlgView::Destroy()
{
      if(m_pDialog){
            delete m_pDialog;
      }
      m_pDialog=NULL;
}

FWIW: The OnOK code is

void CArun31eDlg::OnOK()
{
      // TODO: Add extra validation here
      CA5 A5;
      UpdateData(TRUE);
      if(f05e){
                      Do some processing and place the data into the file
      }
      CDialog::OnOK();
      ((CDlgView*)m_pParent)->CloseIt();
}

void CDlgView::CloseIt()
{
      m_pParentFrame=GetParentFrame();
      m_pParentFrame->SendMessage(WM_CLOSE);      

}



All of this seems to work properly if the user presses CANCEL or OK.  However, when the file fails to open, and the close is called from, as in the example above from EmployerEntry() it fails in the last line of the function below.

void CFrameWnd::InitialUpdateFrame(CDocument* pDoc, BOOL bMakeVisible)
{
      // if the frame does not have an active view, set to first pane
      CView* pView = NULL;
      if (GetActiveView() == NULL)
      {
            CWnd* pWnd = GetDescendantWindow(AFX_IDW_PANE_FIRST, TRUE);
            if (pWnd != NULL && pWnd->IsKindOf(RUNTIME_CLASS(CView)))
            {
                  pView = (CView*)pWnd;
                  SetActiveView(pView, FALSE);
            }
      }

      if (bMakeVisible)
      {
            // send initial update to all views (and other controls) in the frame
            SendMessageToDescendants(WM_INITIALUPDATE, 0, 0, TRUE, TRUE);

            // give view a chance to save the focus (CFormView needs this)
            if (pView != NULL)
                  pView->OnActivateFrame(WA_INACTIVE, this);


This time, I've tried to post enough code to illustrate the problem without making your eyes cross.  If you need more, let me know.

Any Ideas?


Thanks again for taking the time to help, Rick.
0
 

Author Comment

by:rickatseasoft
ID: 16240402
In the previous post I should have mentioned that  EmployerEntry() is called from the views OnInitialUpdate().   My guess is that the Close Message is closing the window before the update is complete.  Have I placed the EmployerEntry() function in the wrong place?  Is there some way to close the view, from within the view without causing these problems?  Can I set a set some variable on the failure to open, and call the close function at some later time?  If so, where whould that be so that it would happen without user input?

Thanks again, Rick
0
 
LVL 45

Expert Comment

by:AndyAinscow
ID: 16244389
If the dialog is modeless do NOT call the CDialog::OnCancel as I said earlier.
0
 
LVL 45

Expert Comment

by:AndyAinscow
ID: 16244398
I'd also do the file opening in the OnInitDialog of the dialog.  At that point the dialog has been created.
If you do anything in the PreCreateWindow then the window has not been created at that point, which could lead to big problems if you have code that is to control a window.
0
 
LVL 49

Accepted Solution

by:
DanRollins earned 1000 total points
ID: 16262179
Another note:
There is nothing kludgy about using a timer -- in fact, that is a very clean way to do a lot of things.  The timer handler will not get called until everything "settles down" and the main event loop is running cleanly.  That would be a good point to close and destroy the dialog because that is when the *user* would be able to do so by clicking a button.

An alternative is to post a private message to the dialog at the end of OnInitDialog().  That message will also only get processed at the desired point in the cycle.

Anather option would be to post the WM_CLOSE message to the dialog rather than calling OnClose().  Again, that message will only be handled when everything is settled down and ready to handle it.

-- Dan

P.S.  None of this really explains why anything fails "in the last line of the function below"  
The way to know why that statement is failing is to put a breakpoint there and single-step to find out what's going on.  That does not always reveal everything (especially if event timing is the issue) but it is a good place to start.
0
 

Author Comment

by:rickatseasoft
ID: 16293522
Dan and Andy:

Thanks for you input; it has been really helpful.  I'm sorry that my responses have been so slow, but I have been out in the Pacific; Internet access is iffy at best, and my being on the back side of the clock didn't help my  cognitive abilities at all.  Anyway, one last question then I'll close this one out with thanks to all:

Since these dialogs are "children" and are allocated with "new", do I still need a WM_CLOSE message?  The documentation that I read indicates that calling delete when I am finished----as part of the OnCloseDocument() function is more than adequate.

Thanks in advance, Rick
0
 
LVL 45

Assisted Solution

by:AndyAinscow
AndyAinscow earned 1000 total points
ID: 16294548
Memory assigned by new MUST be removed by delete - else you have a memory leak.

Just deleting the pointer to a window does not (as far as I know) properly cleanup the window.  USing the WM_CLOSE will let the window close itself properly and release all HANDLES assigned to it.  
0
 

Author Comment

by:rickatseasoft
ID: 16297404
Thanks to all for the help; it has been invaluable.

Rick
0

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

Question has a verified solution.

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

Introduction: Dynamic window placements and drawing on a form, simple usage of windows registry as a storage place for information. Continuing from the first article about sudoku.  There we have designed the application and put a lot of user int…
Introduction: Dialogs (2) modeless dialog and a worker thread.  Handling data shared between threads.  Recursive functions. Continuing from the tenth article about sudoku.   Last article we worked with a modal dialog to help maintain informat…
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.
Integration Management Part 2
Suggested Courses

578 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