65.9K
CodeProject 正在变化。 阅读更多。
Home

所有窗口、视图和控件的自动平移

starIconstarIconemptyStarIconemptyStarIconemptyStarIcon

2.00/5 (5投票s)

1999年11月20日

3分钟阅读

viewsIcon

86874

downloadIcon

2163

在您自己的应用程序中进行自动平移

Sample Image 1 Sample Image 2

自动平移的功能是什么?

自动平移用于通过简单地按下鼠标中键并拖动鼠标到所需方向来平移窗口。您可能在其他应用程序中了解此方法(左图)。

使用自动平移的另一种可能性是在ListBoxComboBoxSpinButton中选择值(右图)。

它有哪些特殊功能?

  • 支持MFC视图
    • CEditViewCFormViewCListView(所有模式)、CRichEditViewCScrollViewCTreeView
  • 支持Windows控件
    • ComboBox(不同的外观)、EditListBoxListCtrl(所有模式)、SpinButton(不同的外观)、TreeCtrl
  • 连续亚像素滚动(改编自Lutz Kretzschmar)
    • 即使速度很慢,滚动也很流畅
  • 加速平移
    • 距离原点超过42像素时加速更快
  • 使用简单
    • 预定义宏,自动检测控件/视图类型
  • 可自定义的行为
    • 样式标志和参数类

如何在自己的代码中集成它?

如果您想在您的应用程序中使用它,只需将源文件添加到您的项目并包含模板中的资源。每次想要开始平移时,创建原始窗口。

在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);
  }

如果您想通过同时按下鼠标左键和右键来模拟鼠标中键,您可以像使用CWheelWnd_OnMButtonDown一样使用CWheelWnd_OnLButtonDownCWheelWnd_OnRButtonDown

在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);
  }

在MFC属性页中使用

  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);
  }

就是这样!

它是如何工作的?

一旦创建了原始窗口,就会通过类名识别用于滚动当前窗口的CAutoPanParameters,除非需要使用特定类。

每10毫秒计算一次与原点的距离,如果距离超过42像素,则虚拟距离将增加以实现更快的加速(可选)。现在还将处理方向标志。

现在,新的距离将添加到长期总和(用于平滑滚动),并且CAutoPanParameters类用于确定滚动一步需要多少像素。基于这些值,计算出要滚动的步数。

如果需要滚动,则调用CAutoPanParameters类进行滚动,并校正长期总和以及设置正确的游标。

CAutoPanParameters类现在计算它将滚动窗口多少个单位,并将这些值传递给DoScrollWindow成员,该成员现在执行滚动。

最好现在看一下代码(也许使用调试器),然后您将看到它是如何真正工作的。

如何自定义行为?

您可以通过提供样式标志或使用您自己的参数类来自定义行为。在这两种情况下,您都必须调用MfxTrackAutoPan()来创建原始窗口并开始平移。

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>

样式标志

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 registered 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)

参数类

CAutoPanParameters类是一个插件类,您可以使用它来定制几乎所有内容。

class CAutoPanParameters
{
    // szClassName: classname for supported class; NULL to use for all
    // nWindowResID: resourceID for background 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;
}

mfxWhlPan.cppmfxWhlPan.inc中,有很多用于平移各种视图和控件的示例实现,因此如果您计划实现自己的行为,这可能是一个不错的起点。

如果您有任何评论、注释或问题,请随时在下面的评论部分留言。

致谢

许可证

本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。

作者可能使用的许可证列表可以在此处找到。

© . All rights reserved.