分享
 
 
 

无标题栏对话框的拖动

王朝vc·作者佚名  2006-01-17
窄屏简体版  字體: |||超大  

无标题栏对话框的拖动

编译/NorthTibet

下载源代码

很多基于对话框的应用程序都是不带框架的,也就是说对话框没有标题栏。众所周知,窗口的移动都是通过鼠标点住标题栏拖动窗口实现的,那么现在没有了标题栏,如何移动对话框呢?本文拟针对这个问题提出解决的办法。

解决这个问题有两种方案。一种很业余,另外一种比较专业。前者使用一种常规思路处理鼠标拖拽事件。当窗口获得WM_LBUTTONDOWN(OnLButtonDown)时,通过设置标志并调用SetCapture控制鼠标使应用程序进入移动模式。进入移动模式之后,只要有WM_MOUSEMOVE消息过来,就可以据此移动框架窗口。最后,当用户释放鼠标按钮,则WM_LBUTTONUP消息处理例程清除标志并调用ReleaseCapture函数将鼠标控制返还给Windows。之所以说这种方法业余,主要是因为比较繁琐,首先要决定窗口移到哪?然后要想好如何重绘窗口等等,而且根据屏幕显示属性对话框“效果”页中“视觉效果”项的“拖动实显示窗口内容”复选框是不是选中,拖动效果是不同的。那么你怎么知道的设置呢?(方法是调用SystemParametersInfo(SPI_GETDRAGFULLWINDOWS)。Windows要程序员来事务巨细地处理这些繁琐的事情真是太遭了。由于Windows本身知道通过鼠标点住标题栏可以移动窗口,那么能不能将鼠标在窗口客户区任何地方的点击拖动行为都模仿成好像是在标题栏中一样呢?

图五 显示器的属性对话框-“效果”标签

答案是肯定的。有心的读者可能已经猜测到下一步该怎么做了答。实际上,用鼠标点住对话框背景进行拖动操作并不难,但是你必须了解在标题栏里拖动窗口的原理。Windows首先确定鼠标点中了那个窗口,然后向那个窗口发送一个WM_NCHITTEST消息找出此窗口的哪个“非客户区”(如边界、最大化/最小化按钮、菜单、标题等等)拥有鼠标光标。接着默认的窗口过程响应消息并返回一个特定的代码。如果鼠标指针落在标题栏中,那么这个神奇的特定代码就是HTCAPTIONA。如果WM_NCHITTEST返回HTCAPTION,那么Windows便进入拖拽模式,以便对窗口进行移动操作。所以要想在客户区里用鼠标拖动对话框,那么只要在客户区里模仿标题栏里的鼠标拖动行为即可。这个我们下面要介绍的比较专业的方法,其主要思路是处理WM_NCHITTEST消息:

UINT CMyDialog::OnNcHitTest(CPoint pt)

{

CRect rc;

GetClientRect(&rc);

ClientToScreen(&rc);

return rc.PtInRect(pt) ? HTCAPTION : CDialog::OnNcHitTest(pt);

}

上面这个代码很容易理解,当鼠标落在客户区内,函数返回HTCAPTION。对于一个简单的对话框来说,仅仅用这个代码就完全可以实现在对话框背景内的拖动操作。因为Windows使用z-order坐标来确定鼠标下是哪个窗口,所以对话框中其它的所有对象照常工作。如果用户单击某个控制,只要这个控制不是静态位图图像或者文本,那么Windows都将鼠标事件发送到该控制上,而不是对话框。由于静态位图图像或者文本对于对话框是透明的,所以鼠标在上面的拖动同样实现移动,而对于对话框中的编辑框、按钮、组合框等其它非静态控制则按通常的行为方式运行。

如图二是本文例子程序运行画面:

如图二

用鼠标在背景上可以拖动对话框。如果应用不是一个纯粹的对话框程序,而是CFormView或其它非对话框视图,处理方法几乎是一样的,只需在视图代码中做一点小小的改动即可,因为Windows在发送WM_NCHITTEST消息时,是将它发送到鼠标光标下的框架/视图最顶层非透明窗口,由于视图首先获得WM_NCHITTEST消息。所以只要在视图的WM_NCHITTEST消息处理例程中返回HTTRANSPARENT,让视图对鼠标点击透明即可。注意是在在视图中,而不是框架中加上下面代码:

UINT CMyView::OnNcHitTest(CPoint pt)

{

return HTTRANSPARENT;

}

这样做以后,Windows将忽略视图并继续搜索能接收WM_NCHITTEST的窗口。如果顺利的话,将找到父窗口,这时用与对话框相同的WM_NCHITTEST处理代码即可,即在客户区中的点击返回HTCAPTION。你甚至可以通过鼠标坐标的象素计算,在规定的局部范围内实现视图透明。

UINT CMyView::OnNcHitTest(CPoint pt)

{

return PointLiesWithinDraggableRegion(pt) ?

HTTRANSPARENT : CView::OnNcHitTest(pt);

}

这样拖拽/移动特性只能在PointLiesWithinDraggableRegion的非零窗口区域内有效。为此请参见另外一篇文章的基于框架/视图的例子:“MFC框架程序中全屏显示特性的实现”,其中就实现了用鼠标在客户区拖动整个框架窗口的效果。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有