首 页 ┆ 源码下载 ┆ IT学院 ┆ 字体下载 ┆ 模板下载 ┆ 源码发布 ┆ 广告合作 ┆ 网站地图
► 设为首页
► 加入收藏
► 联系我们
源码下载 >> ASP源码 | PHP源码 | ASP.net源码 | JSP源码 | CGI源码 | VC/C++源码 | VB源码 | Delphi源码 | Flash源码
文章学院 >> 网络编程 | 网页设计 | 图形图象 | 数据库 | 服务器 | 网络媒体 | 网络安全 | 操作系统 | 办公软件 | 软件开发 | 黑客知识
字体下载 >> 精制字体 | 非英字体 | 艺术字体 | 著名字体 | 哥特式 | 简单字体 | 手写体 | 节假日 | 图案字体 | 精度像素 | 中文字体
模板下载 >> 企业门户 | 数码网络 | 休闲娱乐 | 影视音乐 | 旅游名胜 | 文化艺术 | 电子商务 | 个性展示 | 登陆导航 | Flash模板
►►您当前的位置:源码园 → IT学院 → 软件开发 → VC编程 → 文章内容

智能ABC窗口的实现

作者:王海军  来源:网上收集  发布时间:2007-3-27 10:17:24

智能ABC窗口的实现

作者:王海军

下载源代码

  高级顶层窗口是一种无标题栏、菜单、工具条的一种常居顶层的窗口,最常见的例子就是输入法窗口,比如智能ABC窗口。这类窗口的特点除了上边所说的,最重要的就是窗口移动。普通窗口移动是通过标题栏由系统自动实现的,对于这类窗口就无法依靠系统了,需要手工实现。实现的方法有两种:

  1. 手工处理WM_MOVE、WM_LBUTTONUP消息,并根据鼠标的移动自己实现窗口移动过程中的绘制;
  2. 在WM_MOVE消息处理函数中通过向自己发送参数wParam为HTCAPTION lParam为鼠标位置的WM_NCLBUTTONDOWN消息实现窗口移动,此时窗口移动过程的绘制由系统实现。

显然,后者较前者简单。本文采用后者。
  为了实现移动,还要对窗口定义有效移动区域,就是当鼠标移动到窗口中哪部分时鼠标变为十字箭头,暗示现在可以按下左键开始拖动。本文实现的窗口中有四个紧密排列的位图“按钮”,它们之间没有空隙,所以我定义位图以外窗口以内为有效移动区域。鼠标进入这片区域时将变为十字箭头形状,提示用户现在可以进行拖动。
  在定义窗口类时,如果窗口有边框,那么当鼠标在边框上时,接收到的是WM_NCMOUSEMOVE消息,所以为了在WM_MOUSEMOVE消息处理函数中统一处理,本文窗口没有使用边框,只要鼠标进入窗口,就开始接收到WM_MOUSEMOVE消息了。但这又引入另一个问题:如何绘制3D边框?本文使用了函数:

void Draw3dRect( LPCRECT lpRect, COLORREF clrTopLeft, COLORREF clrBottomRight)

实现了3D边框的绘制。

本文实现的基本原理:

  1. 从CWnd直接派生一个窗口类CMainWnd,并添加一个共有函数bool CreateMainWnd()用来创建窗口;
  2. 在相应WM_PAINT时,在客户区中根据四个标记变量绘制相应的四个位图;
  3. 在WM_LBUTTONDOWN 消息处理中,检测鼠标是否落入某个“按钮”位图,设置相应标志,并强制系统重绘客户区;
  4. 在WM_MOUSEMOVE消息处理中,检测鼠标是否落入有效移动区域,并设置相应光标。如果按下了左键,就开始发送WM_NCLBUTTONDOWN消息,实现窗口移动;
  5. 为了关闭窗口,本程序设置了加速键F12,按F12可关闭程序;
代码如下:

1、创建窗口:
  bool CMainWnd::CreateMainWnd(void)  {     if(!CreateEx(0,                    ::AfxRegisterWndClass(0,                      ::LoadCursor(NULL,MAKEINTRESOURCE(IDC_ARROW)),                      GetSysColorBrush(COLOR_ACTIVEBORDER)                      ),           NULL,           WS_POPUP,           0,0,300,50,           NULL,           NULL))      return false;    return true;  }
2、窗口绘制:根据四个位图“按钮”标志变量绘制相应的位图。
  void CMainWnd::OnPaint()  {    CPaintDC dc(this); // device context for painting    // TODO: 在此处添加消息处理程序代码    // 不为绘图消息调用 CWnd::OnPaint()    CBitmap* pOldBmp;    CDC CompatibleDC;    CompatibleDC.CreateCompatibleDC(&dc);    //绘制第一个按钮    if(m_bBTState[0])    pOldBmp=CompatibleDC.SelectObject(&m_BT1_1);    else    pOldBmp=CompatibleDC.SelectObject(&m_BT1_2);    dc.BitBlt(m_rcBT1.left,m_rcBT1.top,m_rcBT1.Width(),m_rcBT1.Height(),&CompatibleDC,0,0,SRCCOPY);    //绘制第二个按钮    if(m_bBTState[1])    CompatibleDC.SelectObject(&m_BT2_1);    else    CompatibleDC.SelectObject(&m_BT2_2);    dc.BitBlt(m_rcBT2.left,m_rcBT2.top,m_rcBT2.Width(),m_rcBT2.Height(),&CompatibleDC,0,0,SRCCOPY);    //绘制第三个按钮    if(m_bBTState[2])    CompatibleDC.SelectObject(&m_BT3_1);    else    CompatibleDC.SelectObject(&m_BT3_2);    dc.BitBlt(m_rcBT3.left,m_rcBT3.top,m_rcBT3.Width(),m_rcBT3.Height(),&CompatibleDC,0,0,SRCCOPY);    //绘制第四个按钮    if(m_bBTState[3])    CompatibleDC.SelectObject(&m_BT4_1);    else    CompatibleDC.SelectObject(&m_BT4_2);    dc.BitBlt(m_rcBT4.left,m_rcBT4.top,m_rcBT4.Width(),m_rcBT4.Height(),&CompatibleDC,0,0,SRCCOPY);    //绘制第五个按钮    if(m_bBTState[4])    CompatibleDC.SelectObject(&m_BT5_1);    else    CompatibleDC.SelectObject(&m_BT5_2);    dc.BitBlt(m_rcBT5.left,m_rcBT5.top,m_rcBT5.Width(),m_rcBT5.Height(),&CompatibleDC,0,0,SRCCOPY);    //绘制边框    CRect rcClient;    GetClientRect(&rcClient);    dc.Draw3dRect(&rcClient,RGB(192,192,192),RGB(0,0,0));    rcClient.DeflateRect(1,1,1,1);    dc.Draw3dRect(&rcClient,RGB(255,255,255),RGB(144,144,144));    CompatibleDC.SelectObject(pOldBmp);  }
3、WM_MOUSEMOVE 消息处理函数
    void CMainWnd::OnMouseMove(UINT nFlags, CPoint point)  {    // TODO: 在此添加消息处理程序代码和/或调用默认值    bool bInRegionNow=IsInRegion(point);    TRACE("Mouse move:(%d,%d) InRegion=%d\n",point.x,point.y,bInRegionNow);    if(bInRegionNow)    {      SetCursor(m_hCrossCursor);//设置十字形光标      if(nFlags&MK_LBUTTON)      {      POINT pt;      pt.x=point.x;pt.y=point.y;      ClientToScreen(&pt);    //发送移动消息      SendMessage(WM_NCLBUTTONDOWN,HTCAPTION,(LPARAM)(pt.x|(pt.y>>16)));      }     }     CWnd::OnMouseMove(nFlags, point);  }

程序运行效果

  效果如下: 你可以用鼠标拖动它到任意位置。
 
结束语
  本文只是实现了和智能ABC类似的窗口,但我在用spy++查找智能ABC窗口时发现并不能找到它,不知为什么,难道它根本就不是一个真正的窗口?那它又是怎么实现的呢?有谁知道的能否告诉我,谢谢!
 

[] [返回上一页] [打 印]
  • 上一篇文章:软件换肤技术在 BCB 中的实现
  • 下一篇文章:类似于FlashGet的悬浮框的制作

  • 相关文章:
  • 向CCmdTarget的派生类添加一个接口的实现
  • [图文]智能ABC窗口的实现
  • 动画窗口的实现-VC++实例一则
  • Delphi中正常窗口的实现
关于本站 - 网站帮助 - 广告合作 - 下载声明 - 友情连接 - 网站地图 - 源码发布
Copyright © 2003-2009 Ymyasp.Com. All Rights Reserved .
备案序号:粤ICP备07029071号