无标题栏窗口拖动的实现

来源:互联网 发布:java对象是什么意思 编辑:程序博客网 时间:2024/05/22 13:33

普通的Windows应用程序窗口都具有统一的窗口风格,它们一般都包括:用户区和非用户区两部分。非用户区包括标题条、窗口边框、最大化按钮、最小化按钮、关闭按钮和系统默认的快捷键及鼠标支持等。利用鼠标的左键通过拖动窗口的标题条可以在屏幕上任意移动整个窗口,当光标停止在窗口边框上时可以改变窗口的大小。在一些比较经典的软件中,有一类特殊的无标题条的窗口。这种窗口不需要改变窗口的大小,但必须具有窗口客户区域的拖动功能,典型的例子有   Windows中的IME输入法应用程序、中文之星以及一些第三方开发的输入法平台等。由于普通窗口的拖动功能是由系统来完成的,编制一般的应用程序时根本无须考虑客户区域拖动问题,但对于无标题条的Windows应用程序,拖动功能就要靠开发者自己来实现了。

 实现   思路       
        既然Windows已经实现了不错的窗口拖动功能,我们可以通过利用系统这种默认的实现来完成无标题条的窗口的拖动。仔细分析一下,不难发现,无标题条窗口的客户区大都只是作为控件的载体(最常见到的是按钮控件),当鼠标位于其窗口中时(鼠标变为十字箭头)可以拖动整个窗口,而且窗口的大小不可改变,这很像一般窗口标题条的功能,因此只要将无标题条窗口模拟成标题条,使系统将其“误认为”是窗口的标题条,就可以利用系统的默认实现来完成无标题条窗口的拖动了。      
  那么如何使系统将无标题条窗口的客户区“误认为”是窗口的标题条呢?重载函数:      
  UINT   CWnd::OnNcHitTest(CPoint   point)      
     
  每当鼠标在窗口中移动,那么MFC的应用程序框架会发送消息WM_NCHITTEST,由该函数来完成对消息处理。其中参数point鼠标当前所在位置坐标,函数的返回值为:       
 只要重载无标题窗口的OnNcHitTest函数,使其返回值总为HTCAPTION,就使系统将无标题条窗口的客户区“误认为”是窗口的标题条。       
 程序   实现      
  用VC++5.0的MFC   AppWizad(exe)   生成一个对话框应用框架,然后完成下面的修改:      
  1、在对话框资源的属性中,不选Title   Bar。      
  2、在DragDlg.h   文件中添加:    
  //   Generated   message   map   functions    
  //{{AFX_MSG(CDragDlg)    
  ...    
  afx_msg   UINT   OnNcHitTest(CPoint   point);    
  //}}AFX_MSG    
  DECLARE_MESSAGE_MAP()      
  3、在DragDlg.cpp文件中添加:    
  BEGIN_MESSAGE_MAP(CDragDlg,   CDialog)    
  //{{AFX_MSG_MAP(CDragDlg)    
  //   No   message   handlers    
  ...    
  ON_WM_NCHITTEST()    
  //}}AFX_MSG_MAP    
  END_MESSAGE_MAP()    
     
  UINT   CDragDlg::OnNcHitTest(CPoint   point)    
  {    
  CWnd::OnNcHitTest(point);    
  return   HTCAPTION;    
  }    
     
  进一步完善这个程序,可以加入对鼠标的处理,当鼠标位于窗口中时,自动变为十字箭头,提示用户现在可以拖动窗口。注意,由于此时窗口被系统“误认为”是标题条(非用户区),   相应的鼠标移动和鼠标左键按下消息应为   WM_NCMOUSEMOVE和WM_NCLBUTTONDOW(通过VC++的工具spy++可以观察到),具体的实现这里就不详述。 

附:(我在C++ Builder下实现的代码)

.H文件:

//---------------------------------------------------------------------------

#ifndef MonitorWindowH
#define MonitorWindowH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ComCtrls.hpp>
#include <ExtCtrls.hpp>
#include <Graphics.hpp>
#include <winuser.h>
#include <Buttons.hpp>
#define   WS_EX_LAYERED                       0x00080000
#define   LWA_ALPHA                               0x00000002
//---------------------------------------------------------------------------
class TMonitorForm : public TForm
{
__published: // IDE-managed Components
    TPanel *Panel1;
    TStatusBar *StatusBar1;
    TListView *ListView;
    TImage *Image1;
    TBitBtn *BitBtnCancel;
    TBitBtn *BitBtnCance;
    void __fastcall Image1MouseDown(TObject *Sender, TMouseButton Button,
          TShiftState Shift, int X, int Y);
    void __fastcall BitBtnCanceClick(TObject *Sender);
    void __fastcall BitBtnCancelClick(TObject *Sender);
private: // User declarations
public:  // User declarations
    __fastcall TMonitorForm(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TMonitorForm *MonitorForm;
//---------------------------------------------------------------------------
#endif

.CPP文件:

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "MonitorWindow.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TMonitorForm *MonitorForm;
//---------------------------------------------------------------------------
__fastcall TMonitorForm::TMonitorForm(TComponent* Owner)
    : TForm(Owner)
{
    SetWindowLong(Handle,GWL_EXSTYLE,GetWindowLong(Handle,GWL_EXSTYLE)^WS_EX_LAYERED);
    SetLayeredWindowAttributes(Handle,RGB(0,0,0),180,LWA_ALPHA);
}
//---------------------------------------------------------------------------
void __fastcall TMonitorForm::Image1MouseDown(TObject *Sender,
      TMouseButton Button, TShiftState Shift, int X, int Y)
{
    ReleaseCapture();
    //SendMessage(this->Handle,WM_SYSCOMMAND,SC_MOVE+HTCAPTION,0);
    SendMessage(Handle,WM_NCLBUTTONDOWN,HTCAPTION,0);   
}
//---------------------------------------------------------------------------
void __fastcall TMonitorForm::BitBtnCanceClick(TObject *Sender)
{
    Close();
}
//---------------------------------------------------------------------------

void __fastcall TMonitorForm::BitBtnCancelClick(TObject *Sender)
{
    Close();   
}
//---------------------------------------------------------------------------

 

 

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 手机卡坏了收不到快递短信怎么办 pph手术后钛钉没有脱落怎么办 右侧附件囊状透明声可怎么办 刚刚出生小孩睾丸没有掉下来怎么办 汽车被依非法营运之由扣押怎么办 老婆结婚小孩两个又上夜场该怎么办 对于不断无理要求赔偿的房东怎么办 欠的钱越来越多不知道怎么办了 手机壳的开机按键不好按怎么办 对方把保权的房子卖给我怎么办 内存卡在手机上显示损坏怎么办 内存卡显示但是下载不了东西怎么办 相机sd卡没办法读卡怎么办 尼康相机新sd卡显示满了怎么办 修冰箱没几个月又坏了怎么办 星露谷物语活动中心成了仓库怎么办 你家如果油锅起火时应该怎么办 当你遇到电器起火时应该怎么办 酷派大神f2充不进去电怎么办 借车子别人开违章一年了怎么办 快递刚发货我点错了收货怎么办 快递收货地址错了已经发货了怎么办 老公在外地工地上夜班吃不好怎么办 工人在工地干活被吊车撞了怎么办 小米手机记不得保密柜密码怎么办 华为手机文件保密柜密码忘了怎么办 超市寄存柜密码纸丢了怎么办 佳明软件安装不到手机上怎么办 最好的朋友的抢了自己的活怎么办 支付宝被实名验证上限了怎么办 装修预留插座被挡了一半怎么办 衣服放在柜子里面有味道怎么办 河北发货一个柜到天津港口怎么办 家用潜水泵更换电容后压力小怎么办 无塔供水井水水位低了怎么办 应急部成立林场的专业灭火队怎么办 路由器我恢复出厂设置断网了怎么办 多囊卵巢综合症不来月经怎么办 天刀普通血战苍梧城没有太白怎么办 天涯明月刀把沈妄言打入水中怎么办 天涯明月刀刷本队友技能太花怎么办