中易网

怎么用BCB做磁性窗体

答案:1  悬赏:50  
解决时间 2021-03-25 21:43
怎么用BCB做磁性窗体
最佳答案
利用BCB编写具有"磁性"特征的窗口
马明臣
一些著名的共享软件不但功能卓著,而且在程序界面的设计技巧上往往领导了一种时尚,WinAmp就是其中的一个代表。WinAmp有两个绝活,一是可以更换窗体的外观,也就是现在俗称的给软件换“皮肤”;另一个是及时磁性窗体技巧。
那么什么是磁性窗体呢?用过Winamp的用户都知道,Winamp的播放列表或均衡器在被移动的时候,仿佛会受到一股磁力,每当靠近主窗口时就一下子被“吸附”过去,自动沿边对齐。这就是磁性窗体,那么我们如何在自己的程序中实现这种奇妙的特性呢?经过笔者摸索琢磨出了实现这种“磁化”窗口的方法。该法适用于C++ builder的各个版本。下面笔者给大家介绍一下该技术。
实现粘贴的难点在于什么时候进行这个操作,假设有两个窗体Form1和Form2,移动Form2向Form1靠近,当Form2与Form1的最近距离小于一个给定值时粘贴在一起。显然,应该在移动Form2的过程中进行判断,问题是在程序的什么位置插入判断代码呢?
合理的方法是利用系统产生的消息,我们知道窗体在移动时会产生WM_WINDOWPOSCHANGING和WM_MOVING消息,移动结束后会产生WM_WINDOWPOSCHANGED和WM_MOVE消息。我们这里使用WM_WINDOWPOSCHANGING消息来实现这一功能。
下面笔者就把实现磁性窗体的方法介绍如下:
先新建一应用程序项目,把主窗口Form1适当放小些,放一个按钮组件,修改该按钮组件的Caption属性为“创建磁性窗口”双击它并在OnClick事件中写入如下代码:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Form2= new TForm2(Application);
Form2->Show();//显示磁性窗口
}
选择“File”—>“New Form”创建一个新窗口Form2,在Form2上加入一个Edit组件Edit1和一个按钮组件Button1,修改Edit的TEXT属性为50(该值为当Form2靠近Form1时距离为50像素时进行吸附,一般设为20左右即可,这里为了效果明显所以设为50像素),修改按钮的Caption属性为“磁距”,接着在这个新窗口的unit2.h文件中的private:下面加入如下变量定义:
HWND snapwin;//定义Form2吸附到哪一个窗口的句柄
RECT work_area;
bool snapped;//是否吸附标志
bool winprocthing;
int thresh;//距离多远开始吸附
void __fastcall SettingChanged(TMessage &msg);//改变窗口大小时产生
void __fastcall WMWindowPosChanging(TWMWindowPosChanging &msg);//移动窗口时产生
void __fastcall UpdateWorkArea();刷新窗口
接着在public:// User declarations下加入如下消息:
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_WINDOWPOSCHANGING,TWMWindowPosChanging,WMWindowPosChanging);//定义消息当窗口移动时调用WMWindowPosChanging
MESSAGE_HANDLER(WM_SETTINGCHANGE,TMessage,SettingChanged);
END_MESSAGE_MAP(TForm); //当窗口改变大小时调用SettingChanged
在Form2的单元文件unit.cpp中加入如下代码:
void __fastcall TForm2::SettingChanged(TMessage &msg)
{
UpdateWorkArea();
}
//---------------------------------------------------------------------------
void __fastcall TForm2::WMWindowPosChanging(TWMWindowPosChanging &msg)
{
RECT sr;
snapped=false;//设为不吸附
//test window
snapwin = Form1->Handle;//定义Form2吸附到Form1上这里如改为别的软件的窗口句柄还可以吸附到别的软件窗口上
if (snapwin && IsWindowVisible(snapwin))

{
if (GetWindowRect(snapwin,&sr))//得到Form1的位置
{
if ( (msg.WindowPos->x <= (sr.right+thresh)) &&
(msg.WindowPos->x >= (sr.right-thresh)) ) {
if ((msg.WindowPos->y > sr.top) && (msg.WindowPos->y < sr.bottom)) {
snapped=true;
msg.WindowPos->x = sr.right;
}
}
else if ((msg.WindowPos->x + msg.WindowPos->cx) >= (sr.left-thresh) &&
(msg.WindowPos->x + msg.WindowPos->cx) <= (sr.left+thresh)) {
if ((msg.WindowPos->y > sr.top) && (msg.WindowPos->y < sr.bottom)) {
snapped=true;
msg.WindowPos->x = sr.left-msg.WindowPos->cx;
}
}
if ( (msg.WindowPos->y <= (sr.bottom+thresh)) &&
(msg.WindowPos->y >= (sr.bottom-thresh)) ) {
if ((msg.WindowPos->x > sr.left) && (msg.WindowPos->x < sr.right)) {
snapped=true;
msg.WindowPos->y = sr.bottom;
}
}
else if ((msg.WindowPos->y + msg.WindowPos->cy) <= (sr.top+thresh) &&
(msg.WindowPos->y + msg.WindowPos->cy) >= (sr.top-thresh)) {
if ((msg.WindowPos->x > sr.left) && (msg.WindowPos->x < sr.right)) {
snapped=true;
msg.WindowPos->y = sr.top-msg.WindowPos->cy;
}
}
}
}
//测试屏幕
sr = work_area;
if (abs(msg.WindowPos->x) <= (sr.left+thresh)) {
snapped=true;
msg.WindowPos->x = sr.left;
}
else if ((msg.WindowPos->x + msg.WindowPos->cx) >= (sr.right-thresh) &&
(msg.WindowPos->x + msg.WindowPos->cx) <= (sr.right+thresh)) {
snapped=true;
msg.WindowPos->x = sr.right-msg.WindowPos->cx;
}
if (abs(msg.WindowPos->y) <= (sr.top+thresh)) {
snapped=true;
msg.WindowPos->y = sr.top;
}
else if ((msg.WindowPos->y+msg.WindowPos->cy) >= (sr.bottom-thresh) &&
(msg.WindowPos->y+msg.WindowPos->cy) <= (sr.bottom+thresh)) {
snapped=true;
msg.WindowPos->y = sr.bottom-msg.WindowPos->cy;
}
}
//---------------------------------------------------------------------------
void __fastcall TForm2::UpdateWorkArea()
{
SystemParametersInfo(SPI_GETWORKAREA, 0, &work_area, 0);
}
双击“磁距”按钮加入如下代码:
void __fastcall TForm2::Button1Click(TObject *Sender)
{
thresh = StrToInt(Edit1->Text);//设定磁性窗口距Form1为edit1中的数值时开始吸附
}
在窗体Form2的OnCreate事件中加入如下代码:
void __fastcall TForm2::FormCreate(TObject *Sender)
{
snapped=false;//设置为不吸附
UpdateWorkArea();
thresh = StrToInt(Edit1->Text);
snapwin = Form1->Handle;
}
该程序在c++ builder 5.0、windows98系统下调试通过。
我要举报
如以上问答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
元氏县流动人口婚育证明到哪里办
叶嘉茶林地址有知道的么?有点事想过去
苏州十级伤残的一次性伤残补助金怎么算
去邮政速递公司上班好还是去其他快递公司好,
指甲裂开会长好吗
聊城开发区到江苏南京理工大学有高铁吗路程多
好歌歌厅地址在什么地方,我要处理点事
求帮忙取个英文名 倪钰荐 好听好记就行
用取暖器对身体有害吗
服用复方阿胶浆可以吃野菜蒲公英曲曲芽吗
网上销售商品要在工商局注册吗
想问一个关于类似与兰蔻欧莱雅这样名牌化妆品
宝宝缺钾怎么补 该吃些什么
长白山什么湖泊在世界火山湖中是著名的
有丽水到缙云出租车拼车的电话吗?
推荐资讯
镇巴县到武隆要经哪些地方
买房子需要缴纳公共维修基金吗?
最近经常牙疼 太阳穴也疼 连着大脑左边都很疼
地暖的专用木地板多少钱
湖南省郴州安仁在修铁路了吗?
安利雅姿舒焕柔肤乳霜和水动能保湿精华霜晚上
酒后的小腹坠肉改如何减肥?
查染色体怎么查,能查到什么
我开一个补品类店,需要办什么手续啊?
想学美容,请问东莞厚街哪里美容店有收学徒?
江门天力网球场最新的收费?
青春期 什么时候结束?
手机登qq时,显示手机磁盘不足,清理后重新登
刺客的套装怎么选啊?