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:
本来打算在等小静静的时候,学习点新的东西的。
但是实在是太困了,没精神,学习不下去呀。。
小静静几点下班亚,困死我了………………
这个小兔子的窗口,名字就叫兔兔兔,和小静静的名字一样,哈哈~
- windows sdk 根据位图,动态创建不规则窗口
- 使用图片创建不规则窗体 windows sdk
- 使用图片创建不规则窗体 windows sdk
- 使用图片创建不规则窗体 windows sdk
- SDK不规则窗口程序
- Windows动态窗口创建
- 根据窗口类名称动态创建窗口
- 创建不规则窗口
- 创建一不规则窗口
- 如何创建不规则窗口
- 创建不规则窗口
- 创建不规则形状窗口
- swt创建不规则窗口
- mfc创建不规则窗口
- MFC创建不规则窗口
- VC创建不规则窗口
- 创建WPF不规则窗口
- 在windows上创建完美的不规则窗口
- 第二章 数据、变量和计算
- AOP各种的实现
- Android下的任务和Activity栈
- Android将Widget添加到自己的应用程序
- GNU Parallel -- "shell for" not fashion, 用Parallel瞬间将场面hold住
- windows sdk 根据位图,动态创建不规则窗口
- oracle 中 cursor 与refcursor及sys_refcursor的区别 (转载)
- 更改ArchLinux的时间
- Android开发之--(WIFI,蓝牙,电池,背光,SD卡,摄像头,按键,MIC,重力感应等)功能的简单使用
- MOSS域用户帐号从中文变成字母拼音导致的问题
- 摸爬滚打的学习
- MyEclipse6.5的反编译插件的安装
- timer的schedule函数
- JS如何获取屏幕浏览器网页高度宽度