windows sdk 根据位图,动态创建不规则窗口

来源:互联网 发布:qq空间做淘宝客 编辑:程序博客网 时间:2024/05/22 04:38

 <<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++ :

invokeCreateRectRgn,0,0,100,100mov@hRgnResult,eaxmov@TempRgnX,0mov@TempRgnY,0mov@CurX,0mov@CurY,0.whileTRUE.break .if  @CurY>200.whileTRUE.break.if@CurX>200invokeGetPixel,hDcDraw,@CurX,@CurYmovebx,eax.ifeax==COLOR_MASK;invokewsprintf,addr @szBuffer,addr szFormat,@CurX,@CurY;invokeMessageBox,NULL,addr @szBuffer,addr @szBuffer,MB_OKmoveax,@CurXinceaxmov@TempRgnX,eaxmoveax,@CurYinceaxmov@TempRgnY,eaxinvokeCreateRectRgn,@CurX,@CurY,@TempRgnX,@TempRgnYmovebx,eax.ifebx==0invokeMessageBox,NULL,addr szRgnFail,addr szRgnFail,MB_OK.endifinvokeCombineRgn,@hRgnResult,@hRgnResult,ebx,RGN_XOR.endifinc@CurX.endwmov@CurX,0inc@CurY.endwinvokeSetWindowRgn,hWinMain,@hRgnResult,TRUE


 下面是源代码

gj.rc

#include<resource.h>//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>#defineIDB_TEST100//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>IDB_TESTBITMAP"mimic2.bmp"//IDB_TESTBITMAP"gj.bmp"

 

gj.asm

.386.modelflat,stdcalloptioncasemap:none;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>includewindows.incincludeuser32.incincludelibuser32.libincludekernel32.incincludelibkernel32.libincludegdi32.incincludelibgdi32.lib;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>IDB_TESTequ100COLOR_MASKequ0; COLORREF 0x00bbggrr;COLOR_MASKequ0111111h; COLORREF 0x00bbggrr;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>.data?hInstancedd?hWinMaindd?hBmpTestdd?hDcDrawdd?.constszClassNamedb'miaoclass',0szFormatdb'(%d,%d)',0szDebugdb'debug',0szRgnFaildb'fail!',0szERRORAPIdb'ERRORAPI',0szCOMPLEXREGIONdb'COMPLEXREGION',0szSIMPLEREGIONdb'SIMPLEREGION',0szNULLREGIONdb'NULLREGION',0;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>.code;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>_ProcWinMainprocuses ebx edi esi hWnd,uMsg,wParam,lParamLOCAL@hDcLOCAL@stPs:PAINTSTRUCTLOCAL@szBuffer[100]:byteLOCAL@hRgnResultLOCAL@CurX,@CurYLOCAL@TempRgnX,@TempRgnYmoveax,uMsg.ifeax==WM_CREATEpushhWndpophWinMain;load bitmapinvokeLoadBitmap,hInstance,IDB_TESTmovhBmpTest,eax;create buffer dcinvokeGetDC,hWndmov@hDc,eaxinvokeCreateCompatibleDC,@hDcmovhDcDraw,eaxinvokeReleaseDC,hWnd,@hDc;draw sth. on bufferdcinvokeSelectObject,hDcDraw,hBmpTest;invokeCreateEllipticRgn,0,0,100,100;mov@hRgnResult,eax;invokeCreateEllipticRgn,150,150,200,200;invokeCombineRgn,@hRgnResult,@hRgnResult,eax,RGN_OR;invokeSetWindowRgn,hWnd,@hRgnResult,FALSEinvokeCreateRectRgn,0,0,100,100mov@hRgnResult,eaxmov@TempRgnX,0mov@TempRgnY,0mov@CurX,0mov@CurY,0.whileTRUE.break .if  @CurY>200.whileTRUE.break.if@CurX>200invokeGetPixel,hDcDraw,@CurX,@CurYmovebx,eax.ifeax==COLOR_MASK;invokewsprintf,addr @szBuffer,addr szFormat,@CurX,@CurY;invokeMessageBox,NULL,addr @szBuffer,addr @szBuffer,MB_OKmoveax,@CurXinceaxmov@TempRgnX,eaxmoveax,@CurYinceaxmov@TempRgnY,eaxinvokeCreateRectRgn,@CurX,@CurY,@TempRgnX,@TempRgnYmovebx,eax.ifebx==0invokeMessageBox,NULL,addr szRgnFail,addr szRgnFail,MB_OK.endifinvokeCombineRgn,@hRgnResult,@hRgnResult,ebx,RGN_XOR.endifinc@CurX.endwmov@CurX,0inc@CurY.endwinvokeSetWindowRgn,hWinMain,@hRgnResult,TRUE.elseifeax==WM_LBUTTONDOWNinvokeUpdateWindow,hWndinvokeSendMessage,hWnd,WM_NCLBUTTONDOWN,HTCAPTION,0;invokeReleaseCapture;invokeSetCursor,hCursorMain.elseifeax==WM_CLOSEinvokeDeleteObject,hDcDrawinvokeDeleteObject,hBmpTestinvokeDestroyWindow,hWndinvokePostQuitMessage,NULL.elseifeax==WM_PAINTinvokeBeginPaint,hWnd,addr @stPsmov@hDc,eaxinvokeBitBlt,@hDc,0,0,300,300,hDcDraw,0,0,SRCCOPYinvokeEndPaint,hWnd,addr @stPs.elseinvokeDefWindowProc,hWnd,uMsg,wParam,lParamret.endifxoreax,eaxret_ProcWinMainendp_WinMainprocLOCAL@stWndClass:WNDCLASSEXLOCAL@stMsg:MSGinvokeGetModuleHandle,NULLmovhInstance,eaxinvokeRtlZeroMemory,addr @stWndClass,sizeof @stWndClassinvokeLoadCursor,NULL,IDC_ARROWmov@stWndClass.hCursor,eaxpushhInstancepop@stWndClass.hInstancemov@stWndClass.cbSize,sizeof WNDCLASSEXmov@stWndClass.style,CS_HREDRAW or CS_VREDRAWmov@stWndClass.lpfnWndProc,offset _ProcWinMainmov@stWndClass.hbrBackground,COLOR_WINDOW+1mov@stWndClass.lpszClassName,offset szClassNameinvokeRegisterClassEx,addr @stWndClassinvokeCreateWindowEx,WS_EX_CLIENTEDGE,offset szClassName,offset szClassName,\WS_POPUP or WS_SYSMENU,\;WS_OVERLAPPEDWINDOW,\100,100,100,100,NULL,NULL,hInstance,NULLmovhWinMain,eaxinvokeShowWindow,hWinMain,SW_SHOWNORMALinvokeUpdateWindow,hWinMain.whileTRUEinvokeGetMessage,addr @stMsg,NULL,0,0.break.ifeax==0invokeTranslateMessage,addr @stMsginvokeDispatchMessage,addr @stMsg.endwret_WinMainendpstart:call_WinMaininvokeExitProcess,NULLendstart

 

效果图

有点花哨,中间那个小兔兔就是程序的窗口了~


 

顺便说一下 上面的代码里,

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:

本来打算在等小静静的时候,学习点新的东西的。

但是实在是太困了,没精神,学习不下去呀。。

小静静几点下班亚,困死我了………………

这个小兔子的窗口,名字就叫兔兔兔,和小静静的名字一样,哈哈~

原创粉丝点击