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.
| Вернуться в корень Архива |