⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 button.c

📁 深圳市微逻辑电子有限公司 巨果&#8226 Kingmos&reg 系统核心
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************************************************
Copyright(c) 版权所有,1998-2003微逻辑。保留所有权利。
******************************************************/

/*****************************************************
文件说明:按钮类
版本号:1.0.0
开发时期:2000
作者:李林
修改记录:
******************************************************/

#include <eframe.h>
#include <esymbols.h>
#include <eassert.h>
//#include <gwmesrv.h>


#define GETTYPE( dwStyle ) ( (WORD)((dwStyle)&0xf) )

#define ICON_SIZE 16
#define GSB_CHECKNORMAL 0
#define GSB_CHECKSELECT 1
#define GSB_RADIONORMAL 2
#define GSB_RADIOSELECT 3

// 按钮标志
#define BTF_DISABLEFOCUS  0x0001

typedef struct _BUTTON_ATTRIB{
    WORD btState;  // OFFSET_STATE 0
	WORD btFlag;   //	按钮标志
    HANDLE hImage;  // OFFSET_IMAGE 4
	COLORREF cl_Text;
	COLORREF cl_TextBk;     //正常文本的前景与背景色
	COLORREF cl_Disable;
	COLORREF cl_DisableBk;    // 无效文本的前景与背景色
}BUTTON_ATTRIB, * PBUTTON_ATTRIB;

static void DoOwnerDraw( HDC, HWND hWnd, DWORD state, UINT uiAction );
static void DrawCheckState( HDC, HWND hWnd, DWORD state );
static void DrawPushState( HDC, HWND hWnd, BOOL fDefault, DWORD state );
static void DrawButtonState( HDC, HWND hWnd, DWORD style, DWORD state );

static LRESULT DoPAINT( HWND hWnd );
static LRESULT DoLBUTTONDOWN( HWND hWnd );
static LRESULT DoLBUTTONUP( HWND hWnd, short x, short y );
static LRESULT DoSETFOCUS( HWND hWnd );
static LRESULT DoSETSTATE( HWND hWnd, WPARAM wParam );
static LRESULT DoSETCHECK( HWND hWnd, WPARAM wParam );
static LRESULT WINAPI ButtonWndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);

// 类名
static const char strClassButton[] = "BUTTON"; 

// **************************************************
// 声明:ATOM RegisterButtonClass(HINSTANCE hInst)
// 参数:
//		IN hInst - 实例句柄
// 返回值:
//		假如成功,返回非0值;失败,返回0
// 功能描述:
//		注册按钮类
// 引用: 
//		被sysclass.c 调用
// ************************************************
// register my define class
ATOM RegisterButtonClass(HINSTANCE hInst)
{
	WNDCLASS wc;
	
	//初始化类结构
	wc.hInstance=hInst;
	wc.lpszClassName= strClassButton;
	// the proc is class function
	wc.lpfnWndProc=(WNDPROC)ButtonWndProc;
	wc.style=CS_DBLCLKS|CS_CLASSDC;
	wc.hIcon= 0;
	// 基于笔的窗口,没有光标at pen window, no cursor
	wc.hCursor= 0;//LoadCursor(NULL,IDC_ARROW);
	// to auto erase background, must set a valid brush
	// if 0, you must erase background yourself
	wc.hbrBackground = 0;
	wc.lpszMenuName=0;
	wc.cbClsExtra=0;
	// !!! it's important to save state of button, align to long
	wc.cbWndExtra= sizeof( PBUTTON_ATTRIB );
	
	return RegisterClass(&wc);
}

//#define SEND_NOTIFY( hParent, idCtrl, idNotify, hWnd ) \ 
  //      SendMessage( (hParent), WM_COMMAND, MAKELONG( (idCtrl),  (idNotify) ), (LPARAM)(hWnd) )
// **************************************************
// 声明:static int SendNotify( HWND hParent, UINT uiId, UINT uiNotify, HWND hWnd )
// 参数:
//	IN hParent - 父窗口
//	IN uiId - 窗口id
//	IN uiNotify - 通知消息
//	IN hWnd - 窗口句柄
// 返回值:
//	依赖于具体的消息
// 功能描述:
//	向父窗口发送通知消息
// 引用: 
//	
// ************************************************

static int SendNotify( HWND hParent, UINT uiId, UINT uiNotify, HWND hWnd )
{
    return SendMessage( hParent, WM_COMMAND, MAKELONG( uiId, uiNotify ), (LPARAM)hWnd );
}

// **************************************************
// 声明:static void FillSolidRect( HDC hdc, RECT * lprc, COLORREF clr )
// 参数:
//	IN hdc - 显示设备句柄
//	IN lprc - RECT 结构指针,指向需要填充的矩形
//	IN clr - RGB颜色值
// 返回值:
//	无
// 功能描述:
//	用固定颜色填充举行矩形
// 引用: 
//	
// ************************************************

static void FillSolidRect( HDC hdc, RECT * lprc, COLORREF clr )
{
	SetBkColor( hdc, clr );
	ExtTextOut( hdc, 0, 0, ETO_OPAQUE, lprc, NULL, 0, NULL );
}

// **************************************************
// 声明:static void GetDrawRect(	HDC hdc, 
//									LPCRECT lpClientRect, 
//									LPRECT lpTextRect, 
//									LPRECT lpIconRect, 
//									DWORD dwStyle )
// 参数:
//	IN hdc - 显示设备句柄
//	IN lpClientRect - 矩形指针,指向窗口的客户矩形
//	OUT lpTextRect - 矩形指针,用于接受按钮的文本矩形
//	OUT lpIconRect - 矩形指针,用于接受按钮的图标矩形
//	IN dwStyle - 窗口风格
// 返回值:
//	无
// 功能描述:
//	得到按钮窗口的文本部分矩形和图标部分矩形
// 引用: 
//	
// ************************************************

static void GetDrawRect( HDC hdc, LPCRECT lpClientRect, LPRECT lpTextRect, LPRECT lpIconRect, DWORD dwStyle )
{
    int type  = GETTYPE( dwStyle );  // 得到按钮风格
    
    *lpTextRect = *lpIconRect = *lpClientRect;
    
    if( type == BS_DEFPUSHBUTTON ||
        type == BS_PUSHBUTTON ||
        (dwStyle & BS_PUSHLIKE) )
    {	// 按钮风格
        if( type == BS_DEFPUSHBUTTON )
        {	// 默认按钮风格
            InflateRect( lpTextRect, -1, -1 );
        }
        InflateRect( lpTextRect, -1, -1 );
    }
    else if( type == BS_RADIOBUTTON || type == BS_AUTORADIOBUTTON ||
            type == BS_CHECKBOX || type == BS_AUTOCHECKBOX )
    {	// 单选(自动)按钮 或 复选(自动)按钮
        if( dwStyle & BS_LEFTTEXT )
        {	// 按钮文本在左面, 象:[ ButtonText <icon> ] 
            lpIconRect->left = lpIconRect->right - ICON_SIZE;
            lpTextRect->right = lpIconRect->left;// - 2;
        }
        else
        {	// 按钮文本在右面, 象:[ <icon> ButtonText ] 
            lpIconRect->right = lpIconRect->left + ICON_SIZE;
            lpTextRect->left = lpIconRect->right;// + 2;
        }
		// 设置图标的上下边
        lpIconRect->top = ( lpClientRect->bottom + lpClientRect->top) / 2 - ICON_SIZE / 2;
        lpIconRect->bottom = lpIconRect->top + ICON_SIZE;
    }
    else if( type == BS_GROUPBOX )
    {	// 组框
        TEXTMETRIC tm;
        GetTextMetrics( hdc, &tm );
 
        lpTextRect->left += 8;
        lpTextRect->right -= 8;
        lpTextRect->bottom = (short)(lpTextRect->top + tm.tmHeight);
    }
}

// **************************************************
// 声明:static void DrawRadioBox( HDC hdc, LPCRECT lprectIcon, DWORD state )
// 参数:
//	IN hdc - 显示设备句柄
//	IN lprectIcon - 画单选按钮icon的矩形
//	IN state - 单选按钮的状态
// 返回值:
//	无
// 功能描述:
//	画单选按钮
// 引用: 
//	
// ************************************************

static void DrawRadioBox( HDC hdc, LPCRECT lprectIcon, DWORD state )
{
	int iOldMode;
	BYTE bIcon;

	HFONT hfont = SelectObject( hdc, GetStockObject(SYSTEM_FONT_SYMBOL) );
    iOldMode = SetBkMode( hdc, TRANSPARENT );

    if( state & BST_CHECKED )
        bIcon = SYM_RADIO_SET;
	else
		bIcon = SYM_RADIO_NOSET;
	DrawText( hdc, (LPCTSTR)&bIcon, 1, (LPRECT)lprectIcon, DT_CENTER|DT_VCENTER|DT_SINGLELINE );
    SetBkMode( hdc, iOldMode );
	SelectObject( hdc, hfont );
/*
	HDC hMemDC;
    HBITMAP hBitmap;

	hMemDC = CreateCompatibleDC( hdc );
	if( state & BST_CHECKED )
	    hBitmap = (HBITMAP)SelectObject( hMemDC, GetStockBitmap( GSB_RADIOSELECT ) );
	else
	    hBitmap = (HBITMAP)SelectObject( hMemDC, GetStockBitmap( GSB_RADIONORMAL ) );
	BitBlt( hdc, lprectIcon->left, lprectIcon->top, 8, 8, hMemDC, 0, 0, SRCCOPY );
    SelectObject( hMemDC, hBitmap );
	DeleteDC( hMemDC );
*/
}

// **************************************************
// 声明:static void DrawCheckBox( HDC hdc, LPCRECT lprectIcon, DWORD state )
// 参数:
//  IN hdc -  显示设备句柄
//	IN lprectIcon - 画icon的矩形
//	IN state - 复选按钮的状态
// 返回值:
//	无
// 功能描述:
//	画复选按钮
// 引用: 
//	
// ************************************************

static void DrawCheckBox( HDC hdc, LPCRECT lprectIcon, DWORD state )
{
	int iOldMode;
	BYTE bIcon;
	HFONT hfont = SelectObject( hdc, GetStockObject(SYSTEM_FONT_SYMBOL) );
    iOldMode = SetBkMode( hdc, TRANSPARENT );

    if( state & BST_CHECKED )
        bIcon = SYM_CHECK_SET;
	else
		bIcon = SYM_CHECK_NOSET;
	DrawText( hdc, (LPCTSTR)&bIcon, 1, (LPRECT)lprectIcon, DT_CENTER|DT_VCENTER|DT_SINGLELINE );
	SetBkMode( hdc, iOldMode );
	SelectObject( hdc, hfont );

/*
	HDC hMemDC;
    HBITMAP hBitmap;

	hMemDC = CreateCompatibleDC( hdc );
	if( state & BST_CHECKED )
	    hBitmap = (HBITMAP)SelectObject( hMemDC, GetStockBitmap( GSB_CHECKSELECT ) );
	else
	    hBitmap = (HBITMAP)SelectObject( hMemDC, GetStockBitmap( GSB_CHECKNORMAL ) );
	BitBlt( hdc, lprectIcon->left, lprectIcon->top, 8, 8, hMemDC, 0, 0, SRCCOPY );
    SelectObject( hMemDC, hBitmap );
	DeleteDC( hMemDC );
*/
}

// **************************************************
// 声明:static void DrawButtonState( HDC hdc, HWND hWnd, DWORD style, DWORD state )
// 参数:
//  IN hdc -  显示设备句柄
//	IN hWnd - 窗口句柄
//	IN style - 窗口风格
//	IN state - 状态
// 返回值:
//	无	
// 功能描述:
//	画按钮(包含:check button, radio button...)
// 引用: 
//	
// ************************************************

static void DrawButtonState( HDC hdc, HWND hWnd, DWORD style, DWORD state )
{
	WORD type = GETTYPE( style );
	RECT rectClient, rectText, rectIcon;
	HBRUSH hBrush;
    PBUTTON_ATTRIB pAttrib = (PBUTTON_ATTRIB)GetWindowLong( hWnd, 0 ); // 得到按钮属性结构指针
	BOOL bEnable = IsWindowEnabled( hWnd ); // 
	char strBuf[128];
	char * buf = NULL;
	int l, shift = 0;
	WORD textStyle = 0;

	GetClientRect( hWnd, &rectClient );  // 得到窗口客户矩形
	l = GetWindowTextLength( hWnd );	// 得到窗口文本长度
	if( l < sizeof( strBuf ) )
	{		
	    l = GetWindowText( hWnd, strBuf, sizeof( strBuf ) );	// 得到窗口文本
		buf = strBuf;
	}
	else
	{	// 窗口文本太大,动态分配一个
		l = (l + 1 )* sizeof( char ); 
		buf = malloc( l );
		if( buf )
		{
			GetWindowText( hWnd, buf, l );
		}
		else
			return;
	}

	textStyle = DT_SINGLELINE | DT_VCENTER;
	// 用背景色填充
	if( bEnable )
	    FillSolidRect( hdc, &rectClient, pAttrib->cl_TextBk );  // clear background
	else
		FillSolidRect( hdc, &rectClient, pAttrib->cl_DisableBk );  // clear background
	//	选择空刷子
	hBrush = SelectObject( hdc, GetStockObject( NULL_BRUSH ) );
    GetDrawRect( hdc, &rectClient, &rectText, &rectIcon, style );
	
    if( type == BS_DEFPUSHBUTTON ||
        type == BS_PUSHBUTTON ||
        (style & BS_PUSHLIKE) )
    {	// 按钮
		textStyle |= DT_CENTER;
		// 画边界矩形
        if( type == BS_DEFPUSHBUTTON )
        {	
            Rectangle( hdc, rectClient.left, rectClient.top, rectClient.right, rectClient.bottom );
        }
        if( state & (BST_PUSHED|BST_CHECKED) )  // highlight state( sunken or checked )
        {	// 
            DrawEdge( hdc, &rectClient, BDR_SUNKENOUTER, BF_RECT );
            shift = 1;
        }
        else  // normal state
            DrawEdge( hdc, &rectClient, BDR_RAISEDOUTER, BF_RECT );
    }
	else if( type == BS_RADIOBUTTON || type == BS_AUTORADIOBUTTON )
		DrawRadioBox( hdc, &rectIcon, state );	// 单选按钮
	else if( type == BS_CHECKBOX || type == BS_AUTOCHECKBOX )
		DrawCheckBox( hdc, &rectIcon, state );	// 复选按钮
    else if( type == BS_GROUPBOX )
    {	// 组框
		textStyle |= DT_CENTER;
        rectClient.top += (rectText.bottom - rectText.top) / 2;  
		// 画边框
        DrawEdge( hdc, &rectClient, BDR_SUNKENOUTER, BF_RECT );	//
        // 缩小边框一个点宽
		InflateRect( &rectClient, -1, -1 );
		// 画边框
        DrawEdge( hdc, &rectClient, BDR_RAISEDOUTER, BF_RECT );	//
        // 缩小边框一个点宽
        InflateRect( &rectClient, -1, -1 );        
    }

    if( (state & BST_FOCUS) && type != BS_GROUPBOX )
    {   // 按钮有焦点 has focus
	    DrawFocusRect( hdc, &rectText );
		//InflateRect( &rectText, -1, -1 ); // 2003-06-19, DEL, 这行将使文本产生抖动
	}
   	if( shift )  // move down state
	{	// 使文本产生向下移动的视觉感
        rectText.left += 1;
        rectText.top += 1;
	}
    // draw text or image
    if( style & (BS_BITMAP | BS_ICON) )
    {	// 图象位图按钮
        HANDLE hSave, hImage = pAttrib->hImage;
        if( hImage )
        {
            if( style & BS_BITMAP )
            {   // 位图 BITMAP
                HDC hMemDC = CreateCompatibleDC( hdc ); // 创建内存DC
                hSave = SelectObject( hMemDC, hImage );  // 为内存DC选择输出面
                // 贴图
				BitBlt(
                    hdc,
                    rectText.left,
                    rectText.top,
                    rectText.right - rectText.left,
                    rectText.bottom - rectText.top,
                    hMemDC,
                    0,
                    0,
                    SRCCOPY
                    ); 
				// 恢复
                hSave = SelectObject( hMemDC, hSave );
                DeleteDC( hMemDC );
            }
            else
            {  // 图标 ICON
                DrawIcon( hdc, rectText.left, rectText.top, hImage );
            }
        }
    }
    else
    {	// 文本按钮
		// 检查对齐模式并设置文本输出格式
		if( (style & BS_CENTER) == BS_CENTER )
		{
			textStyle |= DT_CENTER; // 居中
		}
		else
		{
			if( style & BS_LEFT )
			{
				textStyle &= ~DT_CENTER;
				textStyle |= DT_LEFT;  // 左对齐
			}			
			else if( style & BS_RIGHT )
			{
				textStyle &= ~DT_CENTER;
				textStyle |= DT_RIGHT;	// 右对齐
			}
		}			
		if( (style & BS_VCENTER) == BS_VCENTER )
		{
			textStyle |= DT_VCENTER;	// 垂直对齐
		}
		else
		{
			if( style & BS_TOP )
			{
				textStyle &= ~DT_VCENTER;
				textStyle |= DT_TOP;	// 上对齐
			}
			else if( style & BS_BOTTOM )
			{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -