VC++ WIN32 sdk实现按钮自绘详解.
#include "resource.h"
HWND hMainWnd = NULL; //接收主窗口的句柄
HWND hDlgNow = NULL; //接收对话框的句柄
staticHICON hOwnerDrawIcon = NULL; //用作自绘按钮的图标
staticLONG prev_proc; //储存按钮先前的回调函数
staticHICON hIcon = NULL; //对话框图标句柄
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
odInst = hInstance;
WNDCLASS wc;
wc.style = 0;
wc.lpfnWndProc = (WNDPROC)ODWndProc; //定义一个窗口默认函数,这里我们会交由默认窗口函数处理
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(odInst,MAKEINTRESOURCE(IDI_OWNERDRAW));
wc.hCursor = NULL;
wc.hbrBackground = 0;
wc.lpszClassName = "OwnerDraw";
wc.lpszMenuName = NULL;
RegisterClass(&wc);
MSG msg;
HWND onlywin= FindWindow("OwnerDraw","MyOwnerDraw");
if(onlywin)
{
ExitProcess(1);
}
hMainWnd=CreateWindow("OwnerDraw","MyOwnerDraw",WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,0,CW_USEDEFAULT,0,NULL,NULL,hInstance,NULL);
if(!hMainWnd)
{
returnFALSE;
}
hDlgNow = DoMainDlg(hMainWnd);
ShowWindow(hDlgNow, nCmdShow);
while(GetMessage(&msg, NULL, 0, 0))
{
if(NULL == hDlgNow || !IsDialogMessage(hDlgNow, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
returnmsg.wParam;
}
{
return DefWindowProc(hWnd, message, wParam, lParam);//返回系统默认的窗口过程
}
if (onlywin)
{
ExitProcess(1);
}
CW_USEDEFAULT,0,CW_USEDEFAULT,0,NULL,NULL,hInstance,NULL);
ShowWindow(hDlgNow, nCmdShow);
{
DWORD dwErr;
HWND hRet = CreateDialog(odInst, (LPCTSTR)IDD_MAIN_DLG, parent, (DLGPROC)MainDlgProc);
if(hRet == NULL)
dwErr = GetLastError();
return hRet;
}
{
if (NULL == hDlgNow || !IsDialogMessage(hDlgNow, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
if(hIcon == NULL)
hIcon = LoadIcon(odInst, MAKEINTRESOURCE(IDI_OWNERDRAW));
if(hOwnerDrawIcon == NULL)
hOwnerDrawIcon = (HICON)LoadImage(odInst,
MAKEINTRESOURCE(IDI_OWNERDRAW),
IMAGE_ICON,
38,
38,
0);
prev_proc = SetWindowLongPtr(GetDlgItem(hDlg, IDC_ODBUTTON), GWLP_WNDPROC, (LONG)ButtWindProc);
SendMessage(hDlg, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
SetFocus(GetDlgItem(hDlg, IDC_ODBUTTON));
break;
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Dialog"
FONT 10, "System"
BEGIN
DEFPUSHBUTTON "OK",IDOK,193,7,50,14
PUSHBUTTON "Cancel",IDCANCEL,193,24,50,14
CONTROL "OwnerDraw",IDC_ODBUTTON,"Button",BS_OWNERDRAW |
WS_TABSTOP,49,31,79,26
END
{
LPDRAWITEMSTRUCT lpDIS = (LPDRAWITEMSTRUCT) lParam;
//声明一个指向DRAWITEMSTRUCT结构体的指针并将其指向存储着按钮构造信息的lParam
if(lpDIS->CtlID != IDC_ODBUTTON)
return(0);
HDC dc = lpDIS->hDC; //用于按钮绘制的DC
BOOL bIsPressed = (lpDIS->itemState & ODS_SELECTED);
BOOL bIsFocused = (lpDIS->itemState & ODS_FOCUS);
BOOL bIsDisabled = (lpDIS->itemState & ODS_DISABLED);
BOOL bDrawFocusRect = !(lpDIS->itemState & ODS_NOFOCUSRECT);
//判断按钮各种状态的BOOL值
RECT itemRect = lpDIS->rcItem; //按钮的矩形区域
SetBkMode(dc, TRANSPARENT); //设置绘制按钮时的背景状态
if(bIsFocused) //判断按钮是否获得了焦点并对其边框进行处理
{
HBRUSH br = CreateSolidBrush(RGB(0,0,0));
FrameRect(dc, &itemRect, br);
InflateRect(&itemRect, -1, -1);
DeleteObject(br);
} // if
COLORREF crColor = GetSysColor(COLOR_BTNFACE);//得到系统按钮颜色
HBRUSH brBackground = CreateSolidBrush(crColor);//创建画刷
FillRect(dc, &itemRect, brBackground);//绘制按钮
DeleteObject(brBackground);
// 这里画被按下去的按钮
if(bIsPressed)
{
HBRUSH brBtnShadow = CreateSolidBrush(GetSysColor(COLOR_BTNSHADOW));
FrameRect(dc, &itemRect, brBtnShadow);
DeleteObject(brBtnShadow);
}
else //如果没有被按下就这样画
{
UINT uState = DFCS_BUTTONPUSH |
((bIsPressed) ? DFCS_PUSHED : 0);
DrawFrameControl(dc, &itemRect, DFC_BUTTON, uState);
}
charsTitle[100];
GetWindowText(GetDlgItem(hDlg, IDC_ODBUTTON), sTitle, 100);//得到按钮的文本
RECT captionRect = lpDIS->rcItem;//把文本的区域设置为按钮区域
BOOL bHasTitle = (sTitle[0] !='/0');//按钮上是否有文本存在
//这里画按钮上的图标,具体实现见下面
(GetDlgItem(hDlg, IDC_ODBUTTON), &dc, bHasTitle,
&lpDIS->rcItem, &captionRect, bIsPressed, bIsDisabled);
if(bHasTitle)//如果按钮有文本标题
{
// 按钮被按下的处理
if(bIsPressed)
OffsetRect(&captionRect, 1, 1);
// 将文本居中
RECT centerRect = captionRect;
DrawText(dc, sTitle, -1, &captionRect, DT_WORDBREAK | DT_CALCRECT|DT_CENTER);
LONG captionRectWidth = captionRect.right - captionRect.left;
LONG captionRectHeight = captionRect.bottom - captionRect.top;
LONG centerRectWidth = centerRect.right - centerRect.left;
LONG centerRectHeight = centerRect.bottom - centerRect.top;
OffsetRect(&captionRect, (centerRectWidth - captionRectWidth)/2, (centerRectHeight - captionRectHeight)/2);
SetBkMode(dc, TRANSPARENT);
if(bIsDisabled)//如果按钮被禁用
{
OffsetRect(&captionRect, 1, 1);
SetTextColor(dc, ::GetSysColor(COLOR_3DHILIGHT));
DrawText(dc, sTitle, -1, &captionRect, DT_WORDBREAK | DT_CENTER);
OffsetRect(&captionRect, -1, -1);
SetTextColor(dc, ::GetSysColor(COLOR_3DSHADOW));
DrawText(dc, sTitle, -1, &captionRect, DT_WORDBREAK | DT_CENTER);
}
else //如果没被禁用正常画
{
SetTextColor(dc, ::GetSysColor(COLOR_BTNTEXT));
SetBkColor(dc, ::GetSysColor(COLOR_BTNFACE));
DrawText(dc, sTitle, -1, &captionRect, DT_WORDBREAK | DT_CENTER);
}
}
// 画按钮得到焦点时的虚线方框
if(bIsFocused && bDrawFocusRect)
{
RECT focusRect = itemRect;
InflateRect(&focusRect, -3, -3);
DrawFocusRect(dc, &focusRect);
} // if
return(TRUE);
}
break;
{
RECT rImage;
PrepareImageRect(hButtonWnd, bHasTitle, rpItem, rpTitle, bIsPressed, 38, 38, &rImage);
// 调用API函数按准备好的形式将图片画到按钮上
DrawState( *dc,
NULL,
NULL,
(LPARAM)hOwnerDrawIcon,
0,
rImage.left,
rImage.top,
(rImage.right - rImage.left),
(rImage.bottom - rImage.top),
(bIsDisabled ? DSS_DISABLED : DSS_NORMAL) | DST_ICON);
}
{
RECT rBtn;
CopyRect(rpImage, rpItem);
GetClientRect(hButtonWnd, &rBtn);
if (bHasTitle == FALSE)//如果按钮上有文本内容
{
// 使图片水平居中
LONG rpImageWidth = rpImage->right - rpImage->left;
rpImage->left += ((rpImageWidth - (long)dwWidth)/2);
}
else
{ //控制图片与焦点方框内部
LONG rpTitleWidth = rpTitle->right - rpTitle->left;
rpTitle->right = rpTitleWidth - dwWidth - 30;
rpTitle->left = 30;
rpImage->left = rBtn.right - dwWidth - 22;
LONG rpImageHeight = rpImage->bottom - rpImage->top;
rpImage->top += ((rpImageHeight - (long)dwHeight)/2);
}
if(bIsPressed)//按钮被按下的处理
OffsetRect(rpImage, 1, 1);
}
HWND hWnd, //window handle
UINT message, // type of message
WPARAM wParam, // additional information
LPARAM lParam) //additional information
{
switch (message)
{
case WM_LBUTTONDBLCLK:
PostMessage(hWnd, WM_LBUTTONDOWN, wParam, lParam);
break;
}
//将不做处理的消息路由给原默认函数
returnCallWindowProc((WNDPROC)prev_proc, hWnd, message, wParam, lParam);
}
DefWindowProc(hDlg, message, wParam, lParam);
break;
case WM_SYSCOMMAND:
{
return DefWindowProc(hDlg, message, wParam, lParam);
}
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDCANCEL:
case IDOK:
DestroyIcon(hOwnerDrawIcon);
PostQuitMessage(0);
return TRUE;
}//switch
break;
VC++ WIN32 sdk实现按钮自绘详解.相关推荐
- php 工商银行公众号支付代码_微信支付PHP SDK —— 公众号支付代码详解
在微信支付 开发者文档页面 下载最新的 php SDK 这里假设你已经申请完微信支付 1. 微信后台配置 如图 我们先进行测试,所以先把测试授权目录和 测试白名单添加上.测试授权目录是你要发起微信请 ...
- php 微信支付开发测试,微信支付PHP SDK —— 公众号支付代码详解
在微信支付 开发者文档页面 下载最新的 php sdk 这里假设你已经申请完微信支付 1. 微信后台配置 如图 我们先进行测试,所以先把测试授权目录和 测试白名单添加上.测试授权目录是你要发起微信请 ...
- Android之高德地图SDK配置及简单使用详解
需要用到的东西请去高德地图API官网下载 本次教程是对比着高德官网的demo一步步添加东西,所以需要有一份demo就够了. 1.打开高德地图的demo(AMap3DDemo),同时新建一个项目 2.将 ...
- android饿了么购物车,Android仿饿了么加入购物车旋转控件自带闪转腾挪动画的按钮效果(实例详解)...
概述 在上文,酷炫Path动画已经预告了,今天给大家带来的是利用 纯自定义View,实现的仿饿了么加入购物车控件,自带闪转腾挪动画的按钮. 效果图如下: 图1 项目中使用的效果,考虑到了View的回收 ...
- js点击取消按钮关闭当前弹框_UI设计中“取消按钮”的分析详解
按钮,无论是在 Web 还是 App 上都被广泛地使用,而很少有设计师会注意到按钮当中的细节,导致在设计过程中出现一些低级的错误,使得用户在完成任务的过程中产生阻碍,无法顺利达成目的. 在许多优秀的产 ...
- RT5350原厂SDK及AP移植步骤详解
最近想搞一下rt5350,所以找了个原厂的SDK包进行了编译,很快路由器就可以用了,把我的编译操作步骤写了下分享给更多的爱好者,供大家参靠,下一步准备移植摄像头玩玩.有兴趣的可以一起交流. RT535 ...
- 微信小程序按钮Button使用详解
最近在出微信小程序系列教程 顺手写了点博客 欢迎大家关注 button 用来实现按钮点击效果,本文章效果如下: 1 wxml 文件中 在这里我就放了三个普通的按钮 <view class=&qu ...
- python tkinter button_Python连载60-Tkinter布局、按钮以及属性详解
一.Tkinter 1.组件的大致使用步骤 (1)创建总面板 (2)创建面板上的各种组件: i.指定组件的父组件,即依附关系:ii.利用相应的属性对组件进行设置:iii.给组件安排布局. (3)同步 ...
- win7 更新android sdk,大神为你详解win7系统android sdk manager无法更新的处理对策
随着电脑的使用率越来越高,我们有时候可能会遇到win7系统android sdk manager无法更新问题,如果我们遇到了win7系统android sdk manager无法更新的问题,要怎么处理 ...
最新文章
- AMNO.6 给出一个不多于5位的整数,要求 1、求出它是几位数 2、分别输出每一位数字 3、按逆序输出各位数字,例如原数为321,应输出123 输入 一个不大于5位的数字
- Maven让资源文件处理插件能够解析资源文件中的Maven属性
- Spring第二讲--利用组件注解符精简Spring配置文件
- NYOJ 904 search 二分查找
- VTK:PolyData之ExtractCellsUsingPoints
- 【bzoj4566】[Haoi2016]找相同字符【后缀自动机】
- win7磁盘设置背景方法
- eclipse 安装和使用AmaterasUML
- pip 安装 opencv
- SpringSecurity应用(二)
- 节选转载:你敢向代码库中添加Boost你就等着被开除吧
- Maven的Snapshot版本与Release版本
- UVA 10247 Complete Tree Labeling
- 为了苦苦寻觅视频素材的你,我们整理了 9 个版权视频网站
- R7 7735HS参数 锐龙77735HS怎么样相当于什么水平级别
- Unable to preventDefault inside passive event listener due to target being treated as passive 怎么办?
- 360权重 360网站权重查询在哪里
- Metal 框架之从可绘制纹理中读取像素数据
- Vue中的@blur事件
- regsvr32 命令使用和regsvr32 dll失败原因介绍