智能ABC窗口的实现

2016-01-29 11:59 4 1 收藏

智能ABC窗口的实现,智能ABC窗口的实现

【 tulaoshi.com - C语言心得技巧 】

智能ABC窗口的实现

作者:王海军

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com)

下载源代码

  高级顶层窗口是一种无标题栏、菜单、工具条的一种常居顶层的窗口,最常见的例子就是输入法窗口,比如智能ABC窗口。这类窗口的特点除了上边所说的,最重要的就是窗口移动。普通窗口移动是通过标题栏由系统自动实现的,对于这类窗口就无法依靠系统了,需要手工实现。实现的方法有两种:手工处理WM_MOVE、WM_LBUTTONUP消息,并根据鼠标的移动自己实现窗口移动过程中的绘制;在WM_MOVE消息处理函数中通过向自己发送参数wParam为HTCAPTION lParam为鼠标位置的WM_NCLBUTTONDOWN消息实现窗口移动,此时窗口移动过程的绘制由系统实现。

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

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

实现了3D边框的绘制。

本文实现的基本原理:

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com)从CWnd直接派生一个窗口类CMainWnd,并添加一个共有函数bool CreateMainWnd()用来创建窗口;在相应WM_PAINT时,在客户区中根据四个标记变量绘制相应的四个位图;在WM_LBUTTONDOWN 消息处理中,检测鼠标是否落入某个“按钮”位图,设置相应标志,并强制系统重绘客户区;在WM_MOUSEMOVE消息处理中,检测鼠标是否落入有效移动区域,并设置相应光标。如果按下了左键,就开始发送WM_NCLBUTTONDOWN消息,实现窗口移动;为了关闭窗口,本程序设置了加速键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
                        

来源:https://www.tulaoshi.com/n/20160129/1484106.html

延伸阅读
标签: Web开发
摘要:SOAP 是一个基于XML的通信协议,在该协议下,软件组件和应用程序能够通过标准的HTTP协议通信。   内容:       SOAP 是一个基于XML的通信协议,在该协议下,软件组件和应用程序能够通过标准的HTTP协议通信。      谁起草了 SOAP?   SOAP 由UserLand, Ariba, Co...
看腻了中规中矩的窗口,怎么办? 这还不简单,换新的呗! 在Authorware中要想创建特殊的不规则窗口,看上去似乎很难。如果我说,半小时之后您也能做得到,这似乎不可思议。可是事实就是如此!不信,您不妨试一试。以下给出笔者在Win98、Authorware4.0中实现不规则窗口的具体过程,其中倒是需要用上Windows动态链接库文...
MFC功能已经非常强大,自己做界面库也许没什么意思,但是这个过程中却能学到很多东西。比如说: 窗口类的封装,从全局窗口消息处理到窗口对象消息处理的映射方法: 对界面进行封装,一般都是一个窗口一个类,比如实现一个最基本的窗口类CMyWnd,你一定会把窗口过程作为这个类的成员函数,但是使用WINAPI创建窗口时必须注册类WNDCL...
一、实现原理 图中两个窗口的实现类是从CControlBar派生出来的,我们并不需要从头到尾实现该类,因为Cristi Posea先生已经为我们实现了一个称为CSizingControlBar的类,而且做得相当完美!我们所要做的便是好好地利用该类,为了尽可能地简洁,笔者将CSizingControlBar类修改了一下并命名为CCoolBar,接下来我们将详细介绍如何利用该类实现我们所...
微信实现多窗口切换的方法   很多微信用户都有这样一个使用困扰,那就是在看微信订阅号里的消息的时候,如果有微信消息尽量,就不得不关闭微信订阅号,才看得了微信消息。那么,有没有什么办法可以让微信变成多窗口呢?今天,图老师小编就给大家分享一下微信多窗口的使用技巧! 微信 更多教程,欢迎关注微信使用技巧全攻略...

经验教程

66

收藏

40
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部