窗口移动无边框各种方式

合集下载

QT:如何移动和缩放一个无边框窗口

QT:如何移动和缩放一个无边框窗口

QT:如何移动和缩放⼀个⽆边框窗⼝⼀个QT窗⼝如下可以做到⽆边框:Window {id: window//Designer 竟然不⽀持..., 设计模式时要注意flags: Qt.FramelessWindowHintwidth: 500height: 300title: "Window Title"}不过要注意, 这样QT Designer不⽀持, 在设计的时候可以先注释掉, 最后在打开.⼀旦设置了FramelessWindowHint, 系统就不管你这个窗⼝的移动和缩放了, 就需要⾃⼰来处理了.那怎么处理哪, ⼤概有以下思路1. 增加⼀个接收拖动事件的组件, 让它跟着⿏标移动2. 增加⼀个缩放锚点, 随着⿏标缩放3. 增加窗⼝四周的⿏标触发区域, 可以随着⿏标向四个⽅向缩放 (此⽂没包括实现) , 可以参考 {:target="_blank"}我们先来看看如果拖动窗⼝, 代码如下:/**头部操作区域.*/Rectangle {id: titleOpRectx: 0y: 0width: parent.widthheight: 30property string title : "Hello Board"MouseArea {id: mouseMoveWindowArea//height: 20anchors.fill: parentacceptedButtons: Qt.LeftButtonproperty point clickPos: "0,0"onPressed: {clickPos = Qt.point(mouse.x, mouse.y)//isMoveWindow = true}onReleased: {//isMoveWindow = false}onPositionChanged: {var delta = Qt.point(mouse.x - clickPos.x, mouse.y - clickPos.y)//如果mainwindow继承⾃QWidget,⽤setPoswindow.setX(window.x + delta.x)window.setY(window.y + delta.y)}}Button {id: closeButtonwidth: 25height: parent.heighttext: "X"anchors.left: parent.leftanchors.leftMargin: 0anchors.bottom: parent.bottomanchors.bottomMargin: 0flat: truefont.bold: truefont.pointSize: 14onClicked: {window.close()}}Text {id: titleTexttext: titleanchors.bottom: parent.bottom//底部留点空间bottomPadding: 5} //end titleTextButton {id: newStrikeButtonwidth: 25height: parent.heighttext: "+"anchors.right: parent.rightanchors.rightMargin: 0anchors.bottom: parent.bottomanchors.bottomMargin: 0flat: truefont.pointSize: 22}Frame {width: titleOpRect.widthheight: 1anchors.bottom: titleOpRect.bottomRectangle {height: parent.heightwidth: parent.widthcolor: "blue"}}}关键代码在MouseArea的onPressed 和 onPositionChanged 事件上. ⽐较容易.我们再来看看如果缩放窗⼝这次我们只是在窗⼝右下⾓放⼀个⼩矩形区域, 来捕获⿏标移动事件, 以实现缩放. /**尾部操作区域.*/Rectangle {id: footOpRectanchors.bottom: parent.bottomwidth: parent.widthheight: 30//resize区域MouseArea {id: resizeanchors {right: parent.rightbottom: parent.bottom}width: 15height: 15cursorShape: Qt.SizeFDiagCursorproperty point clickPos: "1,1"//保持窗⼝左上⾓不动property int oldXproperty int oldYonPressed: {clickPos = Qt.point(mouse.x, mouse.y)//oldWidth = window.width//oldHeight = window.heightoldX = window.xoldY = window.y}onPositionChanged: {var delta = Qt.point(mouse.x - clickPos.x,mouse.y - clickPos.y)var minWidth = 100;var minHeight = 100;//最⼩var newWidth = (window.width + delta.x)<minWidth?minWidth:(window.width + delta.x);//最⼩var newHeight = (window.height + delta.y)<minHeight?minHeight:(window.height + delta.y); window.width = newWidth;window.height = newHeight;window.x = oldXwindow.y = oldY}onReleased: {}Rectangle {id: resizeHintcolor: "red"anchors.fill: resize}}}这段代码⽹上很常见,1. 不过这⾥判断了窗⼝的最⼩⾼度和宽度, 不会导致窗⼝太⼩看不见2. ⿏标移动会导致负数, 所以这⾥也做了判断.3. 保持窗⼝左上⾓不动, 否则⿏标跑来跑去有问题.That's all, Thanks.。

如何使用Delphi实现无边界窗体的移动

如何使用Delphi实现无边界窗体的移动

在⽤Delphi制作Windows程序的窗体时,窗体的边界有四种选择:对话框式(bsDialog),单边固定式(bsSingle),双边可变式(bsSizeable),⽆边界式(bsNone)。

当设置为bsNone时,窗体也就没有标题条,很显然,程序运⾏以后就⽆法移动窗体了。

事实上,⽆边界窗体是很有⽤的,例如,象Word⾥⾯的浮动式⼯具箱其实就是⽆边界窗体,它可以⼤⼤节约屏幕空间。

那么,如何⽤Delphi实现这个功能呢?显然,这需要修改Windows的内部消息,也就是说,需要把“MouseDownonForm”这个消息改为“MouseDownonCaption”,这其中有三个关键:捕捉MouseDown消息、判断光标位置、发送MouseDown消息。

如果光标在窗体中,则发送MouseDownonCaption消息。

在Delphi的对象巡检器中列出的所有事件是不能捕捉到Windows消息的,因为这些都是已经发出的消息,⽆法修改了。

捕捉Win dows消息有两种办法:⼀个就是增加⼀个消息处理句柄,直接处理Windows消息;另⼀个是对消息进⾏过滤,滤出所需消息。

第⼆个办法⽐较常⽤,适⽤于各种情况,下⾯就是移动⽆边界窗体程序⽚断,加注释部分是⼿动加⼊的: unitUnit1; : type TForm1Κclass(TForm) procedureFormCreate(Sender:TObject); : public {申明消息过滤过程} procedureAppMessage(varMsg:TMsg;varHandled:Boolean); : implementation procedureTForm1.FormCreate(Sender:TObject); begin {捕捉消息:将程序的收到消息事件与消息过滤过程关联起来} Application.OnMessage:ΚAppMessage; end; procedureTForm1.AppMessage(varMsg:TMsg;varHandled:Boolean); begin {如果⿏标左键按下的话} ifMsg.messageΚWM—LButtonDownthen begin {判断光标是否在⽤户⼯作区内} ifDefWindowProc(Handle,WM—NCHitTest,0,GetMessagePos)ΚHTClientthen begin {发出⿏标在⽤户标题栏内被按下的消息} SendMessage(Handle,WM—NCLButtonDown, HTCaption,GetMessagePos); Handled:Κtrue;{消息处理完毕,窗体不再接受M ouseDown及Click事件,如果为false,程序的运⾏稍微有些不正常。

电脑视窗操作方法有哪些

电脑视窗操作方法有哪些

电脑视窗操作方法有哪些电脑视窗操作是指在Windows操作系统中,对电脑视窗进行各种操作的方法。

视窗是计算机屏幕上显示的一个矩形区域,用户可以在其中执行各种任务。

下面将介绍一些常见的电脑视窗操作方法。

1. 打开和关闭视窗:在Windows桌面上双击其中一个程序的图标即可打开一个视窗。

关闭视窗的方法有多种,如单击窗口右上角的“关闭”按钮,或使用键盘快捷键Alt+F4。

2. 最大化和还原视窗:在Windows操作系统中,每个视窗都有一个最大化和还原的按钮。

如果点击最大化按钮,视窗将会占据整个屏幕;如果再次点击还原按钮,则视窗将恢复到原来的大小。

3. 最小化视窗:点击窗口右上角的“最小化”按钮或按下键盘快捷键Win+M,可以将视窗最小化到任务栏上,以便在后续需要时方便找回。

4. 移动视窗:在视窗的标题栏上按住鼠标左键不放,即可拖动视窗到其他位置。

也可以使用键盘快捷键Alt+空格,然后按下M键,使用方向键移动视窗。

5. 调整视窗大小:将鼠标移到窗口的边框上,当鼠标变为双向箭头时,按住鼠标左键移动鼠标即可调整视窗的大小。

也可以使用键盘快捷键Alt+空格,然后按下S键,使用方向键调整视窗的大小。

6. 分割视窗:可以将一个屏幕分割成两个窗口,每个窗口显示不同的程序。

点击窗口上方的“最大化”按钮时,会显示一个小箭头,点击之后,屏幕将分割成两个部分,可以在每个部分中打开不同的视窗。

7. 切换视窗:在Windows操作系统中,可以使用Alt+Tab键来切换不同的视窗。

按住Alt键,然后反复按下Tab键,即可在打开的视窗之间切换。

8. 将视窗置顶:在Windows操作系统中,可以将其中一个视窗置顶,即使点击其他视窗,该视窗还是保持在最上方。

右键点击任务栏上的视窗图标,在弹出菜单中选择“将窗口置顶”。

9. 窗口操作命令:在Windows操作系统中,可以使用一些命令来操作视窗。

比如,按下Win+左/右键,可以将视窗移动到屏幕的左侧或右侧;按下Win+上/下键,可以将视窗最大化或还原。

完成窗口切换的方法

完成窗口切换的方法

完成窗口切换的方法嘿,朋友们!今天咱就来聊聊怎么完成窗口切换这档子事儿。

你想想看啊,咱平时用电脑的时候,是不是经常要在好多窗口之间跳来跳去呀?就跟咱在现实生活中一会儿去这个房间瞅瞅,一会儿去那个房间逛逛一样。

这窗口切换可太重要啦,要是不会,那可就像只无头苍蝇到处乱撞,效率低得要命呢!其实完成窗口切换不难,就几种方法。

比如说,用鼠标直接去点那个你想要的窗口,这就好比你在一群人里,一眼就瞅准了你要找的那个人,然后走过去跟他打招呼。

简单吧?还有啊,咱可以用键盘上的快捷键。

这就像是你有了个秘密通道,一下子就蹦到了你想去的地方。

比如说“Alt+Tab”,按一下,就可以在打开的窗口之间来回切换,那感觉,就像孙悟空一个筋斗云就翻到了目的地,快得很呐!再说说“Win+Tab”,这也挺好用的。

就好像你有了个魔法棒,轻轻一挥,那些窗口就都乖乖地排好队让你挑选,多有意思!你说,要是没有这些方法,咱得费多大劲才能在一堆窗口里找到自己想要的那个呀!那不得跟大海捞针似的。

有时候我就在想,这电脑的世界还真是奇妙,就这么几个简单的操作,就能让我们的工作和娱乐变得这么方便。

咱可得把这些小窍门都记好了,别到时候手忙脚乱的。

而且啊,熟练掌握窗口切换,那工作效率不得蹭蹭往上涨啊!你就可以快速地在文档、网页、聊天窗口之间切换,一点都不耽误事儿。

咱再回过头来想想,这生活中不也有很多类似的情况吗?我们不也得在各种事情之间灵活切换嘛。

就好像我们一会儿要工作,一会儿要陪家人,一会儿又要做自己喜欢的事儿,这可不就跟窗口切换一样嘛。

所以说呀,学会了窗口切换,可不仅仅是在电脑上有用,在生活中咱也能变得更加灵活、高效呢!怎么样,朋友们,是不是觉得很有道理呀?别再犹豫啦,赶紧去试试这些方法吧,让你的电脑操作变得溜溜的!就这么简单直接,没啥好纠结的,用起来就对啦!原创不易,请尊重原创,谢谢!。

QTQProgressBarQProgressDialog模态,位置设置,无边框,进度条样式

QTQProgressBarQProgressDialog模态,位置设置,无边框,进度条样式

QTQProgressBarQProgressDialog模态,位置设置,⽆边框,进度条样式⼀关于模态设置QProgressDialog可以设置模态(需要在new的时候传⼊parent),QProgressBar设置不好;只有dialog可以设置模态,widget不能设置模态(QProgressBar继承⾃widget)⼆关于位置设置⼦窗⼝要相对于⽗窗⼝设置合适的位置,⽗窗⼝在屏幕上移动,⼦窗⼝对应跟着改变⼤⼩与位置:1 先设置⼦窗⼝的width与height,可以按⽗窗⼝的⽐例来;2 然后以⽗窗⼝的左上⾓为原点计算⼦窗⼝的位置QPoint;3 将2中的位置使⽤⽗窗⼝的mapToGlobal换算到屏幕的位置;4 将3中得到的位置设置给⼦窗⼝;如果⼦窗⼝设置成⽆边框的,则⼦窗⼝位置设置⾃动转换成相对于⽗窗⼝的位置,此时不再需要转换屏幕坐标设置;三关于⽆边框,⽆取消按钮setCancelButton(0);//隐藏取消按钮setWindowFlags(Qt::FramelessWindowHint);//⽆边框setStyleSheet("QWidget{background-color: rgb(255,255,255);}");//背景板是⽩⾊四关于进度条样式取消显⽰百分⽐,QProgressBar的setTextVisiable可以设置;但是QProgressDialog没有setTextVisiable怎么办?这时new⼀个QProgressBar(该QProgressDialog可构造设置为其parent,⽅便管理),然后QProgressDialog调⽤setBar即可;progressBar再设置setTextVisiable(false)即可。

进度条还可以设置QSS样式;五进度条⼤⼩控制有setFixedSize()与setMinminSize();先设置最⼩⼤⼩,然后设置固定⼤⼩,则最⼩限制被抵消;反之则可⾏;。

让窗口缩小的6种方法

让窗口缩小的6种方法

让窗口缩小的6种方法
哎呀呀,你是不是有时候也想让窗口缩小呀?今天,我就来给你讲讲让窗口缩小的 6 种方法吧!
第一种方法,直接用鼠标去拖窗口的边缘呀。

就好像你拉着一个小玩具车,把它变小一样简单呢!比如说你正在看电影的窗口,你就可以用鼠标抓住它的边边,轻轻一拉,嘿,就变小啦。

第二种方法呢,是按窗口右上角的那个小按钮,那个最小化按钮呀。

这就好比是给窗口施了个魔法,“噗”的一下就变小躲起来啦。

比如你在工作的时候,暂时不想看到某个文档窗口,按一下那个按钮,它就乖乖变小藏起来咯。

第三种方法,嘿,是用快捷键哟!按“Alt+空格+N”,哇,窗口就缩
小了呢。

这就像是给窗口下达了一个神秘的指令,它立马就执行啦!比如你正在玩游戏,突然有人喊你,你就可以快速按这个快捷键,让游戏窗口缩小,然后去回应别人。

第四种方法,在任务栏上找到对应的窗口图标,右键单击,然后选“最小化”。

这就好像是给窗口发出了一个特别的信号,它就变小啦!就像你有好多窗口打开着,你想让其中一个缩小,就用这个方法呗。

第五种方法,有些软件自身会带有缩小的功能哦。

就像有些超级英雄有自己独特的技能一样。

比如说一些绘图软件,里面可能就有一个专门的按钮来让窗口缩小呢。

第六种方法,嘿嘿,想不到吧,关闭再重新打开,它也可能以比较小的形态出现哦。

这就有点像重新洗牌,总会有不一样的结果出现呢!假如你不小心把窗口弄很大了,又不知道怎么调,就试试这个办法呀!
怎么样,是不是很有趣呀?快试试这些方法吧!。

切换窗口的四种方法

切换窗口的四种方法

切换窗口的四种方法
在日常的工作、学习、娱乐等方面,人们都会使用到电脑。

而在使用电脑时,如果多窗口并列,那么切换窗口就变得十分重要。

切换窗口不仅能让用户在多个窗口间快捷切换,而且也能提高工作效率。

因此,掌握切换窗口的方法就显得格外重要。

那么,切换窗口到底有哪些方法?其实,有许多种不同的方法可以用来切换窗口,本文将介绍四种最常见的方法。

第一种方法:键盘快捷键。

大多数电脑都自带有键盘快捷键,只要按下Alt+Tab可以在各个窗口之间快速切换。

但是这种方法只能切换那些已经打开的窗口,不能打开新窗口,也不能结束程序。

第二种方法:鼠标拖动。

使用鼠标可以轻松地从一个窗口切换到另一个窗口。

可以通过控制鼠标,将鼠标移动到另一个窗口,然后松开鼠标即可完成窗口的切换。

第三种方法:任务栏图标法。

任务栏中的任务图标可以显示出当前已经打开的窗口,只要将鼠标移动到需要切换的窗口上,点击一下即可完成窗口的切换。

第四种方法:窗口快速预览。

Windows 7以后的操作系统中提供了一种叫做“快速预览”的功能。

用户只要按下Win+Tab键,就可以快速地看到当前所有打开的窗口,再按下Tab键就可以实现窗口的切换。

以上就是切换窗口的四种方法。

用户可以根据自己的需要选择其中一种或多种方法。

无论选择哪一种,切换窗口都能提高工作效率,
增加操作的便利性,让用户在平时的学习和工作中都能够更好的感受到它的便利性。

窗口的操作

窗口的操作
此时可按下鼠标左键不放,拖动鼠标,从而改 变窗口大小。
窗口大小合适后,松开鼠标左键 处于最大化的窗口不能用此法改变大小
最大化窗口:此窗口中只有恢复按钮.
方法1:单击窗口标题栏右侧的最大化 按钮
方法2:双击窗口标题栏中除按钮外的 空白处
最小化窗口:指窗口缩小为任务栏中的 小图标按钮形式。
窗口的操作窗口的操作一窗口的组成窗口的操作窗口的操作一窗口的组成二窗口的操作11移动窗口移动窗口移动鼠标使鼠标位于要移动窗口的标题栏内此时的光标应呈空心箭头状
窗口的操作
一、窗口的组成
窗口的操作
一、窗口的组成 二、窗口的操作
1、移动窗口
移动鼠标,使鼠标位于要移动窗口的标 题栏内,此时的光标应呈空心箭头状。
单击此小图标按钮,可使最小化程序窗 口恢复成缩小前的窗口状态
关闭窗口: 1、双击窗口标题栏左侧的控制图标 2、单击窗口标题栏右侧的关闭按钮 3、Alt +F4键
按窗口移至合适位置后,放开鼠标左键。
注:最大化的窗口无法移动
2、改变窗口大小
一、窗口的三种状态:最大化、最小化、中间 化窗口。
二、改变窗口大小是针对中间化窗口而言的。 方法如下:
光标指向窗口的四个边框或某一个角时,将显 示成双箭头状;
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

第一步://先定义一个坐标点对象 mypointprivate Point mypoint;第二步:在窗体的点击事件中写private void Form1_MouseDown(object sender, MouseEventArgs e) {//鼠标在窗体内按下时,自动记录鼠标的 x y 值,并将它们改为负数mypoint = new Point(-e.X,-e.Y);}第三步:在窗体的鼠标移动事件中写private void Form1_MouseMove(object sender, MouseEventArgs e){/*鼠标在窗体内移动时,首先判断e.Button按下的是哪个鼠标按钮再判断* 是否等于左键按下,MouseButtons.Left这句的意思是鼠标左键按下状态*/if (e.Button == MouseButtons.Left){/*新建一个坐标点对象,它的坐标等于(Control.MousePosition;)* 桌面上坐标的位置*/Point myposition = Control.MousePosition;/*myposition.offset中的Offset是坐标平移的意思,现在将在窗体* 内点击左键时产生的负数加进来,也就等于现在鼠标在桌面上的坐标* 减去鼠标在窗体内的坐标位置,就等于现在窗体的位置*/myposition.Offset(mypoint.X, mypoint.Y);/*this.DesktopLocation这句的意思是获取或设置窗体在桌面上的位置* 它的位置来自myposition*/this.DesktopLocation = myposition;}其实这是个让人说过无数次的内容,但是最近在写一个测试小程序的时候发现了一个问题,今天没什么事做,就做个小的总结。

通过拖动窗体的客户区来移动一个窗体并不是很新鲜的内容,很多的程序都用到了这一点,尤其是一些可以换肤的程序。

这篇文章并不打算详细论述如何在C#下实现这一功能,因为它的代码实在是简单得不能再简单。

这里简单说一下实现的原理:首先说一个概念——窗体的客户区,窗体的客户区指的是一个窗体除了标题栏和边框以外的部分。

当我们的鼠标在窗体中移动的时候,会触发WM_NCHITTEST系统消息,MSDN中对这个消息的说明为:The WM_NCHITTEST message is sent to a window when the cursor moves, or when a mouse button is pressed or released. If the mouse is not captured, the message is sent to the window beneath the cursor. Otherwise, the message is posted to the window that has captured the mouse. (当光标移动或一个鼠标键被按下或释放时,WM_NCHITTEST消息会被发送到一个窗口中,如果光标没有被捕获,这个消息被送到光标下的窗口。

否则这个消息被送到捕获了光标的窗口。

)这个消息被默认的(请注意是“默认的”)窗口过程(窗口过程这个概念后面再说)处理后,会根据触发这个消息时鼠标的位置返回一个值,例如当鼠标在窗口的标题栏上时,返回HTCAPTION;当鼠标在一个窗口的客户区中时,返回HTCLIENT;如果鼠标指向某个窗口的字窗口的“关闭”按钮或系统菜单(就是点击窗口图标后出现的那个菜单),就返回HTSYSMENU。

所以我们要做的就是骗!我们要欺骗Windows,当我们的鼠标在窗体的客户区中移动时,默认的窗口过程处理后会返回 HTCLIENT,Windows系统根据这个值进行相应的操作,把适当的消息插入到应用程序的消息队列(这个概念同样在后面讨论)中。

这时如果我们做一些改变,人为地修改窗口过程的返回值,把HTCLIENT修改为HTCAPTION并返回给系统,系统就会认为鼠标这时在窗体的标题栏中,而拖动标题栏可以移动一个窗体,所以当我们在一个被这样修改后的应用程序的客户区按下鼠标并拖动时,Windows会认我们在拖动一个窗体的标题栏,于是它把一个移动窗体的消息插入到程序的消息队列中,再经过窗口过程的处理,就实现了我们需要的功能——拖动窗体的客户区移动窗体。

于是就有了下面的代码:protected override WndProc(ref message m){switch (m.Msg){case WM_NCHITTEST: //如果鼠标移动或单击base.WndProc(ref m);//调用基类的窗口过程——WndProc方法处理这个消息if (m.Result == (IntPtr)HTCLIENT)//如果返回的是HTCLIENT{m.Result = (IntPtr)HTCAPTION;//把它改为HTCAPTIONreturn;//直接返回退出方法}break;}base.WndProc(ref m);//如果不是鼠标移动或单击消息就调用基类的窗口过程进行处理}这也是MSDN上的一个例子,重写窗体的WndProc方法,判断消息然后返回。

我本来也是想这样就完事了,可是后来测试的时候却发现有个大问题:双击窗体的时候,窗体会最大化。

那天脑子有点迷糊,也没多想就到网上问了一下,一个高手提醒我说可能是那个重写的窗口过程的问题,于是一下子明白了。

我们向Windows传递了假信息,Windows我们在窗体的客户区双击鼠标在Windows看来是双击了窗体的标题栏,理所当然的Windows会告诉窗口过程窗体需要最大化,窗口过程又理所当然的照做了,于是就出现了这样的现象。

刚开始的时候还不是很确定这样想对不对,不过后来出现的另一个现象证实了这个推断是正确的:因为窗体没有标题栏,每次退出程序都要按Alt+F4实在是比较不爽,我就给窗体添加了一个ContextMenuStrip,只有一个菜单项用来关闭窗体退出程序。

我发现当我修改了窗体的默认窗口过程后,这个右键菜单就显示不出来了。

出现这个现象的原因只能有一个——Windows真的把窗体的客户区当成标题栏处理了,而默认ContextMenuStrip只能用在窗体的客户区或控件上。

后来我又跟那位高手讨论了一下,他给我提供了另一种方法,这个方法需要两个API函数:LRESULT SendMessage(HWND hWnd,// handle of destination windowUINT Msg,// message to sendWPARAM wParam,// first message parameterLPARAM lParam // second message parameter);BOOL ReleaseCapture(VOID)SendMessage函数想必不用多说了,无数个木马制作教学贴里都有详细的描述,这个函数用来向指定的窗体发送Windows消息,功能的确十分强大^_^ReleaseCapture函数相对陌生一些,这个函数用来释放被当前线程中某个窗口捕获的光标。

他给出的代码是这样的:private void Form1_MouseDown(object sender, MouseEventArgs e){ReleaseCapture();SendMessage(this.Handle, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);}也就是说,在窗体的MouseDown(鼠标按下)事件中,首先释放光标,然后向窗口过程发送WM_SYSCOMMAND消息。

说实话这个方式的SendMessage函数调用我也是第一次遇到,刚开始怎么也不明白为什么要把它们(SC_MOVE 和 HTCAPTION)用一个加号连接起来。

这个WM_SYSCOMMAND消息包含了一些信息表示用户要进行的操作,消息的wParam 字段表示用户要最大化、最小化或移动窗体。

我去掉HTCAPTION试了一下,每当我在窗体上按下鼠标左键时,鼠标就会移动到窗体的最顶端——原来标题栏的位置,与我们在系统菜单中选择“移动”菜单项的效果一样。

于是查阅MSDN,在WM_SYSCOMMAND的帮助中查到这样一句话:In WM_SYSCOMMAND messages, the four low-order bits of the uCmdType parameter are used internally by Windows. To obtain the correct result when testing the value of uCmdType, an application must combine the value 0xFFF0 with the uCmdType value by using the bitwise AND operator. (在WM_SYSCOMMAND消息中,uCmdType的低四位是Windows内部使用的。

如果测试时要获得uCmdType的正确结果,应用程序必须把0xFFF0这个值与uCmdType的值通过位相加的方式合并在一起。

)于是豁然开朗:这个所谓的“Windows内部使用的值”在移动这个窗体的时候其实就是表示“窗体的标题栏”,所以我们使用SC_MOVE + HTCAPTION表示窗体将被移动且目前鼠标正在窗体的标题栏中。

至于这里为什么要先释放光标再发送消息,根据前面的WM_NCHITTEST消息的说明,如果光标被当前窗口捕获,那么当鼠标移动时,就会发送 WM_NCHITTEST到我们的窗体,而由于我们这时没有重写窗口过程,这个消息会被按照默认的方式处理,Windows会发现鼠标在窗体的客户区移动,SendMessage发过去的HTCAPTION被WM_NCHITTEST消息中的HTCLIENT覆盖,这样窗体就不会有任何动作。

还有两个名词解释:窗口过程:窗口过程是一个应用程序定义的、用来处理Windows消息的回调(CallBack)函数,当有消息发生时,窗口过程负责处理消息。

消息队列:Windows会把有关一个应用程序的全部消息放到一块内存区域中,这个区域使用一种先进先出(FIFO)的方式工作,就是说最先进入这个区域的消息会第一个离开这个区域,故称消息队列。

应用程序从消息队列中取出一条消息,进行相应的处理,返回一定的信息,然后再取出下一条处理。

例1:using System;using ponentModel;using System.Drawing;using System.Windows.Forms;namespace LiBo.WinControls.Forms {/// <summary>/// DragForm 类是可/// </summary>public class DragForm : System.Windows.Forms.Form {private bool dragEnable;private bool dragging;private int xOld, yOld;public DragForm() : base() {dragEnable = false;}/// <summary>/// 获取或设置一个值,该值指示窗体是否可以通过鼠标左键拖动。

相关文档
最新文档