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 );
}
};
精彩评论