I really need a CSplitterWnd expert!!!
-
Hi all, Surely there has to be someone who knows the internal workings of CSplitterWnd! There is a bug and a problem in CSplitterWnd which I must get rid off. Bug: When having nested splitters and you're clicking a splitter bar WITHOUT miving the bar, the clicked bar jumps 2 pixels to the right (or down depending on splitter orientation). How to eliminate this bug?!?!!? Problem: Having nested splitters again, when I move (see picture) bar1, bar2 automatically gets moved along because bar2 is part of the splitter that is nested inside the splitter of bar1. This implementation works for most of the cases, but how do I make the nested splitter bar (bar2) NOT to move when I move bar1? Having the orientation below and...
+-------------------------+
| |
| |
| |
+-----parent splitter-----+ <--- bar1
| |
+-----nested splitter-----+ <--- bar2
| |
+-------------------------+...moving bar1 up a bit I get this orientation...
+-------------------------+
| |
+-----parent splitter-----+ <--- bar1
| |
+-----nested splitter-----+ <--- bar2
| |
| |
| |
+-------------------------+...where bar2 follows every move of bar1. I don't want this. Any ideas anyone? /Tommy
-
Hi all, Surely there has to be someone who knows the internal workings of CSplitterWnd! There is a bug and a problem in CSplitterWnd which I must get rid off. Bug: When having nested splitters and you're clicking a splitter bar WITHOUT miving the bar, the clicked bar jumps 2 pixels to the right (or down depending on splitter orientation). How to eliminate this bug?!?!!? Problem: Having nested splitters again, when I move (see picture) bar1, bar2 automatically gets moved along because bar2 is part of the splitter that is nested inside the splitter of bar1. This implementation works for most of the cases, but how do I make the nested splitter bar (bar2) NOT to move when I move bar1? Having the orientation below and...
+-------------------------+
| |
| |
| |
+-----parent splitter-----+ <--- bar1
| |
+-----nested splitter-----+ <--- bar2
| |
+-------------------------+...moving bar1 up a bit I get this orientation...
+-------------------------+
| |
+-----parent splitter-----+ <--- bar1
| |
+-----nested splitter-----+ <--- bar2
| |
| |
| |
+-------------------------+...where bar2 follows every move of bar1. I don't want this. Any ideas anyone? /Tommy
- Bug with clicking a splitter bar without moving: There's no easy solution. The fastest way to solve this problem looks more or less like this - add BOOL flag, m_bBarDragged, to CSplitterWnd-derived class. - handle WM_LBUTTONDOWN. Call base class and set m_bBarDragged to FALSE - handle WM_MOUSEMOVE. Call base class and set m_bBarDragged to TRUE - handle WM_LBUTTONUP. This is where resizing occurs. If m_bBarDragged is TRUE, user has really moved the bar. Just call the base class in this case. Otherwise, don't call base class, just StopTracking(FALSE). This should restore the splitter internal state without actually moving child panes. bar2 follows every move of bar1. I don't want this. The only solution is to override CSplitterWnd::RecalcLayout. Or - nest splitters differently: place child splitter into upper pane of parent splitter. Tomasz Sowinski -- http://www.shooltz.com
-
- Bug with clicking a splitter bar without moving: There's no easy solution. The fastest way to solve this problem looks more or less like this - add BOOL flag, m_bBarDragged, to CSplitterWnd-derived class. - handle WM_LBUTTONDOWN. Call base class and set m_bBarDragged to FALSE - handle WM_MOUSEMOVE. Call base class and set m_bBarDragged to TRUE - handle WM_LBUTTONUP. This is where resizing occurs. If m_bBarDragged is TRUE, user has really moved the bar. Just call the base class in this case. Otherwise, don't call base class, just StopTracking(FALSE). This should restore the splitter internal state without actually moving child panes. bar2 follows every move of bar1. I don't want this. The only solution is to override CSplitterWnd::RecalcLayout. Or - nest splitters differently: place child splitter into upper pane of parent splitter. Tomasz Sowinski -- http://www.shooltz.com
Thx Tomasz, I tried the bug solution again (have tried it before) just to realize I need to call the base class' onlbuttonup in order to release the tracking bar rectangle... if I don't I'm stuck with it til I maliciously terminate the program. Any ideas on how to go around this? I've also tried overriding RecalcLayout() but the job seems to be done ion _AfxLayoutRowCols and I can't get to that code anyhow. What I would like to know, but haven't figured out, is to determine where in the CSplitterWnd code the base splitter tells the nested splitter to move it's bar according to the base splitter bar move. Don't know how to debug it... /Tommy
-
Thx Tomasz, I tried the bug solution again (have tried it before) just to realize I need to call the base class' onlbuttonup in order to release the tracking bar rectangle... if I don't I'm stuck with it til I maliciously terminate the program. Any ideas on how to go around this? I've also tried overriding RecalcLayout() but the job seems to be done ion _AfxLayoutRowCols and I can't get to that code anyhow. What I would like to know, but haven't figured out, is to determine where in the CSplitterWnd code the base splitter tells the nested splitter to move it's bar according to the base splitter bar move. Don't know how to debug it... /Tommy
I need to call the base class' onlbuttonup in order to release the tracking bar rectangle Base class just calls StopTracking(TRUE). As I've posted above: when user didn't move the mouse after pressing button, call StopTracking(FALSE). It will release the tracking rectangle and will not resize panes. determine where in the CSplitterWnd code the base splitter tells the nested splitter to move it's bar Nowhere, at least explicitly. When you move the bar, the pane is resized. Child splitter is a pane, it changes its size and gets WM_SIZE. CSplitterWnd::OnSize handler calls RecalcLayout; that's all. Tomasz Sowinski -- http://www.shooltz.com
-
I need to call the base class' onlbuttonup in order to release the tracking bar rectangle Base class just calls StopTracking(TRUE). As I've posted above: when user didn't move the mouse after pressing button, call StopTracking(FALSE). It will release the tracking rectangle and will not resize panes. determine where in the CSplitterWnd code the base splitter tells the nested splitter to move it's bar Nowhere, at least explicitly. When you move the bar, the pane is resized. Child splitter is a pane, it changes its size and gets WM_SIZE. CSplitterWnd::OnSize handler calls RecalcLayout; that's all. Tomasz Sowinski -- http://www.shooltz.com
Thx a lot Tomasz, Just realized the first one! :) Ok, I'll get my hands dirty in RecalcLayout. /Tommy
-
I need to call the base class' onlbuttonup in order to release the tracking bar rectangle Base class just calls StopTracking(TRUE). As I've posted above: when user didn't move the mouse after pressing button, call StopTracking(FALSE). It will release the tracking rectangle and will not resize panes. determine where in the CSplitterWnd code the base splitter tells the nested splitter to move it's bar Nowhere, at least explicitly. When you move the bar, the pane is resized. Child splitter is a pane, it changes its size and gets WM_SIZE. CSplitterWnd::OnSize handler calls RecalcLayout; that's all. Tomasz Sowinski -- http://www.shooltz.com
Tomasz, Thx, first part of the bug eliminated (when clicking and not moving). But, the bug is still there when clicking AND moving the bar. The bar here jumps off 2 pixels to the right (or down). Now this can't be THAT easy?! :) /Tommy
-
Tomasz, Thx, first part of the bug eliminated (when clicking and not moving). But, the bug is still there when clicking AND moving the bar. The bar here jumps off 2 pixels to the right (or down). Now this can't be THAT easy?! :) /Tommy
So you'll have to dig deep into RecalcLayout. BTW: Are you a perfectionist yourself or just have a perfectionist boss? :) Is it really that important? Tomasz Sowinski -- http://www.shooltz.com
-
So you'll have to dig deep into RecalcLayout. BTW: Are you a perfectionist yourself or just have a perfectionist boss? :) Is it really that important? Tomasz Sowinski -- http://www.shooltz.com
:):):) It has to be perfect since we're dealing with high res models and 2 pixels do account for a loss of image quality if it gets in the way of the image... That's why I don't want the bar to jump by itself, mostly because the above and secondly because it's really annoying! If you release the bar tracker then it's supposed to splitt at that exact location, not 2 pixels off... don't you agree...?
-
:):):) It has to be perfect since we're dealing with high res models and 2 pixels do account for a loss of image quality if it gets in the way of the image... That's why I don't want the bar to jump by itself, mostly because the above and secondly because it's really annoying! If you release the bar tracker then it's supposed to splitt at that exact location, not 2 pixels off... don't you agree...?
If you release the bar tracker then it's supposed to splitt at that exact location, not 2 pixels off... don't you agree...? Hmmmm... I would say that most users can't move mouse with pixel or even 2-pixel accuracy. However, I can see that this issue is really important for you ;) Assuming that you have three-way splitter without scrollbar sharing, you could simply implement resizing 'manually' - create the views inside a frame window, leave some space between them, set the frame class cursor to <-|-> (rotated 90 degrees) and handle mouse messages in the frame window. Enter tracking mode at WM_LBUTTONDOWN, capture the mouse, move your views in WM_MOUSEMOVE, end the sequence with WM_LBUTTONUP. This gives you on-the-fly resizing. You may find this technique may be easier to implement than fixing CSplitterWnd. Tomasz Sowinski -- http://www.shooltz.com