设为首页 加入收藏

TOP

1.4 公共模块设计
2013-10-07 00:16:50 来源: 作者: 【 】 浏览:73
Tags:1.4 公共 模块 设计

1.4  公共模块设计

为了使程序的界面更美观,在本系统中使用钩子函数对按钮控件进行了修改,首先创建一个按钮类CDrawButton类。CDrawButton类的代码如下:

//定义按钮状态
enum ButtonState  {bsNormal,bsHot,bsDown};
//按钮包装类
class CDrawButton 
{
public:
ButtonState  m_State;           //按钮当前状态
WNDPROC  m_OldProc;        //记录按钮的窗口函数
int          m_Flag;           //是否释放关联按钮的CDrawButton对象
static int     m_Style;           //按钮风格
public:
 CDrawButton( )        //构造函数
{
m_State   = bsNormal;     //设置按钮状态
m_OldProc = NULL;       //设置窗口函数
m_Flag    = 0;        //设置按钮风格
}
 virtual ~CDrawButton()      //析构函数
{
m_State   = bsNormal;      //设置按钮状态
m_OldProc = NULL;     //设置窗口函数
};
 LRESULT OnPaint( HWND hWnd )   //绘制窗口时处理函数
{
CWnd* pWnd = CWnd::FromHandle(hWnd);
CPaintDC dc(pWnd);
CString  Text;         //标题
CRect  RC;          //区域
CFont  Font;         //字体
CFont  *pOldFont;    //原字体
CBrush  Brush;        //画笔
CBrush  *pOldBrush;     //原画笔
CPoint  PT(2,2);      

 dc.SetBkMode( TRANSPARENT );   //设置透明
  Font.CreateFont( 12, 0, 0, 0, FW_HEAVY, 0, 0, 0, ANSI_CHARSET, \
OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, \
VARIABLE_PITCH | FF_SWISS, "MS Sans Serif" );  //创建字体
pOldFont = dc.SelectObject( &Font );     //将画笔选入设备环境
if( m_State == bsNormal)        //判断按钮状态
{

if (m_Style==2)
{
CBitmap bmp;
bmp.LoadBitmap(IDB_BKBUTTON);   //加载图片资源
Brush.CreatePatternBrush(&bmp);    //根据图片资源创建画笔
}
else
Brush.CreateSolidBrush( RGB( 200, 200, 200 ) );  //用颜色创建画笔
dc.SetTextColor( RGB( 80, 80, 80) );             //设置文本颜色
}
else if( m_State == bsDown )        //判断按钮是否按下
{
Brush.CreateSolidBrush( RGB( 160, 160, 160 ) );  //用颜色创建画笔
dc.SetTextColor( RGB( 50, 50, 250 ) );        //设置文本颜色
}
else if( m_State == bsHot )        //判断按钮是否热点
{
Brush.CreateSolidBrush( RGB( 100, 100, 180 ) );  //用颜色创建画笔
dc.SetTextColor( RGB( 250, 250, 0 ) );        //设置文本颜色
}

pOldBrush = dc.SelectObject( &Brush );     //将画刷选入设备环境中
pWnd->GetClientRect( &RC );          //获得客户区域
dc.RoundRect( &RC, PT );             //绘制圆角矩形

HRGN hRgn = CreateRectRgn( RC.left, RC.top, RC.right,
RC.bottom );  //创建一个矩形区域
pWnd->SetWindowRgn( hRgn, TRUE );                         //设置窗口区域
DeleteObject( hRgn );

pWnd->GetWindowText(Text );          //获得窗口显示文本
dc.DrawText( Text, &RC, DT_CENTER | DT_VCENTER |
DT_SINGLELINE ); //绘制文本

dc.SelectObject( pOldFont );
dc.SelectObject( pOldBrush );

return TRUE;
}
LRESULT OnLButtonDown( HWND hWnd, UINT nFlags, CPoint point ) 
//鼠标左键按下时处理函数
{
m_State = bsDown;                 //设置按钮状态
SetCapture(hWnd);                  //捕获鼠标
SetFocus(hWnd);                    //设置焦点
  InvalidateRect(hWnd,NULL,TRUE);     //重绘窗口区域
return TRUE;
}

LRESULT OnLButtonUp( HWND hWnd, UINT nFlags, CPoint point ) 
//鼠标左键抬起时处理函数
{
if( m_State != bsNormal )         //判断按钮状态
{
m_State = bsNormal;               //设置按钮状态
ReleaseCapture();                  //释放鼠标
InvalidateRect(hWnd,NULL,TRUE);      //重绘窗口区域
//发送WM_COMMAND消息
   SendMessage( GetParent(hWnd), WM_COMMAND,
GetDlgCtrlID(hWnd), (LPARAM) (hWnd) );
}
return TRUE;
}
 LRESULT LoseFocus(HWND  hWnd)       //失去焦点时处理函数
{
m_State = bsNormal;                              //设置按钮状态
InvalidateRect(hWnd,NULL,TRUE);                 //重绘窗口区域
SendMessage( hWnd, WM_KILLFOCUS, (long)hWnd, 0); //
发送WM_KILLFOCUS消息
return TRUE;
}
 LRESULT OnMouseMove(HWND hWnd, UINT nFlags, CPoint point )
//鼠标移动时处理函数
{
HRGN hRgn = CreateRectRgn( 0, 0, 0, 0 );       //创建矩形区域
GetWindowRgn( hWnd,hRgn );                //获得窗口区域
BOOL ret = PtInRegion( hRgn, point.x, point.y );    
//判断鼠标是否在窗口区域中
if( ret )
{
if( m_State == bsDown)         //判断按钮是否按下
return TRUE;
if( m_State != bsHot )         //判断按钮是否热点
{
m_State = bsHot;                   //设置按钮状态
InvalidateRect(hWnd,NULL,TRUE);     //重绘窗口区域
UpdateWindow(hWnd);              //更新显示窗口
SetCap tare(hWnd);        //捕获鼠标
}
}
else
{
m_State = bsNormal;                //设置按钮状态
InvalidateRect(hWnd,NULL,TRUE);      //重绘按钮区域
ReleaseCapture();                   //释放鼠标

DeleteObject( hRgn );
return TRUE;
}
};

代码贴士

SetBkMode:设置背景模式,值为TRANSPARENT时进行透明处理。

CreateFont:初始化用指定特性定义的CFont对象。

InvalidateRect:屏蔽一个窗口客户区的全部或部分区域,会导致窗口在事件期间部分重画。

SendMessage:将指定的消息发送到一个或多个窗口,此函数为指定的窗口调用窗口程序,直到窗口程序处理完消息再返回。

然后,定义一个新的定义按钮窗口函数,以取代按钮默认的窗口函数,对一些消息进行特殊处理。代码如下:

LRESULT __stdcall DefWindowProc1(HWND hWnd,UINT Msg,
WPARAM wParam, LPARAM lParam )
{
CPoint pt;
CDrawButton *pButton=(CDrawButton*)GetWindowLong(hWnd,
GWL_USERDATA); //获得窗口信息
switch (Msg)
{
case WM_LBUTTONDBLCLK:      //屏蔽双击事件
{
return TRUE;
break;
}
case WM_PAINT:       //绘制窗口事件
{
if (pButton->m_Style>0)
return pButton->OnPaint( hWnd);
else
return  CallWindowProc(pButton->m_OldProc, hWnd,Msg,wParam,lParam);
break;
}
case WM_LBUTTONDOWN:    //鼠标左键按下事件
{
pt.x = LOWORD(lParam);  //鼠标按下的横坐标
pt.y = HIWORD(lParam);   //鼠标按下的纵坐标
if (pButton->m_Style>0)
return pButton->OnLButtonDown( hWnd, 0, pt );
else
return  CallWindowProc(pButton->m_OldProc, hWnd,Msg,wParam,lParam);
break;
}
case WM_LBUTTONUP:     //鼠标左键抬起事件
{
pt.x = LOWORD(lParam);  //鼠标按下的横坐标
pt.y = HIWORD(lParam);   //鼠标按下的纵坐标
if (pButton->m_Style>0)
return pButton->OnLButtonUp( hWnd, 0,pt );
else
return  CallWindowProc(pButton->m_OldProc, hWnd,Msg,wParam,lParam);
break;
}
case WM_MOUSEMOVE:     //鼠标移动事件
{
pt.x = LOWORD(lParam);  //鼠标按下的横坐标
pt.y = HIWORD(lParam);   //鼠标按下的纵坐标
if (pButton->m_Style>0)
return pButton->OnMouseMove(hWnd,0, pt);
else
return  CallWindowProc(pButton->m_OldProc, hWnd,Msg,wParam,lParam);
break;
}
case WM_DESTROY:      //销毁窗口
{    
  WNDPROC procOld=pButton->m_OldProc;
SetWindowLong(hWnd,GWL_WNDPROC,(long)procOld); //恢复原来的窗口函数
CWnd* pWnd = ::CWnd::FromHandle(hWnd);    //将按钮对象与控制块分离
if (pWnd)
{
pWnd->Detach();
}
pButton->m_Flag = 1;
return 1;
}
default :
{
break;
}
}
return CallWindowProc(pButton->m_OldProc, hWnd, Msg, wParam, lParam );
}
定义钩子函数,对按钮类控件进行子类化。代码如下:
LRESULT CALLBACK HOOKProc( int nCode, WPARAM wParam, LPARAM lParam )
{
PCWPSTRUCT wc = (PCWPSTRUCT) lParam;
HWND  hWnd = wc->hwnd;
if( hWnd )
{
char ClassName[MAX_PATH] = "";
GetClassName( hWnd, ClassName, MAX_PATH );   //去掉窗口类名
if( strcmp( ClassName, "Button" ) == 0 )
{
CWnd *pWnd = CWnd::FromHandle( hWnd );
if ( pWnd->GetStyle() & BS_RADIOBUTTON )  //判断单选按钮
{
return 1;
}
if ( pWnd->GetStyle() & BS_CHECKBOX )   //判断复选框
{
return 1;
}
WNDPROC WndProc;
WndProc = (WNDPROC) GetWindowLong( hWnd, GWL_WNDPROC );
CDrawButton *pButton=(CDrawButton*)GetWindowLong(hWnd,GWL_USERDATA);
if (pButton != NULL&& pButton->m_Flag==1 )
{
SetWindowLong(hWnd,GWL_USERDATA,0);      //设置窗口信息
//设置窗口对话框函数地址
SetWindowLong( hWnd, GWL_WNDPROC, (LONG)pButton->m_OldProc );
pButton->m_OldProc = NULL;
delete pButton;
}
else if (pButton == NULL )
{
if( WndProc !=DefWindowProc1 )
{
pButton = new CDrawButton;
pButton->m_OldProc = WndProc;
SetWindowLong(hWnd,GWL_USERDATA,(long)pButton);  //设置窗口信息
WndProc =  (WNDPROC) SetWindowLong( hWnd, GWL_WNDPROC,
(LONG) DefWindowProc1);                  //设置窗口函数地址
}
}
}
}
return CallNextHookEx( hWndHook, nCode, wParam, lParam );
}
定义一个安装钩子的函数RunHook,代码如下:
BOOL  RunHook( HMODULE hModule, DWORD dwThreadID)
{
hWndHook = SetWindowsHookEx(
WH_CALLWNDPROC, (HOOKPROC) HOOKProc,
hModule, dwThreadID ); //安装钩子
return TRUE;
}
定义一个卸载钩子的函数StopHook,代码如下:
BOOL  StopHook()
{
UnhookWindowsHookEx(hWndHook);          //卸载钩子
return TRUE;
}
【责任编辑:夏书 TEL:(010)68476606】

回书目   上一节   下一节

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇1.3.2 系统功能结构 下一篇1.3.5 编码规则

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: