Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. I really need a CSplitterWnd expert!!!

I really need a CSplitterWnd expert!!!

Scheduled Pinned Locked Moved C / C++ / MFC
helpquestiontutorial
9 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    Tommy H D Svensson
    wrote on last edited by
    #1

    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

    T 1 Reply Last reply
    0
    • T Tommy H D Svensson

      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

      T Offline
      T Offline
      Tomasz Sowinski
      wrote on last edited by
      #2
      1. 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
      T 1 Reply Last reply
      0
      • T Tomasz Sowinski
        1. 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
        T Offline
        T Offline
        Tommy H D Svensson
        wrote on last edited by
        #3

        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

        T 1 Reply Last reply
        0
        • T Tommy H D Svensson

          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

          T Offline
          T Offline
          Tomasz Sowinski
          wrote on last edited by
          #4

          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

          T 2 Replies Last reply
          0
          • T Tomasz Sowinski

            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

            T Offline
            T Offline
            Tommy H D Svensson
            wrote on last edited by
            #5

            Thx a lot Tomasz, Just realized the first one! :) Ok, I'll get my hands dirty in RecalcLayout. /Tommy

            1 Reply Last reply
            0
            • T Tomasz Sowinski

              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

              T Offline
              T Offline
              Tommy H D Svensson
              wrote on last edited by
              #6

              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

              T 1 Reply Last reply
              0
              • T Tommy H D Svensson

                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

                T Offline
                T Offline
                Tomasz Sowinski
                wrote on last edited by
                #7

                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

                T 1 Reply Last reply
                0
                • T Tomasz Sowinski

                  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

                  T Offline
                  T Offline
                  Tommy H D Svensson
                  wrote on last edited by
                  #8

                  :):):) 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...?

                  T 1 Reply Last reply
                  0
                  • T Tommy H D Svensson

                    :):):) 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...?

                    T Offline
                    T Offline
                    Tomasz Sowinski
                    wrote on last edited by
                    #9

                    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

                    1 Reply Last reply
                    0
                    Reply
                    • Reply as topic
                    Log in to reply
                    • Oldest to Newest
                    • Newest to Oldest
                    • Most Votes


                    • Login

                    • Don't have an account? Register

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • World
                    • Users
                    • Groups