WINDOWS窗口的客户区域拖动技术及其应用

2016-02-19 13:03 25 1 收藏

有了下面这个WINDOWS窗口的客户区域拖动技术及其应用教程,不懂WINDOWS窗口的客户区域拖动技术及其应用的也能装懂了,赶紧get起来装逼一下吧!

【 tulaoshi.com - 编程语言 】

WINDOWS应用程序窗口一般包括两种:普通窗口和常居顶层的无标题条高级窗口。前者是由WINDOWS内部功能定制的,它具有WINDOWS应用程序窗口的所有普通特性:具有标题条、窗口边框、最大化按钮、最小化按钮和系统默认的快捷键及鼠标支持功能等,利用鼠标左键拖动该种窗口的标题条可以在屏幕上任意移动窗口,当鼠标光标停在窗口边框上时可以改变窗口大小;后者是一种定制的高级窗口,它不具有普通窗口的任何属性,整个窗口的控制必须由编程者来一一确定,使用这种窗口的典型实例有WINDOWS中的IME输入法应用程序、UCWIN4.0平台、各种浮动工具箱、Office中的桌面工具栏和第三方开发的汉字输入平台等。
  
    WINDOWS 这种无标题条常居顶层高级窗口的一个显著特点是,不需改变窗口大小但必须具有窗口的客户区域拖动功能。由于普通窗口的拖动功能是由系统来完成的,编制普通的应用程序根据无须考虑客户区域拖动问题,因此一般编程人员很难碰到这个问题,更谈不上如何实现这一功能了。开发者往往希望自己开发出来的软件具有经典软件中的窗口客户区域拖动功能,笔者曾经利用模拟系统鼠标点击标题条拖动窗口和WINDOWS系统内部提供的API发送函数发送内部拖动命令来实现无标题常居顶层高级窗口的客户拖动功能,结果都不理想。后来只好在窗口函数中通过直接处理WM_LBUTTONDOWN、WM_MOUSEMOVE和WM_LBUTTONUP消息,自行控制窗口拖动的客户命令区、拖动开始、窗口移动、拖动虚框绘制、虚框移动和拖动结束等过程,来实现高级顶层窗口的客户区域拖动方案。下面就自己实践经验具体介绍实现该方案的具体方法和主要技巧。
  
    一、WINDOWS检测客户拖动命令及鼠标光标动态提示的实现方法
  
    WINDOWS 无标题条常居顶层高级窗口的客户区域一般分为两种:特定客户命令区域和非特定客户命令区域。特定客户命令区域是指利用"RECT"定义的特定子矩形区域,窗口函数对发生在该区域内的鼠标命令进行检测并处理;非特定客户命令区域是指没有明确定义的窗口客户区域部分,即所有特定客户命令区域之外的部分,窗口函数根据实际需要来确定是否对该区域内发生的鼠标命令进行处理。实现常居顶层高级窗口拖动功能的首要问题,是如何检测和处理特定客户命令区域和非特定客户命令区域内的鼠标命令,以及如何利用鼠标光标来动态提示用户此时可以进行窗口的拖动操作。
  
    1、在特定客户区域检测鼠标命令的方法
  
    当窗口中设置了实现拖动功能的图标命令按钮时,就必须在资源文件中定义命令按钮的特定客户区域,该区域一般也就是显示命令按钮中图标的矩形区域,这个区域的定义方法为"RECT DragRT",其中DragRT为定义的检测鼠标命令矩形区域,它用DragRT.LEFT、DragRT.TOP、DragRT.RIGHT和DragRT.BOTTOM四个参数来描述矩形区域相对于窗口客户区域左上角的相对坐标值,这四个参数必须事先定义具体的数值,也可以利用"SETRECT"函数直接填充。
  
    窗口函数在处理鼠标消息WM_LBUTTONDOWN时,在接收系统传递的鼠标位置参数lParam后,通过MAKEPOINT( )函数将其转换为窗口坐标值,利用判定某坐标点是否位于特定矩形区域内的函数PtInRect(),就可以判定鼠标指针是否点击在拖动命令按钮之内,从而完成窗口拖动功能的启动任务。其描述性功能代码示例如下:
  
    case WM_LBUTTONDOWN://鼠标光标点击处理
  
    POINT pt;//鼠标在屏幕上位置指针,包括pt.X和pt.Y两个参数,
  
     //该指针值利用MAKEPOINT通过lParam参数转换而来
  
    pt=MAKEPOINT(lParam); //获取鼠标当前屏幕位置指针
  
    if(PtInRect(&DragRT,pt)){//判定鼠标是否点击在拖动按钮内
  
     //实现鼠标拖动窗口方案的启动功能
  
    } else {
  
     //进行其它特定或非特定命令客户区域判定处理
  
    }
  
    break;
  
    2、在非特定客户区域检测鼠标命令的方法
  
    当窗口应用程序中采取了非特定客户区域拖动方法时,必须在资源文件中事先确定各个特定客户区域的矩形坐标,这时非特定客户区域是不规则的区域,它需要根据实际的应用程序窗口及各个命令按钮矩形区域来确定,也就是各个命令按钮相对于窗口矩形区域的“非”子集。窗口函数在处理鼠标消息WM_LBUTTONDOWN时,首先利用函数PtInRect()判定当前鼠标指针是否点击在各个命令按钮矩形区域内,假如未点击在任何命令按钮区域内,则可确定鼠标点击在非特定客户区域内,从而实现窗口拖动功能的启动。其描述性功能代码示例如下:
  
    case WM_LBUTTONDOWN: //鼠标光标点击处理
  
  
    POINT pt; //定义鼠标在屏幕上的位置指针
  
    pt=MAKEPOINT(lParam); //取得鼠标光标当前位置指针
  
    for(I=0;I
  
     if(PtInRect(&DragRT[I],pt)){//DragRT[I]为按钮矩形数组
  
     break; //鼠标点击在其它按钮上中断
  
     }
  
    }
  
    if(I
  
     //鼠标点击在其它特定客户区域内则处理其它按钮功能
  
    }else{
  
     //鼠标点击在非客户区域内则完成窗口拖动方案的启动
  
    }
  
    break;
  
    3、窗口拖动功能的鼠标光标动态提示方法
  
    在无标题条常居顶层高级窗口应用程序中,既可以采用将特定客户区域作为拖动命令按钮的方法,也可以采取在非特定客户区域检测窗口拖动命令的方法,或者两种方法兼顾使用。在使用第一种方法时,可以在命令按钮中用特定的图标或文字来提示用户该命令按钮的功能,而后一种方法由于矩形区域无法确定不可能用图标或文字来提示,或根本无法显示图标和文字(如非特定客户区域为窗口边界区域等),用户根本无法知道非特定客户区域具有拖动窗口功能,这时唯有充分利用鼠标光标的动态提示功能,就象WINDOWS 普通窗口中鼠标光标停在窗口边框上时鼠标光标变成双箭头外形来提示用户此时可以改变窗口大小那样,这个功能在高级窗口界面设计中非常重要。
  
    实现鼠标光标动态提示功能前需要定制鼠标光标外形,窗口拖动功能的动态提示光标外形一般为四箭头图案,这可以利用微软公司的SDK、FPT3.0和VC++4.1等高级开发软件中的资源编辑器"IMAGE ED99v"等来实现。光标资源文件一般为32X32的2色或16色.CUR图形文件,可根据实现的功能来具体确定光标图案或直接使用WINDOWS 系统中提供的光标资源文件,当自己利用资源编辑器绘制光标图案后,还需要利用DEBUG. EXE程序修改光标资源文件中的鼠标光标显示偏移坐标,以便光标图案能象WINDOWS 系统中的动态提示光标一样,动态提示时光标图案中心点正好处于屏幕的当前位置。这个偏移坐标值位于光示资源文件中的10和12处的双字节位置,如动态提示光标资源文件名为MOUSEM.CUR,要使32X32(2色)的光标图形显示时图案的中心点正好处于当前屏幕位置,其修改方法如下:
  
    CDEBUG MOUSEM.CUR
  
    -E 10A
  
    XXXX:10A 00.10 00.00 00.10 00.00
  
    -W
  
    建立起自己的鼠标光标资源文件后,首先需要在应用程序的资源文件中定义鼠标光标,资源文件中的定义方法为:
  
    imecurm CURSOR mousem.cur
  
    鼠标光标资源文件只有在定义之后,才能在应用程序中利用LoadCursor()函数调入内存使用,其调用方法为:
  
    HCURSOR hCurm;//将鼠标光标资源文件数据调入内存
  
    hCurm=LoadCursor(hInstance,"imecurm");
  
    当需要动态改变鼠标光标外形的客户区域为整个窗口或某个子窗口的全部客户区域时,在注册客户应用程序窗口类时定义相应的鼠标光标资源句柄,当鼠标光标移到相应窗口内时马上变成定制的光标外形,移出相应窗口时自动恢复原来光标外形。实现鼠标光标这一动态提示功能的定义方法如下:
  
    wc.hCursor=hCurm;
  
    当鼠标光标需要在窗口的特定客户命令按钮区域内或非特定客户命令区域内进行动态提示时,就不能使用上述定义方法,必须在窗口函数处理WM_MOUSEMOVE消息时进行非凡处理:首先判定鼠标光标指针当前位置是否在拖动命令按钮或非特定客户区域内移动,假如鼠标指针位置满足拖动窗口功能区域的要求,则利用API函数SETCURSOR()改变鼠标光标图案,提示用户此时可以进行窗口拖动操作,并将鼠标输入控制权交给当前窗口,同时设置改变鼠标光标标志;当鼠标指针移出拖动窗口启动命令区域时,恢复原来鼠标光标图案同时释放鼠标输入焦点控制权,并清除鼠标光标动态提示标志单元。其功能性代码描述如下:
  
    BOOL DragFlag; //动态提示光标标志
  
    case WM_MOUSEMOVE: //鼠标光标移动处理
  
     pt=MAKEPOINT(lParam); //鼠标光标当前位置指针
  
     if(PtInRect(&DragRT,pt)){//鼠标指针在拖动命令区域内则
  
     SetCursor(hCurm); //动态改变鼠标光标外形
  
     SetCapture(hWnd); //将鼠标输入控制权交当前窗口
  
     iFlag=TRUE; //设置鼠标光标外形改变标志
  
     } else if(iFlag==TRUE){ //鼠标指针未在拖动命令区域内
  
     SetCursor(LoadCursor(NULL,IDC_ARROW));//恢复原外形
  
     ReleaseCapture() //释放鼠标输入控制权

来源:https://www.tulaoshi.com/n/20160219/1602859.html

延伸阅读
在北京工业大学计算机学院 胡击先生的深入MDI客户窗口编程一文中谈到了其在学习过程中摸索出的两种改变MDI客户窗口背景的方法,并具体描述了其中一种实现方法,同时给出了示例代码。我对作者这种孜孜不卷的学习态度表示钦佩,并同时提出自己在遇到同样的情况时所采取的解决方法。 希望能够互相学习、交流。 其实,VC6.0/5.0在其M...
标签: windows 操作系统
本教程为配合Windows 7正式发布,中国专门推出了玩转Win7系列教程,在上一课中我们了解了Win7的任务栏,今天我们来看看如何打开任务栏设置窗口~~ 玩转Win7之打开任务栏设置窗口 在进入WINDOWS7后系统会自动显示任务栏,而此时的任务栏将使用系统默认设置。有的时候这个默认设置并不一定会适合每一位用户,有些朋友为了更便于自己工作或追...
标签: Web开发
    层(Layer)是一种 HTML 页面元素,您可以将它定位在页面上的任意位置。层可以包含文本、图像或其它 HTML 文档。层的出现使网页从二维平面拓展到三维。可以使页面上元素进行重叠和复杂的布局。首先,请看下图: 我们首先来做一个层 1、 在「窗口」菜单>选“层”,或点「插入」菜单>布局对象>选“层”。 ...
Jini技术的出现,使得Java在成功地为网络设备的计算提供了合适的平台之后,更为网络设备,尤其是家庭网络下的消费类电子设备提供了一个全新的网络计算结构,从而实现了人们期待已久的网络设备的即插即用。 对Jini设备的硬件要求 !-- frame contents -- !-- /frame contents -- 虽然Jini本身是一个软件系统,但是一个...
标签: 电脑入门
Win7的透明效果令人惊艳,尤其是桌面透视、窗口透明,想必很多已经升级到Win7系统的用户都体验到了。不过有些用户在使用电脑时,还遇到了一种新的透明效果,就是在Win7中拖动窗口时,窗口内容全都消失了,只剩下一个窗口的边框在移动。 拖动窗口时只显示边框 Win7的Aero特效只能在Win7家庭高级版及以上版本的系统中才有,但这种透明在Win7...

经验教程

218

收藏

77
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部