Link to home
Start Free TrialLog in
Avatar of pikco
pikco

asked on

Linking a CFrameWnd class to a resource


I am aware that what I am about to ask is vague, but once i get a push in the right direction, I can start to be more specific.

My situation is that I am continuing someone else's project.
The code that opens the main window of the application is done in a way I've never used before, and so am confused about.

It is :

      CMainFrame* pFrame = new CMainFrame();
      m_pMainWnd = pFrame;

      pFrame->LoadFrame(IDR_MAINFRAME,
            WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, NULL,
            NULL);

      pFrame->ShowWindow(SW_SHOW);
      pFrame->UpdateWindow();

and this occurs in the InitInstance() method, where CMainFrame is derived from CFrameWnd.

Am i correct in saying that this window is being created on the fly, using the IDR_MAINFRAME toolbar resource only.

Let's say I want to edit this window, add some buttons, change its look and so on.
Up until now I have only done this through editing the resources directly. Since this dialog doesn't exist in the ResourceView, how can I do this?


Cheers for any ideas.
Avatar of Jaime Olivares
Jaime Olivares
Flag of Peru image

>Am i correct in saying that this window is being created on the fly, using the IDR_MAINFRAME toolbar resource only.
Yes, you are, it looks like it is not a doc/view architecture project.

>Let's say I want to edit this window, add some buttons, change its look and so on.
This must be done inside CMainFrame implementation (mainfrm.cpp), because this window it is NOT associated with any graphical template like dialog do.
Avatar of AndyAinscow
I suspect inside the frame a dialog will be created dynamically (eg in the OnCreate of the Frame).  It is this dialog resource you need to edit and add buttons and other controls to.
Avatar of pikco
pikco

ASKER

thanks for your replies..

so Jaime, does that mean that I need to add buttons etc. in code?
is this easy to do?
In OnCreate() you can do pretty much anything you want to change the look of the window.  
I would suggest using PreCreateWindow() if you want to set the system properties of the window - like the close button and the minimize/maximize buttons.  You can also remove the menu here - at least that's what I do.

Since you are not using a dialog resource to create a view inside the mainframe then you will have to add buttons manually.  You can also modify/add toolbars here.

Jim
Avatar of pikco

ASKER


ahhh, okay, so where can i find out how to add buttons manually?
The easiest way is to add some CButton objects to your CFrameWnd derived class then create them in OnCreate().
Call CButton::Create(...) then if need be call MoveWindow() for the buttons.  You will need an event handler for each button.

Sometimes it's just easier to create a view class then create the view and place it into the frame.
Jim
SOLUTION
Avatar of Jaime Olivares
Jaime Olivares
Flag of Peru 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
I would still put a dialog into the frame - no need to do the controls in code, you do them in the resource editor as you would any other dialog.

Just have a member var that is a pointer to the dlg, in the OnCreate of the frame use new to create a new dialog then create.
Avatar of pikco

ASKER

AndyAinscow:

That sounds like exactly what I should do, since its probably faster to do than in code.
I'm still not sure how to do it yet though.

Since it alraedy creates a dialog on the fly, does this mean it will open up two if I do this?

Thanks for your replies also.
ASKER CERTIFIED SOLUTION
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 pikco

ASKER


Hey, thanks for that reply.
I think its getting warmer now, using that idea my main dialog now opens up to be the same size as the CMyDlg class dialog, however, I still can't see any of the things I add in the resource editor. what could i be forgetting?
SOLUTION
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
m_pFormView->ShowWindow(SW_SHOW);

does that help?
Your form view is based on the dialog isn't it?
Calling ShowWindow() is not necessary because of the call to ShowOwnedWindows().

CFormviews are CView classes based on a dialog resource - similar to VB forms.  You can pop them in and out like CViews and they can be used in splitters.  I use them quite a lot.

Jim

Avatar of pikco

ASKER

Yeah, ShowWindow() opens up the original dialog as well as the new dialog.

Jim, would this work in my case,

sContext.m_pNewViewClass    = RUNTIME_CLASS(CMyFrame);   doesn't seem to like my class

SetActiveView(m_pMyDlg);    the method is looking for a CView?

I'm not sure what CMyFormView in your example is, is it a class derived from a dialog?


Thanks.
pikco - you are getting a mix of my idea and that from jimbucci.

I am suggesting a modeless child DIALOG inside your frame.  The other is a CFormView based view inside the frame.
Please post some code so we know what you are doing.

CMyView is a CFormView derived class.  The sContext.m_pNewViewClass requires a CView derived class - placing the frame in their would probably just fail.  SetActiveView requires a CView derived class.

All of the code I provided is for using a CView derived class with a CFrameWnd derived class.  The MFC framework handles a lot of the placement and creation of the windows for you - although you can still set the size of the view as you wish.

Using a dialog as a child to a frame window would work just fine - the fact is that I've never done it.  Using the MFC frame-view type of UI seemed easier to me.  

The best way to try what I suggest is to create a new project and where you select the type of view class select CFormView.  You will then be presented with the resource editor for the dialog.  If you run the program your dialog resource will show in the view.  Looking at the code should reveal how the view gets inside the frame.

Jim

Avatar of pikco

ASKER

Andy:

My code at the moment is pretty similar to what you suggested earlier:

    if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
          return -1;
     
     m_pMyDlg= new CMyFrame(this);

      
     if(!m_pMyDlg->Create(NULL,NULL,WS_CHILD | WS_VISIBLE,CRect(0,0,0,0),this,NULL))
     {
          delete m_pMyDlg;
          m_pMyDlg= NULL;
          return -1;
     }

//size later
     CRect rectClient, rectWindow;
     m_pMyDlg->GetWindowRect(rectWindow);

     SetWindowPos(NULL, 10, 10,  rectWindow.Width()+20, rectWindow.Height()+20,//check later          SWP_NOZORDER | SWP_NOACTIVATE);

     GetClientRect(rectClient);
     m_pMyDlg->SetWindowPos(NULL, 0, 0,
          rectClient.Width(), rectClient.Height(),
          SWP_NOZORDER | SWP_NOACTIVATE);


At the moment it will open up the dialog as before, at the same size as the CMyFrame dialog.
from help

CDialog::Create
BOOL Create( LPCTSTR lpszTemplateName, CWnd* pParentWnd = NULL );

BOOL Create( UINT nIDTemplate, CWnd* pParentWnd = NULL );


Is your m_pMyDlg based on a CDialog derived class?
 
I think you was in the right way when presenting on a CFrameWnd.
Avatar of pikco

ASKER

Andy:

Yeah, interesting about that, my class definitely is derived from CDialog:

CMyFrame::CMyFrame(CWnd* pParent /*=NULL*/)
      : CDialog(CMyFrame::IDD, pParent)
{   etc......

When i use the classwizard to get the Create method, i get:

BOOL CMyFrame::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)
{
      // TODO: Add your specialized code here and/or call the base class
      
      return CDialog::Create(IDD, pParentWnd);
}

I am really confused as to what is what in your app.  Please check the header, you should have something like
class CMyFrame : public CDialog
Avatar of pikco

ASKER

Yes, in the header:


/////////////////////////////////////////////////////////////////////////////
// CMyFrame dialog

class CMyFrame : public CDialog
{
// Construction
public:
      CMyFrame(CWnd* pParent = NULL);   // standard constructor

etc.........
Avatar of pikco

ASKER

What I wrote before was from the .cpp file.
Avatar of pikco

ASKER

Is it fair for me to close this question off?
I haven't really received any ideas that have worked.
Any objections let me know ;)
Does my idea have not worked? Apparently using a dialog template could be simpler, but you have verified this is not necessarily true. When you work with a frame window, it is better to make controls directly as childs, in my opinion.
This advice may be of help.  It really depends on how much was done by your colleague before you took the app over.

Ask yourself the following questions.
Do I need a toolbar?
Do I need a menu?
Do I need a statusbar?
Will I be using accelerators? (Press alt+A and it acts as if you had pressed a button for example)

If the answers are no then create a new dialog based project.
If an answer is yes then create a new SDI, modify settings as required (KEEP doc/view) and at the final stage change the CView to CFormView.  That will create a dialog resource that you can use the resource editor to add buttons ... to.

A bit of info maybe you don't know.  The dialog based app does NOT automatically provide support for some user interface updating and actions the way a SDI/MDI based project does.  Doing the above will mean you have less to code if you did require one of those features in your app.
Avatar of pikco

ASKER

It doesn't really help, but thanks for the advice anyway. I've chosen to just continue workign on top of the old interface.

I think best thiing for me to do is award points across the 3 of you for being so nice and helping.
On an aside, If any of you three want to point me in the direction of some good garbage collection tips or classes that do it for you if such things may exist, that would be nice too.

=)
I don't like garbage collection in general - A memory leak tells me I haven't got the logic correct.