windows sdk 根据位图,动态创建不规则窗口
2011-10-19 22:35
561 查看
<<windows环境下32位汇编语言程序设计>>里面有个小时钟的程序,提供了原始位图和mask位图,可以选定一种透明色,从而动态绘制出不规则的图案.最后踢了一句,说那个mask位图可以不用资源的,可以动态创建那个mask的位图.他指的方法当然不是用TransparentBlt,而是用GetPixel一个点一个点的去判断.
前几天折腾了一会,结合这个GetPixel的启示,作了一个根据位图,动态创建不规则窗口的例子.
原理很简单:
改变wnd的形状,当然还是需要核心的SetWindowRgn.
创建复杂的窗口形状,需要创建复杂形状的Rgn.这就需要一些规则的Rgn,用CombineRgn()把它们Combine起来
当然,你自己画Path,再PathToRgn也可以。但是这个例子里面还是CombineRgn()各个规则的Rgn
主要步骤
1.准备bmp位图一张,把你不需要的部分染色,MaskColor
这里我用这个小兔兔,设置MaskColor是黑色,黑色的COLORREF竖直应该是0,具体可以在MSDN上查COLORREF怎么表示颜色的
2.把位图读取到dc中
3.创建一个dc大小的OriginRgn
4.循环此位图的各个像素点,察看像素的RGB。这里用到GetPixel()这个API
如果是你要去掉的MaskColor,就CreateRectRgn,设置宽高分别是1像素,并CombineRgn到DelRgn上
5.此时DelRgn是要去掉的所有Rgn 的 CombineRgn后的 Rgn ,OriginRgn是原图片大小的Rgn
这时候再CombineRgn,取两个Rgn不同的Rgn作为结果即可
这里用到 CombineRgn的参数 RGN_XOR,取异或。具体可以查MSDN这个函数怎么用
6.SetWindowRgn,把结果Rgn用上。
主要的汇编代码是这么几句,需要的话可以自行翻译成C或者C++ :
下面是源代码
gj.rc
gj.asm
效果图
有点花哨,中间那个小兔兔就是程序的窗口了~
顺便说一下 上面的代码里,
WM_LBUTTONDOWN的部分,是按下鼠标左键,可以拖动窗口的功能。
采用的是转发 WM_NCLBUTTONDOWN+HTCAPTION的原理,就是欺骗WINDOWS,说我点的是标题栏。
总结一下这个例子,
本身就是API的堆积,思想很简单.
但是实现的时候有个地方卡勒好久,就是用汇编计算坐标的时候.
汇编里面的变量不像C语言这种高级语言,能够按照想像中的工作.
比如坐标值+1,最后却出现了一个非常非常大的数值.
而我这里又没法Debug win32 asm程序,这个错误调试了两个小时才发现..
汇编语言处处是坑阿~~!
在网上搜索到一篇文章,VC 6.0 倒是可以 单步调试 win32汇编,
可惜又没有语法高亮,又没有语法提示,反而到不如RadAsm
可RadAsm的Debug工具竟然是OllyDbg!!这东西.....暂时还不会用,还得学习啊....
比 VC 里的Debug工具可难用多了.
真希望能够找到一个好的 win32 asm开发环境.
不过我觉得以后还是很有必要学习学习用OllyDbg来调试程序的,
如果现在就用OllyDbg调试自己的程序,将来用它来破解软件,肯定是轻车熟路了!
恩,有空的时候还得加把劲学习啊!
OK, OVER .
PS:
本来打算在等小静静的时候,学习点新的东西的。
但是实在是太困了,没精神,学习不下去呀。。
小静静几点下班亚,困死我了………………
这个小兔子的窗口,名字就叫兔兔兔,和小静静的名字一样,哈哈~
前几天折腾了一会,结合这个GetPixel的启示,作了一个根据位图,动态创建不规则窗口的例子.
原理很简单:
改变wnd的形状,当然还是需要核心的SetWindowRgn.
创建复杂的窗口形状,需要创建复杂形状的Rgn.这就需要一些规则的Rgn,用CombineRgn()把它们Combine起来
当然,你自己画Path,再PathToRgn也可以。但是这个例子里面还是CombineRgn()各个规则的Rgn
主要步骤
1.准备bmp位图一张,把你不需要的部分染色,MaskColor
这里我用这个小兔兔,设置MaskColor是黑色,黑色的COLORREF竖直应该是0,具体可以在MSDN上查COLORREF怎么表示颜色的
2.把位图读取到dc中
3.创建一个dc大小的OriginRgn
4.循环此位图的各个像素点,察看像素的RGB。这里用到GetPixel()这个API
如果是你要去掉的MaskColor,就CreateRectRgn,设置宽高分别是1像素,并CombineRgn到DelRgn上
5.此时DelRgn是要去掉的所有Rgn 的 CombineRgn后的 Rgn ,OriginRgn是原图片大小的Rgn
这时候再CombineRgn,取两个Rgn不同的Rgn作为结果即可
这里用到 CombineRgn的参数 RGN_XOR,取异或。具体可以查MSDN这个函数怎么用
6.SetWindowRgn,把结果Rgn用上。
主要的汇编代码是这么几句,需要的话可以自行翻译成C或者C++ :
invoke CreateRectRgn,0,0,100,100 mov @hRgnResult,eax mov @TempRgnX,0 mov @TempRgnY,0 mov @CurX,0 mov @CurY,0 .while TRUE .break .if @CurY>200 .while TRUE .break .if @CurX>200 invoke GetPixel,hDcDraw,@CurX,@CurY mov ebx,eax .if eax==COLOR_MASK ;invoke wsprintf,addr @szBuffer,addr szFormat,@CurX,@CurY ;invoke MessageBox,NULL,addr @szBuffer,addr @szBuffer,MB_OK mov eax,@CurX inc eax mov @TempRgnX,eax mov eax,@CurY inc eax mov @TempRgnY,eax invoke CreateRectRgn,@CurX,@CurY,@TempRgnX,@TempRgnY mov ebx,eax .if ebx==0 invoke MessageBox,NULL,addr szRgnFail,addr szRgnFail,MB_OK .endif invoke CombineRgn,@hRgnResult,@hRgnResult,ebx,RGN_XOR .endif inc @CurX .endw mov @CurX,0 inc @CurY .endw invoke SetWindowRgn,hWinMain,@hRgnResult,TRUE
下面是源代码
gj.rc
#include <resource.h> //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> #define IDB_TEST 100 //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> IDB_TEST BITMAP "mimic2.bmp" //IDB_TEST BITMAP "gj.bmp"
gj.asm
.386
.model flat,stdcall
option casemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
include gdi32.inc
includelib gdi32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
IDB_TEST equ 100
COLOR_MASK equ 0 ; COLORREF 0x00bbggrr
;COLOR_MASK equ 0111111h ; COLORREF 0x00bbggrr
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
hInstance dd ?
hWinMain dd ?
hBmpTest dd ?
hDcDraw dd ?
.const
szClassName db 'miaoclass',0
szFormat db '(%d,%d)',0
szDebug db 'debug',0
szRgnFail db 'fail!',0
szERRORAPI db 'ERRORAPI',0
szCOMPLEXREGION db 'COMPLEXREGION',0
szSIMPLEREGION db 'SIMPLEREGION',0
szNULLREGION db 'NULLREGION',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcWinMain proc uses ebx edi esi hWnd,uMsg,wParam,lParam
LOCAL @hDc
LOCAL @stPs:PAINTSTRUCT
LOCAL @szBuffer[100]:byte
LOCAL @hRgnResult
LOCAL @CurX,@CurY
LOCAL @TempRgnX,@TempRgnY
mov eax,uMsg
.if eax==WM_CREATE
push hWnd
pop hWinMain
; load bitmap
invoke LoadBitmap,hInstance,IDB_TEST
mov hBmpTest,eax
; create buffer dc
invoke GetDC,hWnd
mov @hDc,eax
invoke CreateCompatibleDC,@hDc
mov hDcDraw,eax
invoke ReleaseDC,hWnd,@hDc
; draw sth. on bufferdc
invoke SelectObject,hDcDraw,hBmpTest
;invoke CreateEllipticRgn,0,0,100,100
;mov @hRgnResult,eax
;invoke CreateEllipticRgn,150,150,200,200
;invoke CombineRgn,@hRgnResult,@hRgnResult,eax,RGN_OR
;invoke SetWindowRgn,hWnd,@hRgnResult,FALSE
invoke CreateRectRgn,0,0,100,100 mov @hRgnResult,eax mov @TempRgnX,0 mov @TempRgnY,0 mov @CurX,0 mov @CurY,0 .while TRUE .break .if @CurY>200 .while TRUE .break .if @CurX>200 invoke GetPixel,hDcDraw,@CurX,@CurY mov ebx,eax .if eax==COLOR_MASK ;invoke wsprintf,addr @szBuffer,addr szFormat,@CurX,@CurY ;invoke MessageBox,NULL,addr @szBuffer,addr @szBuffer,MB_OK mov eax,@CurX inc eax mov @TempRgnX,eax mov eax,@CurY inc eax mov @TempRgnY,eax invoke CreateRectRgn,@CurX,@CurY,@TempRgnX,@TempRgnY mov ebx,eax .if ebx==0 invoke MessageBox,NULL,addr szRgnFail,addr szRgnFail,MB_OK .endif invoke CombineRgn,@hRgnResult,@hRgnResult,ebx,RGN_XOR .endif inc @CurX .endw mov @CurX,0 inc @CurY .endw invoke SetWindowRgn,hWinMain,@hRgnResult,TRUE
.elseif eax==WM_LBUTTONDOWN
invoke UpdateWindow,hWnd
invoke SendMessage,hWnd,WM_NCLBUTTONDOWN,HTCAPTION,0
;invoke ReleaseCapture
;invoke SetCursor,hCursorMain
.elseif eax==WM_CLOSE
invoke DeleteObject,hDcDraw
invoke DeleteObject,hBmpTest
invoke DestroyWindow,hWnd
invoke PostQuitMessage,NULL
.elseif eax==WM_PAINT
invoke BeginPaint,hWnd,addr @stPs
mov @hDc,eax
invoke BitBlt,@hDc,0,0,300,300,hDcDraw,0,0,SRCCOPY
invoke EndPaint,hWnd,addr @stPs
.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.endif
xor eax,eax
ret
_ProcWinMain endp
_WinMain proc
LOCAL @stWndClass:WNDCLASSEX
LOCAL @stMsg:MSG
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke RtlZeroMemory,addr @stWndClass,sizeof @stWndClass
invoke LoadCursor,NULL,IDC_ARROW
mov @stWndClass.hCursor,eax
push hInstance
pop @stWndClass.hInstance
mov @stWndClass.cbSize,sizeof WNDCLASSEX
mov @stWndClass.style,CS_HREDRAW or CS_VREDRAW
mov @stWndClass.lpfnWndProc,offset _ProcWinMain
mov @stWndClass.hbrBackground,COLOR_WINDOW+1
mov @stWndClass.lpszClassName,offset szClassName
invoke RegisterClassEx,addr @stWndClass
invoke CreateWindowEx,WS_EX_CLIENTEDGE,offset szClassName,offset szClassName,\
WS_POPUP or WS_SYSMENU,\
;WS_OVERLAPPEDWINDOW,\
100,100,100,100,NULL,NULL,hInstance,NULL
mov hWinMain,eax
invoke ShowWindow,hWinMain,SW_SHOWNORMAL
invoke UpdateWindow,hWinMain
.while TRUE
invoke GetMessage,addr @stMsg,NULL,0,0
.break .if eax==0
invoke TranslateMessage,addr @stMsg
invoke DispatchMessage,addr @stMsg
.endw
ret
_WinMain endp
start:
call _WinMain
invoke ExitProcess,NULL
end start
效果图
有点花哨,中间那个小兔兔就是程序的窗口了~
顺便说一下 上面的代码里,
WM_LBUTTONDOWN的部分,是按下鼠标左键,可以拖动窗口的功能。
采用的是转发 WM_NCLBUTTONDOWN+HTCAPTION的原理,就是欺骗WINDOWS,说我点的是标题栏。
总结一下这个例子,
本身就是API的堆积,思想很简单.
但是实现的时候有个地方卡勒好久,就是用汇编计算坐标的时候.
汇编里面的变量不像C语言这种高级语言,能够按照想像中的工作.
比如坐标值+1,最后却出现了一个非常非常大的数值.
而我这里又没法Debug win32 asm程序,这个错误调试了两个小时才发现..
汇编语言处处是坑阿~~!
在网上搜索到一篇文章,VC 6.0 倒是可以 单步调试 win32汇编,
可惜又没有语法高亮,又没有语法提示,反而到不如RadAsm
可RadAsm的Debug工具竟然是OllyDbg!!这东西.....暂时还不会用,还得学习啊....
比 VC 里的Debug工具可难用多了.
真希望能够找到一个好的 win32 asm开发环境.
不过我觉得以后还是很有必要学习学习用OllyDbg来调试程序的,
如果现在就用OllyDbg调试自己的程序,将来用它来破解软件,肯定是轻车熟路了!
恩,有空的时候还得加把劲学习啊!
OK, OVER .
PS:
本来打算在等小静静的时候,学习点新的东西的。
但是实在是太困了,没精神,学习不下去呀。。
小静静几点下班亚,困死我了………………
这个小兔子的窗口,名字就叫兔兔兔,和小静静的名字一样,哈哈~
相关文章推荐
- 根据窗口类名称动态创建窗口
- 根据位图创建区域Rgn--VC
- 根据后台数据动态创建CheckboxGroup的例子
- Drools6.4动态加载规则之(二)动态创建kjar
- Windows SDK笔记(七):创建MDI窗口
- 根据数据源动态创建柱形图
- delphi根据不同图片生成不规则窗口的实现(仅限于BMP格式)
- 动态创建菜单,menustrip,根据权限显示菜单,控制菜单可用,反射,给窗体传值,反射对象传值【转】
- 创建不规则窗口
- 如何创建不规则窗口
- word动态创建不规则表格、页眉、页脚、页码
- PB如何创建动态数据窗口
- 记一次logback传输日志到logstash根据自定义设置动态创建ElasticSearch索引
- 如何创建一个动态的数据窗口对象
- 根据数据表中的内容,动态创建主菜单
- C# 中反射获取某类的子类和根据类型名动态创建对象(转载)
- c# winform 反射 动态创建窗口
- ASP.NET中根据XML动态创建使用WEB组件
- PB 动态创建数据窗口
- 设计模式学习(十四)————抽象工厂模式(使用Qt框架的反射技术——根据字符串动态创建类来实现)