作者:chache
email: cyzhx@263.net
日期:2000-10-23 17:33:49
三、WINDOWS高级窗口客户区域拖动技术实现的“三步曲”
WINDOWS 高级窗口的客户区域拖动命令判断、拖动功能的鼠标光标动态提示和定制窗口
拖动框函数之后,就需要实现整个拖动方案中的拖动过程启动、窗口拖动框移动和拖动结束
处理的三步曲过程。于是必须在窗口函数中直接处理WM_LBUTTONDOWN、WM_MOUSEMOVE和WM_L
BUTTONUP消息,来具体处理上述三个步骤中的细节问题。
第一步,在窗口函数中对鼠标点击消息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 为拖动框宽度。同时需要将鼠标控制权交给当前被拖动窗口、设置拖动窗口标志
单元、保存当前鼠标在屏幕上的位置并显示被拖动窗口的拖动框。拖动功能启动函数的原形
代码如下:
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_MOU
SEMOVE消息处理。拖动框的移动包括上次显示拖动框的清除和本次拖动框的显示两步,由于
拖动框绘制函数中对当前的绘制方式进行重新设置,异或方式使得只要重新在原屏幕坐标位
置处调用一次该函数即可清除拖动框,因此,在鼠标拖动窗口移动过程中显示和清除拖动框
只需要调用两次拖动框绘制函数即可。另外,拖动框在屏幕上位置的计算方法也非常简单,
就是将当前取得的屏幕位置坐标值减去保存的前次屏幕位置坐标值所得鼠标移动偏移量,再
用原来窗口屏幕左上角坐标值加上这个偏移量,就可以确定被拖动窗口和拖动框新的屏幕位
置坐标值。其处理过程的描述性代码如下:
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->leftleft=0;//对窗口超越屏幕
if (rcwin->left>sImeG.xScrWi-wi) //可视区域处理
rcwin->left=sImeG.xScrWi-wi;
ii=sImeG.yScrHi-hi-(sImeG.WinVer
if (rcwin->toptop=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_LBU
TTONUP消息时利用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->leftleft=0;//对窗口超越屏幕
if (rcwin->left>sImeG.xScrWi-wi) //可视区域处理
rcwin->left=sImeG.xScrWi-wi;
ii=sImeG.yScrHi-hi-(sImeG.WinVer
if (rcwin->toptop=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高级窗口的客户区域拖动技术的实际应用
上述介绍的WINDOWS 高级窗口客户区域拖动技术的有关技术和拖动方案“三步曲”的实
现过程,这些技术原理在WINDOWS95和WINDOWS3.X下同样适应,但由于消息是WINDOWS系统中
的最后一道防线,如果处理得不好就会使应用程序“误入歧途”,影响开发效率和程序效果
,若处理得恰到好处就会使你的应用程序具有很高的专业水准,如虎添翼。因此,实现适合
自己应用程序的有效拖动方案,对开发不同应用的影响和程序的运行效率具有深远的影响。
虽然实现WINDOWS 高级窗口应用程序拖动方案的方法不止一种,但笔者仍未见过更加简捷高
效的拖动方案,本文介绍的实现方案较具有很好的适应性和优秀的运行效果,具体表现在:
开发者可根据自己的实际需要控制窗口拖动框的大小、拖动框颜色和拖动框的具体图案
,具有拖动命令区域的鼠标光标动态提示功能,窗口拖动功能的启动、拖动过程和拖动结束
处理均是独立的子程序可提供给多窗口应用程序直接调用,启动过程选择灵活,在拖动结束
时可随时控制被拖动窗口全部显示在屏幕可见区域内,其它功能扩充简便灵活,程序的运行
效果理想等等。
本文给出的WINDOWS 高级窗口拖动方案描述性功能代码和通用子程序,均在笔者开发的
“轻松使用汉字输入法”程序中实际应用,是这个程序中实现窗口拖动功能的关键代码,均
在WINDOWS95和WINDOWS3.X下试用效果很好,因此推荐读者开发应用时将其作为首选方案。
在本文介绍的基础上,相信读者对WINDOWS 高级窗口的客户区域拖动技术有了全面了解
,同时为开发具有客户区域拖动窗口的应用程序提供了可行的实现方案,希望读者在此基础
上进行深入研究,以开发出更加理想的WINDOWS 高级窗口客户区域拖动方案,编制出更加具
有专业特色的WINDOWS高级应用程序。