Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to delegate messages caused by a toolbar to view?

19 views
Skip to first unread message

Stefan Rauch

unread,
Oct 26, 2002, 11:56:39 AM10/26/02
to
Hi,
I have an application with this layout:

====================================
| Toolbar1 || Toolbar2 |
|----------------||----------------|
| || |
| View1 || View2 |
| || |
====================================
| Toolbar3 || Toolbar4 |
|----------------||----------------|
| || |
| View3 || View4 |
| || |
====================================

I did this, by dividing my MainFrame in 4 panes with a splitter. After that,
I splitt each of this panes again in two panes, one for the toolbar, an the
otherone for the view.
My Problem with this layout is, that all messages, caused by any toolbar are
delegated to the currently active view, but I can't ensure, that this view
is that view, I would expect. E.g. if I press a button in toolbar2, but
previously did sth. in view 4, view 4 is the target of the messages, caused
by toolbar 2. But I want, that they arrive in view 2.
How can I achieve, that messages, caused by toolbar1 are delegated to view1?
I tried getting a reference to the toolbar, which sent the message with
GetActiveWindow an GetForegroundWindow, but this didn't work for me. But
maybe this possible.
Even better would be, delegateing messages directly to the concerned view.
Any hints?
thanks in advance

--
Stefan Rauch mailto:st.r...@NO-SPAMgmx.de
(please remove NO-SPAM)


Scott McPhillips

unread,
Oct 26, 2002, 2:45:58 PM10/26/02
to

The toolbar sends messages to its parent window. As an experiment you
might try calling SetParent of each toolbar to reparent it to the
correct view. That's a little weird and I don't know if it would mess
something else up, but it's easy to try.

A more conventional solution would be to create each toolbar as a child
of its view so it will send its messages to that view. To do that you
would get rid of the 4 interior splitters and create each toolbar in its
view's OnInitialUpdate, passing 'this' as the pParent for the toolbar.

The DlgCbr32 MFC sample shows how to create a toolbar on a dialog. The
same technique and fix works for creating a toolbar on a view. This
works nicely if your view is a CFormView. If your views draw graphics
and you don't want the toolbar obstructing your graphic origin then ask
for more suggestions :)

--
Scott McPhillips [VC++ MVP]

Ajay Kalra

unread,
Oct 26, 2002, 8:27:01 PM10/26/02
to
One thing that you can try is to combine the toolbar and the view in a
CFrameWnd. Then you will have 4 CFrameWnd's as the panes of CMainFrame. This
will automatically route the messages from a toolbar to the individual view
that is attached to the same parent CFrameWnd.

--
Ajay Kalra [MVP - VC++]
ajay...@yahoo.com


"Stefan Rauch" <st.r...@gmx.de> wrote in message
news:apee0t$1ag$01$1...@news.t-online.com...

Stefan Rauch

unread,
Oct 27, 2002, 2:00:48 PM10/27/02
to
Hi Scott,
meanwhile I've tried a few things. But I'm not really satisfied with my
current sollution.
"Scott McPhillips" <scot...@mvps.org> schrieb im Newsbeitrag
news:3DBAE2E6...@mvps.org...

>
> The DlgCbr32 MFC sample shows how to create a toolbar on a dialog. The
> same technique and fix works for creating a toolbar on a view. This
> works nicely if your view is a CFormView. If your views draw graphics
> and you don't want the toolbar obstructing your graphic origin then ask
> for more suggestions :)

Something like this would be very nice. But my view is not a Formview, so
the way, shown in that Example doesn't work. I also tried the way, suggested
by Ajay Kalra, posted in a message in this thread. He suggested, to use a
FrameWnd as Child in the splitter. So I get rid of the inner splitter.
There's also an sample at http://www.codeproject.com/docking/splittest.asp,
where this approach is explained. But if I try it this way, something ugly
happens, when my MainFrame receives the WM_CLOSE message. It seems, that
something is wrong with the viewlist in the document. But I can't step into
the code, where the crash is caused.
So far, I do it this way:
In MainFrame, I overwrote the OnCommand. There I can get a handle to the
Toolbar, in which a button was clicked. I set the associated view as the
current view, an so the message is routed to the correct view.
The code looks something like this:

if(HIWORD(wParam) == 0)
{
if( (LOWORD(wParam) == ID_CAMERA_FRONT) ||
(LOWORD(wParam) == ID_CAMERA_LEFT) ||
(LOWORD(wParam) == ID_CAMERA_TOP) ||
(LOWORD(wParam) == ID_CAMERA_FREE) ||
(LOWORD(wParam) == ID_TOGGLE_VIEWLAYOUT) )
{
COGLViewToolBar* pTB;

if( (pTB=dynamic_cast<COGLViewToolBar*>(CWnd::FromHandle((HWND)lParam))) )
{
pTB->m_nViewMode = LOWORD(wParam);

if(pTB == &this->m_wndViewBar1)
{
CView* pView = (CView*)m_barSplitter1.GetPane(1,0);
SetActiveView(pView);
switchActiveView((CMKSPreProView*)pView);
}

I'm not very happy with this solution, so if you have more ideas, let me
know.
Thanks,
Stefan


Stefan Rauch

unread,
Oct 27, 2002, 2:07:51 PM10/27/02
to
Hi Ajay ,
I've alread tried it this way. There's also an example, explaining this at
approach at http://www.codeproject.com/docking/splittest.asp. But it didn't
work for me. Something is going wrong, when the MainFrame receives the
WM_CLOSE message. It seems, if something is wrong with the viewlist in the
Document. Tomorow, when I am back in the office, I can send a more detailed
description of the problem. This approach would be my favourite.
Thanks

Stefan
"Ajay Kalra" <ajay...@yahoo.com> schrieb im Newsbeitrag
news:O5uGH7UfCHA.1300@tkmsftngp08...

Scott McPhillips

unread,
Oct 27, 2002, 6:33:10 PM10/27/02
to
Stefan Rauch wrote:
> Something like this would be very nice. But my view is not a Formview, so
> the way, shown in that Example doesn't work. I also tried the way, suggested
> by Ajay Kalra, posted in a message in this thread. He suggested, to use a
> FrameWnd as Child in the splitter. So I get rid of the inner splitter.
> There's also an sample at http://www.codeproject.com/docking/splittest.asp,
> where this approach is explained. But if I try it this way, something ugly
> happens, when my MainFrame receives the WM_CLOSE message. It seems, that
> something is wrong with the viewlist in the document. But I can't step into
> the code, where the crash is caused.

As I recall, you "unprotected" the view c'tor so you could create it
yourself. That could be the problem. When MFC creates a view it
registers it with the document, which keeps a pointer to it. If you're
going to use a frame window in each pane then let the frame create it
(OnCreateClient), or if not using frames then create it using code like
CSplitterWnd::CreateView. That protected c'tor is a warning from the
MFC folks: "You need to do more than just create a view object."

Did you install the MFC source from the VC CD? That would be invaluable
if you don't have it. You're well beyond the basics with this design
and will be learning a lot about the doc/frame/view interaction by the
time it's right.

You are already working on two approaches - here's a third: In a similar
design I used a CFormView in each splitter, put toolbars and status bars
on the formviews, and then put another view (for graphics) in the rest
of the form client area. This lets me have no titlebar - or a
custom-drawn imitation titlebar like Outlook's panes.

Ajay Kalra

unread,
Oct 27, 2002, 9:28:38 PM10/27/02
to
It should work. I recall seeing an example some time ago on codeproject
where a CFrameWnd was a child of a dialog and a toolbar was inserted in it.
The toolbar coudl docked, floated etc. Pretty amazing. So you should be able
to do this but you may have to tweak stuff as you are introducing another
layer between CMainFrame and the view.

--
Ajay Kalra [MVP - VC++]
ajay...@yahoo.com

"Stefan Rauch" <st.r...@gmx.de> wrote in message

news:aphdjc$5ov$05$1...@news.t-online.com...

Stefan Rauch

unread,
Oct 28, 2002, 5:12:22 AM10/28/02
to
Hi,
Scott McPhillips <scot...@mvps.org> wrote in message
>
> As I recall, you "unprotected" the view c'tor so you could create it
> yourself. That could be the problem. When MFC creates a view it
> registers it with the document, which keeps a pointer to it. If you're
> going to use a frame window in each pane then let the frame create it
> (OnCreateClient), or if not using frames then create it using code like
> CSplitterWnd::CreateView. That protected c'tor is a warning from the
> MFC folks: "You need to do more than just create a view object."

Thats exactly, what I'm trying, to do.
I derived a class form CFrameWnd, CSplitterFrame, and call the create
function of the view in CSplitterFrame::OnCreateClient.
At the first sight, everything seems to work well, but if I close my
application, this nasty crash occurs.

>
> Did you install the MFC source from the VC CD? That would be invaluable
> if you don't have it. You're well beyond the basics with this design
> and will be learning a lot about the doc/frame/view interaction by the
> time it's right.

I have installed the MFC-sources and tried again - but I can't step
into.
The crash is caused in this Line in CFrameWnd::OnClose (File
Winfrm.cpp in line 829): POSITION pos =
pDocument->GetFirstViewPosition();
I figured out, that every thing works fine, if the view, I create in
CSplitterFrame::OnCreateClient is NOT connected with the document
(m_pCurrentDoc in CCreateContext is NULL). But if I connect the view
with the Document, it doesn't work.
But I need the view, connected with the document.

Best regards,
Stefan

0 new messages