zoukankan      html  css  js  c++  java
  • GDI 画出半透明

    #pragma once
    
    
    // FButton
    
    class FButton : public CButton
    {
        DECLARE_DYNAMIC(FButton)
    
    public:
        //按钮的状态  
        BOOL m_bOver;       //鼠标位于按钮之上时该值为true,反之为flase  
        BOOL m_bTracking;   //在鼠标按下没有释放时该值为true  
        BOOL m_bSelected;   //按钮被按下是该值为true  
        BOOL m_bFocus;      //按钮为当前焦点所在时该值为true  
        FButton(UINT nID);
        virtual ~FButton();
        CPen m_OutBorderPen;
        Image *image;
        bool ImageFromIDResource(UINT nID, LPCTSTR sTR,Image *&pImg);//从图片资源ID中装载图像到Image类的指针对象
        afx_msg void OnMouseMove(UINT nFlags, CPoint point);
        afx_msg LRESULT OnMouseLeave(WPARAM wParam, LPARAM lParam); 
        afx_msg LRESULT OnMouseHover(WPARAM wParam, LPARAM lParam);
        virtual void DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/);
        afx_msg BOOL OnEraseBkgnd(CDC* pDC);
    protected:
        DECLARE_MESSAGE_MAP()
        virtual void PreSubclassWindow();
    };
    // FButton.cpp : 实现文件
    //
    
    #include "stdafx.h"
    #include "TuDai.h"
    #include "FButton.h"
    
    
    // FButton
    
    IMPLEMENT_DYNAMIC(FButton, CButton)
    
    FButton::FButton(UINT nID)
    {
    #ifndef _WIN32_WCE
        EnableActiveAccessibility();
    #endif
    
        //m_BoundryPen.CreatePen(PS_INSIDEFRAME | PS_SOLID, 1, RGB(55, 98, 6));
        ImageFromIDResource(nID,L"PNG",image);
    
    }
    
    FButton::~FButton()
    {
    }
    
    BEGIN_MESSAGE_MAP(FButton, CButton)
        ON_WM_MOUSEMOVE()
        ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
        ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover)
        ON_WM_ERASEBKGND()
    END_MESSAGE_MAP()
    
    // FButton 消息处理程序
    
    void FButton::OnMouseMove(UINT nFlags, CPoint point) {
    
        if(!m_bTracking)  //定义的一个标志变量,如果已经注册了就不需要再次注册,直到这两个消息中有人响应了
        {                //再注册
            TRACKMOUSEEVENT v_tme;
            v_tme.cbSize = sizeof(v_tme);
            v_tme.hwndTrack = m_hWnd; //指明的是哪个控件
            v_tme.dwFlags = TME_LEAVE | TME_HOVER;  //离开和延时两个消息
            v_tme.dwHoverTime = 1;  //指鼠标在控件上停留多少时间后才会响应停留消息OnMouseLeave
            m_bTracking = _TrackMouseEvent(&v_tme); //注册消息,响应完成后要再次注册,否则响应一次后就不响应
        }
        HCURSOR hCur  =  LoadCursor( NULL  , IDC_HAND ) ;
        ::SetCursor(hCur);
    
        CButton::OnMouseMove(nFlags, point);
    }
    
    LRESULT FButton::OnMouseLeave(WPARAM wParam, LPARAM lParam) {
        //if (m_bOver == true) {
        m_bOver = false;  
        m_bTracking = false;
        Invalidate();
        //}
        CRect   rect; 
        GetWindowRect(&rect); 
        GetParent()-> ScreenToClient(&rect); 
        GetParent()-> InvalidateRect(&rect);
        /*InvalidateRect(NULL, FALSE);  */
        return 0;  
    }
    
    LRESULT FButton::OnMouseHover(WPARAM wParam, LPARAM lParam) {
    
        //if (m_bOver == false) {
        m_bOver = true;
        m_bTracking = true;
        Invalidate();  
        //}
        CRect   rect; 
        GetWindowRect(&rect); 
        GetParent()-> ScreenToClient(&rect); 
        GetParent()-> InvalidateRect(&rect);
        return 0;
    }
    
    void FButton::PreSubclassWindow()
    {
        CButton::PreSubclassWindow();
        m_bTracking = false;
        m_bOver = false;
    
        ModifyStyle(0, BS_OWNERDRAW);
    }
    
    bool FButton::ImageFromIDResource(UINT nID, LPCTSTR sTR,Image *&pImg)//从图片资源ID中装载图像到Image类的指针对象
    //特别说明:参数3中使用了指针引用,使得传入的参数(指针)在函数中可以改变其地址(例如本函数),也可以将指针引用改为指针的指针,
    //如Image **pImg,当然其他有关pImg的引用也需要做出相应的更改。
    {
        HINSTANCE hInst = AfxGetResourceHandle();//利用这个函数返回的HINSTANCE句柄来直接访问应用程序的句柄,例如,在调用Windows函数FindResource时使用
        HRSRC hRsrc = ::FindResource (hInst,MAKEINTRESOURCE(nID),sTR); //该函数确定指定模块中指定类型和名称的资源所在位置
        if (!hRsrc)
            return FALSE;
    
        DWORD len = SizeofResource(hInst, hRsrc);//该函数返回指定资源字节数大小。
        BYTE* lpRsrc = (BYTE*)LoadResource(hInst, hRsrc);//该函数装载指定资源到全局存储器,返回值是相关资源的数据的句柄
        if (!lpRsrc)
            return FALSE;
    
        HGLOBAL m_hMem = GlobalAlloc(GMEM_FIXED, len);//分配一个全局内存块 
        //GlobalAlloc是winxx的一个api函数,new是c++的一个操作符。 
        //new可以根据操作系统有不同的实现,但是无论他怎么实现,在一个进程中开辟的内存只有该进程才能访问。 
        //但是GlobalAlloc不同,在一个进程中创建的内存,可以被其他进程调用。这就是GlobalAlloc的全局概念,和new是不一样的。 
        //使用new和delete对一个进程中的两个模块进行跨模块的内存开辟和释放,程序可能被崩溃,使用GlobalAlloc开辟内存不存在这个问题。
        //一般除了在剪贴板等函数中使用GlobalAlloc函数返回的句柄外,在其它地方使用GlobalAlloc函数的地方不多啊。
    
        BYTE* pmem = (BYTE*)GlobalLock(m_hMem);//锁定内存块,该函数接受一个内存句柄作为参数,然后返回一个指向被锁定的内存块的指针,您可以用该指针来读写内存。 
    
        memcpy(pmem,lpRsrc,len);//由lpRsrc所指内存区域复制len个字节到pmem所指内存区域
    
        IStream* pstm;
        CreateStreamOnHGlobal(m_hMem,FALSE,&pstm);//在全局内存块(m_hMem)中创建一个流对象(pstm),第二个参数为flase时,则不再使用流(pstm)时需要调用pstm->Release()
        //如果为true时,则系统会自动释放该流(pstm)
    
        pImg=Gdiplus::Image::FromStream(pstm);//在流对象(pstm)的基础上建立一个image对象,返回对象的指针
    
        GlobalUnlock(m_hMem);//调用GlobalUnlock函数来解锁先前被锁定的内存,该函数使得指向内存块的指针无效。 
        pstm->Release();        //释放流对象
        FreeResource(lpRsrc);    //释放资源数据指针
        return true;
    }
    
    void FButton::DrawItem(LPDRAWITEMSTRUCT lpDS)
    {
        CRect Rect;
        UINT W = image->GetWidth(),H = image->GetHeight(); 
    
        GetClientRect(&Rect);
    
        Graphics g(lpDS->hDC);   
        
        Bitmap bmp(Rect.Width(),Rect.Height());
        Graphics* gs = Graphics::FromImage(&bmp);
    
    
        if(lpDS->itemState & ODS_SELECTED)//按钮按下  
        {  
            gs->DrawImage(image,(0 - Rect.Width() * 2),0,W,H);  
        }  
        else if(m_bOver)//鼠标移上  
        {  
            gs->DrawImage(image,(0 - Rect.Width()),0,W,H);  
        }  
        else//普通形态  
        {  
            gs->DrawImage(image,0,0,W,H);  
        }
    
        delete gs;
        g.DrawImage(&bmp,0,0);
        g.ReleaseHDC(lpDS->hDC);
    }
    
    BOOL FButton::OnEraseBkgnd(CDC* pDC)
    {return true;
    }
  • 相关阅读:
    NHibernate之旅(14):探索NHibernate中使用视图
    NHibernate之旅(18):初探代码生成工具使用
    NHibernate之旅(15):探索NHibernate中使用存储过程(上)
    接下来5年中有用的10项开发技能
    NHibernate之旅(22):探索NHibernate一级缓存
    NHibernate之旅(24):探索NHibernate二级缓存(下)
    NHibernate之旅(17):探索NHibernate中使用存储过程(下)
    NHibernate之旅(11):探索多对多关系及其关联查询
    Python入门示例系列18 条件控制
    .NET计划之配置ASP.NET运行环境
  • 原文地址:https://www.cnblogs.com/shengshuai/p/3107739.html
Copyright © 2011-2022 走看看