Click here to Skip to main content
13,251,556 members (65,014 online)
Click here to Skip to main content
Add your own
alternative version


34 bookmarked
Posted 19 Nov 1999

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 1Sample 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)
        // 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
        // If panning was not started, continue as usual...
        CDialog::OnMButtonDown(nFlags, point);
    BOOL CAutopanDialog::PreTranslateMessage(MSG* pMsg)
        // The WM_MBUTTONDOWN handler
        // 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
        // If panning was not started, continue as usual...
        CPropertyPage::OnMButtonDown(nFlags, point);
    BOOL CAutopanPage::PreTranslateMessage(MSG* pMsg)
        // The WM_MBUTTONDOWN handler
        // 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:

        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

    No diagonal scrolling.
    Allow vertical scrolling only.
    Allow horizontal scrolling only.
    No smooth subpixel-scrolling.
    Use WM_HSCROLL/WM_VSCROLL messages with SB_THUMBPOSITION to scroll
    the window. (CAutoPanParametersMessage)
    SB_LINEUP/SB_LINEDOWN to scroll the window. (CAutoPanParametersLineMessages)
    Use a registred message (rjf_OriginWindowUpdate) with the distance provided
    as LPARAM. (CAutoPanParametersRegMessage)
    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 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.


    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

    You may also be interested in...


    Comments and Discussions

    GeneralError while compiling.. Pin
    patrutkar1-Dec-03 23:53
    memberpatrutkar1-Dec-03 23:53 
    I am getting compiler error. Frown | :(

    c:\Documents and Settings\Administrator.E-ZEST\Desktop\autopan_demo\mfxWhlPan.h(211): error C2143: syntax error : missing ';' before '<'

    Will you just explore the thing '<>' from the header file?
    GeneralRe: Error while compiling.. Pin
    Maximilian Pasternak2-Dec-03 9:37
    memberMaximilian Pasternak2-Dec-03 9:37 
    GeneralResources at src-zip Pin
    Stephan Strittmatter24-Feb-00 22:57
    sussStephan Strittmatter24-Feb-00 22:57 
    GeneralRe: Resources at src-zip Pin
    Maximilian Pasternak27-Mar-00 9:29
    sussMaximilian Pasternak27-Mar-00 9:29 

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

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

    Permalink | Advertise | Privacy | Terms of Use | Mobile
    Web04 | 2.8.171114.1 | Last Updated 20 Nov 1999
    Article Copyright 1999 by Maximilian Pasternak
    Everything else Copyright © CodeProject, 1999-2017
    Layout: fixed | fluid