OCX's, Control Bars & OnUpdateCmdUI
Michael R Thompson -- mike@tracker.com.au
Tuesday, April 16, 1996
Environment: Win95, VC 4.0 & OCX
I am attempting to create an MFC ControlBar from an OCX and I am having =
problems with OnUpdateCmdUI -- none of the buttons on my ControlBar are =
getting their OnUpdate methods called.
I had to trick MFC into letting me create the ControlBar in the first =
place, so I shall explain how I did this, as it may have some bearing on =
my problem.
When a Control Bar is created it requires a Frame Window as a parent. =
This enables the ControlBar to be docked. I require my ControlBar to be =
floating only, so I don't really need a Frame Window, however, MFC won't =
let you specify a CWnd as the owner - it must be a CFrameWnd. I got =
around this problem by creating an empty FrameWnd and putting the =
ControlBar in it. This works fine - I have a floating control bar for my =
OCX, but since the OnUpdateCmdUI mechanism isn't working properly I =
cannot dynamically control the state of the buttons on the control bar.
Has anybody attempted anything like this? Any help much appreciated.
Mike.
Steve Loughran -- slo@hplb.hpl.hp.com
Thursday, April 18, 1996
>I am attempting to create an MFC ControlBar from an OCX and I am having
>problems with OnUpdateCmdUI -- none of the buttons on my ControlBar are
>getting their OnUpdate methods called.
I did something similar, and had pretty much the same problems, too.
The fundamental problem is that not only do the controls require a frame
window, they also seem to require document and view classes so that they can
route the enablers properly.
I solved the problems differently, and never actually created a frame window.#
As I recall I
-derived a class from CToolBarCtl
-stole the private CToolCmdUI enabler class from the MFC source to manage button
enablement, pasting it into my own module
-Modified my toolbar class's update function to not require a frame window,
but instead route all update functions directly to its parent
-Added a timer to the toplevel OCX window to regularly trigger UI updates
void COcxBar::OnUpdateCmdUI(CFrameWnd* /*pTarget*/, BOOL bDisableIfNoHndler)
{
CToolCmdUI state;
state.m_pOther = this;
state.m_nIndexMax = (UINT)DefWindowProc(TB_BUTTONCOUNT, 0, 0);
for (state.m_nIndex = 0; state.m_nIndex < state.m_nIndexMax;
state.m_nIndex++)
{
// get buttons state
TBBUTTON button;
_GetButton(state.m_nIndex, &button);
state.m_nID = button.idCommand;
// ignore separators
if (!(button.fsStyle & TBSTYLE_SEP))
{
// allow the toolbar itself to have update handlers
if (CWnd::OnCmdMsg(state.m_nID,
CN_UPDATE_COMMAND_UI, &state, NULL))
continue;
//and our owner control
m_owner->OnCmdMsg(state.m_nID,
CN_UPDATE_COMMAND_UI, &state, NULL);
}
}
}
Adding tooltips was another complication, which actually took more time. Nancy
Clut's articles covered the basics, but it turned out that my subclassed toolbar
wndProc needed to process the ansi TTN_NEEDTEXTA and unicode TTN_NEEDTEXTW
notifications, in order to work properly under both win95 and winNT.
-Steve
Jeff_Stong@bio-rad.com
Thursday, April 18, 1996
<< When a Control Bar is created it requires a Frame Window as a
parent. >>
This is not my experience. I have created a CToolBar (which is
directly derived from CControlBar) that has a CDialogBar as its
parent.
However, I also had trouble with on OnUpdateCmdUI mechanism behaving
as expected. In my case the tool bar buttons were only correctly
updated when the dialog bar that was their parent was docked with a
frame window.
I was able to solve the problem by deriving a class from CToolBar and
overriding the virtual function CControlBar::OnUpdateCmdUI. In my
case all I had was ensure that the pTarget parameter always pointed to
my frame window (GetParentFrame() did the trick). It was broken
because when the dialog bar was undocked, pTarget pointed to the
CMiniFrameWnd of the dialog bar. There were no appropriate
ON_UPDATE_COMMAND_UI in the mini-frame wnd class so MFC defaulted to
disabled.
In your case overriding CToolBar::OnUpdateCmdUI still might work.
CToolBar::OnUpdateCmdUI requires that pTarget be a CFrameWnd.
However, inspection of the MFC code shows that MFC only uses pTarget
in calls to CCmdUI::DoUpdate() and CWnd::UpdateDialogControls(), both
of which require only CCmdTarget pointers. While not the safest C++
practice it might be possible to cast a CCmdTarget pointer to a class
with your ON_UPDATE_COMMAND_UI handlers to CFrameWnd and pass that on
instead of the pTarget MFC comes up with (in this case your empty
CFrameWnd).
Or you might try adding ON_UPDATE_COMMAND_UI handlers to your empty
CFrameWnd class.
______________________________ Reply Separator _________________________________
Subject: OCX's, Control Bars & OnUpdateCmdUI
Author: mfc-l@netcom.com at Internet
Date: 4/17/96 11:27 PM
Environment: Win95, VC 4.0 & OCX
I am attempting to create an MFC ControlBar from an OCX and I am having =
problems with OnUpdateCmdUI -- none of the buttons on my ControlBar are =
getting their OnUpdate methods called.
I had to trick MFC into letting me create the ControlBar in the first =
place, so I shall explain how I did this, as it may have some bearing on =
my problem.
When a Control Bar is created it requires a Frame Window as a parent. =
This enables the ControlBar to be docked. I require my ControlBar to be =
floating only, so I don't really need a Frame Window, however, MFC won't =
let you specify a CWnd as the owner - it must be a CFrameWnd. I got =
around this problem by creating an empty FrameWnd and putting the =
ControlBar in it. This works fine - I have a floating control bar for my =
OCX, but since the OnUpdateCmdUI mechanism isn't working properly I =
cannot dynamically control the state of the buttons on the control bar.
Has anybody attempted anything like this? Any help much appreciated.
Mike.
Niels Ull Jacobsen -- nuj@kruger.dk
Saturday, April 20, 1996
At 18:44 16-04-96 +-1000, you wrote:
>Environment: Win95, VC 4.0 & OCX
>
>I am attempting to create an MFC ControlBar from an OCX and I am having
problems with OnUpdateCmdUI -- none of the buttons on my ControlBar are
getting their OnUpdate methods called.
>
>I had to trick MFC into letting me create the ControlBar in the first
place, so I shall explain how I did this, as it may have some bearing on =
my
problem.
>
>When a Control Bar is created it requires a Frame Window as a parent. Th=
is
enables the ControlBar to be docked. I require my ControlBar to be floati=
ng
only, so I don't really need a Frame Window, however, MFC won't let you
specify a CWnd as the owner - it must be a CFrameWnd. I got around this
problem by creating an empty FrameWnd and putting the ControlBar in it. T=
his
works fine - I have a floating control bar for my OCX, but since the
OnUpdateCmdUI mechanism isn't working properly I cannot dynamically contr=
ol
the state of the buttons on the control bar.
>
During idle time (no messages pending), MFC works through the children of
your main frame and call OnUpdateCmdUI for the UI elements the contain. S=
o
if you create your=20
own, separate, frame window, you won't get the functionality you want.you
won't get the functionality you require.
I think the best solution would simply be to turn off docking for the
control bar with m_Bar.SetBarStyle(m_Bar.GetBarStyle() & ~(CBRS_ALIGN_TO=
P |
CBRS_ALIGN_BOTTOM | CBRS_ALIGN_LEFT | CBRS_ALIGN_RIGHT | CBRS_ALIGN_ANY)=
).
Or, alternatively, you can call it's OnUpdateCmdUI directly in an overrid=
den
CWinApp::OnIdle.
Be sure to read the notes on how to override CWinApp::OnIdle.
>Has anybody attempted anything like this? Any help much appreciated.
>
>Mike.
>
>
>
>
Niels Ull Jacobsen, Kr=FCger A/S (nuj@kruger.dk)
Everything stated herein is THE OFFICIAL POLICY of the entire Kruger grou=
p
and should be taken as legally binding in every respect. Pigs will grow
wings and fly.
| Вернуться в корень Архива
|