【转载】G-Spider大作《窗体透明示例二》的完善版 演示了兼容16/32位色的UpdateLayeredWindow的写法
G-Spider大作《窗体透明示例二》的完善版 演示了兼容16/32位色的UpdateLayeredWindow的写法自己转自己的 http://www.
;*****************************************************************************************************************
;作者:zklhp
;Email:zklhp@
;QQ:493165744
;*****************************************************************************************************************
windows环境下用汇编语言写普通程序 速度上快了点 但快的那点人是感觉不出来的 文件大小内存占用是小 但还是没感觉。。。
其实在这里用汇编不过是API编程的一种方式 图的是个简单明了
G-Spider大作 窗体透明示例二 展现了窗口透明的一种实现方式 值得我们学习 但原文程序有bug 表现在如果显示模式是16位色时程序无法正常工作
GDI的东东太复杂我搞不明白 不过百度一下我就知道了 可是 网上并没有完整的实现代码 于是 重写了一下G-Spider大大的大作
至于bug的原理和解决方法网上有详细的解释我就不多说了 我不过是Demo了网上的代码罢了
相对于G-Spider大大的版本 我加了个右键退出的功能 省得老按Alt+F4麻烦
代码全贴了
程序代码:
;MASMPlus 代码模板 - 普通的 Windows 程序代码 ;***************************************************************************************************************** ;作者:zklhp ;Email:zklhp@ ;QQ:493165744 ;最后更新:2012.1.16 ;本程序系G-Spider大作(http://www.)的完善版本 本程序部分重写自作者的Fasm版本 ;感谢G-Spider大大提供优秀的代码供我们学习! ;***************************************************************************************************************** .386 .Model Flat, StdCall Option Casemap :None Include windows.inc Include user32.inc Include kernel32.inc Include gdi32.inc includelib gdi32.lib IncludeLib user32.lib IncludeLib kernel32.lib include macro.asm WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD .DATA szClassName db "MASMPlus_Class",0 stBlend BLENDFUNCTION <AC_SRC_OVER,0,255,AC_SRC_ALPHA> stBMIH BITMAPINFOHEADER <> stPoint POINT <0,0> stSize POINT <0,0> .DATA? hInstance dd ? hRegion dd ? hMemDC dd ? hDIB dd ? nBmpW dd ? nBmpH dd ? hBMPfile dd ? pBits dd ? pbuf dd ? nFileSize dd ? .CODE START: invoke GetModuleHandle,NULL mov hInstance,eax invoke WinMain,hInstance,NULL,NULL,SW_SHOWDEFAULT invoke ExitProcess,0 WinMain proc hInst:DWORD,hPrevInst:DWORD,CmdLine:DWORD,CmdShow:DWORD LOCAL wc :WNDCLASSEX LOCAL msg :MSG local hWnd :HWND mov wc.cbSize,sizeof WNDCLASSEX mov wc.style,0 mov wc.lpfnWndProc,offset WndProc mov wc.cbClsExtra,NULL mov wc.cbWndExtra,NULL push hInst pop wc.hInstance mov wc.hbrBackground,COLOR_BTNFACE+1 mov wc.lpszMenuName,NULL mov wc.lpszClassName,offset szClassName invoke LoadIcon,hInst,100 mov wc.hIcon,eax invoke LoadCursor,NULL,IDC_ARROW mov wc.hCursor,eax mov wc.hIconSm,0 invoke RegisterClassEx, ADDR wc .if !eax jmp ExitLoop .endif invoke CreateWindowEx,WS_EX_LAYERED,ADDR szClassName,CTXT("右键正常退出. By zklhp"),WS_VISIBLE or WS_POPUP,100,100,500,500,NULL,NULL,hInst,NULL .if !eax jmp ExitLoop .endif mov hWnd,eax invoke ShowWindow,hWnd,SW_SHOWNORMAL invoke UpdateWindow,hWnd StartLoop: invoke GetMessage,ADDR msg,NULL,0,0 cmp eax, 0 je ExitLoop invoke TranslateMessage, ADDR msg invoke DispatchMessage, ADDR msg jmp StartLoop ExitLoop: mov eax,msg.wParam ret WinMain endp WndProc proc hWin:DWORD,uMsg:DWORD,wParam :DWORD,lParam :DWORD .if uMsg==WM_CREATE invoke CreateCompatibleDC,0 ;要点1 此处不可用桌面DC 若为桌面DC则16位色创建一个16位色的DC了 mov hMemDC,eax ;先读文件 invoke CreateFile,CTXT('bk.bmp'),GENERIC_ALL,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0 .if eax == INVALID_HANDLE_VALUE invoke DeleteObject,hRegion invoke DeleteDC,hMemDC ret .endif mov hBMPfile,eax ;BMP文件头的两个结果 后面一个什么调色板这里没有 ;typedef struct tagBITMAPFILEHEADER { ;WORD bfType; ;DWORD bfSize; ;WORD bfReserved1; ;WORD bfReserved2; ;DWORD bfOffBits; ;} BITMAPFILEHEADER; ;typedef struct tagBITMAPINFOHEADER{ ;DWORD biSize; ;LONG biWidth; ;LONG biHeight; ;WORD biPlanes; ;WORD biBitCount ;DWORD biCompression; ;DWORD biSizeImage; ;LONG biXPelsPerMeter; ;LONG biYPelsPerMeter; ;DWORD biClrUsed; ;DWORD biClrImportant; ;} BITMAPINFOHEADER; ;读文件大小 invoke SetFilePointer,hBMPfile,2,0,FILE_BEGIN ;这里用了一个无关痛痒的小技巧 应该都看的明白 push ecx mov ecx,esp invoke ReadFile,hBMPfile,offset nFileSize,sizeof nFileSize,ecx,0 pop ecx ;读数据开始的位置 invoke SetFilePointer,hBMPfile,10,0,FILE_BEGIN push ecx mov ecx,esp invoke ReadFile,hBMPfile,offset pbuf,sizeof pbuf,ecx,0 pop ecx ;读BMP长 invoke SetFilePointer,hBMPfile,18,0,FILE_BEGIN push ecx mov ecx,esp invoke ReadFile,hBMPfile,offset nBmpW,sizeof pbuf,ecx,0 pop ecx ;读BMP宽 invoke SetFilePointer,hBMPfile,22,0,FILE_BEGIN push ecx mov ecx,esp invoke ReadFile,hBMPfile,offset nBmpH,sizeof pbuf,ecx,0 pop ecx ;此为要点2 这里必须明确是32位 原理和上面一样 百度一下你就知道 invoke RtlZeroMemory,offset stBMIH,sizeof stBMIH mov stBMIH.biSize,sizeof(BITMAPINFOHEADER) mov eax,nBmpW mov stBMIH.biWidth,eax mov eax,nBmpH mov stBMIH.biHeight,eax ;mov stBMIH.biSizeImage,320000 ;267*154*4 貌似可以不写 mov stBMIH.biPlanes,1 mov stBMIH.biBitCount,32 mov stBMIH.biCompression,BI_RGB invoke CreateDIBSection,NULL,offset stBMIH,0,offset pBits,NULL,0 ;pBits返回一个内存区域的指针 mov hDIB,eax invoke SetFilePointer,hBMPfile,pbuf,0,FILE_BEGIN mov eax,pbuf inc eax sub nFileSize,eax ;nFileSize - 位图数据开始位置 - 1 是 要复制的字符数 push ecx mov ecx,esp ;读入系统分配的内存中 不需释放 invoke ReadFile,hBMPfile,pBits,nFileSize,ecx,0 pop eax ;可以关闭文件了 invoke CloseHandle,hBMPfile ;大功告成 invoke SelectObject,hMemDC,hDIB mov eax,nBmpW mov stSize.x,eax mov eax,nBmpH mov stSize.y,eax invoke UpdateLayeredWindow,hWin,NULL,NULL,offset stSize,hMemDC,offset stPoint,0,offset stBlend,ULW_ALPHA .if !eax invoke MessageBox,hWin,CTXT('UpdateLayeredWindow error.'),CTXT('Error!'),0 invoke DeleteObject,hDIB invoke DeleteDC,hMemDC invoke PostQuitMessage,NULL ret .endif mov ecx,nBmpW sub ecx,10 mov edx,nBmpH sub edx,10 invoke CreateRectRgn,10,10,ecx,edx mov hRegion,eax invoke SetWindowRgn,hWin,hRegion,TRUE invoke DeleteObject,hRegion invoke DeleteObject,hDIB invoke DeleteDC,hMemDC .elseif uMsg==WM_RBUTTONDOWN ;加一个右键退出的功能 invoke PostQuitMessage,NULL .elseif uMsg==WM_LBUTTONDOWN invoke UpdateWindow,hWin invoke ReleaseCapture invoke SendMessage,hWin,WM_NCLBUTTONDOWN,2,0 .elseif uMsg == WM_DESTROY invoke PostQuitMessage,NULL .else invoke DefWindowProc,hWin,uMsg,wParam,lParam .endif ret WndProc endp END START
代码+程序+MasmPlus工程文件
AlphaWindow.zip
(22.88 KB)