WINDOWS窗口的客户区域拖动技能及其应用
副标题#e#
WINDOWS应用措施窗口一般包罗两种:普通窗口和常居顶层的无标题条高级窗口。前者是由WINDOWS内部成果定制的,它具有WINDOWS应用措施窗口的所有普通特性:具有标题条、窗口边框、最大化按钮、最小化按钮和系统默认的快捷键及鼠标支持成果等,操作鼠标左键拖动该种窗口的标题条可以在屏幕上任意移动窗口,当鼠标光标停在窗口边框上时可以改变窗口巨细;后者是一种定制的高级窗口,它不具有普通窗口的任何属性,整个窗口的节制必需由编程者来一一确定,利用这种窗口的典范实例有WINDOWS中的IME输入法应用措施、UCWIN4.0平台、各类浮动东西箱、OFFICE中的桌面东西栏和第三方开拓的汉字输入平台等。
WINDOWS 这种无标题条常居顶层高级窗口的一个显著特点是,不需改变窗口巨细但必需具有窗口的客户区域拖动成果。由于普通窗口的拖动成果是由系统来完成的,体例普通的应用措施按照无须思量客户区域拖动问题,因此一般编程人员很难碰着这个问题,更谈不上如何实现这一成果了。开拓者往往但愿本身开拓出来的软件具有经典软件中的窗口客户区域拖动成果,笔者曾经操作仿照系统鼠标点击标题条拖动窗口和WINDOWS系统内部提供的API发送函数发送内部拖动呼吁来实现无标题常居顶层高级窗口的客户拖动成果,功效都不抱负。厥后只亏得窗口函数中通过直接处理惩罚WM_LBUTTONDOWN、WM_MOUSEMOVE和WM_LBUTTONUP动静,自行节制窗口拖动的客户呼吁区、拖动开始、窗口移动、拖动虚框绘制、虚框移动和拖动竣事等进程,来实现高级顶层窗口的客户区域拖动方案。下面就本身实践履历具体先容实现该方案的详细要领和主要能力。
一、WINDOWS检测客户拖动呼吁及鼠标光标动态提示的实现要领
WINDOWS 无标题条常居顶层高级窗口的客户区域一般分为两种:特定客户呼吁区域和非特定客户呼吁区域。特定客户呼吁区域是指操作"RECT"界说的特定子矩形区域,窗口函数对产生在该区域内的鼠标呼吁举办检测并处理惩罚;非特定客户呼吁区域是指没有明晰界说的窗口客户区域部门,即所有特定客户呼吁区域之外的部门,窗口函数按照实际需要来确定是否对该区域内产生的鼠标呼吁举办处理惩罚。实现常居顶层高级窗口拖动成果的首要问题,是如何检测和处理惩罚特定客户呼吁区域和非特定客户呼吁区域内的鼠标呼吁,以及如何操作鼠标光标来动态提示用户此时可以举办窗口的拖动操纵。
#p#副标题#e#
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()判定当前鼠标指针是否点击在各个呼吁按钮矩形区域内,假如未点击在任何呼吁按钮区域内,则可确定鼠标点击在非特定客户区域内,从而实现窗口拖动成果的启动。其描写性成果代码示譬喻下:
#p#分页标题#e#
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 EDIT"等来实现。光标资源文件一般为32X32的2色或16色.CUR图形文件,可按照实现的成果来详细确定光标图案或直接利用WINDOWS 系统中提供的光标资源文件,当本身操作资源编辑器绘制光标图案后,还需要操作DEBUG. EXE措施修改光标资源文件中的鼠标光标显示偏移坐标,以便光标图案能象WINDOWS 系统中的动态提示光标一样,动态提示年华标图案中心点正长处于屏幕的当前位置。这个偏移坐标值位于光示资源文件中的10和12处的双字节位置,如动态提示光标资源文件名为MOUSEM.CUR,要使32X32(2色)的光标图形显示时图案的中心点正长处于当前屏幕位置,其修改要领如下:
C>DEBUG 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() //释放鼠标输入节制权
iFlag=FALSE; //规复鼠标光标形状改变符号
}
break;
二、WINDOWS高级窗口拖动方案中拖动框的客户定制要领
#p#分页标题#e#
以上先容了窗口拖动前鼠标光标位置检测及客户呼吁区域内拖动成果的鼠标光标动态提示要领,当用户通过鼠标光标动态提示成果取得满意拖动窗口条件时,通过点击鼠标左键来启动拖动方案,这时最要害的技能问题是鼠标拖动窗口移动进程中的拖动框显示与擦除成果实现。窗口拖动虚框就是在WINDOWS 整个屏幕区域内显示描写被拖动窗口巨细的线框,它的巨细需要按照被拖动窗口的矩形区域巨细和实际需要来详细确定,一般环境下为被拖动窗口的矩形区域巨细。
WINDOWS 系统中的画图要领是通过显示设备描写表实现的,画图操纵需要占用必然的GDI 资源,系统为窗口、菜单、对话框、字体和各类画图函数分派足够的GDI资源,WINDOWS 95中的GDI资源要比WINDOWS3.X中的GDI资源大得多。WINDOWS中有两种利用显示设备描写符表的要领:更新窗口显示客户区域和直接操纵窗口显示客户区域。更新窗口显示客户区域是直接针对应用措施窗口矩形区域而言的,在窗口函数响应WM_PAINT动静时操作图形操纵呼吁举办窗口更新处理惩罚:
InvalidateRect(hWnd,&WinRECT,TRUE);//WinRECT为要更新区域
UpdateWindow(hWnd);
窗口初始成立时默认更新窗口的全部区域,当要更新的矩形区域为NULL时暗示更新窗口所有矩形区域。函数UpdateWindow()通知系统向要更新矩形区域的窗口发送WM_PAINT动静,窗口函数吸收到WM_PAINT动静后首先操作BeginPaint()函数取得设备描写符表,然后操作图形呼吁直接对显示设备举办更新操纵,最后操作EndPaint()函数通知系统更新操纵竣事。其描写性成果代码如下:
case WM_PAINT:
PAINTSTRUCT ps;
hdc=BeginPaint(hWnd,&ps);//取得设备描写符表
SetBkMode(hdc,OPAQUE); //设备更新方法
SetBkColor(hdc,0x00c0c0c0);
//更新矩形区域内图形操纵
EndPaint(hWnd,&ps); //竣事更新操纵
break;
更新窗口矩形区域直接利用窗口类中界说的屏幕画刷,纵然操作SelectObject()函数选择相应屏幕画刷也无效,并且更新矩形区域范畴是通过InvalidateRect()函数累加的,由UpdateWindow()函数通知系统开始举办窗口更新操纵,整个进程是由系统来调治的,因此利用这种要领无法实现窗口的拖动虚框绘制和及时操纵。
直接操纵窗口客户区域的要领是操作GetDC( )函数直接取得显示设备句柄,操作各类图形操纵呼吁直接对显示设备举办画图,它利用屏幕当前配置的画笔和画刷来实现各类图形绘制操纵,无须系统任何动静应用措施就可以及时地对屏幕窗口举办更新和画图操纵。其操纵进程是首先取得显示设备描写符句柄:
HDC hDC;
hDC=GetDC(hWnd);//取得hWnd窗口设备描写符表句柄
当hWnd参数为NULL时取得的是整个屏幕的设备描写符表句柄,然后操作SelectObject()函数配置当前屏幕的画笔和画刷,就可以操作各类绘图函数完成屏幕的画图操纵,最后操作ReleaseDC( )函数释放获取的显示设备描写表。由于这种要领可以直接节制当前屏幕的画笔和画刷,而且无需系统调治就可以直接对屏幕设备举办操纵,因此操作这种要领完全可以实现窗口的拖动虚框。窗口的拖动虚框是用来描写要移动窗口巨细的虚线框和实线框,当矩形拖动框为虚线时,需要操作画点或画线函数颠末必然算法来实现,这就需要配置当前的屏幕画笔;当窗口的拖动框为实线框时,假如操作画线函数只需配置屏幕画笔即可,假如操作画矩形函数Rectangle( )在配置当前屏幕画笔的同时必需利用SelectObject(hDC,GetStockObject(NULL_BRUSH))屏蔽掉任何屏幕画刷,不然WINDOWS措施会很快吞筮掉所有GDI资源,相当于在屏幕设备资源中增加了无数矩形区域。
对付窗口拖动框的擦除操纵,只需在拖动框绘制函数中将屏幕的图形画笔操纵方法配置为R2_XORPEN异或方法,即SetROP2(hDC2,R2_XORPEN),在拖动框绘制竣事时留意规复,然后在窗口拖动框移动到下一个位置前,在原屏幕位置从头挪用绘制函数一次将本来拖动框擦除。下面给出笔者操作画矩形、画线和画点函数实现的拖动框函数,用户在利用时可选择本身喜欢的实线或虚线拖动框函数。
函数1为操作画矩形函数实现的拖动实框,其特点是函数的结果高,拖动框作图速度快;函数2为操作画线函数实现的拖动框,其特点是通过配置差异的画线范例可以画虚框也可以画实框;函数3为操作画线函数实现的拖动虚框函数,特点是拖动虚框图案变革机动,不敷是函数效率低作图速度慢。函数通过参数可选择差异的拖动虚框图案或密度。函数3参数XY为1时与WINDOWS 3.X窗口拖动缺省虚框沟通为单虚线框,假如XY参数为2 则拖动虚框为矩齿形边框。也可以按照需要选择差异的拖动虚框图案和相应画笔和画刷以到达差异的结果。
//函数1:操作画矩形函数实现拖动实框
#p#分页标题#e#
void DrawMoveRect(int xx1,int yy1,int xx2,int yy2,int xy)
{
HDC hDC;
int oldrop2,m,k;
hDC = GetDC(NULL); //取得全屏幕设备描写句柄
oldrop2= GetROP2(hDC); //取得本来屏幕绘图方法
SetROP2(hDC,R2_XORPEN); //配置异或屏幕绘图方法
SelectObject(hDC,GetStockObject(NULL_BRUSH));//屏蔽画刷
SelectObject(hDC2,GetStockObject(WHITE_PEN));//选择画笔
for (k=0;k
xx1-=1;
xx2+=1;
yy1-=1;
yy2+=1;
Rectangle(hDC2,xx1,yy1,xx2,yy2);
}
SetROP2(hDC2,oldrop2); //规复本来作图方法
ReleaseDC(NULL,hDC2); //释放设备描写符表
}
//函数2:操作画线函数实现拖动实框或虚框
void DrawMoveRect(int xx1,int yy1,int xx2,int yy2,int xy)
{ HDC hDC2;
int oldrop2,m,k;
hDC = GetDC(NULL); //取得全屏幕设备描写句柄
oldrop2= GetROP2(hDC); //取得本来屏幕绘图方法
SetROP2(hDC,R2_XORPEN); //配置异或屏幕绘图方法
SelectObject(hDC,GetStockObject(NULL_BRUSH));//屏蔽画刷
SelectObject(hDC2,GetStockObject(WHITE_PEN));//选择画笔
for (k=0;k
xx1-=1;
xx2+=1;
yy1-=1;
yy2+=1;
MoveTo(hDC2,xx1,yy1);
LineTo(hDC2,xx2,yy1);
MoveTo(hDC2,xx1,yy1);
LineTo(hDC2,xx2,yy1);
}
SetROP2(hDC2,oldrop2); //规复本来作图方法
ReleaseDC(NULL,hDC2); //释放设备描写符表
}
//函数3:操作画点函数实现差异图案的拖动虚框
void DrawMoveRect(int xx1,int yy1,int xx2,int yy2,int xy)
{ HDC hDC2;
int oldrop2,I,j,x1,x2,y1,y2;
hDC = GetDC(NULL); //取得全屏幕设备描写句柄
oldrop2= GetROP2(hDC); //取得本来屏幕绘图方法
SetROP2(hDC,R2_XORPEN); //配置异或屏幕绘图方法
SelectObject(hDC,GetStockObject(NULL_BRUSH));//屏蔽画刷
SelectObject(hDC2,GetStockObject(WHITE_PEN));//选择画笔
for (j=0;j
x1=xx1-j; //带注释部门为另一图案
x2=xx2+j;
y1=yy1-j;
y2=yy2+j;
for (I=x1;I
SetPixel(hdc,I,y1,RGB(255,0,0));
//if (I
for (I=y1;I
SetPixel(hdc,x2,I,RGB(255,0,0));
//if (I
for (I=x2;I>x1;I-=2)
SetPixel(hdc,I,y2,RGB(255,0,0));
//if (I>x1+2) SetPixel(hdc,I-1,y2-1,RGB(255,0,0));}
for (I=y2;I>y1;I-=2)
SetPixel(hdc,x1,I,RGB(255,0,0));
//if (I>y1+2) SetPixel(hdc,x1+1,I-1,RGB(255,0,0));}
}
SetROP2(hDC2,oldrop2); //规复本来作图方法
ReleaseDC(NULL,hDC2); //释放设备描写符表
}
三、WINDOWS高级窗口客户区域拖动技能实现的“三步曲”
WINDOWS 高级窗口的客户区域拖动呼吁判定、拖动成果的鼠标光标动态提示和定制窗口拖动框函数之后,就需要实现整个拖动方案中的拖动进程启动、窗口拖动框移动和拖动竣事处理惩罚的三步曲进程。于是必需在窗口函数中直接处理惩罚WM_LBUTTONDOWN、WM_MOUSEMOVE和WM_LBUTTONUP动静,来详细处理惩罚上述三个步调中的细节问题。
第一步,在窗口函数中对鼠标点击动静WM_LBUTTONDOWN举办判定处理惩罚,以处理惩罚用户通过鼠标光标动态提示成果获取满意窗口拖动条件时,按下鼠标左键发生的启动拖动进程动静,其成果性代码如下:
POINT pt;
BOOL MoveFlag=FALSE;
case WM_LBUTTONDOWN:
pt = MAKEPOINT(lParam); //获取鼠标光标指针
if(PtInRect(&DragRT,pt)){//DragRT为拖动呼吁区域
DragBegin((LPRECT)&WinRT,lParam,hWnd,2);
//启动窗口拖动进程
} else {举办其它处理惩罚}
break;
上述DragBegin( )函数为笔者开拓的窗口拖动启动函数,由于一个高级窗口应用措施中往往存在许多窗口,所以将其作为一个单独函数处理惩罚。个中WinRT 为高级窗口矩形区域,这里作为拖动框矩形区域参数来通报,lParam为鼠标光标指针长整数,hWnd为当前被拖动窗口的句柄,2 为拖动框宽度。同时需要将鼠标节制权交给当前被拖动窗口、配置拖动窗口符号单位、生存当前鼠标在屏幕上的位置并显示被拖动窗口的拖动框。拖动成果启动函数的原形代码如下:
#p#分页标题#e#
void DragBegin(
LPRECT WinRect, //拖动框的矩形区域
LPARAM lParam, //鼠标光标当前指针
HWND hwnd, //当前窗口句柄
unsigned int kk) //拖动框显示的宽度
{
SetCapture(hwnd); //拖动时窗口必需具有鼠标输入权
MoveFlag=TRUE; //配置拖动符号
oldmx=LOWORD(lParam);//记录当前鼠标屏幕坐标X
oldmy=HIWORD(lParam);//记录当前鼠标屏幕坐标Y
DrawMoveRect(WinRect->left,WinRect->top,//显示拖动框
WinRect->right,WinRect->bottom,kk);
}
第二步,需要处理惩罚鼠标拖动窗口时的拖动框移动进程,这需要在窗口函数中举办WM_MOUSEMOVE动静处理惩罚。拖动框的移动包罗上次显示拖动框的排除和本次拖动框的显示两步,由于拖动框绘制函数中对当前的绘制方法举办从头配置,异或方法使得只要从头在原屏幕坐标位置处挪用一次该函数即可排除拖动框,因此,在鼠标拖动窗口移动进程中显示和排除拖动框只需要挪用两次拖动框绘制函数即可。别的,拖动框在屏幕上位置的计较要领也很是简朴,就是将当前取得的屏幕位置坐标值减去生存的前次屏幕位置坐标值所得鼠标移动偏移量,再用本来窗口屏幕左上角坐标值加上这个偏移量,就可以确定被拖动窗口和拖动框新的屏幕位置坐标值。其处理惩罚进程的描写性代码如下:
case WM_MOUSEMOVE:
DragMove((LPRECT)&WinRT,WinWT,WinHi,lParam,2);
//WinRT为窗口矩形区域,WinWT为窗口宽度,WinHI为窗口高度
} else {举办其它处理惩罚}
break;
鉴于高级窗口应用措施一般为多个子窗口,所以将拖动框移动处理惩罚进程单独体例成函数,而且对鼠标拖动窗口进程中,窗口不能完全位于屏幕可见区域之内举办了非凡处理惩罚,开拓者可按照需要自行调解其位置,以便被拖动的窗口可以或许完全被显示于屏幕可视区域内,其拖动进程函数原形代码部门如下:
void DragMove(
LPRECT rcwin, //拖动框矩形区域
unsigned int wi, //被拖动窗口宽度
unsigned int hi, //被拖动窗口高度
LPARAM lParam, //鼠标位置指针
unsigned int kk) //拖动框边框宽度
{
DrawMoveRect(rcwin->left,rcwin->top,
rcwin->right,rcwin->bottom,kk);//排除上次画拖动框
rcwin->left+=LOWORD(lParam)-sImeG.oldmx;//计较窗口
rcwin->top+=HIWORD(lParam)-sImeG.oldmy; //新位置
sImeG.oldmx=LOWORD(lParam); //生存当前坐标值
sImeG.oldmy=HIWORD(lParam);
if (rcwin->left<0) rcwin->left=0;//对窗口逾越屏幕
if (rcwin->left>sImeG.xScrWi-wi) //可视区域处理惩罚
rcwin->left=sImeG.xScrWi-wi;
ii=sImeG.yScrHi-hi-(sImeG.WinVer<0x35f ? 0:BOTOFF);
if (rcwin->top<0) rcwin->top=0; //对WIN95举办底部
if (rcwin->top>ii) rcwin->top=ii;//非凡保存处理惩罚
rcwin->right =rcwin->left+wi-1;
rcwin->bottom=rcwin->top+hi-1;
DrawMoveRect(rcwin->left,rcwin->top,
rcwin->right,rcwin->bottom,kk);//画新位置拖动框
}
第三步,在鼠标拖动窗口竣事时需要举办窗口的实际移动处理惩罚,这就需要在处理惩罚WM_LBUTTONUP动静时操作MOVEWINDOW()呼吁举办实际移动处理惩罚。同样鉴于多窗口原因仍然需要将这个处理惩罚进程单独形成一个函数,并且在移动窗口前还需要操作绘制函数排除屏幕上所画的拖动框,假如窗口未完全位于屏幕的可见位置,还必需举办适当调解使被拖动的窗口可以或许完全位于屏幕可视区内,同时释放鼠标节制权并排除拖动窗口符号单位。竣事进程的描写性代码部门如下:
case WM_LBUTTONUP:
if (sImeG.MoveFlag==TRUE){//拖动符号有效
DragEnd((LPRECT)&WinRT,WinWT,WinHI,hWnd);
}
拖动竣事处理惩罚函数的原形代码部门如下:
void DragEnd(
LPRECT rcwin, //拖动框矩形区域
unsigned int wi, //被拖动窗口宽度
unsigned int hi, //被拖动窗口高度
unsigned int kk) //拖动框边框宽度
{
DrawMoveRect(rcwin->left,rcwin->top,
rcwin->right,rcwin->bottom,1); //排除拖动框
if (rcwin->left<0) rcwin->left=0;//对窗口逾越屏幕
if (rcwin->left>sImeG.xScrWi-wi) //可视区域处理惩罚
rcwin->left=sImeG.xScrWi-wi;
ii=sImeG.yScrHi-hi-(sImeG.WinVer<0x35f ? 0:BOTOFF);
if (rcwin->top<0) rcwin->top=0; //对WIN95举办底部
if (rcwin->top>ii) rcwin->top=ii;//非凡保存处理惩罚
rcwin->right =rcwin->left+wi-1;
rcwin->bottom=rcwin->top+hi-1;
MoveWindow(hwnd,rcwin->left,rcwin->top,
wi,hi,TRUE); //将窗话柄际移到新位置
sImeG.MoveFlag=FALSE; //排除拖动符号单位
ReleaseCapture(); //释放鼠标节制权
}
四、WINDOWS高级窗口的客户区域拖动技能的实际应用
#p#分页标题#e#
上述先容的WINDOWS 高级窗口客户区域拖动技能的有关技能和拖动方案“三步曲”的实现进程,这些技能道理在WINDOWS95和WINDOWS3.X下同样适应,但由于动静是WINDOWS系统中的最后一道防地,假如处理惩罚得欠好就会使应用措施“误入歧途”,影响开拓效率和措施结果,若处理惩罚得恰到长处就会使你的应用措施具有很高的专业水准,如虎添翼。因此,实现适合本身应用措施的有效拖动方案,对开拓差异应用的影响和措施的运行效率具有深远的影响。固然实现WINDOWS 高级窗口应用措施拖动方案的要领不止一种,但笔者仍未见过越发简便高效的拖动方案,本文先容的实现方案较具有很好的适应性和优秀的运行结果,详细表示在:
开拓者可按照本身的实际需要节制窗口拖动框的巨细、拖动框颜色和拖动框的详细图案,具有拖动呼吁区域的鼠标光标动态提示成果,窗口拖动成果的启动、拖动进程和拖动竣事处理惩罚均是独立的子措施可提供应多窗口应用措施直接挪用,启动进程选择机动,在拖动竣事时可随时节制被拖动窗口全部显示在屏幕可见区域内,其它成果扩充轻便机动,措施的运行结果抱负等等。
本文给出的WINDOWS 高级窗口拖动方案描写性成果代码和通用子措施,均在笔者开拓的“轻松利用汉字输入法”措施中实际应用,是这个措施中实现窗口拖动成果的要害代码,均在WINDOWS95和WINDOWS3.X下试用结果很好,因此推荐读者开拓应用时将其作为首选方案。
在本文先容的基本上,相信读者对WINDOWS 高级窗口的客户区域拖动技能有了全面相识,同时为开拓具有客户区域拖动窗口的应用措施提供了可行的实现方案,但愿读者在此基本长举办深入研究,以开拓出越发抱负的WINDOWS 高级窗口客户区域拖动方案,体例出越发具有专业特色的WINDOWS高级应用措施。