最近在看<<Windows环境下32位汇编语言程序设计>>这本书。与其说在看汇编,更像是在看windows sdk.这本书基本上就是<<Windows程序设计>>的汇编版。但是我觉得这本书比<<Windows程序设计>>看起来更舒服,也许是那本书是翻译过来的原因吧,总觉得看起来没有这本书说得透彻。
看了7、8章,收获非常大,都是win32 api方面的收获。具体的知识点就不罗列了,总的说有几个关键性的技术比一下了解了,感觉很爽。当然,收获大也跟自己太菜的原因有关,要是我特别牛奔,早就啥都知道了,看啥也就都不会觉得有收获了~
比较让我兴奋的,是创建不规则窗口、窗口的随意拖动等东西。这些东西书上都有例子,照着例子按也不觉得如何复杂。创建不规则窗口主要依赖SetWindowRgn这个API.窗口能够不规则了,按钮可不可以呢?
直接给按钮这个子窗口SetWindowRgn是行不通的。
上网上搜索了许多不规则按钮,都是MFC的例子,没有SDK的,于是自己琢磨了琢磨,也上网上提问了,终于解决了问题。
给子窗口设置形状,依然需要SetWindowRgn.
但是区别在于,子窗口都包含CS_PARENTDC,需要把这个东西从Class中去除,才能使得SetWindowRgn生效.
步骤
1.GetClassLong,取出Style,
2.Style=Style and (not CS_PARENTDC)
3.SetClassLong,设置为新的Style
做完了这3步骤,就可以像设置对话框一样形状一样,SetWindowRgn了~
汇编代码主要是这几句
; Get handle of btn
invoke GetDlgItem,hWnd,IDC_NOTBLOCK
mov @hBtn,eax
; Delete CS_PARENTDC from btn
invoke GetClassLong,@hBtn,GCL_STYLE
mov @BtnStyle,eax
mov eax,0ffffH
xor eax,CS_PARENTDC
and @BtnStyle,eax
invoke SetClassLong,@hBtn,GCL_STYLE,@BtnStyle
; Set btn's region
invoke CreateEllipticRgn,0,0,130,130
push eax
invoke SetWindowRgn,@hBtn,eax,FALSE
pop eax
invoke DeleteObject,eax
这里面有个值得注意的地方,
那就是 Set/GetClassLong和Set/GetWindowLong的区别。把SetClassLong换成SetWindowLong就不管用了。
网上许多地方都说,这两个的区别,一个是设置整个所有类的属性,另外一个是设置单个窗口的。我到现在也不是很理解,也非常希望路过的高人给我留言指点指点。
说说自己的猜测吧:
SetWindowLong能够修改除了类别以外,所能控制的属性
SetClassLong能够修改类别而决定的属性
而且还可能是因为
只有CS_PARENTDC(Class Style)
而没有 "WS_PARENTDC",
所以只能 SetClassLong来消除掉这个属性
上代码:
ns.rc
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#include <resource.h>
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#define DLG_MAIN 1000
#define IDC_NOTBLOCK 1001
#define IDB_BACK 100
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
IDB_BACK BITMAP "back.bmp"
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
DLG_MAIN DIALOG 100,100,200,200
STYLE DS_MODALFRAME|WS_POPUP|WS_VISIBLE|WS_CAPTION|WS_SYSMENU
CAPTION "MiaoLearn"
FONT 9,"宋体"
{
PUSHBUTTON "我不是方块!",IDC_NOTBLOCK,50,50,100,100
}
ns.asm
.386
.model flat,stdcall
option casemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.inc
include kernel32.inc
includelib kernel32.lib
include user32.inc
includelib user32.lib
include gdi32.inc
includelib gdi32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
DLG_MAIN equ 1000
IDC_NOTBLOCK equ 1001
IDB_BACK equ 100
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
hInstance dd ?
hDlgMain dd ?
hBmpBack dd ?
hBrushBack dd ?
.const
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcDlgMain proc uses ebx edi esi hWnd,wMsg,wParam,lParam
LOCAL @hDc
LOCAL @stPs:PAINTSTRUCT
LOCAL @hBtn
LOCAL @BtnStyle
mov eax,wMsg
.if eax==WM_INITDIALOG
push hWnd
pop hDlgMain
; Get handle of btn
invoke GetDlgItem,hWnd,IDC_NOTBLOCK
mov @hBtn,eax
; Delete CS_PARENTDC from btn
invoke GetClassLong,@hBtn,GCL_STYLE
mov @BtnStyle,eax
mov eax,0ffffH
xor eax,CS_PARENTDC
and @BtnStyle,eax
invoke SetClassLong,@hBtn,GCL_STYLE,@BtnStyle
; Set btn's region
invoke CreateEllipticRgn,0,0,130,130
push eax
invoke SetWindowRgn,@hBtn,eax,FALSE
pop eax
invoke DeleteObject,eax
.elseif eax==WM_PAINT
; draw a background for seeing result
invoke BeginPaint,hWnd,addr @stPs
mov @hDc,eax
invoke LoadBitmap,hInstance,IDB_BACK
mov hBmpBack,eax
invoke CreatePatternBrush,hBmpBack
mov hBrushBack,eax
invoke SelectObject,@hDc,hBrushBack
invoke PatBlt,@hDc,0,0,300,300,PATCOPY
invoke DeleteObject,eax
invoke EndPaint,hWnd,addr @stPs
.elseif eax==WM_CLOSE
invoke DeleteObject,hBmpBack
invoke EndDialog,hWnd,NULL
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
_ProcDlgMain endp
start:
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke DialogBoxParam,hInstance,DLG_MAIN,NULL,_ProcDlgMain,NULL
invoke ExitProcess,NULL
end start
截图:
ns.exe
Ps:
为了便于观察,给了DIALOG一个背景.中间那个圆形的是按钮,可以点的……
如果想用位图绘制按钮,就在父窗口里处理WM_DRAWITEM事件即可。
如果想实现一个比较复杂的窗口,可以控制Rgn,具体可以参考Rgn相关的API.
本想把这个实例做复杂点,把最近觉得新鲜的东西全用上,但是时间有限啊~
而且我想做的其它功能书上都有,就择出来这个书上没提的功能,把它说清楚吧
再ps:
本来打算和小静静十一期间浪漫浪漫的,但是限制于各种因素,没浪起来…………
但是咱们那天去怀柔,玩的也挺好的。
最近的小静静很烦....都在烦些什么呢?
1.十一休息完了,又该上班了,小静静迎来了不爽期。
2.因为一下要上7天班,导致小静静一直愁眉苦脸;
3.再加上胃疼、肚子疼、牙碎等身体因素困扰小静静,小静静的心情更是雪上加霜了;
4.再再加上小静静总觉得自己胖了(其实一点也没有),所以小静静的心情一下跌落到了谷底。
乖乖的小静静呀~
咱们周六就去医院看看你的胃、肚子和牙,
然后咱们跑跑步锻炼锻炼,别不高兴了~
至于上班连续7天……
这个没办法了,还请可爱的小静静再忍忍吧!
小静静不爽没有关系,我最大的兴趣爱好同时也是我所有课余时间都投身的事业,就是当小静静的出气筒阿!!
有啥不爽就来A我吧!!