Toolbar out of visible area.
Poul A. Costinsky -- wizsofti@datasrv.co.il Tuesday, January 16, 1996 Hi MFC-ers! My app (MFC 3.2, NT 3.51 & Win95) has 3 toolbars. When an user drags one of them and drops it over another, the second toolbar moves right, and if it's too much right, it becomes out of mainframe window - so user cannot see it. Next time user runs a program (after SaveBarState/LoadBarState) it remains out. Can I prevent toolbar from being moved out of client area of mainframe window? Here is a code: //*********************************************************************** int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1) return -1; if (!m_wndToolBar.Create(this) || !m_wndToolBar.LoadBitmap(IDR_MAINFRAME) || !m_wndToolBar.SetButtons(buttons, sizeof(buttons)/sizeof(buttons [0]))) { TRACE0("Failed to create toolbar\n"); return -1; // fail to create } if (!m_wndStatusBar.Create(this) || !m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(indicators [0]))) { TRACE0("Failed to create status bar\n"); return -1; // fail to create } { UINT nID, nStyle; int cx; m_wndStatusBar.GetPaneInfo (0, nID, nStyle, cx); m_wndStatusBar.SetPaneInfo (0, nID, SBPS_STRETCH | SBPS_NORMAL, cx); } if (!m_wndNavigationBar.Create (this)) { TRACE0("Failed to create navig. bar\n"); return -1; // fail to create } if (!m_wndInputDialogBar.Create (this, IDD_INPUT_DIALOG_BAR, CBRS_TOP | CBRS_TOOLTIPS | CBRS_FLYBY, IDD_INPUT_DIALOG_BAR)) { TRACE0("Failed to create Dialog bar\n"); return -1; // fail to create } m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); EnableDocking(CBRS_ALIGN_ANY); DockControlBar(&m_wndToolBar); DockControlBar(&m_wndNavigationBar); m_wndInputDialogBar.EnableDocking(CBRS_ALIGN_ANY); DockControlBar(&m_wndInputDialogBar); m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY); m_wndInputDialogBar.SetBarStyle(m_wndInputDialogBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY); LoadBarState (TOOLBAR_STR); return 0; } void CMainFrame::OnDestroy() { SaveBarState (TOOLBAR_STR); CMDIFrameWnd::OnDestroy(); } Regards, Poul A. Costinsky(PoulACost@msn.com). ("`-''-/").___..--''"`-._ (`6_ 6 ) `-. ( ).`-.__.`) (_Y_.)' ._ ) `._ `. ``-..-' _..`--'_..-_/ /--'_.' ,' (il).-'' (li).' ((!.-
Ghislain Lachapelle -- Ghislain.Lachapelle@Matrox.COM Monday, January 22, 1996 At 11:27 96-01-16 +-200, you wrote: >Hi MFC-ers! > >My app (MFC 3.2, NT 3.51 & Win95) has 3 toolbars. When an user >drags one of them and drops it over another, the second toolbar >moves right, and if it's too much right, it becomes out of mainframe >window - so user cannot see it. Next time user runs a program >(after SaveBarState/LoadBarState) it remains out. > >Can I prevent toolbar from being moved out of client area of >mainframe window? > > >Here is a code: > >//*********************************************************************** >int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) >{ > if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1) > return -1; > > if (!m_wndToolBar.Create(this) || > !m_wndToolBar.LoadBitmap(IDR_MAINFRAME) || > !m_wndToolBar.SetButtons(buttons, > sizeof(buttons)/sizeof(buttons [0]))) > { > TRACE0("Failed to create toolbar\n"); > return -1; // fail to create > } > > if (!m_wndStatusBar.Create(this) || > !m_wndStatusBar.SetIndicators(indicators, > sizeof(indicators)/sizeof(indicators [0]))) > { > TRACE0("Failed to create status bar\n"); > return -1; // fail to create > } > { > UINT nID, nStyle; > int cx; > m_wndStatusBar.GetPaneInfo (0, nID, nStyle, cx); > m_wndStatusBar.SetPaneInfo (0, nID, SBPS_STRETCH | SBPS_NORMAL, cx); > } > if (!m_wndNavigationBar.Create (this)) > { > TRACE0("Failed to create navig. bar\n"); > return -1; // fail to create > } > > if (!m_wndInputDialogBar.Create (this, IDD_INPUT_DIALOG_BAR, > CBRS_TOP | CBRS_TOOLTIPS | CBRS_FLYBY, IDD_INPUT_DIALOG_BAR)) > { > TRACE0("Failed to create Dialog bar\n"); > return -1; // fail to create > } > m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); > EnableDocking(CBRS_ALIGN_ANY); > > DockControlBar(&m_wndToolBar); > DockControlBar(&m_wndNavigationBar); > m_wndInputDialogBar.EnableDocking(CBRS_ALIGN_ANY); > DockControlBar(&m_wndInputDialogBar); > m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() | > CBRS_TOOLTIPS | CBRS_FLYBY); > m_wndInputDialogBar.SetBarStyle(m_wndInputDialogBar.GetBarStyle() | > CBRS_TOOLTIPS | CBRS_FLYBY); > > LoadBarState (TOOLBAR_STR); > return 0; >} Hi is the code is right. Unfortunately, it seems our dear friends at Microsoft didn't test so much their stuff with real world control bars (except DOCKTOOL sample!!). I got a very similar problem last fall and partially solved it. In addition to what you said, the same problem appears if the user changes its resolution for a lower one. Each time I load the application (in CMainframe::OnCreate) and each time I make my control bar visible (in View menu), I call the following utility function (for all controls in OnCreate and only one in View menu): // GLachape, November 10th, 1995, BUG FIX: The MFC LoadBarState and SaveBarState functions // do not check the screen resolution. If a CControlBar is undocked and positionned to the // right of the screen, changing the video resolution for a lower one will make this control // appear outside the monitor screen and it is impossible to recover it without destroying // the registry database. // This simple function is intended to prevent this problem to appear. It simply checks if // the window is visible and undocked. If yes, it verifies that the control origin is not // outside the screen resolution right and bottom sides. void CMainFrame::CheckControlToFitInScreen(CControlBar* pControlBar) { int ScreenResX= GetSystemMetrics(SM_CXSCREEN); int ScreenResY= GetSystemMetrics(SM_CYSCREEN); int nOffsetFactor= 15; BOOL bVisibilityCheck= ( (pControlBar->GetStyle() & WS_VISIBLE) != 0); if (!bVisibilityCheck) return; // toolbar not visible if (!pControlBar->IsFloating()) { // GLachape, November 14th, 1995, Second bug fix. // a toolbar is moved when we dock another toolbar over it. // this moved toolbar can be outside the screen. CRect ControlBarRect; pControlBar->GetWindowRect(&ControlBarRect); BOOL bControlBarMoved= FALSE; DWORD dwStyle= 0; if (ControlBarRect.left >= (ScreenResX - nOffsetFactor) ) { bControlBarMoved= TRUE; dwStyle= CBRS_ALIGN_TOP; ControlBarRect.left= ScreenResX- ControlBarRect.Width(); } if ( ControlBarRect.top >= (ScreenResY - nOffsetFactor)) { bControlBarMoved= TRUE; dwStyle= CBRS_ALIGN_LEFT; ControlBarRect.top= ScreenResY- ControlBarRect.Height(); } if (bControlBarMoved) { CPoint ControlBarOrigin(ControlBarRect.TopLeft()); FloatControlBar( pControlBar, ControlBarOrigin, dwStyle); } return; // toolbar is docked } // Not sure it is neccessary RecalcLayout(); // ok, criterias meet: visible and undocked CFrameWnd* pControlFrame= pControlBar->GetDockingFrame(); if (pControlFrame== NULL) return; CRect ControlRect; pControlFrame->GetWindowRect(ControlRect); BOOL bControlMoved= FALSE; if (ControlRect.left >= (ScreenResX - nOffsetFactor) ) { bControlMoved= TRUE; ControlRect.left= ScreenResX- ControlRect.Width(); } if (ControlRect.top >= (ScreenResY - nOffsetFactor) ) { bControlMoved= TRUE; ControlRect.top= ScreenResY- ControlRect.Height(); } // move the control bar if needed if (bControlMoved) { pControlFrame->SetWindowPos(&wndTop, ControlRect.left, ControlRect.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER ); //| SWP_NOACTIVATE); } } Be aware that this function doesn't solve completely the problem because a control bar still can be moved outside the screen area. But it will come back if the user swicth the View-->my_bar option in the menu or the next time he reloads the application. To solve completely the problem, we should perhaps derive the CToolbar or overwrite the CMainFrame::RecalcLayout function. I didn't have the time to try it for now, if you do or have other suggestions, please reply me. Hope this will help /////////////////////////////////////////////////////////////////////// Ghislain Lachapelle(Ghislain.Lachapelle@matrox.com) Ghislain Lachapelle, ext. 2495 Matrox Electronic Systems Ltd. Imaging Group 1055 St-Regis Blvd. Dorval, Quebec, Canada H9P 2T4 (514) 685-7230, ext. 2495 ////////////////////////////////////////////////////////////////////////
Poul A. Costinsky -- wizsofti@datasrv.co.il Thursday, January 25, 1996 Thank you, it worked. Actually, I did the same thing. I just wondered maybe there is an easier way. Anybody? Regards, Poul A. Costinsky(PoulACost@msn.com). ("`-''-/").___..--''"`-._ (`6_ 6 ) `-. ( ).`-.__.`) (_Y_.)' ._ ) `._ `. ``-..-' _..`--'_..-_/ /--'_.' ,' (il).-'' (li).' ((!.- ---------- From: owner-mfc-l@netcom.com on behalf of Ghislain Lachapelle Sent: Monday, January 22, 1996 3:34 PM To: mfc-l@netcom.com Subject: Re: Toolbar out of visible area. Hi is the code is right. Unfortunately, it seems our dear friends at Microsoft didn't test so much their stuff with real world control bars (except DOCKTOOL sample!!). I got a very similar problem last fall and partially solved it. In addition to what you said, the same problem appears if the user changes its resolution for a lower one. Each time I load the application (in CMainframe::OnCreate) and each time I make my control bar visible (in View menu), I call the following utility function (for all controls in OnCreate and only one in View menu): // GLachape, November 10th, 1995, BUG FIX: The MFC LoadBarState and SaveBarState functions // do not check the screen resolution. If a CControlBar is undocked and positionned to the // right of the screen, changing the video resolution for a lower one will make this control // appear outside the monitor screen and it is impossible to recover it without destroying // the registry database. // This simple function is intended to prevent this problem to appear. It simply checks if // the window is visible and undocked. If yes, it verifies that the control origin is not // outside the screen resolution right and bottom sides. void CMainFrame::CheckControlToFitInScreen(CControlBar* pControlBar) { int ScreenResX= GetSystemMetrics(SM_CXSCREEN); int ScreenResY= GetSystemMetrics(SM_CYSCREEN); int nOffsetFactor= 15; BOOL bVisibilityCheck= ( (pControlBar->GetStyle() & WS_VISIBLE) != 0); if (!bVisibilityCheck) return; // toolbar not visible if (!pControlBar->IsFloating()) { // GLachape, November 14th, 1995, Second bug fix. // a toolbar is moved when we dock another toolbar over it. // this moved toolbar can be outside the screen. CRect ControlBarRect; pControlBar->GetWindowRect(&ControlBarRect); BOOL bControlBarMoved= FALSE; DWORD dwStyle= 0; if (ControlBarRect.left >= (ScreenResX - nOffsetFactor) ) { bControlBarMoved= TRUE; dwStyle= CBRS_ALIGN_TOP; ControlBarRect.left= ScreenResX- ControlBarRect.Width(); } if ( ControlBarRect.top >= (ScreenResY - nOffsetFactor)) { bControlBarMoved= TRUE; dwStyle= CBRS_ALIGN_LEFT; ControlBarRect.top= ScreenResY- ControlBarRect.Height(); } if (bControlBarMoved) { CPoint ControlBarOrigin(ControlBarRect.TopLeft()); FloatControlBar( pControlBar, ControlBarOrigin, dwStyle); } return; // toolbar is docked } // Not sure it is neccessary RecalcLayout(); // ok, criterias meet: visible and undocked CFrameWnd* pControlFrame= pControlBar->GetDockingFrame(); if (pControlFrame== NULL) return; CRect ControlRect; pControlFrame->GetWindowRect(ControlRect); BOOL bControlMoved= FALSE; if (ControlRect.left >= (ScreenResX - nOffsetFactor) ) { bControlMoved= TRUE; ControlRect.left= ScreenResX- ControlRect.Width(); } if (ControlRect.top >= (ScreenResY - nOffsetFactor) ) { bControlMoved= TRUE; ControlRect.top= ScreenResY- ControlRect.Height(); } // move the control bar if needed if (bControlMoved) { pControlFrame->SetWindowPos(&wndTop, ControlRect.left, ControlRect.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER ); //| SWP_NOACTIVATE); } } Be aware that this function doesn't solve completely the problem because a control bar still can be moved outside the screen area. But it will come back if the user swicth the View-->my_bar option in the menu or the next time he reloads the application. To solve completely the problem, we should perhaps derive the CToolbar or overwrite the CMainFrame::RecalcLayout function. I didn't have the time to try it for now, if you do or have other suggestions, please reply me. Hope this will help /////////////////////////////////////////////////////////////////////// Ghislain Lachapelle(Ghislain.Lachapelle@matrox.com) Ghislain Lachapelle, ext. 2495 Matrox Electronic Systems Ltd. Imaging Group 1055 St-Regis Blvd. Dorval, Quebec, Canada H9P 2T4 (514) 685-7230, ext. 2495 ////////////////////////////////////////////////////////////////////////
| Вернуться в корень Архива |