C++ 在MFC视图中固定位置显示子窗口

C++ 在MFC视图中固定位置显示子窗口,c++,windows,mfc,C++,Windows,Mfc,我从CScrollView继承了一个窗口,它处理WM_绘制并显示图形。此图具有不同类型的元素,元素的类型由元素的形状标记 我想显示一些图例,以便用户知道每个形状的含义。由于用户不会经常查看此图例,因此在视图控件的右上角将有一个小图标。当用户将鼠标移动到此图标上时,它将展开为小矩形,显示图形中使用的形状图例。当鼠标移到该矩形外时,它将折叠回小图标 这就是我迄今为止所尝试的: 在视图类的WM_PAINT处理程序中使用GDI绘制热点图标和图例矩形 将热点实现为一个单独的窗口,该窗口作为滚动视图的子窗口

我从CScrollView继承了一个窗口,它处理WM_绘制并显示图形。此图具有不同类型的元素,元素的类型由元素的形状标记

我想显示一些图例,以便用户知道每个形状的含义。由于用户不会经常查看此图例,因此在视图控件的右上角将有一个小图标。当用户将鼠标移动到此图标上时,它将展开为小矩形,显示图形中使用的形状图例。当鼠标移到该矩形外时,它将折叠回小图标

这就是我迄今为止所尝试的:

  • 在视图类的WM_PAINT处理程序中使用GDI绘制热点图标和图例矩形
  • 将热点实现为一个单独的窗口,该窗口作为滚动视图的子窗口创建
  • 实现热点作为一个单独的窗口,但创建一个没有父窗口的弹出窗口
  • 如果用户滚动图形视图,则版本1和版本2的行为异常

    在版本1中,我可以在执行滚动时看到瑕疵(按钮在视图中被涂抹),我猜在滚动过程中,现有图像不会失效,只是移动了

    在版本2中,没有涂抹,但每当我得到VM_HSCROLL和WM_VSCROLL消息时,我需要移动子窗口,而这些消息不够精确,无法以这种方式使用。在滚动过程中,我可以看到我的按钮移动了几个像素,然后跳到正确的位置

    版本3是最令人不安的,因为图例不是图形视图的子版本,所以即使图形视图没有显示,我也会看到一些奇怪的行为,图例按钮也会显示出来,我认为这一版本存在太多的问题,不可能成为投入时间的可行开发路径

    我认为版本2是最有前途的,但我需要找到一种方法,使子窗口在滚动期间停留在一个地方


    有人成功地实现了这样的东西吗?我还可以研究其他实现吗?

    您只需使用

    CPoint GetScrollPosition( ) const;
    
    方法获取滚动视图的当前滚动位置,并相应地重新计算“静态”标签偏移

    顺便说一句:使用CScrollView的方法代替WM_PAINT

    virtual void OnDraw( CDC* pDC );
    

    这很重要

    您只需使用

    CPoint GetScrollPosition( ) const;
    
    方法获取滚动视图的当前滚动位置,并相应地重新计算“静态”标签偏移

    顺便说一句:使用CScrollView的方法代替WM_PAINT

    virtual void OnDraw( CDC* pDC );
    

    重要的是

    CScrollView
    具有滚动视图控件的整个客户端区域的
    OnScrollBy
    虚拟方法。您可以重写此方法并实现自己的滚动功能

    具有参数
    prcScroll
    ,该参数只能指定要滚动的客户端区域的一部分

    新的
    OnScrollBy
    将客户端区域分成4个条带,并为每个条带调用
    ::ScrollWindowEx

    这些条纹是:

  • 图标上方的客户区(整个客户区的矩形宽度)
  • 图标左侧的客户区(矩形高度与图标相同)
  • 图标右侧的客户端区域(矩形高度与图标相同)
  • 图标下方的客户区(整个客户区的矩形宽度)

    1
    2*3
    4
    4


  • 滚动所有单个客户端矩形后,只需使图标所在的客户端区域无效。

    CScrollView
    具有滚动视图控件的整个客户端区域的
    OnScrollBy
    虚拟方法。您可以重写此方法并实现自己的滚动功能

    具有参数
    prcScroll
    ,该参数只能指定要滚动的客户端区域的一部分

    新的
    OnScrollBy
    将客户端区域分成4个条带,并为每个条带调用
    ::ScrollWindowEx

    这些条纹是:

  • 图标上方的客户区(整个客户区的矩形宽度)
  • 图标左侧的客户区(矩形高度与图标相同)
  • 图标右侧的客户端区域(矩形高度与图标相同)
  • 图标下方的客户区(整个客户区的矩形宽度)

    1
    2*3
    4
    4


  • 滚动所有单独的客户端矩形后,只需使图标所在的客户端区域无效。

    OnDraw
    WM_PAINT
    处理程序。IInspectable,当使用打印机DC时,您将记得OnDraw。特别是对于CSCrollView:)哇。。。我不知道你想说什么。无论是
    OnDraw
    被传递一个绘画DC、一个窗口DC、一个打印机DC还是一个元DC,都与我的评论无关,
    OnDraw
    WM_绘画
    处理程序。所以,如果你说“使用X(当Y发生时调用),而不是调用X来响应Y”,这表明你对MFC缺乏基本的了解。那么,为什么你认为微软在CView中公开了OnDraw方法,而不是告诉人们直接使用WM_PAINT?我的意见是最好使用标准的MFC方式来完成这项工作,并在真正需要时返回WinAPI。@IInspectable OnDraw和WM_PAINT不一样。OnDraw发生在DC设置之后,这在CScrollView中很重要,因为它正在设置其视口。查看CScrollView::OnPrepareDC了解更多信息。
    OnDraw
    WM_PAINT
    处理程序。ii不可检测,使用打印机DC时,您会记得OnDraw。特别是对于CSCrollView:)哇。。。我不知道你想说什么。无论是
    OnDraw
    被传递一个绘画DC、一个窗口DC、一个打印机DC还是一个元DC,都与我的评论无关,
    OnDraw
    WM_绘画
    处理程序。所以,如果你说“使用X(当Y发生时调用),而不是调用X来响应Y”,这表明你对MFC缺乏基本的了解。那么,你为什么这么做呢