Link to home
Start Free TrialLog in
Avatar of docieb
docieb

asked on

Convert CDialog to CFormView

I have joined a few dialog applications into a MDI application. I now want those dialogs to be windows inside the MDI application instead of them opening up as seperate dialogs.  I'm guessing I need to change them into CFormView class instead of CDialog classes.  Is this correct?  If so, what is everything that I need to do.  I assume I need change all the CDialog that is in the code to CFormView.  I also assume I need to move everything that I have in the OnInitDialog function somewhere else but where.  Once I do this, how do I go about opening and closing the window properly.  Are there any other ways of making a dialog  into a internal window that Might be easier.
ASKER CERTIFIED SOLUTION
Avatar of mahesh1402
mahesh1402
Flag of India image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of AndyAinscow
You could set the dialogs as child (not popup) and dynamically position them inside a view.
But it is probably neater to change the base class from CDialog to CFormView, it would be of benefit later when someone else (or yourself) needs to make changes because the overall structure would be simpler.
Avatar of GautamSYadav
GautamSYadav

1. In resource view, for every dialog, create IDD_FormView
2. Copy/Paste all controls from dialog to form.
3. Double click the form view, you will be prompted to add a new class , add a new class and select base class as CFormview.
4. In the xxxview.cpp, there is a function OnInitialUpdate(). Shift your OnInitDialog() initializations to this function.
5. Now in place of creating your dialog object, if in your app class, call the following:
   CMultiDocTemplate* pDocTemplate1;
pDocTemplate1 = new CMultiDocTemplate(
            IDR_MDICONTYPE,
            RUNTIME_CLASS(CMDIContainDoc),
            RUNTIME_CLASS(CChildFrame), // custom MDI child frame
            RUNTIME_CLASS(CControlView));
    AddDocTemplate(m_pDocTemplate);
regards,
Gautam
Avatar of docieb

ASKER

I have changed one of the dialogs into and when I try to run it, I get an Assertion error at line 319 of winocc.cpp.  What are some things that I might of done wrong.  Do I need to make a seperate doc class for the dialog that I just made a view for or can I use the one I already have with my app.  Besides opening my newly create view at the beginning to the program, how I can open it at other places in the code like if I wanted to make a menu item to open it.
Avatar of docieb

ASKER

Well I found my assertion error, it is my OnSize function.  Is there anyway I can get my OnSize to work with CFormView.
can you post some code ?

-MAHESH
Avatar of docieb

ASKER

Sure, here is my OnSize function

void CMyNewView::OnSize(UINT nType, int cx, int cy)
{
      CFormView::OnSize(nType, cx, cy);
      CRect rect;
      GetClientRect(&rect);
      int wid = rect.right - rect.left;      // Width of dialog
      int len = rect.bottom - rect.top;      // Height of Dialog
      int Xt = 10;                              // Distance from left of window to left of the left most control
      int Yt = 10;                              // Distance from top of window to top of the top most control
      int Xb = 10;                              // Distance from right of window to right of the right most control
      int Yb = 10;                              // Distance from bottom of window to bottom of the bottom most control
      int Xs = 6;                              // Width Spacing between controls
      int Ys = 5;                              // Height Spacing between controls

      int x = Xt;                              // x position of Upper left corner
      int y = Yt;                              // y position of Upper right corner
      int lx = 126;                              // Width of control
      int ly = 21;                              // Height of control
      double tmp = 0;
      // Reposition Combo Boxes
      m_ctlCombo1.SetWindowPos(&CWnd::wndNoTopMost, x, y, lx, ly, SWP_NOZORDER);
      y = (((len-Yt-Yb-Ys)/2)+Ys)+Yt;
      m_ctlCombo2.SetWindowPos(&CWnd::wndNoTopMost, x, y, lx, ly, SWP_NOZORDER);
      m_ctlCombo2.RedrawWindow();
      // Repostion Lists
      y = Yt+21+Ys;
      tmp = (wid-Xt-Xb-Xs)*.65; lx = (int)tmp; ly = (len-Yt-Yb-3*Ys-2*21)/2;
      m_ctlList1.SetWindowPos(&CWnd::wndNoTopMost, x, y, lx, ly, SWP_NOZORDER);
      y = Yt+((len-Yt-Yb)/2)+Ys+21+Ys;
      m_ctlList2.SetWindowPos(&CWnd::wndNoTopMost, x, y, lx, ly, SWP_NOZORDER);
      m_ctlList2.RedrawWindow();
      // Reposition Tabs
      x = (int)tmp+Xs+Xt; y = Yt;
      lx = (int)((wid-Xt-Xb-Xs)*.35); ly = (len-Yt-Yb-Ys)/2;
      m_ctlTab1.SetWindowPos(&CWnd::wndTop, x, y, lx, ly, SWP_NOZORDER);
      y = ly+Yt+Ys;
      m_ctlTab2.SetWindowPos(&CWnd::wndTop, x, y, lx, ly, SWP_NOZORDER);
      // Reposition Buttons
      x = 144;      y = (((len-Yt-Yb-5)/2)+5)+Yt;
      lx = 36; ly = 20;
      m_ctlEditItem2.SetWindowPos(&CWnd::wndNoTopMost, x, y, lx, ly, SWP_NOZORDER);
      m_ctlEditItem2.RedrawWindow();
      x = 180;
      m_ctlDeleteItem2.SetWindowPos(&CWnd::wndNoTopMost, x, y, lx, ly, SWP_NOZORDER);
      m_ctlDeleteItem2.RedrawWindow();
      // Reset the column widths
      m_ctlList1.GetClientRect(&rect);
      int nColWid = rect.Width() / 20;
      int nColWidRem = rect.Width() % 20; // Get the remainder
    SCROLLINFO info = {sizeof( SCROLLINFO)};
    info.fMask = SIF_RANGE;
    if ((m_ctlList1.GetScrollInfo( SB_VERT, &info, SIF_RANGE)) && ((info.nMax - info.nMin) < (rect.Height()-19)/17))
      {
        nColWidRem = nColWidRem - 17;
      }
      // Column width and heading
      m_ctlList1.SetColumnWidth(0, (nColWid*8)+nColWidRem);
      m_ctlList1.SetColumnWidth(1, nColWid*3);
      m_ctlList1.SetColumnWidth(2, nColWid*3);
      m_ctlList1.SetColumnWidth(3, nColWid*3);
      m_ctlList1.SetColumnWidth(4, nColWid*3);
      m_ctlList2.SetColumnWidth(0, (nColWid*8)+nColWidRem);
      m_ctlList2.SetColumnWidth(1, nColWid*3);
      m_ctlList2.SetColumnWidth(2, nColWid*3);
      m_ctlList2.SetColumnWidth(3, nColWid*3);
      m_ctlList2.SetColumnWidth(4, nColWid*3);
      m_ctlTab1.RedrawList();                        // Redraw the List inside the tab
      m_ctlTab2.RedrawList();

}
Avatar of docieb

ASKER

The error occurs the I try do SetWindowPos for any of the controls
its happening for any particular SetWindowPos or every ? You may check that by putting messageboxes after every call to SetWindowPos()...

-MAHESH
also try to detect if window is alive like :

void CMyNewView::OnSize(UINT nType, int cx, int cy)
{
     CFormView::OnSize(nType, cx, cy);
   ....

   if( ::IsWindow(m_ctlEditItem2.m_hWnd ) )
  {
    m_ctlEditItem2.SetWindowPos(.....);
  }
 
//Do same for every control you are setting
...

}

-MAHESH
Avatar of docieb

ASKER

That is what was causing the assertion errors was the window wasn't alive.  Now though, the window doesn't size itself to the View window until I go to resize the window and then it jumps to the size of the window.  Do I need to call resize at the end of OnInitialUpdate.  Also my OnGetMinMaxInfo doesn't seem to set a minimum size for the view window.  Is there any way of getting that to work.  Also, I would like to know how of open and close MyView from somewhere in CMainFrame.  
>>Do I need to call resize at the end of OnInitialUpdate
>>Also my OnGetMinMaxInfo doesn't seem to set a minimum size for the view window.  Is there any way of getting that to work.

void CMyView::OnInitialUpdate()
{
    ....

    CFormView::OnInitialUpdate();
    ResizeParentToFit(FALSE);
    ResizeParentToFit();
 
}

Use the SizeParentToFit call to resize the child frame to fit the formview.  Usually you have to call it twice, once with TRUE and once with FALSE, to handle the cases where the frame is initially larger than the form and where it is initially smaller (as long as your form doesn't exceed 640x480 this is fine; otherwise, you end up forcing the form scrollbars off the window, so it is often a good idea to see if the form dimensions are greater than the screen size before calling the one that sizes to the full size).  After you've called this in the OnInitialUpdate handler, you can legitimately respond to the WM_GETMINMAXINFO messages.  Declare child frame with a Boolean set in the constructor to FALSE, and after the ResizeParentToFit,  do GetParent()->SendMessage(UWM_LOCK_SIZE) to the parent window (the child frame).  It then gets its current size, sets the internal Boolean to TRUE, and thereafter responds to the WM_GETMINMAXINFO message with the saved values.

Also have a look at sample code here : http://www.codeproject.com/dialog/formview2.asp <== resizable form view class.

-MAHESH
Avatar of docieb

ASKER

>>Declare child frame with a Boolean set in the constructor to FALSE, and after the ResizeParentToFit,  do GetParent()->SendMessage(UWM_LOCK_SIZE) to the parent window (the child frame)

First off, I'm not exactly following what you are saying.  After I do the ResizeParentToFit, I need to Declared a ChildFrame.  Next I need to call GetParent()->SendMessage(UWM_LOCK_SIZE).  Is that correct?  Also I get UWM_LOCK_SIZE is undefined.
ok forget that thats about custom message sending to parent frame..

have you referred above sample about resizing view ?

-MAHESH
Avatar of docieb

ASKER

Yeah, I looked at the article and it explained how to use his class and I looked through his class some (or should I say his derived class from Paolo's class) and I didn't see where he handled the WM_GETMINMAXINFO.
Avatar of docieb

ASKER

Ok, scratch the  WM_GETMINMAXINFO thing.  The window goes to scroll bars when it gets to the size of the default dialog resource and the controls don't get too small so thats good enough for me.  Now that I think about it, I think this is how I want it to be.

The final thing that I want to know how to open CMyNewView from a menu on CMainFrame.  I am going to have a few different Views and I would like to be able to open and close them.