VC 实现无标题窗口的拖拽
2010-11-08 20:26
281 查看
VC 实现无标题窗口的拖拽
到底我们怎样来欺骗Windows呢?
我们主动来响应WM_NCHITTEST消息。//NC == noneclient 非客户区
用ClassWizard添加WM_NCHITTEST的消息响应函数。
注:用ClassWizard添加消息响应函数时候,在右下角的“Filter for message available to”选择“Windows”。否则你找不到WM_NCHITTEST消息。
编写代码如下:
UINT CTestDlg::OnNcHitTest(CPoint point)
{
//得到鼠标点击的窗口的部位
UINT nHitTest = CDialog::OnNcHitTest(point);
// 如果鼠标点击的是客户区,则返回HTCAPTION给Windows
if (nHitTest == HTCLIENT)
{
return HTCAPTION; //HT==hit 点击 ,HTCAPTION== hit caption 点击标题栏
}
else
return nHitTest;
}
Windows会根据紧接着发送的WM_NCLBUTTONDOWN消息的wParam的内容来决定是否启用“拖拽状态”。实际上,就是根据OnNcHitTest的返回值来确定是否启用。如果返回值是HTCAPTION,就启用。我们正是利用这个特性来欺骗了Windows。
你可能觉得这样处理会有问题,因为我们虽然欺骗了Windows,但鼠标确实不在标题栏上。试想鼠标拖动的时候,Windows必须使窗口和鼠标同步移动。此刻Windows误以为我们的鼠标就在标题栏上,要实现“同步移动”,Windows会一下子把标题栏移动到鼠标当前位置。
你的担心是多余的,Windows移动窗口的时候是根据鼠标位置的改变量来改变窗口坐标的。它不是以鼠标的实际坐标来直接确定窗口坐标的。
另外一个更简单的处理方法是,是在OnLButtonDown中加上一句话。如下:
void CTsDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
SendMessage(WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x, point.y));
CDialog::OnLButtonDown(nFlags, point);
}
上面已经说过,Windows先向窗口发送WM_NCHITTEST消息以确定鼠标点击的部位,如果点击的是非客户区,则又会发送WM_NCLBUTTONDOWN消息。我们现在伪造了一条WM_NCLBUTTONDOWN消息来欺骗Windows,这样更加直接。
我们主动来响应WM_NCHITTEST消息。//NC == noneclient 非客户区
用ClassWizard添加WM_NCHITTEST的消息响应函数。
注:用ClassWizard添加消息响应函数时候,在右下角的“Filter for message available to”选择“Windows”。否则你找不到WM_NCHITTEST消息。
编写代码如下:
UINT CTestDlg::OnNcHitTest(CPoint point)
{
//得到鼠标点击的窗口的部位
UINT nHitTest = CDialog::OnNcHitTest(point);
// 如果鼠标点击的是客户区,则返回HTCAPTION给Windows
if (nHitTest == HTCLIENT)
{
return HTCAPTION; //HT==hit 点击 ,HTCAPTION== hit caption 点击标题栏
}
else
return nHitTest;
}
Windows会根据紧接着发送的WM_NCLBUTTONDOWN消息的wParam的内容来决定是否启用“拖拽状态”。实际上,就是根据OnNcHitTest的返回值来确定是否启用。如果返回值是HTCAPTION,就启用。我们正是利用这个特性来欺骗了Windows。
你可能觉得这样处理会有问题,因为我们虽然欺骗了Windows,但鼠标确实不在标题栏上。试想鼠标拖动的时候,Windows必须使窗口和鼠标同步移动。此刻Windows误以为我们的鼠标就在标题栏上,要实现“同步移动”,Windows会一下子把标题栏移动到鼠标当前位置。
你的担心是多余的,Windows移动窗口的时候是根据鼠标位置的改变量来改变窗口坐标的。它不是以鼠标的实际坐标来直接确定窗口坐标的。
另外一个更简单的处理方法是,是在OnLButtonDown中加上一句话。如下:
void CTsDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
SendMessage(WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x, point.y));
CDialog::OnLButtonDown(nFlags, point);
}
上面已经说过,Windows先向窗口发送WM_NCHITTEST消息以确定鼠标点击的部位,如果点击的是非客户区,则又会发送WM_NCLBUTTONDOWN消息。我们现在伪造了一条WM_NCLBUTTONDOWN消息来欺骗Windows,这样更加直接。
相关文章推荐
- (收藏)VC 实现无标题窗口的拖拽
- VC 实现无标题窗口的拖拽(转载)
- Python实现遍历windows所有窗口并输出窗口标题的方法
- VC中模态窗口启动就隐藏界面的实现
- 在VC++中实现无标题栏对话框的拖动
- C#下如何实现无标题可拖动窗口
- Qt 实现无标题窗口的移动
- VC实现解压 隐藏解压窗口
- EyesBaby功能实现之窗口拖拽与缩放功能
- VC 制作系统托盘程序实现将窗口最小化到系统托
- 如何在 PB 中实现无标题可拖动的窗口
- VC项目开发之单文档多视图实现-非分割窗口[转]
- VC 利用SetWindowRgn实现程序窗口的圆角多角矩形 .
- [VC/MFC]一条语句实现程序运行时隐藏窗口
- 用VC++实现不规则窗口
- vc 实现窗口最小化 最大化
- VC++ 6.0中实现三叉切分窗口与多视图实现
- 怎样在pb里实现无标题栏 如何使PB窗口总在最上层 显示或隐藏Windows的任务栏
- 将OSG嵌入QT窗口系统中,实现拖拽界面
- 实现CDHtmlDialog无标题栏拖动窗口