I am not sure that this is a problem - OnCaptureChanged will be called when
you lose capture, for instance by switching to another app, or by pressing
Escape. In that case, splitter bar should return to its original position
because operation was cancelled. It should have the same behavior as, for
instance, resizing a window with mouse or keyboard.
I am not sure that this is a problem - OnCaptureChanged will be called when
you lose capture, for instance by switching to another app, or by pressing
Escape. In that case, splitter bar should return to its original position
because operation was cancelled. It should have the same behavior as, for
instance, resizing a window with mouse or keyboard.
Do you see something else?
Thanks,
Nenad
On Tue, Mar 25, 2014 at 9:48 AM, Crise markuwil@users.sf.net wrote:
This causes the next WM_PAINT to reposition the splitter in the default
position, because the original splitter position has been lost.
I am not using keyboard navigation at all, so there is no action to cancel. What I am doing is opening a context menu in one of the controls (a listview) in a pane. When said context menu is dismissed the splitter jumps to the default position.
None of the events that modify m_xySplitterPosNew get processed (well they do but since the mouse is not actually on the splitter they do not set it).
In other similar setups I also see that the splitter sometimes looses the ability to be moved at all. The mobility will be restored when the window looses and regains focus.
Last edit: Crise 2014-03-26
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
That doesn't sound right. WM_CAPTURECHANGED will be sent to a window that
previously set capture and now lost it. I don't see how could a context
menu cause capture to be release, which was not set in the first place.
I tried to reproduce this problem, but couldn't. Can you plase try to check
if there are any other calls to SetCapture in your project?
I am not using keyboard navigation at all. What I am doing is opening a
context menu in one of the controls in the panes. When said context menu is
dismissed the splitter jumps to the default position.
None of the events that modify m_xySplitterPosNew get processed (well they
do but since the mouse is not actually on the splitter they do not set it).
Not directly anyways, it is an MDI application (and all the windows that have issues are MDI children), maybe that has something to do with it. There is also quite a bit of passing the focus from control to control based on user action, but I never had any issues until recently.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The splitter window is set up so that each pane houses a single control and the message maps for these controls (and their associated context menus) are on the splitter window class which means that I call TrackPopupMenu with the HWND of the splitter window which moves the capture to it from the pane (which got the capture as a result of the mouse click I presume).
Because if I call TrackPopupMenu with the pane's HWND I don't have any splitter problems (but because the pane does not have a logic of its own, being that it is literally just a listview, that of course breaks all menu items).
Now because I don't intend to enable keyboard navigation for the splitter windows and I use live splitter updating I don't actually need the splitter to do anything on OnCaptureChanged, so I can just stop it from being handled by it easily enough, but others might not be quite so lucky.
Last edit: Crise 2014-03-28
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The splitter window is set up so that each pane houses a single control
and the message maps for these controls (and their associated context
menus) are on the splitter window class which means that I call
TrackPopupMenu with the HWND of the splitter window which moves the capture
to it from the pane (which got the capture as a result of the mouse click I
presume).
Because if I call TrackPopupMenu with the pane's HWND I don't have any
splitter problems (but because the pane does not have a logic of its own,
being that it is literally just a listview, that of course breaks all menu
items).
Now because I don't intend to enable keyboard navigation for the splitter
windows and I use live updating I don't actually need the splitter to do
anything on OnCaptureChanged, so I can just stop it from being handled by
it easily enough, but others might not be quite so lucky.
I agree that would be the proper solution, although the MDI child itself is what is housing the splitter.
Doing this would probably snowball out of control far too easily, because both of the panes have logic that exchanges information between the two. If it was just a matter of moving the context menu handlers to a new window class then it would be all too easy but alas it is not.
That said if I was building the project from scratch I would probably do just that, but thankfully I am lucky in that I can take a shortcut. Hopefully this topic helps other people having similar setups.
Edit: of course an ALT_MSG_MAP with CContainedWindow could also be a solution.
Last edit: Crise 2014-03-29
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
WM_CAPTURECHANGED is also sent after resizing a MDI child, which will now reset the splitter position set by the application. Shouldn't the position be reset only when the splitter is being adjusted manually by the user?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Yes, it should. That is why it is not a good idea to make MDI child frame
be a splitter window as well. It is all OK if you use a splitter as a child
of the MDI child frame.
WM_CAPTURECHANGED is also sent after resizing a MDI child, which will now
reset the splitter position set by the application. Shouldn't the position
be reset only when the splitter is being adjusted manually by the user?
How about the MDI client window, looking at the examples WTL provides combining MDI with a splitter window were one of the panes houses the MDI itself seems quite tricky looking at those examples alone (that is without deriving the main MDI client window class from CSplitterImpl, which seems to be the go to answer after some searching).
I suppose the proper way is to make the splitter a child of the main frame but parent to the MDI client (and whatever the second pane would be) is the correct way of doing it. But it is certainly not the common way.
Last edit: Crise 2014-04-15
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
In that case, you have to make main frame be a splitter window as well. MDI
requires hierarchy of [MDI frame]---[MDI client]---[MDI child] and you
cannot insert any other windows in between.
Main frame would derive from CMDIFrameWindowImpl<> and CSplitterImpl<>.
Also, it would not set m_hWndClient, since the layout is handled through
splitter code.
How about the MDI client window, looking at the examples WTL provides
combining MDI with a splitter window were one of the panes houses the MDI
itself seems quite tricky looking at those examples alone (that is without
deriving the main MDI client from CSplitterImpl, which seems to be the go
to answer after some searching).
I suppose the proper way is to make the splitter a child of the main frame
but parent to the MDI client (and whatever the second pane would be) is the
correct way of doing it. But it is certainly not the common way.
This causes the next WM_PAINT to reposition the splitter in the default position, because the original splitter position has been lost.
Thanks for you report.
I am not sure that this is a problem - OnCaptureChanged will be called when
you lose capture, for instance by switching to another app, or by pressing
Escape. In that case, splitter bar should return to its original position
because operation was cancelled. It should have the same behavior as, for
instance, resizing a window with mouse or keyboard.
Do you see something else?
Thanks,
Nenad
On Tue, Mar 25, 2014 at 9:48 AM, Crise markuwil@users.sf.net wrote:
Could it be the case of losing capture immediately after setting it?
On Tue, Mar 25, 2014 at 5:46 PM, Nenad Stefanovic nenadstefanovic@users.sf.net wrote:
I am not using keyboard navigation at all, so there is no action to cancel. What I am doing is opening a context menu in one of the controls (a listview) in a pane. When said context menu is dismissed the splitter jumps to the default position.
None of the events that modify m_xySplitterPosNew get processed (well they do but since the mouse is not actually on the splitter they do not set it).
In other similar setups I also see that the splitter sometimes looses the ability to be moved at all. The mobility will be restored when the window looses and regains focus.
Last edit: Crise 2014-03-26
That doesn't sound right. WM_CAPTURECHANGED will be sent to a window that
previously set capture and now lost it. I don't see how could a context
menu cause capture to be release, which was not set in the first place.
I tried to reproduce this problem, but couldn't. Can you plase try to check
if there are any other calls to SetCapture in your project?
Cheers,
Nenad
On Wed, Mar 26, 2014 at 3:37 AM, Crise markuwil@users.sf.net wrote:
Not directly anyways, it is an MDI application (and all the windows that have issues are MDI children), maybe that has something to do with it. There is also quite a bit of passing the focus from control to control based on user action, but I never had any issues until recently.
Just figured out why I had these problems.
The splitter window is set up so that each pane houses a single control and the message maps for these controls (and their associated context menus) are on the splitter window class which means that I call TrackPopupMenu with the HWND of the splitter window which moves the capture to it from the pane (which got the capture as a result of the mouse click I presume).
Because if I call TrackPopupMenu with the pane's HWND I don't have any splitter problems (but because the pane does not have a logic of its own, being that it is literally just a listview, that of course breaks all menu items).
Now because I don't intend to enable keyboard navigation for the splitter windows and I use live splitter updating I don't actually need the splitter to do anything on OnCaptureChanged, so I can just stop it from being handled by it easily enough, but others might not be quite so lucky.
Last edit: Crise 2014-03-28
Thanks for following up on this and providing this explanation.
I would recommend that you put handlers in the MDI child class, not in the
splitter. That would avoid this problem.
Cheers,
Nenad
On Fri, Mar 28, 2014 at 3:57 PM, Crise markuwil@users.sf.net wrote:
I agree that would be the proper solution, although the MDI child itself is what is housing the splitter.
Doing this would probably snowball out of control far too easily, because both of the panes have logic that exchanges information between the two. If it was just a matter of moving the context menu handlers to a new window class then it would be all too easy but alas it is not.
That said if I was building the project from scratch I would probably do just that, but thankfully I am lucky in that I can take a shortcut. Hopefully this topic helps other people having similar setups.
Edit: of course an ALT_MSG_MAP with CContainedWindow could also be a solution.
Last edit: Crise 2014-03-29
WM_CAPTURECHANGED is also sent after resizing a MDI child, which will now reset the splitter position set by the application. Shouldn't the position be reset only when the splitter is being adjusted manually by the user?
Yes, it should. That is why it is not a good idea to make MDI child frame
be a splitter window as well. It is all OK if you use a splitter as a child
of the MDI child frame.
Cheers,
Nenad
On Mon, Apr 14, 2014 at 11:37 AM, maksis maksis@users.sf.net wrote:
How about the MDI client window, looking at the examples WTL provides combining MDI with a splitter window were one of the panes houses the MDI itself seems quite tricky looking at those examples alone (that is without deriving the main MDI client window class from CSplitterImpl, which seems to be the go to answer after some searching).
I suppose the proper way is to make the splitter a child of the main frame but parent to the MDI client (and whatever the second pane would be) is the correct way of doing it. But it is certainly not the common way.
Last edit: Crise 2014-04-15
In that case, you have to make main frame be a splitter window as well. MDI
requires hierarchy of [MDI frame]---[MDI client]---[MDI child] and you
cannot insert any other windows in between.
Main frame would derive from CMDIFrameWindowImpl<> and CSplitterImpl<>.
Also, it would not set m_hWndClient, since the layout is handled through
splitter code.
Cheers,
Nenad
On Tue, Apr 15, 2014 at 3:57 PM, Crise markuwil@users.sf.net wrote: