Docking panes - no WM_WINDOWPOSCHANGING |
Post Reply |
Author | |
Matchay
Newbie Joined: 25 May 2005 Location: Germany Status: Offline Points: 9 |
Post Options
Thanks(0)
Posted: 15 June 2005 at 6:28am |
Hello! I am struggling with integrating MFC/XTreme Toolkit Pro into an old application, where the main window was written in API (and there's no chance to rewrite it in MFC). I managed to create an object of CXTPFrameWnd class and subclass the application window. It works fine then, I can create the Pane Manager and panes, attach windows to panes and so on, but I can't fight over a few problems with refreshing positions of panes and splitter gripper. Look here, this is the initial state: then I click the "pin" to hide the pane, but it seems just to disappear: so I slightly move the Menu Bar around and only then the whole area gets updated: Generally in most of sizing/positioning actions the pane's position gets updated only when I explicitely move for example the Menu Bar. Sometimes you can see that the splitter gripper doesn't stick to the pane, sometimes it suddenly gets very wide, being the size of the whole window. What I noticed when debugging with Spy++ is that e.g. on moving the gripper to resize the pane there's no WM_WINDOWPOSCHANGING message being sent around. I noticed that this message should be sent by the gripper , but it seems it's neither sent or receieved by the pane. I guess it must be about message routing but I have no idea what should I fix.Any ideas would be really appreciated. Regards! Maciej |
|
Matchay
Newbie Joined: 25 May 2005 Location: Germany Status: Offline Points: 9 |
Post Options
Thanks(0)
|
One more thing: when redocking the pane, for example from the left side to the top edge of the frame it disappears and the OnDockingPaneNotify message comes only when I move the toolbar. Then the pane reappears at the right position. Maciej |
|
Oleg
Admin Group Joined: 21 May 2003 Location: United States Status: Offline Points: 11234 |
Post Options
Thanks(0)
|
You must make all appliaction MFC based. DockingPanes need
WM_IDLEUPDATECMDUI message to update its state. |
|
Oleg, Support Team
CODEJOCK SOFTWARE SOLUTIONS |
|
Stephen12
Newbie Joined: 20 July 2005 Status: Offline Points: 5 |
Post Options
Thanks(0)
|
As Oleg said you need to have WM_IDLEUPDATECMDUI send to your panes. Your main message loop doesn't have it, so you need to "fake" MFC framework behavior. One solution is to create timer in your CXTPFrameWnd that will send this message to all the panes. Good place for creating timer is in your CMyFrameWnd::OnCreate of the FrameWnd.
SetTimer(EVENT_IDLEUPDATE, 150, NULL);
Add handler for WM_TIMER
CMyFrameWnd::OnTimer(UINT nIDEvent) { if(nIDEvent == EVENT_IDLEUPDATE && m_hWnd) {
} I hope this will give you idea! Regards, - Slobodan
|
|
jaredf
Newbie Joined: 13 October 2005 Status: Offline Points: 4 |
Post Options
Thanks(0)
|
Great post, fixed my problem also!
|
|
Stephen12
Newbie Joined: 20 July 2005 Status: Offline Points: 5 |
Post Options
Thanks(0)
|
I am not big fan of timer solution, but it was easier to paste some real code. Even better solution is to change your main windows message loop in trying to simulate MFC behaviour by kicking idle if there are no messages in your queue for certain time (or more precise there are no messages that are important updating your UI - search MFC code for AfxInternalIsIdleMessage()). You would then call into your DLL based on CodeJock. There you just transfer call to your instance of CWinApp, in fact to its OnIdle() method. If you see how MFC loop is implemeted you will notice counters that provide facility for task separation , but you may not need to be so perfect to implement counter logic in your main windows message loop. It should be enough to pass parameter -1. So, something like CMyCodeJockBasedDllApp.OnIdle(-1) in your MFC part shall do the magic.
Main part will be to change your windows message loop so that instead of while((bRet =GetMessage(...))!=0) ... TranslateMessage(...); DispatchMessage(...); } you PeekMessage(...) first, see if it is the one that is important for UI (see AfxInternalIsIdleMessage()) , if yes set some flag that you want to triger OnIdle and process the message, if no just process the message (GetMessage, Translate, Dispacth). If there are no messages in your queue see your flag and if it is set make call to your CodeJock based DLL and reset it. If not just wait for your next message. The advantage of this solution is that it triggers idleupdatecmdui only when needed and there is nothing else to do, not when the timer ticks.
|
|
jaredf
Newbie Joined: 13 October 2005 Status: Offline Points: 4 |
Post Options
Thanks(0)
|
Thanks for the feedback. As it turns out in my scenario, the WinApp was already handling the OnIdle and pumping WM_IDLEUPDATECMDUI messages to descendants but not parents. Upgrading this forwarding to send to both principles and descendants eliminated the need to use the timer.
|
|
Post Reply | |
Tweet
|
Forum Jump | Forum Permissions You cannot post new topics in this forum You cannot reply to topics in this forum You cannot delete your posts in this forum You cannot edit your posts in this forum You cannot create polls in this forum You cannot vote in polls in this forum |