开发者

Make caption icon become drag source like explorer window

I made an editor which written in pure WinAPI. Some users want the caption icon become a drag source of the file that opened in editor, like what the exp开发者_运维问答lorer window does. I have no idea to implement such feature. Can someone give me example please?


Here is a sample showing how to use the system menu ("caption icon") to detect when to initiate a drag-drop operation:

  class SysMenuDragSample
    : public CWindowImpl< SysMenuDragSample, CWindow, CFrameWinTraits >
  {
  private:
    static const UINT WM_SHOWSYSTEMMENU = 0x313;
    bool mouse_down_in_sys_menu_;

  public:
    BEGIN_MSG_MAP_EX( SysMenuDragSample )
      MSG_WM_NCLBUTTONDOWN( OnNcLButtonDown )
      MSG_WM_NCLBUTTONUP( OnNcLButtonUp )
      MSG_WM_MOUSEMOVE( OnMouseMove )
      MSG_WM_LBUTTONUP( OnLButtonUp )
    END_MSG_MAP()

    SysMenuDragSample()
      : mouse_down_in_sys_menu_( false )
    {
    }

    void BeginDragDropOperation()
    {
      // TODO: Implement
    }

    void OnNcLButtonDown( UINT hit_test, CPoint cursor_pos )
    {
      if( hit_test == HTSYSMENU )
      {
        mouse_down_in_sys_menu_ = true;
        SetCapture();

        // NOTE: Future messages will come through WM_MOUSEMOVE, WM_LBUTTONUP, etc.
      }
      else
        SetMsgHandled( FALSE );
    }

    void OnNcLButtonUp( UINT hit_test, CPoint cursor_pos )
    {
      if( hit_test == HTSYSMENU )
      {
        // This message and hit_test combination should never be received because
        // SetCapture was called in OnNcLButtonDown.
        assert( false );
      }
      else
        SetMsgHandled( FALSE );
    }

    void OnMouseMove( UINT modifiers, CPoint cursor_pos )
    {
      if( mouse_down_in_sys_menu_ )
      {
        ClientToScreen( &cursor_pos );

        UINT hit_test = SendMessage( WM_NCHITTEST, 0, MAKELPARAM( cursor_pos.x, cursor_pos.y ) );
        if( hit_test != HTSYSMENU )
        {
          // The cursor has moved outside of the system menu icon so begin the drag-
          // drop operation.
          mouse_down_in_sys_menu_ = false;
          ReleaseCapture();

          BeginDragDropOperation();
        }
      }
      else
        SetMsgHandled( FALSE );
    }

    void OnLButtonUp( UINT modifiers, CPoint cursor_pos )
    {
      if( mouse_down_in_sys_menu_ )
      {
        // The button was released inside the system menu so simulate a normal click.
        mouse_down_in_sys_menu_ = false;
        ReleaseCapture();

        ClientToScreen( &cursor_pos );
        SendMessage( WM_SHOWSYSTEMMENU, 0, MAKELPARAM( cursor_pos.x, cursor_pos.y ) );
      }
      else
        SetMsgHandled( FALSE );
    }
  };
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜