里面用到了很多常用的技巧
//////////////////////////////////////////////////////////////////////////////// 1、单字节字符转化为双字节字符 ... WCHAR str[256]; ZeroMemory( str , 256 );
CString stra; this->GetWindowText( stra );
int len = sizeof( stra.GetBuffer() ); MultiByteToWideChar( CP_ACP , 0 , (LPCSTR)stra.GetBuffer() , len , str , len ); ... 与 MultiByteToWideChar() 对应的,有一个 WideCharToMultiByte() 后者把双字节字符转为单字节GDI+编程中经常用到 char szANSIString[MAX_PATH]; WideCharToMultiByte( CP_ACP , WC_COMPOSITECHECK , wszSomeString , -1 , szANSIString , sizeof( szANSIString ) , NULL , NULL );
这里有一个A2W与W2A宏 char temp[] = "how are you"; USES_CONVERSION; LPWSTR string = A2W( temp ); ... USES_CONVERSION; szANSIString = W2A( wszSomeString );
参考资料: 《精通GDI+编程》清华大学出版社
//////////////////////////////////////////////////////////////////////////////// 2、当鼠标进入按钮区域后,又移动时,检测指针是否移出了该区域
当鼠村进入按钮区域并移动时,会触发 OnMouseMove() 事件 这时你可以用 ::SetCapture( this->GetSafeHwnd() ); 把鼠标梆定到该按钮 这样在 OnMouseMove() 事件处理函数中,可以检测出指针是否已经离开区域 ... CRect rect; GetClientRect( rect ); BOOL ptIn = rect.PtInRect( point ); ... if( !ptIn ) { //哈哈,鼠标已经移出按钮区域啦 //你可以用 ::ReleaseCapture(); //释放刚才的梆定 } 具体可以看下面的代码,要结合上下文才能理解噢!
////////////////////////////////////////////////////////////////////////////////
文件: d1_dynamicBtn.h d1_dynamicBtn.cpp 定义按钮外形、鼠标移动到上面时色彩的变化。
文件: userBtn1.h userBtn1.cpp 继承 class d1_dynamicBtn 里面只需实现 构造函数 及 响应必要的按钮行为,如clicked
源文件
//////////////////////////////////////////////////////////////////////////////// // d1_dynamicBtn.h // 程序员:黄江斌 // 功能:动态按钮类声明 // 时间:20:05 2005-10-1 // 最后修改时间:20:05 2005-10-1 ////////////////////////////////////////////////////////////////////////////////
#pragma once
// d1_dynamicBtn
class d1_dynamicBtn : public CButton { DECLARE_DYNAMIC(d1_dynamicBtn)
public: //定义是不创建,要在下文中创建按钮 d1_dynamicBtn(); //定义对象时创建按钮 d1_dynamicBtn( LPCTSTR lpszCaption , DWORD dwStyle , const RECT &rect , CWnd *pParentWnd , UINT nID ); //定义对象时创建按钮,并且指定配方方案 d1_dynamicBtn( LPCTSTR lpszCaption , DWORD dwStyle , const RECT &rect , CWnd *pParentWnd , UINT nID , Color colorLeveal , Color colorEnter , Color colorDown , Color colorFont );
virtual ~d1_dynamicBtn(); public: void SetColor( Color colorLeavel , Color colorEnter , Color colorDown , Color colorFont ); private: //变量初始化,每个构造函数都要调用 void init(); private: Color *m_colorLeavel; Color *m_colorEnter; Color *m_colorDown; Color *m_colorFont; //按钮当前状态
//0鼠标没有进入按钮区,或已经离开 //1鼠标进入按钮区 //2鼠标被按下 int m_nState; //为 m_nState 定义的常量 static const int MOUSE_LEAVEL = 0; static const int MOUSE_ENTER = 1; static const int MOUSE_DOWN = 2; protected: DECLARE_MESSAGE_MAP() public: afx_msg void OnPaint(); virtual BOOL Create(LPCTSTR lpszCaption, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID); afx_msg void OnMouseMove(UINT nFlags, CPoint point); afx_msg void OnLButtonDown(UINT nFlags, CPoint point); afx_msg void OnLButtonUp(UINT nFlags, CPoint point); };
//////////////////////////////////////////////////////////////////////////////// // d1_dynamicBtn.cpp // 程序员:黄江斌 // 功能:动态按钮类实现 // 时间:20:05 2005-10-1 // 最后修改时间:20:05 2005-10-1 ////////////////////////////////////////////////////////////////////////////////
// d1_dynamicBtn.cpp : 实现文件 //
#include "stdafx.h" #include "d1_dynamicBtn.h"
// d1_dynamicBtn
IMPLEMENT_DYNAMIC(d1_dynamicBtn, CButton)
//构造函数
//定义是不创建,要在下文中创建按钮 d1_dynamicBtn::d1_dynamicBtn() { this->init(); this->m_colorLeavel = new Color( 255 , 0 , 0 , 0 ); this->m_colorEnter = new Color( 255 , 255 , 0 , 0 ); this->m_colorDown = new Color( 255 , 255 , 0 , 0 ); this->m_colorFont = new Color( 255 , 255 , 255 , 255 ); } //定义对象时创建按钮 d1_dynamicBtn::d1_dynamicBtn( LPCTSTR lpszCaption , DWORD dwStyle , const RECT &rect , CWnd *pParentWnd , UINT nID ) { this->init(); this->m_colorLeavel = new Color( 255 , 0 , 0 , 0 ); this->m_colorEnter = new Color( 255 , 255 , 0 , 0 ); this->m_colorDown = new Color( 255 , 255 , 0 , 0 ); this->m_colorFont = new Color( 255 , 255 , 255 , 255 );
this->Create( lpszCaption , dwStyle , rect , pParentWnd , nID );
} //定义对象时创建按钮,并且指定配方方案 d1_dynamicBtn::d1_dynamicBtn( LPCTSTR lpszCaption , DWORD dwStyle , const RECT &rect , CWnd *pParentWnd , UINT nID , Color colorLeavel , Color colorEnter , Color colorDown , Color colorFont ) { this->init();
this->m_colorLeavel = new Color( colorLeavel.GetA() , colorLeavel.GetR() , colorLeavel.GetG() , colorLeavel.GetB() ); this->m_colorEnter = new Color( colorEnter.GetA() , colorEnter.GetR() , colorEnter.GetG() , colorEnter.GetB() ); this->m_colorDown = new Color( colorDown.GetA() , colorDown.GetR() , colorDown.GetG() , colorDown.GetB() ); this->m_colorFont = new Color( colorFont.GetA() , colorFont.GetR() , colorFont.GetG() , colorFont.GetB() );
this->Create( lpszCaption , dwStyle , rect , pParentWnd , nID ); } d1_dynamicBtn::~d1_dynamicBtn() { delete this->m_colorLeavel; delete this->m_colorEnter; delete this->m_colorDown; delete this->m_colorFont; }
BEGIN_MESSAGE_MAP(d1_dynamicBtn, CButton) ON_WM_PAINT() ON_WM_MOUSEMOVE() ON_WM_LBUTTONDOWN() ON_WM_LBUTTONUP() END_MESSAGE_MAP()
//自定义函数
//函数名:private void init() //功能:变量初始化,每个构造函数都要调用 void d1_dynamicBtn::init() { this->m_nState = 0; } // //函数名:public void SetColor() //功能:设定按三种状态下的色彩值 void d1_dynamicBtn::SetColor( Color colorLeavel , Color colorEnter , Color colorDown , Color colorFont ) { this->m_colorLeavel->SetValue( colorLeavel.GetValue() ); this->m_colorEnter->SetValue( colorEnter.GetValue() ); this->m_colorDown->SetValue( colorDown.GetValue() ); this->m_colorFont->SetValue( colorFont.GetValue() );
this->Invalidate(); } // // d1_dynamicBtn 消息处理程序
void d1_dynamicBtn::OnPaint() { CPaintDC dc(this); // device context for painting // TODO: 在此处添加消息处理程序代码 // 不为绘图消息调用 CButton::OnPaint() Graphics graphics( dc.m_hDC ); SolidBrush *brush; switch( this->m_nState ) { case 0: brush = new SolidBrush( *this->m_colorLeavel ); break; case 1: brush = new SolidBrush( *this->m_colorEnter ); break; case 2: brush = new SolidBrush( *this->m_colorDown ); break; }
CRect rect; GetClientRect( rect ); RectF rectf( rect.left , rect.top , rect.Width() , rect.Height() ); graphics.FillRectangle( brush , rectf );
SolidBrush fontBrush( *this->m_colorFont ); Pen pen( &fontBrush , 10 ); graphics.DrawRectangle( &pen , rectf );
WCHAR str[256]; ZeroMemory( str , 256 );
CString stra; this->GetWindowText( stra );
int len = sizeof( stra.GetBuffer() ); MultiByteToWideChar( CP_ACP , 0 , (LPCSTR)stra.GetBuffer() , len , str , len );
Font myFont( L"黑体" , 20 ); RectF layoutRect = rectf; StringFormat format; format.SetAlignment( StringAlignmentCenter ); format.SetLineAlignment( StringAlignmentCenter );
graphics.DrawString( str , wcslen( str ) , &myFont , layoutRect , &format , &fontBrush ); }
BOOL d1_dynamicBtn::Create( LPCTSTR lpszCaption, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID) { // TODO: 在此添加专用代码和/或调用基类 BOOL result = CButton::Create(lpszCaption, dwStyle, rect, pParentWnd, nID); //如果创建成功 if( result ) { //指定按钮为 自定义风格 this->SetButtonStyle( BS_USERBUTTON ); }
return result; }
void d1_dynamicBtn::OnMouseMove(UINT nFlags, CPoint point) { // TODO: 在此添加消息处理程序代码和/或调用[s:292]值 CRect rect; GetClientRect( rect ); BOOL ptIn = rect.PtInRect( point );
if( ptIn && this->m_nState == 0 ) { //鼠标进入按钮区,则设置为进入,并且 SetCapture() this->m_nState = MOUSE_ENTER; this->Invalidate(); ::SetCapture( this->GetSafeHwnd() ); } else if( !ptIn && this->m_nState != 0 ) { //如果鼠标已经离开按钮区,则设置为离开,并且 ReleaseCapture() this->m_nState = MOUSE_LEAVEL; this->Invalidate(); ::ReleaseCapture(); } CButton::OnMouseMove(nFlags, point); }
void d1_dynamicBtn::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: 在此添加消息处理程序代码和/或调用[s:292]值 this->m_nState = MOUSE_DOWN; this->Invalidate();
CButton::OnMButtonDown(nFlags, point); }
void d1_dynamicBtn::OnLButtonUp(UINT nFlags, CPoint point) { // TODO: 在此添加消息处理程序代码和/或调用[s:292]值 CRect rect; GetClientRect( rect ); BOOL ptIn = rect.PtInRect( point );
this->m_nState = MOUSE_LEAVEL; if( !ptIn ) ::ReleaseCapture();
CButton::OnLButtonUp(nFlags, point); }
//////////////////////////////////////////////////////////////////////////////// // userBtn1.h // 程序员:黄江斌 // 功能:动态按钮类应用举例声明部分 // 时间:20:05 2005-10-1 // 最后修改时间:20:05 2005-10-1 ////////////////////////////////////////////////////////////////////////////////
#pragma once #include "d1_dynamicbtn.h"
class myBtn : public d1_dynamicBtn { public: myBtn(void); //定义是不创建,要在下文中创建按钮 //定义对象时创建按钮 myBtn( LPCTSTR lpszCaption , DWORD dwStyle , const RECT &rect , CWnd *pParentWnd , UINT nID ); virtual ~myBtn(void); DECLARE_MESSAGE_MAP() afx_msg void OnBnClicked(); };
//////////////////////////////////////////////////////////////////////////////// // userBtn1.cpp // 程序员:黄江斌 // 功能:动态按钮类应用举例实现 // 时间:20:05 2005-10-1 // 最后修改时间:20:05 2005-10-1 ////////////////////////////////////////////////////////////////////////////////
#include "StdAfx.h" #include ".\userBtn1.h"
myBtn::myBtn(void) { } myBtn::myBtn( LPCTSTR lpszCaption , DWORD dwStyle , const RECT &rect , CWnd *pParentWnd , UINT nID ) : d1_dynamicBtn( lpszCaption , dwStyle , rect , pParentWnd , nID ) { } myBtn::~myBtn(void) { } BEGIN_MESSAGE_MAP(myBtn, d1_dynamicBtn) ON_CONTROL_REFLECT(BN_CLICKED, OnBnClicked) END_MESSAGE_MAP()
void myBtn::OnBnClicked() { // TODO: 在此添加控件通知处理程序代码 AfxMessageBox( "hi" ); } |