 |
|
 |
Hi, Used the classes which worked well for me so thanks. Though I had one small problem I thought I'd better document as it may help someone out. In my WTL 8.0 app I created horizontal and vertical splitters in CMainFrame::OnCreate as mentioned in your point 5 but had to modify the window creation because of this.
Each time the main window got created the horizontal splitter irritatingly always got restored slightly lower down and the vertical splitter bar always got restored slightly to the right. This was found to be due to the code in atlsplit.h/CSplitterImpl::SetSplitterPos which did an "Adjust if out of valid range" and because the CMainFrame window size hadn't yet been restored it always found it to be "out of valid range" and aways adjusted the position.
This was solved by changing the code creating the CMainFrame window to pass in the position when calling OnCreateEx as below:
int Run(LPTSTR = NULL, int nCmdShow = SW_SHOWDEFAULT) { CMessageLoop theLoop; _Module.AddMessageLoop(&theLoop);
CWindowSettings ws; CMainFrame wndMain; if(ws.Load(_T("Software\\Domain\\Application"), _T("MainFrame"))) { if(wndMain.CreateEx(0,ws.m_WindowPlacement.rcNormalPosition) == NULL) { ... The creation of splitters which now don't be seen as "out of valid range":
CMainFrame::OnCreate(...) { ...
CRect rcVert; GetClientRect(&rcVert); m_vSplit.Create(m_hWnd, rcVert, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN); m_vSplit.SetSplitterExtendedStyle(SPLIT_PROPORTIONAL);
CSplitterSettings vSet; if(vSet.Load(_T("Software\\Domain\\Application"), _T("VertSplit"))) vSet.ApplyTo(m_vSplit); else m_vSplit.SetSplitterPos(330); m_vSplit.m_bFullDrag = false; ... }
|
|
|
|
 |
|
 |
Thank you for sharing useful information. This article has been written nearly 8 years ago. It's amazing that they are helpful today.
Cheers, Magomed Abdurakhmanov
|
|
|
|
 |
|
 |
I suppose it says something about how long lasting WTL is as well.
One more small hint to be correct - and seeing as how it took me 3 hours to find it! My original message shows how the problem of a vertical splitter that has the CMainFrame for parent moving to the right when restoring position was solved. I thought the same fix would apply to a horizontal splitter (which has the vertical splitter for a parent). It didn't. Though there is a suggestion here [^] that it should. The same source also suggested setting the frame's m_hwndClient and calling UpdateLayout as an alternative. This did work. So my code for creating and restoring position on a horizontal splitter that has a vertical splitter for a parent is now:
CRect rcHorz; m_vSplit.GetSplitterPaneRect(SPLIT_PANE_RIGHT, &rcHorz); m_hzSplit.Create(m_vSplit.m_hWnd, rcHorz, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
m_hWndClient = m_vSplit.m_hWnd; UpdateLayout();
CSplitterSettings hSet; if(hSet.Load(_T("Software\\Domain\\Aplication"), _T("HzSplit"))) hSet.ApplyTo(m_hzSplit); else m_hzSplit.SetSplitterPos(100);
Why is this needed? Calling UpdateLayout caused the client area to be recalculated allowing the height of a Rebar added to the main frame to be taken into account. Without this when the horizontal splitter internally makes a call to GetClientRect it returns the client area without allowing for the rebar. This then results in the splitter in the wrong position.
|
|
|
|
 |
|
 |
Any thoughts of doing one for other controls like listview in report mode to save column widths?
|
|
|
|
 |
|
 |
Why wouldn't you include the RBBS_HIDDEN style in the saved informations. This would be also usefull to automatically restore toolbars when they are hidden. btw Nice designed-easy-to-use class. I just found today and I incorporated in my project. Thanks.
Yarp http://www.senosoft.com/
|
|
|
|
 |
|
 |
This looks good so far but how about using the WindowsPlacement structure as this will also contain the state of the window and not just the size and position. Then in your Load method, you can call CWnd::SetWindowPlacement()
Terry
|
|
|
|
 |
|
 |
What else in WINDOWPLACEMENT need to be saved other than rcNormal and window state (when maximized)?
Magomed G. Abdurakhmanov +------------------------ | http://mickels.iwt.ru/en |
|
|
|
|
 |
|
 |
I was just thinking that others might have a need to use more information than just rcNormal and window state. Since the WINDOWPLACEMENT structure holds the current state of the window and if you want to restore the window to its last saved state, placement, min/max size then this structure wraps it all up nice and neat.
Terry
|
|
|
|
 |
|
 |
Take a look at my article http://www.codeproject.com/useritems/windowplacement.asp which explains how to use the WINDOWPLACEMENT struct.
James\
|
|
|
|
 |
|
 |
First of all thanks for the code!
Unfortunately there are some problems. If you leave your app in a maximized state and you restart your app, clicking the restore button not really has an effect. Further more: If you have an Application-Bar on the top on your screen (like the office shortcut bar (don't check "Auto Hide")) and you open and close your app a few times, then the Main Window moves higher and higher. The same applies if an AppBar is on the left(the Window moves more and more to the left).
Here are some changes I have made (not tested very well)
First:
void CWindowSettings::ApplyTo(CWindow& Wnd, bool bDontShow)const
changed to
void CWindowSettings::ApplyTo(CWindow& Wnd, int nCmdShow)const { if(SW_SHOWNORMAL!=nCmdShow) { Wnd.ShowWindow(nCmdShow); return; }
if(m_WindowState == ws_Normal) { Wnd.MoveWindow(m_rcNormal,FALSE); Wnd.ShowWindow(SW_SHOW); } else Wnd.ShowWindow(SW_MAXIMIZE); }
Restoring the Window Position happens in the global Run function:
CWindowSettings ws; if(ws.Load("SoftWare\\WTLApps\\DemoApp", "MainFrame")) ws.ApplyTo(wndMain,nCmdShow); else wndMain.ShowWindow(nCmdShow);
Second:
CWindowSettings::Load(...) {
m_rcNormal.top+=rc.top; m_rcNormal.left+=rc.left;
return err == ERROR_SUCCESS; }
CU
Max
|
|
|
|
 |
|
 |
Thanks a lot. I will correct these problems.
Magomed G. Abdurakhmanov +------------------------ | http://mickels.iwt.ru/en |
|
|
|
|
 |
|
 |
I mentionned in a previous message, I suggest using GetWindowPlacement and SetWindowPlacement as it will properly save the current state including the restored size if the window is maximized or minimized and it will also save the "restore to maximized" flag properly so that you or the user ca restore a minimized window to the previous state.
Generally it is good to have a minimum of validation to ensure that the window will be (at least partially) visible if the user changes its screen resolution (or edit the registry).
For application windows, if "start maximized" or "start minimized" was specified, it should have priority over saved settings. Also, if the window was saved minimized, you may want to start it to its last non-minimized state (You may call ShowWindow after SetWindowPlacement for that).
Philippe
|
|
|
|
 |
|
 |
Ok. I will agree with you. I have uploaded an updated code for this article.
Cheers,
Magomed Abdurakhmanov
|
|
|
|
 |
|
 |
>I have uploaded an updated code for this article.
Great!
Max
|
|
|
|
 |