• 扩 展Visual c++ MFC 类 库


    ---- Visual c++ 提 供 了 功 能 强 大 的 类 库, 基 本 上 应 用 开 发 的 要 求, 但 对 于 某 些 特 殊 要 求 的 界 面, 如 图 像 兼 文 字 的 按 纽, 列 表 框 中 插 入 图 像, 中 国 式 报 表 等 等, 仍 显 得 力 不 从 心, 因 而 很 有 必 要 创 建 扩 展MFC 类 库, 以 满 足 实 际 开 发 的 需 求。

    ---- MFC 支 持 自 绘 制(owner-draw) 概 念, 自 绘 制 的 控 制 类, 通 过 调 用DrawItem() 函 数 实 现 控 件 的 绘 制, 由 于 控 件 绘 制, 消 息 检 测 和 消 息 比 较 代 码 是 在 控 件 中 实 现 而 不 足 在 拥 有 控 件 的 窗 口 中 实 现, 因 而 叫 自 绘 制。 因 而 通 过 重 载DrawItem(LPDRAWITEMSTRUCT 函 数 来 控 制 控 件 的 外 观 和 行 为, 实 现 控 制 所 需 要 的 参 数, 都 包 含 在LPDRAWITEMSTRUCT 结 构 中。

    ---- LPDRAWITEMSTRUCT 结 构:

    typedef struct tagDRAWITEMSTRUCT                
    {                    
     UINT   CtlType;                      
    UINT   CtlID;                   
      UINT   itemID;                   
      UINT   itemAction;                    
     UINT   itemState;                     
    HWND   hwndItem;                    
      HDC    hDC;                    
     RECT   rcItem;                   
      DWORD  itemData;            
      } DRAWITEMSTRUCT;

    ---- 最 重 要 的 参 数 是itemAction,itemState,hDC,rcItem, 它 们 是 实 现 控 件 外 观 绘 制, 消 息 响 应 所 必 须 的。

    ---- itemAction: 绘 制 动 作, 有 以 下 几 种 取 值:ODA_DRAWENTIRE,ODA_FOCUS, ODA_SELECT.

    ---- itemState: 状 态, 有 以 下 几 种 取 值:ODS_CHECKED,ODS_DISABLED,ODS_FOCUS, ODS_GRAYED,ODS_SELECTED,ODS_DEFAULT.

    ---- hDC: 设 备 环 境 的 句 柄。

    ---- rcItem: 控 件 外 观 大 小 的 矩 形。

    ---- 下 面 给 出 一 个 基 于CButton 类 的 图 象Button 类:CMybtn

    ---- 利 用MFC Wizard 创 建 一 个 新 类CMybtn, 基 类 是CButton

     mybtn.h:     
            class CMybtn : public CButton
               {
                // Construction
            ...
    public:
      virtual void DrawItem
                (LPDRAWITEMSTRUCT lpDrawItemStruct);
    ...
            ...
           public:
    void setbitmapid(UINT id);
    ...
           protected:
    UINT m_bitmapid;
           //图象的按纽id值
    ...
         DECLARE_MESSAGE_MAP()
         };

       mybtn.cpp
        CMybtn::CMybtn()
        {
         m_bitmapid=0;
         //在构造函数中初始化m_bitmaoid  
        }      

      void CMybtn::DrawItem(LPDRAWITEMSTRUCT lpdis)
         {

    HBITMAP hbitmap=NULL;
    ASSERT(lpdis!=NULL);
    CDC *pdc=CDC::FromHandle(lpdis- >hDC);
         //lpdis- >hdc是设备环境的句柄,
           fromhandle函数将handle- >指针
    CRect r1;
    r1.CopyRect(&lpdis- >rcItem);
    //得到控件的矩形范围
        UINT state=lpdis- >itemState;
    //得到控件的状态
    if((state & ODS_SELECTED))
    pdc- >Draw3dRect(r1,GetSysColor
                   (COLOR_3DDKSHADOW),
                   GetSysColor(COLOR_3DHILIGHT));
          //selected时,用COLOR_3DDKSHADOW画左上部,
            COLOR_HILIGHT画右下部,表现为凹陷   
    else
       pdc- >Draw3dRect(r1,GetSysColor(COLOR_3DHILIGHT),
                 GetSysColor(COLOR_3DDKSHADOW));
    //正常时,用COLOR_3DHILIGHT画左上部,
              COLOR_3DDKSHADOW画右下部,表现为突起
    // TODO: Add your code to draw the specified item

    if(m_bitmapid)
      hbitmap=(HBITMAP)LoadImage(AfxGetInstanceHandle(),
          MAKEINTRESOURCE(m_bitmapid),IMAGE_BITMAP,0,0,
                           LR_DEFAULTCOLOR);
        //如有图象,则装载图象,
    CString s1;
    GetWindowText(s1);
    //得到BUTTON的CAPTION
        if(!s1.IsEmpty())
    {
    int mode1=pdc->SetBkMode(TRANSPARENT);
         if(!hbitmap)
        pdc- >DrawText(s1,r1,
                DT_CENTER|DT_VCENTER|DT_SINGLELINE);
            //如没有图象,则在整个BUTTON范围输出文字
    else
    {
    CRect r2=r1;
    r2.DeflateRect(2,2);
    CDC memdc;
    CBitmap bmp;
    CBitmap *oldbitmap;
    bmp.Attach(hbitmap);
    BITMAP  bitmap;
    bmp.GetBitmap(&bitmap);
    //由BITMAP结构可以得出图象的高,宽
    memdc.CreateCompatibleDC(pdc);
    oldbitmap=memdc.SelectObject(&bmp);
    pdc- >StretchBlt(r2.left,r2.top,r2.Width()/2,
                   r2.Height(),&memdc,0,0,bitmap.bmWidth,
                   bitmap.bmHeight,SRCCOPY);
         //把图象从内存压缩拷贝到BUTTON范围
    memdc.SelectObject(oldbitmap);
    bmp.Detach();
             CRect r3=r2;
             r3.left=r2.left+r2.Width()/2;
             pdc- >DrawText(s1,r3,
                   DT_CENTER|DT_VCENTER|DT_SINGLELINE);
    }
    }
          }

       void CMybtn::setbitmapid(UINT id)
       {
          m_bitmapid=id;
       }

      ---- 利用CMybtn类代码可以在应用系统中实现图象文字按纽,在dialog中加入按纽 (IDC_BUTTON1),(IDC_BUTTON2)设置它们的属性为 owner-draw.
    利用resource editor 加入两个图象文件,id值为:IDB_BITMAP1,IDB_BITMAP2。 
    class CWs3Dlg : public CDialog
       {
         ...
       public:

       // Dialog Data
       //{{AFX_DATA(CWs3Dlg)
    enum { IDD = IDD_WS3_DIALOG };
    CMybtnm_btn1;
    CMybtnm_btn2;
    //定义图象按纽
         //}}AFX_DATA
    ...
    protected:
    virtual void DoDataExchange(CDataExchange* pDX);
         // DDX/DDV support
    //}}AFX_VIRTUAL

           ....
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()
      };
     
      void CWs3Dlg::DoDataExchange(CDataExchange* pDX)
       {
    CDialog::DoDataExchange(pDX);
    //{{AFX_DATA_MAP(CWs3Dlg)
    DDX_Control(pDX, IDC_BUTTON2, m_btn2);
    DDX_Control(pDX, IDC_BUTTON1, m_btn1);
    //}}AFX_DATA_MAP
    }

      在初始化代码加入:
       BOOL CWs3Dlg::OnInitDialog()
      {
    ...
      // TODO: Add extra initialization here
       m_btn1.setbitmapid(IDB_BITMAP1);
       m_btn2.setbitmapid(IDB_BITMAP2);
       return TRUE;  // return TRUE  unless
                        you set the focus to a control
    }

    ---- 本 文 给 出 了 自 绘 制 类 的 实 现 代 码, 读 者 可 以 利 用 此 思 路 开 发 出 其 他 扩 展 类 库, 丰 富 开 发 资 源。

  • 相关阅读:
    创建基于MailKit和MimeKit的.NET基础邮件服务
    MailKit---获取邮件
    C# 与JAVA 的RSA 加密解密交互,互通,C#使用BouncyCastle来实现私钥加密,公钥解密的方法
    .net 开源 FTP 组件 edtFTPnet
    Consul1-window安装consul
    通信传输利器Netty(Net is DotNetty)介绍
    工作中,如何衡量一个人的 JavaScript 编码水平?
    10个有趣又能编译为JavaScript的语言,你用过哪些?
    一定要你明白Java中的volatile
    面试总被问到HTTP缓存机制及原理?看完你就彻底明白了
  • 原文地址:https://www.cnblogs.com/lzjsky/p/1828133.html
Copyright © 2020-2023  润新知