|
珞珈山水BBS →
电脑网络 →
程序人生 →
单文区文章阅读
|
| 单文区文章阅读 [返回] |
|---|
|
发信人: pcj2008 (☆蓬草江☆), 信区: Programm 标 题: 求VC一问题解答,帮帮我吧,牛人们! 发信站: BBS 珞珈山水站 (Tue Jun 6 23:25:31 2006) 我自己扩展了一个CButton类,之后不停当鼠标移近时会按钮显得非常闪烁!问题好严重啊 !求牛人帮忙! //PCJbirdButton.h /************************************************************************/ /***************************************************************************** ******/ /******设计者:☆蓬草江☆ 于2006年6月,武汉大学**************************** ******/ /******飞思工作室 版权所有 武汉大学计算机学院03级计科1班******************* ******/ /***************************************************************************** ******/ #if !defined(AFX_PCJBIRDBUTTON_H__068B0DC5_909A_48B6_8019_BEE0B2D84B6A__INCLUD ED_) #define AFX_PCJBIRDBUTTON_H__068B0DC5_909A_48B6_8019_BEE0B2D84B6A__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 // PCJbirdButton.h : header file // //ico图标对齐方式 #define AL_LEFT 0//左对齐 #define AL_TOP 1//上对齐 //按钮类型 #define NormalBtn 0//普通按钮 #define BitmapBtn 1//bitmap位图按钮 #define IconBtn 2//icon按钮 // 鼠标状态 #define ST_MOVEIN 0//鼠标在按钮范围内 #define ST_MOVEOUT 1//鼠标在按钮范围外 #define ST_MOUSEUP 2//鼠标释放状态 #define ST_MOUSEDOWN 3//鼠标按下状态 ///////////////////////////////////////////////////////////////////////////// // PCJbirdButton window class PCJbirdButton : public CButton { // Construction public: PCJbirdButton(); // Attributes public: UINT m_NomalPic;//正常情况下显示的图片 UINT m_FocusPic;//鼠标经过按钮时显示的图片 UINT m_DownPic;//鼠标按下时显示的图片 UINT m_EnablePic;//按钮实效时显示的图片 //bool m_IsInRect;//是否在按钮范围内 UINT CursorID;//焦点鼠标ID HCURSOR FocusCursor;//焦点鼠标图标 UINT btnType;//按钮类型:0 普通按钮,1 bitmap按钮,2 icon按钮 bool m_bDCStored;//按钮设备背景是否已经被保存 int m_IconYPos;//ico图标y坐标 int m_IconXPos;//ico图标x坐标 int m_IconAlign;//ico图标对齐方式 int m_DrawState;//鼠标与按钮的位置关系或鼠标的状态 HICON m_hMouseInIcon;//鼠标经过按钮时的ico图标 HICON m_hNormalIcon;//正常情况下的ico图标 HICON m_hDownIcon;//按下时的ico图标 bool m_bBkTransparent;//按钮背景是否透明 COLORREF m_clText;//当前文本颜色 COLORREF m_clMouseDownText;//鼠标按下时文本颜色 COLORREF m_clActiveText;//按钮激活时的文本颜色 COLORREF m_clNormalText;//按钮正常情况下的文本颜色 bool m_bIsEnabled;//按钮是否可用状态 bool m_bMove;//鼠标是否移动 bool m_bUseIcon;//是否使用ico图标 bool m_bIsCreated;//是否已经创建 bool m_bCapture;//是否捕捉到按钮 CDC baseDC;//基本设备,用于拷贝按钮背景部分 // Operations public: // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(PCJbirdButton) public: virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct); protected: virtual void PreSubclassWindow(); //}}AFX_VIRTUAL // Implementation public: void SetNormalTextColor(COLORREF color); void SetMouseDownTextColor(COLORREF color); void SetIconYPos(int y); void SetIconXPos(int x); void SetAlign(int nAlign); void SetActiveTextColor(COLORREF color); void SetIcon(HICON hNormal,HICON hMouseIn); void SetIcon(UINT nNormal,UINT nMouseIn); void DrawText(); void DrawIcon(HICON hIcon,BOOL bDisabled=FALSE); void DrawIcon(); BOOL SetCursor(UINT nCursorID); void SetBitmapIDS(UINT Normalbmp, UINT Focusbmp, UINT Downbmp,UINT Disable dbmp); void DrawBitmap(UINT bmpID); void DrawBitmap(); void SetButtonType(UINT btntype); void Draw(); void Refresh(); void SetBkMode(bool bTransparent); virtual ~PCJbirdButton(); // Generated message map functions protected: //{{AFX_MSG(PCJbirdButton) afx_msg BOOL OnEraseBkgnd(CDC* pDC); afx_msg void onMouseMove(UINT nFlags, CPoint point); afx_msg void OnTimer(UINT nIDEvent); afx_msg void OnLButtonDown(UINT nFlags, CPoint point); afx_msg void OnLButtonUp(UINT nFlags, CPoint point); afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message); afx_msg void OnKillFocus(CWnd* pNewWnd); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; ///////////////////////////////////////////////////////////////////////////// //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_PCJBIRDBUTTON_H__068B0DC5_909A_48B6_8019_BEE0B2D84B6A__ INCLUDED_) //PCJbirdButton.cpp /****************************************************************************/ // PCJbirdButton.cpp : implementation file // #include "stdafx.h" #include "PCJbirdButton.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // PCJbirdButton PCJbirdButton::PCJbirdButton() { m_bIsCreated=false; btnType=NormalBtn; m_bBkTransparent=true; m_bIsEnabled=true; m_bDCStored=false; m_bMove=false; m_bUseIcon=false; m_bCapture = false; m_hMouseInIcon=NULL; m_hNormalIcon=NULL; m_IconAlign=AL_LEFT; m_DrawState=ST_MOVEOUT; m_IconYPos=5; m_IconXPos=5; m_clNormalText=::GetSysColor(COLOR_WINDOWTEXT); m_clActiveText=::GetSysColor(COLOR_HIGHLIGHT); m_clMouseDownText=::GetSysColor(COLOR_WINDOWTEXT); m_clText=m_clNormalText; m_NomalPic=-1; m_FocusPic=-1; m_DownPic=-1; m_EnablePic=-1; } PCJbirdButton::~PCJbirdButton() { } BEGIN_MESSAGE_MAP(PCJbirdButton, CButton) //{{AFX_MSG_MAP(PCJbirdButton) ON_WM_ERASEBKGND() ON_WM_MOUSEMOVE() ON_WM_TIMER() ON_WM_LBUTTONDOWN() ON_WM_LBUTTONUP() ON_WM_SETCURSOR() ON_WM_KILLFOCUS() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // PCJbirdButton message handlers BOOL PCJbirdButton::OnEraseBkgnd(CDC* pDC) //擦除按钮背景 { // TODO: Add your message handler code here and/or call default // 首先我们要保存设备 DC. if(!m_bDCStored) { CRect clientRect; GetClientRect(&clientRect); int cx=clientRect.Width (); int cy=clientRect.Height (); // Store our orignal DC. CBitmap bitmap; baseDC.CreateCompatibleDC (pDC); bitmap.CreateCompatibleBitmap (pDC,cx,cy); baseDC.SelectObject (&bitmap); baseDC.BitBlt (0,0,cx,cy,pDC,0,0,SRCCOPY); m_bDCStored=true; } return true; } void PCJbirdButton::onMouseMove(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default CRect rc; GetClientRect(&rc); if (nFlags & MK_LBUTTON) return; if(!m_bMove && m_bIsEnabled && rc.PtInRect(point)&&m_bIsCreated==true) { m_bMove=true; m_DrawState=ST_MOVEIN; if (!m_bCapture) { SetCapture(); m_bCapture = true; } //Draw(); Invalidate(); SetTimer(1,10,NULL); } else { if(!rc.PtInRect(point)) { if (m_bCapture) { ReleaseCapture(); m_bCapture = false; } } } CButton::onMouseMove(nFlags, point); } void PCJbirdButton::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default if(nIDEvent!=1) return; CPoint point; CRect rect; GetWindowRect(&rect); GetCursorPos(&point); // 如果鼠标离开按钮且处于可用状态,则重画按钮。 if (!rect.PtInRect(point) && m_bMove && m_bIsEnabled) { KillTimer (1); m_DrawState=ST_MOVEOUT; m_bMove=false; //Draw(); Invalidate(); if (m_bCapture) { ReleaseCapture(); m_bCapture = false; } } CButton::OnTimer(nIDEvent); } void PCJbirdButton::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default CRect rc; GetClientRect(&rc); if (!m_bCapture) { SetCapture(); m_bCapture = true; } if(m_bIsEnabled && rc.PtInRect(point)) { //SetCapture(); m_DrawState=ST_MOUSEDOWN; //Draw(); Invalidate(); } CButton::OnLButtonDown(nFlags, point); } void PCJbirdButton::OnLButtonUp(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default if (!m_bCapture) { SetCapture(); m_bCapture = true; } if(m_bIsEnabled) { m_DrawState=ST_MOUSEUP; //Draw(); Invalidate(); } CButton::OnLButtonUp(nFlags, point); } BOOL PCJbirdButton::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) { // TODO: Add your message handler code here and/or call default if (FocusCursor != NULL) { ::SetCursor(FocusCursor); return TRUE; } return CButton::OnSetCursor(pWnd, nHitTest, message); } void PCJbirdButton::SetBkMode(bool bTransparent)//设置按钮背景是否透明 { m_bBkTransparent=bTransparent; } void PCJbirdButton::Refresh() { CRect rect; GetClientRect(&rect); CClientDC dc(this); if(m_bBkTransparent==false) dc.FillRect(&rect,&CBrush(::GetSysColor(COLOR_BTNFACE)) ); else dc.BitBlt (0,0,rect.Width (),rect.Height (),&baseDC,0,0,SRCCOPY); } void PCJbirdButton::Draw() { m_bIsCreated=true; Refresh(); switch(btnType) { case NormalBtn: break; case BitmapBtn: DrawBitmap(); break; case IconBtn: DrawIcon(); DrawText(); break; default: break; } } void PCJbirdButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { // TODO: Add your code to draw the specified item if(lpDrawItemStruct->itemState & ODS_DISABLED ) { m_bIsEnabled=false; m_DrawState=ST_MOVEOUT; } if(lpDrawItemStruct->itemState & ODS_SELECTED ) { m_DrawState=ST_MOUSEDOWN; } if(!(lpDrawItemStruct->itemState & ODS_DISABLED) ) { m_bIsEnabled=true; } //if(m_bIsCreated==false) { Draw(); } } void PCJbirdButton::PreSubclassWindow() //设置按钮初始风格 { // TODO: Add your specialized code here and/or call the base class SetButtonStyle(GetButtonStyle() | BS_OWNERDRAW); CButton::PreSubclassWindow(); } void PCJbirdButton::SetButtonType(UINT btntype)//设置按钮类型 { btnType=btntype; } void PCJbirdButton::DrawBitmap()//选择画的Bitmap位图 { if(m_bIsEnabled) { switch(m_DrawState) { case ST_MOUSEDOWN: { if(m_DownPic!=-1) { DrawBitmap(m_DownPic); } else { if(m_NomalPic!=-1) DrawBitmap(m_NomalPic); } } break; case ST_MOVEIN: case ST_MOUSEUP: { if(m_FocusPic!=-1) { DrawBitmap(m_FocusPic); } else { if(m_NomalPic!=-1) DrawBitmap(m_NomalPic); } } break; case ST_MOVEOUT: { if(m_NomalPic!=-1) DrawBitmap(m_NomalPic); } break; default: break; } } else { if(m_EnablePic!=-1) { DrawBitmap(m_EnablePic); } else { if(m_NomalPic!=-1) DrawBitmap(m_NomalPic); } } } void PCJbirdButton::DrawBitmap(UINT bmpID)//画Bitmap位图按钮 { /*这段程序还有待改进,图片非常闪烁!*/ int x,y; COLORREF TrancColor,color; CRect rcWnd; // CRgn tmpRgn,WndRgn; CClientDC dc(this); // device context for painting CBitmap bitM; bitM.LoadBitmap(bmpID); BITMAP bitstruct; bitM.GetBitmap(&bitstruct); CDC memDC; CDC memDCdraw; CDC *pDC; pDC=this->GetDC(); this->GetWindowRect(&rcWnd); // CBitmap* pBitmap = new CBitmap; // pBitmap->CreateCompatibleBitmap(&baseDC, bitstruct.bmWidth, bitstruct.bm Height); //WndRgn.CreateRectRgn(0,0,rcWnd.Width(),rcWnd.Height()); memDC.CreateCompatibleDC(&dc); memDC.SelectObject(&bitM); // memDCdraw.CreateCompatibleDC(&dc); // memDCdraw.SelectObject(pBitmap); // memDCdraw.BitBlt(0,0,rcWnd.Width(),rcWnd.Height(),&baseDC,0,0,SRCCOPY); TrancColor=memDC.GetPixel(0,0);//取出透明色 for(x=0;x<rcWnd.Width();x++)//bitstruct.bmWidthbitstruct.bmHeight { for(y=0;y<rcWnd.Height();y++) { color=memDC.GetPixel(x,y); if(color!=TrancColor) { //tmpRgn.CreateRectRgn(x,y,x+1,y+1); //WndRgn.CombineRgn(&WndRgn,&tmpRgn,RGN_XOR); //tmpRgn.DeleteObject(); pDC->SetPixel(x,y,color); } } } //memDC.DeleteDC(); //this->SetWindowRgn(WndRgn,true); //CRect rcClient; //GetClientRect(&rcClient); //dc.BitBlt(0,0,rcClient.Width(),rcClient.Height(),&memDCdraw,0,0,SRCCOPY) ; } void PCJbirdButton::SetBitmapIDS(UINT Normalbmp, UINT Focusbmp, UINT Downbmp, UINT Disabledbmp)//设置Bitmap { m_NomalPic=Normalbmp; m_FocusPic=Focusbmp; m_DownPic=Downbmp; m_EnablePic=Disabledbmp; } BOOL PCJbirdButton::SetCursor(UINT nCursorID)//为按钮选择鼠标形状 { HINSTANCE hInstResource; // Destroy any previous cursor if (FocusCursor != NULL) ::DestroyCursor(FocusCursor); FocusCursor = NULL; // If we want a cursor if (nCursorID != -1) { hInstResource = AfxFindResourceHandle(MAKEINTRESOURCE(nCursorID), RT_GROUP_CURSOR); // Load icon resource FocusCursor = (HCURSOR)::LoadImage(hInstResource/*AfxGetApp()->m_hInst ance*/, MAKEINTRESOURCE(nCursorID), IMAGE_CURSOR, 0, 0, 0); // If something wrong then return FALSE if (FocusCursor == NULL) return FALSE; } return TRUE; } void PCJbirdButton::DrawIcon()//选择ico图标 { if(m_bIsEnabled) { switch(m_DrawState) { case ST_MOVEIN: case ST_MOUSEDOWN: case ST_MOUSEUP: { if(m_hMouseInIcon!=NULL) { DrawIcon(m_hMouseInIcon); } } break; case ST_MOVEOUT: { if(m_hNormalIcon!=NULL) DrawIcon(m_hNormalIcon); } break; default: break; } } else { DrawIcon(m_hNormalIcon,TRUE); } } void PCJbirdButton::DrawIcon(HICON hIcon, BOOL bDisabled)//画ico图标 { CRect clientrect; CClientDC dc(this); int cx=::GetSystemMetrics(SM_CXICON); int cy=::GetSystemMetrics(SM_CYICON); int x,y; // the icon's output position. int rectwidth,rectheight; GetClientRect(&clientrect); rectwidth=clientrect.Width (); rectheight=clientrect.Height (); CString itemString; GetWindowText(itemString); if(itemString!="") { switch(m_IconAlign) { case AL_LEFT: // draw the icon left. { x=m_IconXPos; y=(rectheight-cy)/2; break; } case AL_TOP: { x=(rectwidth-cx)/2; y=m_IconYPos; break; } default: break; } } else // If there is not any text,we'll center the icon. { x=(rectwidth-cx)/2; y=(rectheight-cy)/2; } // Draw the icon,as if it is pressed if(m_DrawState==ST_MOUSEDOWN) { x++; y++; } // Draw the icon. if(!bDisabled) { dc.DrawIcon (x,y,hIcon); } else { dc.DrawState(CPoint(x,y),CSize(32,32),hIcon,DST_ICON | DSS_DISABLED,(H BRUSH)NULL); } } void PCJbirdButton::DrawText()//画按钮文本 { CString itemString; CRect clientRect; CClientDC dc(this); GetClientRect(&clientRect); GetWindowText(itemString); // Draw text depend on different state. if(itemString) { // First Get some necessary infomation. CSize size=dc.GetTextExtent (itemString); int rectwidth=clientRect.Width(); int rectheight=clientRect.Height(); int textwidth=size.cx ; int textheight=size.cy ; int iconwidth=::GetSystemMetrics(SM_CXICON); int iconheight=::GetSystemMetrics(SM_CYICON); int x,y; // the position of the text. // Next caculate the text output position. switch(m_IconAlign) { case AL_LEFT: { if(m_bUseIcon==true) { x=m_IconXPos+iconwidth+ (rectwidth-textwidth-m_IconXPos-iconwidth)/2; } else { x=(rectwidth-textwidth)/2; } y=(rectheight-textheight)/2; break; } case AL_TOP: { if(m_bUseIcon==true) { y=m_IconYPos+iconheight+ (rectheight-textheight-m_IconYPos-iconheight)/2; } else { y=(rectheight-textheight)/2; } x=(rectwidth-textwidth)/2; break; } default: break; } // Should we draw the text as if it is disabled? if(!m_bIsEnabled) { // .. Yes.Now draw the text disabled. dc.DrawState(CPoint(x,y),CSize(0,0),itemString,DST_TEXT | DSS_DISA BLED,FALSE,0,(HBRUSH)NULL); } else { switch(m_DrawState) { case ST_MOVEIN: { m_clText=m_clActiveText; } break; case ST_MOVEOUT: { m_clText=m_clNormalText; } break; case ST_MOUSEUP: { m_clText=m_clActiveText; } break; case ST_MOUSEDOWN: { m_clText=m_clNormalText; } break; default: break; } // Draw the text,as if it is pressed if(m_DrawState==ST_MOUSEDOWN) { x++; y++; } dc.SetTextColor(m_clText); dc.SetBkMode(TRANSPARENT); dc.TextOut (x,y,itemString); } } } void PCJbirdButton::SetIcon(UINT nNormal, UINT nMouseIn) { m_hNormalIcon=AfxGetApp()->LoadIcon(nNormal); m_hMouseInIcon=AfxGetApp()->LoadIcon(nMouseIn); m_bUseIcon=true; } void PCJbirdButton::SetIcon(HICON hNormal, HICON hMouseIn) { m_hNormalIcon=hNormal; m_hMouseInIcon=hMouseIn; m_bUseIcon=true; } void PCJbirdButton::SetActiveTextColor(COLORREF color) { m_clActiveText=color; Draw(); } void PCJbirdButton::SetAlign(int nAlign) { m_IconAlign=nAlign; Draw(); } void PCJbirdButton::SetIconXPos(int x) { m_IconXPos=x; Draw(); } void PCJbirdButton::SetIconYPos(int y) { m_IconYPos=y; Draw(); } void PCJbirdButton::SetMouseDownTextColor(COLORREF color) { m_clMouseDownText=color; Draw(); } void PCJbirdButton::SetNormalTextColor(COLORREF color) { m_clNormalText=color; Draw(); } void PCJbirdButton::OnKillFocus(CWnd* pNewWnd) { CButton::OnKillFocus(pNewWnd); m_DrawState=ST_MOVEOUT; //Invalidate(); //ReleaseCapture(); // TODO: Add your message handler code here } -- 我本是那漂泊在万里长江中的蓬草,随风远飘,万里独行,不知江月待何人,但见长江送流水。 ※ 来源:·珞珈山水BBS站 http://bbs.whu.edu.cn·[FROM: 222.20.236.*] |
| [返回单文区目录] |
|
|