如何实现窗口跟随鼠标移动?不要定时器方法噢。

时间:2021-06-29 00:13:54
在LBUTTONDOWN消息里,调用

SendMessageA(hWnd, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, 0);

可以拖动窗口移动,而且几乎是即时的,看不到有延迟的效果,就是紧跟的。


我现在想做的功能是:

鼠标点击一下窗口之后(鼠标可放开,即可以UP状态),窗口就一直跟随鼠标移动了。

而且希望效果是即时的,即窗口一直能马上跟上鼠标的移动,而不希望出现窗口会落后于鼠标的移动。

(速度效果就象是拖动标题栏一样快)


有什么方法可以实现?


关键点是我想:鼠标处于UP状态,而且窗口跟随鼠标移动的速度要即时(就像拖动标题栏一样快)


20 个解决方案

#1


重写那个消息函数,在里边加一个延迟响应,应该可能做到吧

#2


哪个消息?

还要加延迟?

我要的是即时噢,不是延迟噢。

引用 1 楼 zhangyonghui2117 的回复:
重写那个消息函数,在里边加一个延迟响应,应该可能做到吧

#3


响应鼠标单击消息记录下此时的鼠标位置pos。
响应鼠标移动消息,计算出与pos的差值,窗口移动差值,把pos的值修改成当前鼠标位置。

#4


不行,这个方法,延迟会很大。WM_MOUSEMOVE,窗口并不是即时收到的。

当鼠标移动很快时,就会出现鼠标移动了很多个像素后,窗口才收到了一次WM_MOUSEMOVE,延迟是很大的。



引用 3 楼 PDD123 的回复:
响应鼠标单击消息记录下此时的鼠标位置pos。
响应鼠标移动消息,计算出与pos的差值,窗口移动差值,把pos的值修改成当前鼠标位置。

#5


在WM_MOUSEMOVE消息里调用
SendMessageA(hWnd, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, 0);
不就行了。
需要加一个flag变量控制,什么时候需要拖动对话框。
在ONLBUTTONDOWN的时候将设为true,在ONMOUSEMOVE中根据flag的状态来决定要不要调用sendMessage呗,可以试试

#6


如果能让鼠标在UP的状态下,也能

SendMessageA(hWnd, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, 0);

就最好了,拖动标题栏,感觉是窗口跟随鼠标的效果最好的,速度最快的,无论鼠标多快去到哪里,窗口都不会落后。

#7


鼠标移动很快的时候,窗口如果真能和鼠标移动一样快,请问谁能看清窗口上显示的啥? 如何实现窗口跟随鼠标移动?不要定时器方法噢。

#8


不行,这个方法,延迟会很大。WM_MOUSEMOVE,窗口并不是即时收到的。

当鼠标移动很快时,就会出现鼠标移动了很多个像素后,窗口才收到了一次WM_MOUSEMOVE,延迟是很大的。



引用 5 楼 NexTor 的回复:
在WM_MOUSEMOVE消息里调用
SendMessageA(hWnd, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, 0);
不就行了。
需要加一个flag变量控制,什么时候需要拖动对话框。
在ONLBUTTONDOWN的时候将设为true,在ONMOUSEMOVE中根据flag的状态来决定要不要调用sendMessage呗,可以试试

#9


我要的效果就像拖动标题栏啊。

你随便打开一个IE窗口,用鼠标快速来回拖动,窗口是紧跟的,不会落后。

内容也能看清啊。

不过我想要的是,不是鼠标拖动,而是鼠标状态是UP,也能实现窗口跟随鼠标。


引用 7 楼 zhao4zhong1 的回复:
鼠标移动很快的时候,窗口如果真能和鼠标移动一样快,请问谁能看清窗口上显示的啥? 如何实现窗口跟随鼠标移动?不要定时器方法噢。

#10


在WM_MOUSEMOVE消息里调用
PostMessage()试试,不知道可不可以。

#11


不行噢,这方法,问题在于WM_MOUSEMOVE消息本身就不是即时的,

窗口收到WM_MOUSEMOVE消息时,鼠标已经移动好好多个像素了。



引用 10 楼 NexTor 的回复:
在WM_MOUSEMOVE消息里调用
PostMessage()试试,不知道可不可以。

#12


我很快拖动窗口时只能看出窗口是跳步的,并不是逐像素紧随鼠标的。

#13


是不是逐个像素,肉眼很难看出吧?

但我就像希望能达到这种速度级别啊。(其它方法似乎很难达到这种效果。)




引用 12 楼 zhao4zhong1 的回复:
我很快拖动窗口时只能看出窗口是跳步的,并不是逐像素紧随鼠标的。

#14


GDI:BitBlt够快了吧,还嫌不够快的话,上DirectDraw!

#15


不关GDI的事吧?只是窗口移动的问题。不是绘图的问题。

引用 14 楼 zhao4zhong1 的回复:
GDI:BitBlt够快了吧,还嫌不够快的话,上DirectDraw!

#16


有可能移动窗口并ShowWindow的速度比不上先将这个Windows截图,再BitBlt这个截图到窗口当前所在位置快。
ShowWindow
The ShowWindow function sets the specified window's show state. 

BOOL ShowWindow(
  HWND hWnd,     // handle to window
  int nCmdShow   // show state of window
);
 
Parameters
hWnd 
Handle to the window. 
nCmdShow 
Specifies how the window is to be shown. This parameter is ignored the first time an application calls ShowWindow, if the program that launched the application provides aSTARTUPINFO structure. Otherwise, the first time ShowWindow is called, the value should be the value obtained by the WinMain function in its nCmdShow parameter. In subsequent calls, this parameter can be one of the following values: Value Meaning 
SW_FORCEMINIMIZE Windows NT 5.0 and later: Minimizes a window, even if the thread that owns the window is hung. This flag should only be used when minimizing windows from a different thread. 
SW_HIDE Hides the window and activates another window. 
SW_MAXIMIZE Maximizes the specified window. 
SW_MINIMIZE Minimizes the specified window and activates the next top-level window in the Z order. 
SW_RESTORE Activates and displays the window. If the window is minimized or maximized, the system restores it to its original size and position. An application should specify this flag when restoring a minimized window. 
SW_SHOW Activates the window and displays it in its current size and position.  
SW_SHOWDEFAULT Sets the show state based on the SW_ flag specified in theSTARTUPINFO structure passed to theCreateProcess function by the program that started the application.  
SW_SHOWMAXIMIZED Activates the window and displays it as a maximized window. 
SW_SHOWMINIMIZED Activates the window and displays it as a minimized window. 
SW_SHOWMINNOACTIVE Displays the window as a minimized window. The active window remains active. 
SW_SHOWNA Displays the window in its current state. The active window remains active. 
SW_SHOWNOACTIVATE Displays a window in its most recent size and position. The active window remains active. 
SW_SHOWNORMAL Activates and displays a window. If the window is minimized or maximized, the system restores it to its original size and position. An application should specify this flag when displaying the window for the first time. 


Return Values
If the window was previously visible, the return value is nonzero. 

If the window was previously hidden, the return value is zero. 

Remarks
The first time an application calls ShowWindow, it should use the WinMain function's nCmdShow parameter as its nCmdShow parameter. Subsequent calls to ShowWindow must use one of the values in the given list, instead of the one specified by the WinMain function's nCmdShow parameter. 

As noted in the discussion of the nCmdShow parameter, the nCmdShow value is ignored in the first call to ShowWindow if the program that launched the application specifies startup information in theSTARTUPINFO structure. In this case, ShowWindow uses the information specified in the STARTUPINFO structure to show the window. On subsequent calls, the application must call ShowWindow with nCmdShow set to SW_SHOWDEFAULT to use the startup information provided by the program that launched the application. This behavior is designed for the following situations: 

Applications create their main window by calling CreateWindow with the WS_VISIBLE flag set. 
Applications create their main window by calling CreateWindow with the WS_VISIBLE flag cleared, and later call ShowWindow with the SW_SHOW flag set to make it visible. 
Windows CE: The nCmdShow parameter does not support the following values: 

SW_MAXIMIZE

SW_MINIMIZE

SW_RESTORE

SW_SHOWDEFAULT

SW_SHOWMAXIMIZED

SW_SHOWMINIMIZED

SW_SHOWMINNOACTIVE

QuickInfo
  Windows NT: Requires version 3.1 or later.
  Windows: Requires Windows 95 or later.
  Windows CE: Requires version 1.0 or later.
  Header: Declared in winuser.h.
  Import Library: Use user32.lib.

See Also
Windows Overview, Window Functions,CreateProcess, CreateWindow, ShowOwnedPopups,STARTUPINFO, WinMain 

 

#17


我试了一下,貌似用以下的方法看着效果还可以呀。


BOOL CDragDialogDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();

// Add "About..." menu item to system menu.

// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}

// Set the icon for this dialog.  The framework does this automatically
//  when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon

// TODO: Add extra initialization here
CPoint pt;
::GetCursorPos(&pt);
CRect rect;
::GetWindowRect(this->GetSafeHwnd(), &rect);
::SetWindowPos(this->GetSafeHwnd(), 0, pt.x - rect.Width() / 2, pt.y - rect.Height() / 2, 0, 0,SWP_NOSIZE);

return TRUE;  // return TRUE  unless you set the focus to a control
}

void CDragDialogDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
m_flag = true;
CRect rW;
GetWindowRect(rW);
CPoint ptW = point;
ClientToScreen(&ptW);
m_oldPt.x = ptW.x - rW.left;
m_oldPt.y = ptW.y - rW.top;
}

void CDragDialogDlg::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if(m_flag)
{
CPoint ptW = point;
ClientToScreen(&ptW);
ptW.x -= m_oldPt.x;
ptW.y -= m_oldPt.y;
::SetWindowPos(m_hWnd, 0,ptW.x,ptW.y,0,0,SWP_NOSIZE); 
}
// CDialogEx::OnMouseMove(nFlags, point);
}

#18


你把窗口大小,设为3*3像素,就知道我为什么说这种方法,不行了。



引用 17 楼 NexTor 的回复:
我试了一下,貌似用以下的方法看着效果还可以呀。


BOOL CDragDialogDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();

// Add "About..." menu item to system menu.

// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}

// Set the icon for this dialog.  The framework does this automatically
//  when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon

// TODO: Add extra initialization here
CPoint pt;
::GetCursorPos(&pt);
CRect rect;
::GetWindowRect(this->GetSafeHwnd(), &rect);
::SetWindowPos(this->GetSafeHwnd(), 0, pt.x - rect.Width() / 2, pt.y - rect.Height() / 2, 0, 0,SWP_NOSIZE);

return TRUE;  // return TRUE  unless you set the focus to a control
}

void CDragDialogDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
m_flag = true;
CRect rW;
GetWindowRect(rW);
CPoint ptW = point;
ClientToScreen(&ptW);
m_oldPt.x = ptW.x - rW.left;
m_oldPt.y = ptW.y - rW.top;
}

void CDragDialogDlg::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if(m_flag)
{
CPoint ptW = point;
ClientToScreen(&ptW);
ptW.x -= m_oldPt.x;
ptW.y -= m_oldPt.y;
::SetWindowPos(m_hWnd, 0,ptW.x,ptW.y,0,0,SWP_NOSIZE); 
}
// CDialogEx::OnMouseMove(nFlags, point);
}

#19


引用 2 楼 u014761480 的回复:
哪个消息?

还要加延迟?

我要的是即时噢,不是延迟噢。

Quote: 引用 1 楼 zhangyonghui2117 的回复:

重写那个消息函数,在里边加一个延迟响应,应该可能做到吧
就是添加OnMouseMove,这个handle

#20


引用 18 楼 u014761480 的回复:
你把窗口大小,设为3*3像素,就知道我为什么说这种方法,不行了。



Quote: 引用 17 楼 NexTor 的回复:

我试了一下,貌似用以下的方法看着效果还可以呀。


BOOL CDragDialogDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();

// Add "About..." menu item to system menu.

// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}

// Set the icon for this dialog.  The framework does this automatically
//  when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon

// TODO: Add extra initialization here
CPoint pt;
::GetCursorPos(&pt);
CRect rect;
::GetWindowRect(this->GetSafeHwnd(), &rect);
::SetWindowPos(this->GetSafeHwnd(), 0, pt.x - rect.Width() / 2, pt.y - rect.Height() / 2, 0, 0,SWP_NOSIZE);

return TRUE;  // return TRUE  unless you set the focus to a control
}

void CDragDialogDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
m_flag = true;
CRect rW;
GetWindowRect(rW);
CPoint ptW = point;
ClientToScreen(&ptW);
m_oldPt.x = ptW.x - rW.left;
m_oldPt.y = ptW.y - rW.top;
}

void CDragDialogDlg::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if(m_flag)
{
CPoint ptW = point;
ClientToScreen(&ptW);
ptW.x -= m_oldPt.x;
ptW.y -= m_oldPt.y;
::SetWindowPos(m_hWnd, 0,ptW.x,ptW.y,0,0,SWP_NOSIZE); 
}
// CDialogEx::OnMouseMove(nFlags, point);
}


3x3像素还搞毛窗口呀!直接BitBlt。

#1


重写那个消息函数,在里边加一个延迟响应,应该可能做到吧

#2


哪个消息?

还要加延迟?

我要的是即时噢,不是延迟噢。

引用 1 楼 zhangyonghui2117 的回复:
重写那个消息函数,在里边加一个延迟响应,应该可能做到吧

#3


响应鼠标单击消息记录下此时的鼠标位置pos。
响应鼠标移动消息,计算出与pos的差值,窗口移动差值,把pos的值修改成当前鼠标位置。

#4


不行,这个方法,延迟会很大。WM_MOUSEMOVE,窗口并不是即时收到的。

当鼠标移动很快时,就会出现鼠标移动了很多个像素后,窗口才收到了一次WM_MOUSEMOVE,延迟是很大的。



引用 3 楼 PDD123 的回复:
响应鼠标单击消息记录下此时的鼠标位置pos。
响应鼠标移动消息,计算出与pos的差值,窗口移动差值,把pos的值修改成当前鼠标位置。

#5


在WM_MOUSEMOVE消息里调用
SendMessageA(hWnd, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, 0);
不就行了。
需要加一个flag变量控制,什么时候需要拖动对话框。
在ONLBUTTONDOWN的时候将设为true,在ONMOUSEMOVE中根据flag的状态来决定要不要调用sendMessage呗,可以试试

#6


如果能让鼠标在UP的状态下,也能

SendMessageA(hWnd, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, 0);

就最好了,拖动标题栏,感觉是窗口跟随鼠标的效果最好的,速度最快的,无论鼠标多快去到哪里,窗口都不会落后。

#7


鼠标移动很快的时候,窗口如果真能和鼠标移动一样快,请问谁能看清窗口上显示的啥? 如何实现窗口跟随鼠标移动?不要定时器方法噢。

#8


不行,这个方法,延迟会很大。WM_MOUSEMOVE,窗口并不是即时收到的。

当鼠标移动很快时,就会出现鼠标移动了很多个像素后,窗口才收到了一次WM_MOUSEMOVE,延迟是很大的。



引用 5 楼 NexTor 的回复:
在WM_MOUSEMOVE消息里调用
SendMessageA(hWnd, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, 0);
不就行了。
需要加一个flag变量控制,什么时候需要拖动对话框。
在ONLBUTTONDOWN的时候将设为true,在ONMOUSEMOVE中根据flag的状态来决定要不要调用sendMessage呗,可以试试

#9


我要的效果就像拖动标题栏啊。

你随便打开一个IE窗口,用鼠标快速来回拖动,窗口是紧跟的,不会落后。

内容也能看清啊。

不过我想要的是,不是鼠标拖动,而是鼠标状态是UP,也能实现窗口跟随鼠标。


引用 7 楼 zhao4zhong1 的回复:
鼠标移动很快的时候,窗口如果真能和鼠标移动一样快,请问谁能看清窗口上显示的啥? 如何实现窗口跟随鼠标移动?不要定时器方法噢。

#10


在WM_MOUSEMOVE消息里调用
PostMessage()试试,不知道可不可以。

#11


不行噢,这方法,问题在于WM_MOUSEMOVE消息本身就不是即时的,

窗口收到WM_MOUSEMOVE消息时,鼠标已经移动好好多个像素了。



引用 10 楼 NexTor 的回复:
在WM_MOUSEMOVE消息里调用
PostMessage()试试,不知道可不可以。

#12


我很快拖动窗口时只能看出窗口是跳步的,并不是逐像素紧随鼠标的。

#13


是不是逐个像素,肉眼很难看出吧?

但我就像希望能达到这种速度级别啊。(其它方法似乎很难达到这种效果。)




引用 12 楼 zhao4zhong1 的回复:
我很快拖动窗口时只能看出窗口是跳步的,并不是逐像素紧随鼠标的。

#14


GDI:BitBlt够快了吧,还嫌不够快的话,上DirectDraw!

#15


不关GDI的事吧?只是窗口移动的问题。不是绘图的问题。

引用 14 楼 zhao4zhong1 的回复:
GDI:BitBlt够快了吧,还嫌不够快的话,上DirectDraw!

#16


有可能移动窗口并ShowWindow的速度比不上先将这个Windows截图,再BitBlt这个截图到窗口当前所在位置快。
ShowWindow
The ShowWindow function sets the specified window's show state. 

BOOL ShowWindow(
  HWND hWnd,     // handle to window
  int nCmdShow   // show state of window
);
 
Parameters
hWnd 
Handle to the window. 
nCmdShow 
Specifies how the window is to be shown. This parameter is ignored the first time an application calls ShowWindow, if the program that launched the application provides aSTARTUPINFO structure. Otherwise, the first time ShowWindow is called, the value should be the value obtained by the WinMain function in its nCmdShow parameter. In subsequent calls, this parameter can be one of the following values: Value Meaning 
SW_FORCEMINIMIZE Windows NT 5.0 and later: Minimizes a window, even if the thread that owns the window is hung. This flag should only be used when minimizing windows from a different thread. 
SW_HIDE Hides the window and activates another window. 
SW_MAXIMIZE Maximizes the specified window. 
SW_MINIMIZE Minimizes the specified window and activates the next top-level window in the Z order. 
SW_RESTORE Activates and displays the window. If the window is minimized or maximized, the system restores it to its original size and position. An application should specify this flag when restoring a minimized window. 
SW_SHOW Activates the window and displays it in its current size and position.  
SW_SHOWDEFAULT Sets the show state based on the SW_ flag specified in theSTARTUPINFO structure passed to theCreateProcess function by the program that started the application.  
SW_SHOWMAXIMIZED Activates the window and displays it as a maximized window. 
SW_SHOWMINIMIZED Activates the window and displays it as a minimized window. 
SW_SHOWMINNOACTIVE Displays the window as a minimized window. The active window remains active. 
SW_SHOWNA Displays the window in its current state. The active window remains active. 
SW_SHOWNOACTIVATE Displays a window in its most recent size and position. The active window remains active. 
SW_SHOWNORMAL Activates and displays a window. If the window is minimized or maximized, the system restores it to its original size and position. An application should specify this flag when displaying the window for the first time. 


Return Values
If the window was previously visible, the return value is nonzero. 

If the window was previously hidden, the return value is zero. 

Remarks
The first time an application calls ShowWindow, it should use the WinMain function's nCmdShow parameter as its nCmdShow parameter. Subsequent calls to ShowWindow must use one of the values in the given list, instead of the one specified by the WinMain function's nCmdShow parameter. 

As noted in the discussion of the nCmdShow parameter, the nCmdShow value is ignored in the first call to ShowWindow if the program that launched the application specifies startup information in theSTARTUPINFO structure. In this case, ShowWindow uses the information specified in the STARTUPINFO structure to show the window. On subsequent calls, the application must call ShowWindow with nCmdShow set to SW_SHOWDEFAULT to use the startup information provided by the program that launched the application. This behavior is designed for the following situations: 

Applications create their main window by calling CreateWindow with the WS_VISIBLE flag set. 
Applications create their main window by calling CreateWindow with the WS_VISIBLE flag cleared, and later call ShowWindow with the SW_SHOW flag set to make it visible. 
Windows CE: The nCmdShow parameter does not support the following values: 

SW_MAXIMIZE

SW_MINIMIZE

SW_RESTORE

SW_SHOWDEFAULT

SW_SHOWMAXIMIZED

SW_SHOWMINIMIZED

SW_SHOWMINNOACTIVE

QuickInfo
  Windows NT: Requires version 3.1 or later.
  Windows: Requires Windows 95 or later.
  Windows CE: Requires version 1.0 or later.
  Header: Declared in winuser.h.
  Import Library: Use user32.lib.

See Also
Windows Overview, Window Functions,CreateProcess, CreateWindow, ShowOwnedPopups,STARTUPINFO, WinMain 

 

#17


我试了一下,貌似用以下的方法看着效果还可以呀。


BOOL CDragDialogDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();

// Add "About..." menu item to system menu.

// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}

// Set the icon for this dialog.  The framework does this automatically
//  when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon

// TODO: Add extra initialization here
CPoint pt;
::GetCursorPos(&pt);
CRect rect;
::GetWindowRect(this->GetSafeHwnd(), &rect);
::SetWindowPos(this->GetSafeHwnd(), 0, pt.x - rect.Width() / 2, pt.y - rect.Height() / 2, 0, 0,SWP_NOSIZE);

return TRUE;  // return TRUE  unless you set the focus to a control
}

void CDragDialogDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
m_flag = true;
CRect rW;
GetWindowRect(rW);
CPoint ptW = point;
ClientToScreen(&ptW);
m_oldPt.x = ptW.x - rW.left;
m_oldPt.y = ptW.y - rW.top;
}

void CDragDialogDlg::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if(m_flag)
{
CPoint ptW = point;
ClientToScreen(&ptW);
ptW.x -= m_oldPt.x;
ptW.y -= m_oldPt.y;
::SetWindowPos(m_hWnd, 0,ptW.x,ptW.y,0,0,SWP_NOSIZE); 
}
// CDialogEx::OnMouseMove(nFlags, point);
}

#18


你把窗口大小,设为3*3像素,就知道我为什么说这种方法,不行了。



引用 17 楼 NexTor 的回复:
我试了一下,貌似用以下的方法看着效果还可以呀。


BOOL CDragDialogDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();

// Add "About..." menu item to system menu.

// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}

// Set the icon for this dialog.  The framework does this automatically
//  when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon

// TODO: Add extra initialization here
CPoint pt;
::GetCursorPos(&pt);
CRect rect;
::GetWindowRect(this->GetSafeHwnd(), &rect);
::SetWindowPos(this->GetSafeHwnd(), 0, pt.x - rect.Width() / 2, pt.y - rect.Height() / 2, 0, 0,SWP_NOSIZE);

return TRUE;  // return TRUE  unless you set the focus to a control
}

void CDragDialogDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
m_flag = true;
CRect rW;
GetWindowRect(rW);
CPoint ptW = point;
ClientToScreen(&ptW);
m_oldPt.x = ptW.x - rW.left;
m_oldPt.y = ptW.y - rW.top;
}

void CDragDialogDlg::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if(m_flag)
{
CPoint ptW = point;
ClientToScreen(&ptW);
ptW.x -= m_oldPt.x;
ptW.y -= m_oldPt.y;
::SetWindowPos(m_hWnd, 0,ptW.x,ptW.y,0,0,SWP_NOSIZE); 
}
// CDialogEx::OnMouseMove(nFlags, point);
}

#19


引用 2 楼 u014761480 的回复:
哪个消息?

还要加延迟?

我要的是即时噢,不是延迟噢。

Quote: 引用 1 楼 zhangyonghui2117 的回复:

重写那个消息函数,在里边加一个延迟响应,应该可能做到吧
就是添加OnMouseMove,这个handle

#20


引用 18 楼 u014761480 的回复:
你把窗口大小,设为3*3像素,就知道我为什么说这种方法,不行了。



Quote: 引用 17 楼 NexTor 的回复:

我试了一下,貌似用以下的方法看着效果还可以呀。


BOOL CDragDialogDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();

// Add "About..." menu item to system menu.

// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}

// Set the icon for this dialog.  The framework does this automatically
//  when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon

// TODO: Add extra initialization here
CPoint pt;
::GetCursorPos(&pt);
CRect rect;
::GetWindowRect(this->GetSafeHwnd(), &rect);
::SetWindowPos(this->GetSafeHwnd(), 0, pt.x - rect.Width() / 2, pt.y - rect.Height() / 2, 0, 0,SWP_NOSIZE);

return TRUE;  // return TRUE  unless you set the focus to a control
}

void CDragDialogDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
m_flag = true;
CRect rW;
GetWindowRect(rW);
CPoint ptW = point;
ClientToScreen(&ptW);
m_oldPt.x = ptW.x - rW.left;
m_oldPt.y = ptW.y - rW.top;
}

void CDragDialogDlg::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if(m_flag)
{
CPoint ptW = point;
ClientToScreen(&ptW);
ptW.x -= m_oldPt.x;
ptW.y -= m_oldPt.y;
::SetWindowPos(m_hWnd, 0,ptW.x,ptW.y,0,0,SWP_NOSIZE); 
}
// CDialogEx::OnMouseMove(nFlags, point);
}


3x3像素还搞毛窗口呀!直接BitBlt。

#21