如何在标题栏上添加自己的按钮

如何在标题栏上添加自己的按钮
  Windows 的窗口似乎总是一成不变的,标题栏也是那个老样子。如果用过 ReadBook 的人可能会注意到,在它的标题栏上多出来了两个按钮:全屏、缩小到托盘。跟最小化、最大化、关闭按钮排列在一起,而且功能也相近,让人觉得它们本来就应该是在那的。下面介绍实现原理和细节。图示为示例程序的运行效果,例子
程序运行界面
原理
  标题栏上的按钮并不是标准的按钮子窗口,按钮的按下与弹起效果完全就是两幅位图模拟出来的。为此,我们需要处理 WM_NCPAINT 和 WM_ACTIVATE 消息。首先计算出按钮的位置,利用 GetWindowRect 得到窗口的大小位置,再调用函数 GetSystemMetrics 得到标题栏的高度等系统参数。函数原型比较简单:
  int GetSystemMetrics(
    int nIndex // system metric or configuration setting to retrieve
  );
当需要查询什么时就传递相应的参数给它,下面是我们要用到的参数:
SM_CXFRAME 窗口边框宽度
SM_CYFRAME 窗口边框高度
SM_CXSIZE 标题栏上的按钮宽度
SM_CYSIZE 标题栏上的按钮高度
接着就可以计算出按钮的位置,然后我们就可以根据按钮的状态(按下、弹起)画上相应的位图。好,到这我们已经把按钮显示出来啦。
  按钮显示出来后还要能响应鼠标消息才能真正的起到按钮的作用,我们在这处理鼠标按下的消息,也就是 WM_NCLBUTTONDOWN,还有 WM_NCLBUTTONUP 等。想要实现什么功能都可以在消息里面实现,示例程序中简单的调用函数 invoke SetWindowPos, hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE or SWP_NOMOVE 设置窗口始终处在最上面。按钮按下后还需要绘制响应的按下的位图来模拟按钮按下的样子。

  当我们把鼠标放在关闭按钮上的时候会发现弹出一个提示条“关闭”,我们的自绘按钮如果也具有这个功能弹出一个提示条指示按钮的作用,就完全跟窗口的缺省按钮融合在了一起。通过创建工具提示控件可以做到这一点。

 



.
386
.model flat,stdcall
option
casemap:none
;****************************************************************************************
include c:\masm32\include\windows.inc
include
c:\masm32\include\user32.inc
include
c:\masm32\include\kernel32.inc
include
c:\masm32\include\gdi32.inc
include
c:\masm32\include\comctl32.inc
includelib
c:\masm32\lib\user32.lib
includelib
c:\masm32\lib\kernel32.lib
includelib
c:\masm32\lib\gdi32.lib
includelib
c:\masm32\lib\comctl32.lib
;****************************************************************************************
DlgProc proto :DWORD,:DWORD,:DWORD,:DWORD
DrawNcBtn proto :DWORD
GetNcBtnRect proto :DWORD,:DWORD
;****************************************************************************************
.data
DlgName db
"DLG_MAIN",0
TooltipClassName db
"Tooltips_class32",0
strNcBtn db
"窗口总在最上",0
.data?
hInstance HINSTANCE ?
hToolTip dd ?
;工具提示控件的句柄
bPressed BOOL ? ;标题栏上的自绘按钮是否被按下
.const
IDC_STATIC equ -
1
IDI_MAIN equ
900
IDB_PRESSED equ
901
IDB_UNPRESSED equ
902
;****************************************************************************************
.code
start:
    invoke GetModuleHandle, NULL
    
mov hInstance,eax
    invoke DialogBoxParam,hInstance,addr DlgName,NULL,addr DlgProc,
0
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值