Archived

This topic is now archived and is closed to further replies.

FERNANDO-BRASIL

MFC: #$@#$##$#@$#@

Recommended Posts

Hi guys, I''ve been trying to make a MFC application in the last 3 days, and I''m getting nervous with all this.... I didn''t understand well, but I think we can say MFC is subvided in 3 parts: CFrameWnd, CView and CDocument. Well, ok... My problem is that I have a toolbar declared in CFrameWnd and I want to access this toolbar when I''m inside CView. How can I do this? I just can''t understand this!! The application has a class CFrameWnd, but I don''t see anywhere the declaration of a variable for this class... so, how I''m going to access it?? By mind? Thank you guys. Fernando

Share this post


Link to post
Share on other sites
Yeah, but how Am'I goind to send the toolbar a message if there isn't a way to reference it?

The problem is that the toolbar is declared in the CFrameWnd class of the application.

To reference it, i would have to use something like this:

framewnd.Toolbar.SendMessage();

But I don't know how to do this! MFC is so different, I searched on the entire code, but I didn't find something like this:

CFrameWnd framewnd;

So, how does it work? I really don't know.

[edited by - FERNANDO-BRASIL on August 31, 2002 2:47:24 PM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
I think what''s going on here is that you are trying to put code in the wrong class. The way MFC was explained to me was as three layers of abstraction:

CFrameWnd handles the user interface (toolbar, menus, buttons, etc.)
CDocument stores the instance-specific data for a single document
CView creates a visual representation based on the given CDocument instance

So if there is a block of code which, say, enables or disables buttons on the toolbar, I would put that block of code in your CFrameWnd class.

Otherwise, CView should have a pointer to its CDocument, and CDocument should have a pointer to the CFrameWnd. There again I''m working from memory, as I haven''t used MFC in years.

Hope that helps.

Tom

Share this post


Link to post
Share on other sites
Thank you for the information Tom! It really helped me!

But let's say I want to enable all the buttons of the Toolbar when the mouse Moves on the Principal Application, How can I do that?

I tryed to make a CFrameWnd::OnMouseMove, but the application didn't send the message to it, it only sended the message to CView::OnMouseMove. And here, I don't have access to CFrameWnd...



[edited by - FERNANDO-BRASIL on August 31, 2002 3:01:39 PM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Glad I can be of help. But I''ve been playing with MFC for a few minutes and I can''t figure out how CView accesses CFrameWnd.

My only further suggestion is to let CView send a custom Window Message to the parent window by its window handle, and catch that in the CFrameWnd.

Hope that works out for you.

Tom

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Code is as follows:

void CMfctestView::OnMouseMove(UINT nFlags, CPoint point)
{
CWnd *w = GetParent();
w->SendMessage(WM_MOUSEMOVE, nFlags, point.x + (point.y<<16));

CView::OnMouseMove(nFlags, point);
}

Then you can catch WM_MOUSEMOVE messages in CFrameWnd.

Tom

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Simple answer to your problem (2 actually);

For the default toolbar included in your Application:

First, include the MainFrame.h header in your view class:
#include "MainFrame.h" 


After that, take the tool bar declaration out of the protected member section of the MainFrame class header and put it in the public section.

Next where ever you want to use the tool bar, insert this snippet of code.

CMainFrame* pMainFrame;
pMainFrame = (CMainFrame*)AfxGetApp()->m_pMainWnd;


And use the tool bar like this:
pMainFrame->m_wndToolbar.ShowWindow(SW_HIDE) 

Or what ever you want to do with the toolbar.

For future tool bars, goto the "project" menu, goto "insert component and controls", open up the VC++ library and insert a tool bar. Register the tool bar to the CView class when you are asked to provide the class that handles it.

-James

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Excellent. If you want to know where I derived my solution from, check out singleton patterns. Only instead of the class storing the pointer to it''s only initialization, the CWinApp class has a pointer the the MainFrame (CFrameWnd) object it created. AfxGetApp() will allow you to access any of the application class members.

Also, check out how MFC gets the CDocument in the CView class. You will find out that this is the same method I used. Leanring the Document/View archetecture was a speed bump for me until I learned the Singleton pattern, then it all made sence.

Cheers
-James

Share this post


Link to post
Share on other sites
Or you can do:

MyFrame *pFrame = (MyFrame*)GetParentFrame();

or

MyFrame *pFrame = (MyFrame*)AfxGetMainWnd();

within view class.

View has easy access to document thru GetDocument(), Frame has access to document thru GetActiveDocument(), you can use AfxGetApp() or global pApp. I wrote from my memory.

Don''t forget the hierarchy chain thru which messages are passed around. Frame is first then view then frame then docs I think. MSDN has tons of useful mfc articles. Also check out knowledge base articles for mfc hints.

Share this post


Link to post
Share on other sites
Also wanted to say that don''t get discouraged with mfc. I took two weeks off to read all the mfc info I could find and that has helped me a lot. Don''t forget once you get good at it you can use undocumented mfc functions to do what you want. But make sure you document them in your code. I had to resort to this type of thing to get at the filename before save as.. box got opened and replace it with different name. If something seems impossible to do in mfc then reading thru the mfc source can help.

Share this post


Link to post
Share on other sites
Thank you guys!! You really helped me a lot!!!

I think I''m starting to love MFC now.. hehe

But, by the way, when using Win32API to do an application, we have to do our message handler by hand, like this:

loop {
   PeekMessage()
   TranslateMessage()
   DispathMessage()
}

With MFC, this message handler disappear. But with my old win32 applications I used to put a call to a function there, like:

loop {
   if (PeekMessage() == TRUE) {
     PeekMessage()
     TranslateMessage()
     DispathMessage
   } else {
     Process();
   }
}

Is there in MFC, an OnSomething function that I can use to put a call to a function like I used to put in my win32 applications?

THank you again guys!

Share this post


Link to post
Share on other sites
In MFC I think the best way to handle that might be threads. You could make a looping thread that does your processing function. Otherwise you might have to do the OnTimer function which isn''t very accurate.

Check the MFC examples in the DX SDK, they should have a method layed out for that very thing.

Always remember, you''''re unique. Just like everyone else.

Share this post


Link to post
Share on other sites
the other day I decided I am finished with MFC. With .net coming out and DX samples not using it no use wasting brain power on it

DOWN WITH MFC!

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
I''ve never done MFC, but maybe OnIdle is what your looking for?

Share this post


Link to post
Share on other sites
Hi!

I tested it here, but it didn''t work the way I expected.

The help says that OnIdle function is called when the message queue is empty, and it''s true! I tested here, but I don''t know, it''s not perfect... There are sometimes that the function would be called, but its not.

BTW, can you guys could tell me why OnKeyUp and OnKeyDown don''t process VK_DOWN and VK_RIGHT messages? I tryed to get them, but I don''t know why, the dialog box only sends the VK_UP and VK_LEFT.

Thank you.

Share this post


Link to post
Share on other sites
Hey! I did it!

I''m using OnIdle, but now I''m returning a nonzero value and the things are right.

I read the MSDN help about OnIdle, and didn''t understand very well why I have to return a nonzero value, but now it''s working.

Share this post


Link to post
Share on other sites