Cannot get MDI view windows to appear above new custom windows

QUESTION: I have an MDI application, and I've created a couple of custom windows (not a dialog box, but a straight text control in a FrameWnd). The problem is, I cannot get the current view to show above any of the custom windows (not permanently, but only when clicked on). I have set the parent of the custom windows as the main frame window, the child frame, the MDI client, and pretty much everything I could think of, all to no avail. Can someone tell me how to get this right?

Along these same lines (but not necessarily part of this question) is: once I've designed an app with the doc/view architecture, but then later decide I don't really need doc/view, does anyone know of a good way to remove this structure?

 Thanks a lot!
LVL 7
Bill NolanOwner, Lead Technology ProgrammerAsked:
Who is Participating?
 
Janusz CzopowikConnect With a Mentor Commented:
Instead Create do this. Use CMDIChildWnd class derivative. I used in the example CcustomFrm.

Just paste this code (after making adjustments by changing classes names) to whatever place that you need a new frame. The rest is in comments.

//      if you want a view or any other window in your frame
      CCreateContext context;       
//      this will tell frame to create window of that class
//      could be any CWnd derived class with DECLARE_DYNCREATE and IMPLEMENT_DYNCREATE
      context.m_pNewViewClass = RUNTIME_CLASS(CCustomView);

//      we have protected constructor as frame windows are created dynamically
//      with memory on the heap.
      CRuntimeClass *pNewFrmClass = RUNTIME_CLASS(CCustomFrm);
//      create frmae object
      CCustomFrm *pFrm = (CCustomFrm *)pNewFrmClass->CreateObject();
      ASSERT_VALID(pFrm);      //if failed will fire assert

//      you create frames resources, or reuse ones you have.
//      if you create it is up to you what (menu, icon, string for a frame)
//      you will have to manually change
//      menu anyway, since doc template has nothing to do wit this window
      pFrm->LoadFrame(IDR_CUSTOMTYPE, WS_OVERLAPPEDWINDOW, this, &context);
//      this is done by template - you have to do it explicitely
      pFrm->InitialUpdateFrame(NULL, TRUE);
0
 
Vinayak KumbarSr Program ManagerCommented:
HI,

U want to add Ur windows to a MDI app?. Then follow the steps
1. Create an MDI app
2. Go to resouce editor and insert a dialog. And set the property as child
3. Place the controls over it.
4. Double click on it, it asks for adding class, add the class say CMyView derived from CFormView
5. Using class wizard add one more class say CMyChild derived from CMDIChildWnd.
6. Open the app class .h file and add the following line under publiuc section
CMultiDocTemplate *pDocTemplate1
7. Then in InitInstance add
pDocTemplate1 = new CMultiDocTemplate(
            IDR_MAINFRAME,
            RUNTIME_CLASS(CAppDoc),
            RUNTIME_CLASS(CMyChild), // custom MDI child frame
            RUNTIME_CLASS(CMyView));
AddDocTemplate(pDocTemplate1);

8. Then map any menu item function to app class and in that function to open our window do
pDocTemplate1->OpenDocumentFile(NULL);

U will get Ur window.

Thats it. Try it out.
VinExpert

0
 
Bill NolanOwner, Lead Technology ProgrammerAuthor Commented:
Thanks for your answer.  But I already have multiple windows that work fine with the exception that the MDI views won't move to the top.  Surely it is a minor issue to fix this.  If not, I would rather remove MDI architecture than to do the preceding contortions.  Would have an idea how to do that?
0
2018 Annual Membership Survey

Here at Experts Exchange, we strive to give members the best experience. Help us improve the site by taking this survey today! (Bonus: Be entered to win a great tech prize for participating!)

 
Vinayak KumbarSr Program ManagerCommented:
HI,

>that the MDI views won't move to the top
>I would rather remove MDI architecture than to do the                    preceding contortions
sorry, I could not get U. Can U be bit more clear pls.

VinExpert

0
 
Bill NolanOwner, Lead Technology ProgrammerAuthor Commented:
Ok.

1. I have an MDI app.
2. I have made some custom windows of my own and inserted them into the app.  They function perfectly, and whichever I click on comes to the top.
3. The MDI view window will not come to the top no matter what I do.
4.  Rather than doing all the things you detailed above, I would rather just scrap MDI and build the view window on my own.

The question: Is there a simple way to bring the view to the top.  If not, is there a clean way of removing doc/view architecture from an existing app?
0
 
Vinayak KumbarSr Program ManagerCommented:
Hi,

To make Ur view to come on top, after creating it may in OnInitialUpdate or like that, use
SetWindowPos( const CWnd* pWndInsertAfter, int x, int y, int cx, int cy, UINT nFlags );

with first parameter as
wndTop   or  wndTopMost.

I have not tried it. Try it and tell to me too.

And to remove existing architecture, I feel it is better to create one more app with new architecture and merge the code.

Thanks
VinExpert
0
 
migelCommented:
Hi
what info you know about window being activated?
is it view or frame?
you can activate MDIChildWnd by
calling MDIActivate() for it;
0
 
ZoppoCommented:
Hi Slimfinger,

Perhaps the problem is that the mainframe window is not the parent of the childframes, so create a window with mainframe as parent makes this window a sibling to the childframe's parent.

The childframe's parent is a MDICLIENT windows, stored as a handle within the CMDIFrameWnd::m_hwndMDIClient. Try using this as parent for creation of the 'custom' windows.

hope that helps,

ZOPPO
0
 
Bill NolanOwner, Lead Technology ProgrammerAuthor Commented:
Adjusted points to 125
0
 
Bill NolanOwner, Lead Technology ProgrammerAuthor Commented:
Thanks for your answers.  However, none of these things work.
Zoppo, I thought you had the right idea,and maybe you still do, but I couldn't get it to work.  This has baffled me, and I'm sure the answer is probably very simple....
0
 
ZoppoCommented:
What exactly are the styles of your 'custom' windows?

Or couldn't you derive your 'custom' windows from CMDIChildWnd and give them a doc/view architecure too?
0
 
Bill NolanOwner, Lead Technology ProgrammerAuthor Commented:
Adjusted points to 200
0
 
Bill NolanOwner, Lead Technology ProgrammerAuthor Commented:
I've tried every style and every combination.  (Well, at least I think I have).  Can't get CMDIChildWnd to work either.
0
 
Bill NolanOwner, Lead Technology ProgrammerAuthor Commented:
Edited text of question.
0
 
Bill NolanOwner, Lead Technology ProgrammerAuthor Commented:
Edited text of question.
0
 
abancroftCommented:
Sounds like your view window isn't responding to the WM_MDIACTIVATE message.

I'd suggest running your app & using Spy++ to check the window hierarchy above your MDI view. It should be something like:

App Main Frame
 |-MDI Client
    |-MDI Child Frame (Afx....)
       |-Your view (AfxFrameOrView42d)
0
 
Bill NolanOwner, Lead Technology ProgrammerAuthor Commented:
Adjusted points to 220
0
 
Bill NolanOwner, Lead Technology ProgrammerAuthor Commented:
Yes, that is the hierarchy, as Zoppo has stated.
0
 
Bill NolanOwner, Lead Technology ProgrammerAuthor Commented:
Edited text of question.
0
 
ZoppoCommented:
How do you create the window? Have you tried it with CreateMDIWindow()? Have you also tried CreateWindowEx() with WS_EX_MDICHILD?
0
 
migelCommented:
Hi!
I try create child window for MDIclient and it appears good. My code:
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
      // TODO: Add your specialized code here and/or call the base class
      
      BOOL bRes = CMDIFrameWnd::OnCreateClient(lpcs, pContext);
      if (!bRes)
            return bRes;
      //m_hWndMDIClient;
      RECT rc = {0,0,150,40};
      m_wndButton.Create("Button Text", WS_CLIPSIBLINGS| WS_CHILD|WS_VISIBLE|BS_DEFPUSHBUTTON, rc, CWnd::FromHandle(m_hWndMDIClient), 1);
      return bRes;
}

// CButton m_wndButton member of the CMainFrame class
Try it out.
0
 
Janusz CzopowikCommented:
I think you are referring to a frame not a view. Frame contains a view.

Anyway, you did not specify what frame class you have used as a base class of your custom windows. I presume CFrameWindow, seeing description of your problem. I don’t know how you create them…

The solution:

Use CMDIChildWnd instead CFrameWindow as a base class.
If you need some sample code post a question.
0
 
Bill NolanOwner, Lead Technology ProgrammerAuthor Commented:
I am not outright rejecting this answer; thismay be on the right track.  However, I've tried using CMDIChildWnd but haven't had any success with it, either.  It might be the answer, but I'm still not sure how to implement it...If you have sample code as you mentinon, that would be nice.

Thanks.
0
 
Janusz CzopowikCommented:
I would be more than glad to. Just to save some time for both of us, would you consider to post snippet of your code creating frames?
0
 
Bill NolanOwner, Lead Technology ProgrammerAuthor Commented:
Here you go, pretty straightforward.  Class overrides some messages.
Then in .cpp file, I merely create the frame, using some parameters I've shown here, but didn't bother showing you their values, since they are unimportant.  This frame holds other things, obviously, but that should be irrelevant.  Hope I didn't leave something out, but as I said, it's pretty straightforward...


IN .H FILE:

class CMyFrame : public CFrameWnd { //CMDIChildWnd

protected:

      // message handlers
      afx_msg void OnKeyDown( UINT nChar, UINT nRepCnt, UINT nFlags );
      afx_msg BOOL OnNcActivate( BOOL bActive );
      afx_msg void OnSize( UINT nType, int cx, int cy );
      afx_msg void OnClose();
      DECLARE_MESSAGE_MAP()

public:
      BOOL      m_bResizeable;      // True if window is resizeable
};

IN .CPP FILE:

m_pCommWindowFrame = new CMyFrame;

m_pCommWindowFrame->m_pCWParent = this;//***
m_pCommWindowFrame->m_bResizeable = bResizeable;
      m_pCommWindowFrame->Create(NULL,"CommWindow",dwStyle,WinSize,pParent,NULL,WS_EX_MDICHILD,NULL);
      
0
 
migelCommented:
unclear code
wnat class create CMyFrame?
0
 
Bill NolanOwner, Lead Technology ProgrammerAuthor Commented:
Does it matter?  It's just a class that manages a lot of the functionality of my application.  It is a member of the main application class in an MDI application.  It is NOT a Doc  or View.
0
 
migelCommented:
It is important!
since you pass pointer to it as parent odf the frame wnd!
what Window hierarchy in the your APP?
is it manager child of the MainFrame or anythong else?
0
 
Bill NolanOwner, Lead Technology ProgrammerAuthor Commented:
It escapes me how this is important.  I don't really care how it is done.  Really, my code seems unnecessary completely.

What I have is an MDI app.  There is a CWinApp object.  There is a member of that which contains certain functions, etc.  This object creates the Frame, and I can pass ANY window in as the parent.  It works fine, with the exception that it doesn't coexist properly with the CView.
0
 
migelCommented:
It is important!
since you pass pointer to it as parent odf the frame wnd!
what Window hierarchy in the your APP?
is it manager child of the MainFrame or anythong else?
0
 
Janusz CzopowikCommented:
Instead Create do this. Use CMDIChildWnd class derivative. I used in the example CcustomFrm.

Just paste this code (after making adjustments by changing classes names) to whatever place that you need a new frame. The rest is in comments.

//      if you want a view or any other window in your frame
      CCreateContext context;       
//      this will tell frame to create window of that class
//      could be any CWnd derived class with DECLARE_DYNCREATE and IMPLEMENT_DYNCREATE
      context.m_pNewViewClass = RUNTIME_CLASS(CCustomView);

//      we have protected constructor as frame windows are created dynamically
//      with memory on the heap.
      CRuntimeClass *pNewFrmClass = RUNTIME_CLASS(CCustomFrm);
//      create frmae object
      CCustomFrm *pFrm = (CCustomFrm *)pNewFrmClass->CreateObject();
      ASSERT_VALID(pFrm);      //if failed will fire assert

//      you create frames resources, or reuse ones you have.
//      if you create it is up to you what (menu, icon, string for a frame)
//      you will have to manually change
//      menu anyway, since doc template has nothing to do wit this window
      pFrm->LoadFrame(IDR_CUSTOMTYPE, WS_OVERLAPPEDWINDOW, this, &context);
//      this is done by template - you have to do it explicitely
      pFrm->InitialUpdateFrame(NULL, TRUE);
0
All Courses

From novice to tech pro — start learning today.