Click here to Skip to main content
Click here to Skip to main content

Autopanning all Windows, Views and Controls

, 19 Nov 1999
Rate this:
Please Sign up or sign in to vote.
Autopan within your own application
  • Download demo project - 83 Kb
  • Download source - 12 Kb <!-- Article Starts -->
    Sample Image 1 Sample Image 2

    What does Autopan do?

    Autopan is used for panning windows by simply pressing the middle mouse button and dragging the mouse to the desired direction. You probably know this method from other applications. (left picture)

    Another posibility of using Autopan is choosing a value in ListBoxes, ComboBoxes or with SpinButtons. (right picture)

    What particular Features does it have?

    • Support of MFC-Views:
      CEditView, CFormView, CListView (all modes), CRichEditView, CScrollView, CTreeView
    • Support of Windows Controls:
      ComboBox (different look&feel), Edit, ListBox, ListCtrl (all modes), SpinButton (different look&feel), TreeCtrl
    • Continous subpixel scrolling (adapted form Lutz Kretzschmar):
      Smooth scrolling even with very slow speed
    • Accelerated panning:
      Faster acceleration when more the 42 pixel away from origin
    • Simple usage:
      Predefined Macros, Automated detection of control/view type
    • Customizable behavior:
      Style Flags and Paranmeter classes

    How do I integrate it in my own Code?

    If you want to use it in your application, simply add the source files to your project and include the resources from the template. Every time you want to start panning, create the origin window:

    Using in a MFC CView:

      void CAutoPanView::OnMButtonDown(UINT nFlags, CPoint point)
      {
          // Try to create the window (neither ctrl nor shift may be pressed)
          CWheelWnd_OnMButtonDown;
          
          // If panning was not started, continue as usual...
          CScrollView::OnMButtonDown(nFlags, point);
      }
    
    

    If you want to simulate the 3rd mouse button by pressing the left and the right same time, you can use CWheelWnd_OnLButtonDown and CWheelWnd_OnRButtonDown in the same way as CWheelWnd_OnMButtonDown.

    Using in a MFC CDialog:

      void CAutopanDialog::OnMButtonDown(UINT nFlags, CPoint point) 
      {
          // Try to create the window (neither ctrl nor shift may be pressed)
          // and find desired control
          CWheelWnd_OnMButtonDown_Dlg;
          
          // If panning was not started, continue as usual...
          CDialog::OnMButtonDown(nFlags, point);
      }
    
      BOOL CAutopanDialog::PreTranslateMessage(MSG* pMsg) 
      {
          // The WM_MBUTTONDOWN handler
          CWheelWnd_PreTranslateMessage;
          
          // Processing as usual
          return CDialog::PreTranslateMessage(pMsg);
      }
    
    

    Using in a MFC PropertyPage:

      void CAutopanPage::OnMButtonDown(UINT nFlags, CPoint point) 
      {
          // Try to create the window (neither ctrl nor shift may be pressed)
          // and find desired control - this time we have to find a
          // child-window
          CWheelWnd_OnMButtonDown_PropPg;
          
          // If panning was not started, continue as usual...
          CPropertyPage::OnMButtonDown(nFlags, point);
      }
    
      BOOL CAutopanPage::PreTranslateMessage(MSG* pMsg) 
      {
          // The WM_MBUTTONDOWN handler
          CWheelWnd_PreTranslateMessage;
          
          // Processing as usual
          return CPropertyPage::PreTranslateMessage(pMsg);
      }
    
    

    Yes, that's all!

    How does it work?

    As soon as the Origin-Window is created the CAutoPanParameters for scrolling the current window is identified by the classname except the usage of a specific class is demanded.
    Every 10 millisecs the distance from the origin is calculated, if the distance is more than 42 pixel, the virtual distance will be increased for a faster acceleration (optional). Also the direction-flags will be handled now.
    Now the new distances are added to the long-time-sums (for smooth scrolling) and the CAutoPanParameters class is used to determine how many pixels are neccesary for scrolling one step. Based on these values the ammount of steps to scroll is calculated.
    If we need to scroll the CAutoPanParameters class is called to do the scrolling and the long-time-sums are corrected as well as the right cursor is set.
    The CAutoPanParameters class now calculates how many units it will scroll the window and passes these values to the DoScrollWindow member, which now does the scrolling.
    Best you now have a look on the code (perhaps with the debugger) then you will see how it really works.

    And how do I the customize the behavior?

    You can customize the behavior either by providing Style Flags or by using your own Parameter Class. In either case you have to call MfxTrackAutoPan() to create the origin window and start panning:

    MfxTrackAutoPan(
        CWnd*                pParentWnd, 
        WORD                 wStyle = MFX_WHEELWNDSTYLE_DEFAULT, 
        CAutoPanParameters*  pAutoPanParameters = NULL
        );
    
    pParentWnd               Pointer to the window to be scrolled
    wStyle                   optional <A href="#flags">Style Flags</A>
    pAutoPanParameters       optional <A href="#class">Parameter Class</A>
    
    

    Style Flags

    MFX_WHEELWNDSTYLE_ONEDIRECTION
    No diagonal scrolling.
    
    MFX_WHEELWNDSTYLE_UPDOWNONLY
    Allow vertical scrolling only.
    
    MFX_WHEELWNDSTYLE_LEFTRIGHTONLY
    Allow horizontal scrolling only.
    
    MFX_WHEELWNDSTYLE_NOSUBPIXELSCROLLING
    No smooth subpixel-scrolling.
    
    
    MFX_WHEELWNDSTYLE_SCROLLBYMESSAGE
    Use WM_HSCROLL/WM_VSCROLL messages with SB_THUMBPOSITION to scroll
    the window. (CAutoPanParametersMessage)
    
    MFX_WHEELWNDSTYLE_SCROLLBYMESSAGEEX
    Use multiple WM_HSCROLL/WM_VSCROLL messages with SB_LINERIGHT/SB_LINELEFT/
    SB_LINEUP/SB_LINEDOWN to scroll the window. (CAutoPanParametersLineMessages)
    
    MFX_WHEELWNDSTYLE_SCROLLBYMESSAGEREG
    Use a registred message (rjf_OriginWindowUpdate) with the distance provided
    as LPARAM. (CAutoPanParametersRegMessage)
    
    MFX_WHEELWNDSTYLE_SCROLLBYMESSAGETRK
    Use WM_HSCROLL/WM_VSCROLL messages with SB_THUMBTRACK to scroll
    the window. (CAutoPanParametersMessageThumbTrack)
    
    

    Parameter Class

    The CAutoPanParameters class is a plugin-class which you can use to customize nearly everything:

    class CAutoPanParameters
    {
        // szClassName: classname for supported class; NULL to use for all
        // nWindowResID: resourceID for backgound bitmap
        CAutoPanParameters(LPCTSTR szClassName = NULL, UINT nWindowResID = 0);
        virtual ~CAutoPanParameters();
    
        // Which background bitmap shall we show?
        virtual UINT GetWindowResID(CWnd* /*pParentWnd*/) 
                                    const {return m_nWindowResID;};
        virtual void GetBitmapDimensions(CSize& size, CWnd* pParentWnd) const;
        virtual void CreateWindowRegion(CRgn& rgn, CWnd* /*pParentWnd*/) const;
    
        // Can we use this class to pan which window?
        virtual CWnd* PanThisWindow(CWnd* pParentWnd) const;
    
        // We are scrolling! So which cursor to show?
        virtual int GetCursorResID(int nScrollX, int nScrollY, 
                                   bool bNoHorzScroll, bool bNoVertScroll) const;
    
        // Implementation of scrolling:
        // This one is called if we have to scroll at least one step. The default
        // implementation assumes scrollbars.
        virtual bool DoScroll(CWnd* pParentWnd, int nScrollStepsX, 
                              int nScrollStepsY) const;
        // And here we know the Origin and Destination, so really Do scroll 
        // the window to the new position. 
        // It is only needed for the default "DoScroll"
        virtual bool DoScrollWindow(CWnd* pParentWnd, int nScrollToX, 
                               int nOriginX, int nScrollToY, int nOriginY) const;
    
        // Scroll one step if you have to scroll ? pixels
        virtual int GetPixelsInAStepX  (CWnd* /*pParentWnd*/, 
                                             int /*nScrollX*/) const {return 1;};
        virtual int GetPixelsInAStepY  (CWnd* /*pParentWnd*/, 
                                             int /*nScrollY*/) const {return 1;};
        // Scroll by ? substeps if scrolling one step
        virtual int GetSubstepsInAStepX(CWnd* /*pParentWnd*/, 
                                             int /*nScrollX*/) const {return 1;};
        virtual int GetSubstepsInAStepY(CWnd* /*pParentWnd*/, 
                                             int /*nScrollY*/) const {return 1;};
    
        // Can scroll this window?
        virtual bool NoVertScroll(CWnd* pParentWnd) const;
        virtual bool NoHorzScroll(CWnd* pParentWnd) const;
    }
    
    

    In mfxWhlPan.cpp and mfxWhlPan.inc there are many sample implementations for panning all kinds of views and controls, so this is probably a good point to start with, if you plan to realize your own behavior.

    If you have any comments, annotations or questions, feel free to send mail.

    Credits

    Auto-Panning Windows by Umut Alev: May 6, 1998
    Intellimouse panning by Lutz Kretzschmar: May 22, 1998
    Intellimouse panning 2 original posting: June 16, 1998
    Auto-Panning Windows 2 by Russel Freeman: June 24, 1998

  • License

    This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

    A list of licenses authors might use can be found here

    About the Author

    Maximilian Pasternak
    Systems Engineer
    Germany Germany
    No Biography provided

    Comments and Discussions

     
    GeneralError while compiling.. Pinmemberpatrutkar1-Dec-03 22:53 
    GeneralRe: Error while compiling.. PinmemberMaximilian Pasternak2-Dec-03 8:37 
    GeneralResources at src-zip PinsussStephan Strittmatter24-Feb-00 21:57 
    GeneralRe: Resources at src-zip PinsussMaximilian Pasternak27-Mar-00 8:29 

    General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

    Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

    | Advertise | Privacy | Mobile
    Web02 | 2.8.140709.1 | Last Updated 20 Nov 1999
    Article Copyright 1999 by Maximilian Pasternak
    Everything else Copyright © CodeProject, 1999-2014
    Terms of Service
    Layout: fixed | fluid