1. 程式人生 > >CButton重繪

CButton重繪

MFC下一個簡單的按鈕重繪,功能不是那麼全

#if !defined(AFX_BMPBUTTON_H__FBB70540_EC88_4021_9272_574C1A7A571B__INCLUDED_)
#define AFX_BMPBUTTON_H__FBB70540_EC88_4021_9272_574C1A7A571B__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// BmpButton.h : header file
//

/////////////////////////////////////////////////////////////////////////////
// CBmpButton window

class CBmpButton : public
CButton { // Construction public: BOOL m_bNonToolBarBtn; UINT m_uiDisBmpID; UINT m_uiNorBmpID; CBmpButton(); void SetNonToolBarBtn(BOOL bBtn); void SetBitmap(UINT nBmpID); void SetItemData(DWORD dwData){m_dwData=dwData;} void SetDisableBmp(UINT nBmpID){m_uiDisBmpID=nBmpID;} void
SetNormalBmp(UINT nBmpID){m_uiNorBmpID=nBmpID;} /* OK 可用 不可用 SetNorBmp SetDisBmp Select All 可用 可用 Zoomin 可用 不可用 可用 不可用 SetNorBmp SetDisBmp SetNorBmp SetDisBmp */
DWORD GetItemData(){return m_dwData;} // Attributes public: // Operations public: // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CBmpButton) public: virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct); protected: virtual void PreSubclassWindow(); afx_msg LRESULT OnMouseLeave(WPARAM wParam, LPARAM lParam); afx_msg LRESULT OnMouseHover(WPARAM wParam, LPARAM lParam); //}}AFX_VIRTUAL // Implementation public: virtual ~CBmpButton(); // Generated message map functions protected: //{{AFX_MSG(CBmpButton) afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor); afx_msg void OnCaptureChanged(CWnd *pWnd); afx_msg void OnKillFocus(CWnd* pNewWnd); afx_msg void OnMouseMove(UINT nFlags, CPoint point); afx_msg void OnSize(UINT nType, int cx, int cy); afx_msg BOOL OnEraseBkgnd(CDC* pDC); afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message); //}}AFX_MSG void ResetWndRgn(); DECLARE_MESSAGE_MAP() private: BOOL m_bIsTracking; BOOL m_bIsHovering; HBITMAP m_hBitmap; BOOL m_MouseOnButton; DWORD m_dwData; }; ///////////////////////////////////////////////////////////////////////////// //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_BMPBUTTON_H__FBB70540_EC88_4021_9272_574C1A7A571B__INCLUDED_)

實現

// BmpButton.cpp : implementation file
//

#include "stdafx.h"
#include "BmpButton.h"
#include "resource.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

extern CFont* g_DisplayFont24;
/////////////////////////////////////////////////////////////////////////////
// CBmpButton

CBmpButton::CBmpButton()
{
    m_hBitmap=NULL;
    m_MouseOnButton=FALSE;
    m_dwData=0xFFFFFFFF;

    m_bIsTracking = FALSE;
    m_bIsHovering = FALSE;
    m_uiDisBmpID = -1;
    m_uiNorBmpID = -1;
    m_bNonToolBarBtn = FALSE;
}

CBmpButton::~CBmpButton()
{
    if(m_hBitmap)::DeleteObject(m_hBitmap);
}
BEGIN_MESSAGE_MAP(CBmpButton, CButton)
    //{{AFX_MSG_MAP(CBmpButton)
    ON_WM_CTLCOLOR()
    ON_WM_CAPTURECHANGED()
    ON_WM_KILLFOCUS()
    ON_WM_MOUSEMOVE()
    ON_WM_SIZE()
    ON_WM_ERASEBKGND()
    ON_WM_SETCURSOR()
    ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
    ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover)
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CBmpButton message handlers

HBRUSH CBmpButton::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
{
    return (HBRUSH)::GetStockObject(NULL_BRUSH);
}
void CBmpButton::PreSubclassWindow() 
{
    ModifyStyle(0,BS_OWNERDRAW);    
    ResetWndRgn();
    CButton::PreSubclassWindow();
}
void CBmpButton::OnMouseMove(UINT nFlags, CPoint point)
{
    CWnd* pWnd;
    CWnd* pParent;

    if(!m_bIsTracking)
    {
        TRACKMOUSEEVENT tme;
        tme.cbSize      = sizeof(tme);
        tme.hwndTrack   = m_hWnd;
        tme.dwFlags     = TME_LEAVE|TME_HOVER;
        tme.dwHoverTime = 1;
        m_bIsTracking = _TrackMouseEvent(&tme);
    }
    CButton::OnMouseMove(nFlags, point);

    if (nFlags & MK_LBUTTON && m_MouseOnButton == FALSE) return;

    pWnd = GetActiveWindow();
    pParent = GetOwner();

    if ((GetCapture() != this) && (pWnd != NULL && pParent != NULL)) 
    {
        m_MouseOnButton = TRUE;
        SetFocus();
        SetCapture();
        Invalidate();
    }
    else
    {
        CRect rc;
        GetClientRect(&rc);
        if(!rc.PtInRect(point))
        {
            if(m_MouseOnButton == TRUE)
            {
                m_MouseOnButton = FALSE;
                Invalidate();
            }
            if(!(nFlags & MK_LBUTTON)) ReleaseCapture();
        }
    }
}

LRESULT CBmpButton::OnMouseLeave(WPARAM wParam, LPARAM lParam)
{
    m_bIsTracking = FALSE;
    m_bIsHovering = FALSE;
    Invalidate();
    return 0;
}

LRESULT CBmpButton::OnMouseHover(WPARAM wParam, LPARAM lParam)
{
    m_bIsHovering = TRUE;
    Invalidate();
    return 0;
}

void CBmpButton::OnKillFocus(CWnd * pNewWnd)
{
    CButton::OnKillFocus(pNewWnd);

    if(m_MouseOnButton == TRUE){
        m_MouseOnButton = FALSE;
        Invalidate();
    }
}
void CBmpButton::OnCaptureChanged(CWnd *pWnd) 
{
    if (m_MouseOnButton == TRUE){
        ReleaseCapture();
        Invalidate();
    }
    CButton::OnCaptureChanged(pWnd);
}
void CBmpButton::SetBitmap(UINT nBmpID)
{
    HINSTANCE   hInstResource   = NULL; 
    hInstResource = AfxFindResourceHandle(MAKEINTRESOURCE(nBmpID), RT_BITMAP);
    if(m_hBitmap)::DeleteObject(m_hBitmap);
    m_hBitmap = (HBITMAP)::LoadImage(hInstResource, MAKEINTRESOURCE(nBmpID), IMAGE_BITMAP, 0, 0, 0);
}
void CBmpButton::ResetWndRgn()
{
    CRect rcItem;
    GetClientRect(&rcItem);
#define DOTS    5
    CPoint pt[8];
    pt[0].x=DOTS;               pt[0].y=0;
    pt[1].x=rcItem.right-DOTS;  pt[1].y=0;
    pt[2].x=rcItem.right;       pt[2].y=DOTS;
    pt[3].x=rcItem.right;       pt[3].y=rcItem.bottom-DOTS;
    pt[4].x=rcItem.right-DOTS;  pt[4].y=rcItem.bottom;
    pt[5].x=DOTS;               pt[5].y=rcItem.bottom;
    pt[6].x=rcItem.left;        pt[6].y=rcItem.bottom-DOTS;
    pt[7].x=rcItem.left;        pt[7].y=DOTS;

    HRGN hRgn=::CreatePolygonRgn(pt,8,ALTERNATE);
//  HRGN hRgn = CreateRoundRectRgn(0,0,rcItem.right-rcItem.left,rcItem.bottom-rcItem.top,50,50);
    SetWindowRgn(hRgn,TRUE);
    ::DeleteObject(hRgn);
}

void CBmpButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
{
    HDC hDC          = lpDrawItemStruct->hDC;
    BOOL bIsPressed  = (lpDrawItemStruct->itemState & ODS_SELECTED);
    BOOL bIsFocused  = (lpDrawItemStruct->itemState & ODS_FOCUS);
    BOOL bIsDisabled = (lpDrawItemStruct->itemState & ODS_DISABLED);
    CRect rcItem     = lpDrawItemStruct->rcItem;
    CDC *pDC=CDC::FromHandle(lpDrawItemStruct->hDC);

    CString strTitle;
    GetWindowText(strTitle);

    CFont *pOldFont=pDC->SelectObject(g_DisplayFont24);
    CSize szText=pDC->GetTextExtent(strTitle);

    ::SetBkMode(hDC,TRANSPARENT);

    CRect rcCalc=rcItem;
    if(bIsDisabled)
    {
        pDC->FillSolidRect(&rcItem,RGB(97,198,49));
        pDC->SetTextColor(RGB(128,128,128));
    }
    else if(m_bIsHovering)
    {
        CBrush brsh;
        brsh.CreateSolidBrush(RGB(32,143,255));//76,137,189     18,118,191
        CPoint pt(10,10);
        CPen pen(PS_SOLID,1,RGB(32,143,255));//76,137,189       18,118,191
        pDC->SelectObject(&brsh);
        pDC->SelectObject(&pen);
        pDC->RoundRect(&rcItem,pt);
        if(bIsPressed)
            pDC->SetTextColor(RGB(255,0,0));
        else
            pDC->SetTextColor(RGB(0,0,0));
    }
    else
    {
//      pDC->FillSolidRect(&rcItem,RGB(97,198,49));
        pDC->SetTextColor(RGB(0,0,0));//設定按鈕文字的顏色
        CPen pen(PS_SOLID,1,RGB(0,128,255));//98,177,245        8,109,169
        CBrush brsh;
        brsh.CreateSolidBrush(RGB(0,128,255));//98,177,245      8,109,169
        CPoint pt(10,10);
        pDC->SelectObject(&brsh);
        pDC->SelectObject(&pen);
        pDC->RoundRect(&rcItem,pt);
    }

    if(szText.cx>rcItem.Width())
    {
        rcCalc.left = rcItem.left;
        rcCalc.right= rcItem.right;
    }
    else
    {
        rcCalc.left = (rcItem.Width()-szText.cx)/2;
        rcCalc.right= rcCalc.left+szText.cx;
    }
    rcCalc.top = rcItem.top;
    rcCalc.bottom = rcItem.bottom;

    pDC->DrawText(strTitle,rcCalc,/*DT_WORDBREAK*/DT_CENTER|DT_VCENTER|DT_SINGLELINE);
    pDC->SelectObject(pOldFont);
}

void CBmpButton::OnSize(UINT nType, int cx, int cy) 
{
    CButton::OnSize(nType, cx, cy);
    if(IsWindow(m_hWnd))ResetWndRgn();
}

BOOL CBmpButton::OnEraseBkgnd(CDC* pDC) 
{
    return TRUE;
}

BOOL CBmpButton::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
    ::SetCursor(AfxGetApp()->LoadStandardCursor(MAKEINTRESOURCE(32649)));
    return TRUE;
}

void CBmpButton::SetNonToolBarBtn(BOOL bBtn)
{
    m_bNonToolBarBtn = bBtn;
}
//////////////////////////////////////////////////////////////////////////
/*
void CBmpButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
{
    HDC hDC          = lpDrawItemStruct->hDC;
    BOOL bIsDisabled = (lpDrawItemStruct->itemState & ODS_DISABLED);
    CRect rcItem     = lpDrawItemStruct->rcItem;
    CDC *pDC=CDC::FromHandle(lpDrawItemStruct->hDC);
    HDC hMemDC;

    CString strTitle;
    GetWindowText(strTitle);
    CSize szText=pDC->GetTextExtent(strTitle);
    CFont *pOldFont=pDC->SelectObject(g_DisplayFont16);

    ::SetBkMode(hDC,TRANSPARENT);

    CRect rcCalc=rcItem;
    CRect rcBmp(0,0,39,36);

    if(bIsDisabled)
        pDC->SetTextColor(RGB(128,128,128));
    else if(m_bIsHovering)
    {
        HRGN hRgnRct;
        hRgnRct = CreateRoundRectRgn(0,0,rcItem.right-rcItem.left,rcItem.bottom-rcItem.top,5,5);
        SetWindowRgn(hRgnRct,TRUE);

        pDC->FillSolidRect(&rcItem,RGB(255,255,255));
        pDC->SetTextColor(RGB(0,0,0));
    }
    else
    {
        HRGN hRgnRct;
        hRgnRct = CreateRoundRectRgn(0,0,rcItem.right-rcItem.left,rcItem.bottom-rcItem.top,5,5);
        SetWindowRgn(hRgnRct,TRUE);

        pDC->FillSolidRect(&rcItem,RGB(23,75,153));
        pDC->SetTextColor(RGB(255,255,255));
    }


    if(szText.cx>rcItem.Width())
    {
        rcCalc.left = rcItem.left;
        rcCalc.right= rcItem.right;
    }
    else
    {14
        rcCalc.left = (rcItem.Width()-szText.cx)/2;
        rcCalc.right= rcCalc.left+szText.cx;
    }
    rcCalc.top = rcBmp.Height()+5;
    rcCalc.bottom = rcItem.bottom;

    hMemDC=::CreateCompatibleDC(hDC);
    ::SelectObject(hMemDC,m_hBitmap);
    ::SetStretchBltMode(hDC,COLORONCOLOR);
    ::StretchBlt(hDC,(rcItem.Width()-rcBmp.Width())/2,5,rcBmp.Width(),rcBmp.Height(),hMemDC,rcBmp.left,rcBmp.top,rcBmp.Width(),rcBmp.Height(),SRCCOPY);

    pDC->DrawText(strTitle,rcCalc,DT_WORDBREAK);

    pDC->SelectObject(pOldFont);
    ::DeleteDC(hMemDC);
}*/

相關推薦

CButton (支援PNG圖片作為背景)

按鈕重繪支援PNG圖片作為背景很使用。可以實現按鈕一種背景圖片,然後滑鼠點選按鈕,增加一個透明的png邊框,也可以修改以下實現滑鼠停留在某個按鈕上面,改變按鈕的狀態。 #if !defined(AFX_PICBUTTON_H__4A8AEB90_4455_

CButton

MFC下一個簡單的按鈕重繪,功能不是那麼全 #if !defined(AFX_BMPBUTTON_H__FBB70540_EC88_4021_9272_574C1A7A571B__INCLUDED_) #define AFX_BMPBUTTON_H__FBB7

控件

text string lag right graphics brush draw str eight 1. 設置控件DrawMode屬性為OwnerDrawFixed,編輯控件DrawItem事件 重繪tabControl——選項卡控件     string text

瀏覽器的和重排的影響

包含 時間 邊框 渲染器 外邊距 數據 出現 又一 構建 瀏覽器下載完頁面中全部的組件之後,會解析生成兩個內部數據結構: 1. DOM樹:表示頁面結構 2. 表示DOM節點怎樣顯示 當DOM和渲染樹構建完畢之後,瀏覽器就開始顯示(繪制)頁面元素。當

[Android FrameWork 6.0源碼學習] View的過程

nds 源碼學習 most leg shift isp window round ces View繪制的三部曲, 測量,布局,繪畫今天我們分析測量過程 view的測量是從ViewRootImpl發起的,View需要重繪,都是發送請求給ViewRootImpl,然後他組織重

[Android FrameWork 6.0源碼學習] View的過程之Layout

種子 noop cond req cor ide boolean 需要 bound View繪制的三部曲,測量,布局,繪畫現在我們分析布局部分測量部分在上篇文章中已經分析過了。不了解的可以去我的博客裏找一下View的布局和測量一樣,都是從ViewRootImpl中發起,Vi

[Android FrameWork 6.0源碼學習] View的過程之Draw

鐘表 store 傳遞 lan play deb kill gre 學習 View繪制的三部曲,測量,布局,繪畫現在我們分析繪畫部分測量和布局 在前兩篇文章中已經分析過了。不了解的可以去我的博客裏找一下 下面進入正題,開始分析調用以及函數原理 private void

高性能WEB開發:重排與

對象 保存 一般來說 結束 com 導致 選項 fix 低版本   DOM編程可能最耗時的地方,重排和重繪。 1、什麽是重排和重繪  瀏覽器下載完頁面中的所有組件——HTML標記、JavaScript、CSS、圖片之後會解析生成兩個內部數據結構——DOM樹和渲染樹。   D

Qt中制窗口方法:

get spa style () time color ack == brush 1 void CircleWidget::paintEvent(QPaintEvent * event) 2 { 3 QPainter painter(this); 4

css 頁面和回流(重排)以及優化

有用 其他 第一次 pos fix 更新 幾何 完成 進行 一、html頁面的呈現流程 1. 瀏覽器把獲取到的HTML代碼解析成1個DOM樹,HTML中的每個tag都是DOM樹中的1個節點,根節點就是我們常用的document對象。DOM樹裏包含了所有HTML標簽,包

頁面和回流以及優化(轉)

圖片大小 處理流 create 意圖 borde 基本上 nal arch 似的 源文章地址:http://www.css88.com/archives/4996 在討論頁面重繪、回流之前。需要對頁面的呈現流程有些了解,頁面是怎麽把html結合css等顯示到瀏覽器上的,下面

阻止控件

port user error extern set cnblogs text and sta //控件重繪 [DllImport("USER32.DLL ", CharSet = CharSet.Auto, SetLastError = true)] public st

窗體背景的制(Windows窗體每次都會其窗體背景,所以我們可以通過攔截窗體背景的消息(WM_ERASEBKGND),並自定義方法來實現窗體背景)

height com call 消息響應 int idt http msg mes 核心思想:由於Windows窗體每次都會重繪其窗體背景,所以我們可以通過攔截窗體重繪背景的消息(WM_ERASEBKGND),並自定義方法來實現重繪窗體背景。通過TImage組件也可以實現,

自行實現透明的控件如Panel GroupBox(使用不需要父控件的效果,一切都因為窗口有了WS_EX_TRANSPARENT屬性)

AR highlight ner alignment 重繪 == 答案 nsh none CSDN的Blog開通了。我想這裏的Blog作為今後自己回答別人問題的時候,收藏答案的地方很不錯呢。 因為社區的貼子早晚都會沈下去,查找起來很不方便,甚至再也找不到呢。 Q: ht

JAVA 畫圖板實現(基本畫圖功能+界面UI)二、功能實現及實現

cos 博客 tint ext min click 代碼 hints 按鈕 上篇博客中介紹了界面的實現方法,在這篇博客中將對每個按鈕的功能的實現進行講解並介紹重繪 首先肯定要添加事件監聽機制了,那麽問題來了,事件源對象是誰?需要添加什麽方法?事件接口是什麽? 1、我們需要點

第11章 圖形的保存和

http sdn ref lan https pan tar spa target 參考: https://blog.csdn.net/u014162133/article/details/46573873第11章 圖形的保存和重繪

頁面和回流以及優化

inf title col try 至少 com round 繪制 邊框 頁面重繪和回流以及優化 回流與重繪 1. 當render tree中的一部分(或全部)因為元素的規模尺寸,布局,隱藏等改變而需要重新構建。這就稱為回流(reflow)。每個頁面至少需要一次回流,就是在

html頁面和迴流以及優化

在討論頁面重繪、迴流之前。需要對頁面的呈現流程有些瞭解,頁面是怎麼把html結合css等顯示到瀏覽器上的,下面的流程圖顯示了瀏覽器對頁面的呈現的處理流程。可能不同的瀏覽器略微會有些不同。但基本上都是類似的。 1.瀏覽器把獲取到的HTML程式碼解析成1個DOM樹,HTML中的每個tag都是D

ListCtrl中增加子控制元件Edit是,在父控制元件失去焦點時,子控制元件不進行隱藏

問題:現在有一個listctrl控制元件,需要在某一列上新增一個子控制元件edit。當點選子控制元件(edit)時,子控制元件顯示出來,父控制元件(ListCtrl)已經失去焦點了。此時,要是滑鼠點選的位置不在該控制元件內,edit處於顯示狀態,父控制元件(ListCtrl)是失去焦點狀態。

display和visibility的區別以及迴流和

display:none會脫離文件流,不佔據頁面空間; visibility:hidden,只是隱藏內容,並沒有脫離文件流,會佔據頁面的空間。 講述迴流以及重繪之前需要先了解頁面在文件載入完成之後到完全顯示中間的過程: 1.根據文件生成DOM樹(包括display:none的節點) 2.在D