From: nano on 26 Oct 2009 05:30 Hi, Good day. When i develop my Start Bar feature. I add the StatusBar to the bottom of my main window form. When i change the main window size, The status Bar can't move to the new position with my mouse action. Could you please give me some suggestion Thanks in advance. ========================================== BOOL CMyAppDlg::OnInitDialog() { /////////////////////////////////// Move Window //////////////////////////////// int screenx = GetSystemMetrics(SM_CXSCREEN); int screeny = GetSystemMetrics(SM_CYSCREEN); screenx = screenx * 1/3; screeny = screeny * 3/5; int mainwndx = 500; int mainwndy = 150; MoveWindow(mainwndx, mainwndy, screenx, screeny); GetWindowRect(m_mainPos); CRect rect; GetClientRect(&rect); m_TreeCommand.MoveWindow(GetTreeRect(), TRUE); m_bar.Create(this); //We create the status bar m_bar.SetIndicators(indicators,2); //Set the number of panes //Size the two panes m_bar.SetPaneInfo(0,ID_INDICATOR_NISH, SBPS_NORMAL,rect.Width()-100); m_bar.SetPaneInfo(1,ID_INDICATOR_TIME,SBPS_STRETCH ,0); //This is where we actually draw it on the screen RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST, ID_INDICATOR_TIME); //m_bar.GetStatusBarCtrl().SetBkColor(RGB(180,180,180)); m_bar.GetStatusBarCtrl().SetTimer(100,1000,NULL); m_bar.MoveWindow(GetStatusBarRect(),TRUE); } ========================================== CRect CMyAppDlg::GetTreeRect() { CRect rect, rectHead; GetClientRect(&rect); rectHead.left = static_cast<int>(rect.left + rect.Width() * 0.02); rectHead.top = static_cast<int>(rect.top + 95); rectHead.right = static_cast<int>(rect.left + rect.Width() * 0.98); //rectHead.bottom = static_cast<int>(rect.top + rect.Height() * 0.95); rectHead.bottom = static_cast<int>(rect.bottom - 25); return rectHead; } CRect CMyAppDlg::GetStatusBarRect() { CRect rect, rectHead; GetClientRect(&rect); rectHead.left = static_cast<int>(rect.left + rect.Width() * 0.02); rectHead.top = static_cast<int>(rect.bottom - 25); rectHead.right = static_cast<int>(rect.left + rect.Width() * 0.98); rectHead.bottom = static_cast<int>(rect.bottom); //rectHead.bottom = static_cast<int>(rect.top + 445); return rectHead; } ========================================== void CMyAppDlg::OnSize(UINT nType, int cx, int cy) { if(m_bInit == true) { m_TreeCommand.MoveWindow(GetTreeRect(), TRUE); //m_bar.MoveWindow(GetStatusBarRect(), TRUE); // when i uncommented this line, will jumped out runtime error.. } Invalidate(); CDialog::OnSize(nType, cx, cy); if ( !IsWindowVisible() ) return; } ==========================================
From: Joseph M. Newcomer on 26 Oct 2009 09:22 See below... On Mon, 26 Oct 2009 02:30:13 -0700 (PDT), nano <nano.he(a)gmail.com> wrote: >Hi, > > >Good day. > >When i develop my Start Bar feature. > >I add the StatusBar to the bottom of my main window form. >When i change the main window size, >The status Bar can't move to the new position with my mouse action. > >Could you please give me some suggestion > >Thanks in advance. >========================================== > >BOOL CMyAppDlg::OnInitDialog() >{ > /////////////////////////////////// Move >Window //////////////////////////////// > int screenx = GetSystemMetrics(SM_CXSCREEN); > int screeny = GetSystemMetrics(SM_CYSCREEN); **** I have no idea what this is intended for, because it cannot possibly work in a multiple-monitor situation. If I want this in the second monitor, you have sized it to my primary monitor. You should ask for the size of the monitor in which the application is currently displayed. Which may not be the primary monitor. **** > screenx = screenx * 1/3; **** This turns out to say screenx = 0; **** > screeny = screeny * 3/5; **** This turns out to say screeny = 0; Perhaps you meant to write screenx = (screenx * 1) / 3; screeny = (screeny * 3) / 5 or possibly screenx = (int)((double)screenx * 1.0/3.0); screeny = (int)((double)screeny * 3.0/5.0); **** > int mainwndx = 500; > int mainwndy = 150; **** The choice of random numbers here seems a bit strange. Why do you think these numbers have meaning on any machine but your own, this week, with your current settings, including your current display, your current display driver, your current screen resolution, and your current default font? They probably won't make sense on your machine next week if you change any one of these parameters, and they certainly won't make sense on my machine, which has two monitors, which run at two different resolutions, and which use a default font somewhat larger than normal. **** > MoveWindow(mainwndx, mainwndy, screenx, screeny); > GetWindowRect(m_mainPos); > CRect rect; > GetClientRect(&rect); > > m_TreeCommand.MoveWindow(GetTreeRect(), TRUE); > > m_bar.Create(this); //We create the status bar **** I see no test to validate this creation worked **** > m_bar.SetIndicators(indicators,2); //Set the number of panes **** m_bar.SetIndicators(indicators, _countof(indicators)); **** > //Size the two panes > m_bar.SetPaneInfo(0,ID_INDICATOR_NISH, > SBPS_NORMAL,rect.Width()-100); **** Evert comma should be followed by a space to make parameter lists readable! How is it that the semirandom number 100 is supposed to have meaning on my machine? It may have meaning on your machine this week (see above). **** > m_bar.SetPaneInfo(1,ID_INDICATOR_TIME,SBPS_STRETCH ,0); > //This is where we actually draw it on the screen > RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST, > ID_INDICATOR_TIME); > //m_bar.GetStatusBarCtrl().SetBkColor(RGB(180,180,180)); > m_bar.GetStatusBarCtrl().SetTimer(100,1000,NULL); **** Why are you setting a timer on the status bar? You have not shown that you have a derived subclass of the status bar...in fact, you have not shown the declaration of m_bar at all! **** > > m_bar.MoveWindow(GetStatusBarRect(),TRUE); >} > >========================================== > >CRect CMyAppDlg::GetTreeRect() >{ > CRect rect, rectHead; > GetClientRect(&rect); > rectHead.left = static_cast<int>(rect.left + rect.Width() * 0.02); > rectHead.top = static_cast<int>(rect.top + 95); **** How does 95 have meaning? **** > rectHead.right = static_cast<int>(rect.left + rect.Width() * 0.98); > //rectHead.bottom = static_cast<int>(rect.top + rect.Height() * >0.95); > rectHead.bottom = static_cast<int>(rect.bottom - 25); **** How does 25 have meaning? I see no place in the code that creates a status bar that suggests or implies that its height is 25. If you want to eliminate the status bar size from your area, you would first ask the status bar how high it is and subtract THAT value! **** > > return rectHead; >} > >CRect CMyAppDlg::GetStatusBarRect() >{ > CRect rect, rectHead; > GetClientRect(&rect); > rectHead.left = static_cast<int>(rect.left + rect.Width() * 0.02); > rectHead.top = static_cast<int>(rect.bottom - 25); > rectHead.right = static_cast<int>(rect.left + rect.Width() * 0.98); > rectHead.bottom = static_cast<int>(rect.bottom); > //rectHead.bottom = static_cast<int>(rect.top + 445); **** Similar comments here. You are using "magic numbers" that have no meaning. How did you determine 2% and 98% were meaningful values? What are 25 and 445 and how could they possibly make sense? If I have a 1920-wide monitor, how does 2% translate into pixels (38 pixels). I can display this window as 2944 pixels wide (across two monitors) so why should I have to deal with a 58-pixel border if I have a wide window? It doesn't make sense to create values that can vary depending on the window size in such a situation. A fixed border value would make sense. You can either use the client area (which takes the window borders into account) or use a fixed size such as 2 * ::GetSystemMetrics(SM_CXEDGE) which is computed based on the border sizes on a particular monitor environment and therefore will make sense across many machines in many contexts. Would it not make more sense to do { CRect rect; GetClientRect(&rect); CRect bar; m_bar.GetWindowRect(&bar); ScreenToClient(&bar); rect.top = rect.bottom - bar.Height(); return rect; } Note that the client rect already takes into account the border thicknesses, so the 2%-98% split is not necessary, and the position is merely the bottom of the client rect minus the height of the bar. The *actual* height of the bar, not some random number (25) that may or may not represent the height of the bar. You would also be better served using SetWindowPos instead of MoveWindow since SetWindowPos wants a width, height rather than absolute coordinates. I rarely write a MoveWindow call, and have used them only infrequently in the last 20 years. Also, SetWindowPos allows you to move without resizing and resize without moving, which is often convenient (although you must do both to handle a status bar resize) **** > > return rectHead; >} > > >========================================== > >void CMyAppDlg::OnSize(UINT nType, int cx, int cy) >{ > if(m_bInit == true) **** I don't understand. If m_bInit is a BOOL (or bool), it is *already* true or false, so why are you comparing it to true? You don't write if( (a > 0) == true) so why the unnecessary test here? You could write if(m_bInit) and it would be done! > { > > > m_TreeCommand.MoveWindow(GetTreeRect(), TRUE); > //m_bar.MoveWindow(GetStatusBarRect(), TRUE); // when i >uncommented this line, will jumped out runtime error.. > } > Invalidate(); > > CDialog::OnSize(nType, cx, cy); > if ( !IsWindowVisible() ) > return; *** Most of the above code is confused. The correct code would be CDialog::OnSize(nType, cx, cy); if(m_TreeCommand.GetSafeHwnd() != NULL) { m_TreeCommand.MoveWindow(GetTreeRect(), TRUE); } if(m_bar.GetSafeHwnd() != NULL) { m_bar.MoveWindow(GetStatusBarRect(), TRUE); } Conspicuous changes: Do the CDialog::OnSize FIRST! Testing validity of windows before attempting to use them! No tests of visibility required since nothing happens anyway No Invalidate() call because it is pointless >} > >========================================== Joseph M. Newcomer [MVP] email: newcomer(a)flounder.com Web: http://www.flounder.com MVP Tips: http://www.flounder.com/mvp_tips.htm
|
Pages: 1 Prev: 17 KewaSa.com DDL Torrents Next: CSliderCtrl discrepancy between using keys and mouse |