做网站珠海,咸宁企业网络推广方案,公司网站需要多少钱,百度主页网址在这儿下载本节的所有源程序。有关GDI和位图GDI 即图形设备界面#xff0c;是 Windows 最重要的部分之一#xff0c;它大部分由 GDI32.DLL 库中的 API 来处理#xff0c;GDI 的主要目的之一是支持与设备无关的图形编程#xff0c;对于 Dos 下的图形编程#xff0c;很多人可…在这儿下载本节的所有源程序。有关GDI和位图GDI 即图形设备界面是 Windows 最重要的部分之一它大部分由 GDI32.DLL 库中的 API 来处理GDI 的主要目的之一是支持与设备无关的图形编程对于 Dos 下的图形编程很多人可能“心有余悸”因为PC 中有太多种类的显示卡而几乎每个显示卡的处理都是不同的即使后来有了 Vesa 编程我们还是不能全部撇开具体的硬件Windows GDI 使我们对图形的编程变得相对简单了很多由于GDI 是 Windows 最庞大的部分并不是几句话能讲清楚的本节要讲的是 Windows 下GDI 的基本处理步骤和简单的位图处理并没有涉及到 Directx 一类的编程。只希望能对朋友们有所启发。Windows 并不允许程序员访问显示硬件它的所有对屏幕的操作是通过环境设备DC来处理的屏幕上的每一个窗口对应一个DC你可以把一个DC 想象成这个窗口的视频缓冲区你对DC的操作结果会反映到屏幕上在窗口的DC之外你也可以自己建立DC这相当于建立一个内存中的缓冲区你对这个DC的操作结果保存在内存中。你也可以用 API 在不同的DC之间拷贝数据比如说你可以在内存DC 中先建立好数据然后拷贝到窗口的DC中就相当于完成了屏幕的刷新。与DC的取得、建立取消有关的API有以下几种GetDC(hWnd) - 取得某个窗口的DCAPI 返回对应的 DC 句柄ReleaseDC(hWnd,hDC) - 释放用 GetDC 取得的 DC 句柄CreateCompatibleDC(hDC) - 从一个已知的 DC 句柄中建立一个内存 DC各种参数、属性参考已知的 DCDeleteDC(hDC) - 删除用CreateCompatibleDC 建立的 DC上面的4个API必须成对出现用 GetDC 取得的DC 必须用 ReleaseDC 释放而用 CreateCompatibleDC 建立的 DC 必须用 DeleteDC 删除不能混淆。DC 的作用范围用 GetDC 取得的窗口 DC 必须尽快释放你不应该在 Windows 的不同消息之间保存 DC 句柄而用 CreateCompatibleDC 建立的 DC 可以长期保存举例说明如果你在 WM_PAINT 和 WM_SIZE 消息中都要对窗口的 DC 进行操作你不能在 WM_INIT 时先 GetDC然后保存句柄最后在 WM_CLOSE 消息时 ReleaseDC而是必须在 WM_PAINT 和 WM_SIZE 开始的地方 GetDC在消息结束的地方就 ReleaseDC而用 CreateCompatibleDC 建立的则相反你可以在 WM_INIT 时建立在 WM_CLOSE 时删除。如果想把一个位图画到 DC 中你只需简单的用 invoke SelectObject,hDc,hBitmap 就行了是不是很简单但图形操作并不是单单把位图放入屏幕就行了还要涉及到位的操作如把前景位图的边缘去掉贴入背景位图等。 Windows 的 GDI 提供了下面一些 DC 间的拷贝 API中间就包括了拷贝的模式BitBlt hDcDest,XDest,YDest,Width,Height,hDcSource,XSrc,YSrc,dwRop这个 API 把 hDcSource 的 XSrc,YSrc 坐标处的内容拷贝到 hDcDest 的 XDest,YDest 处拷贝大小为 Width,Height。PatBlt hDc,X,Y,Width,Height,dwRop 是用预定义的刷子等 Object 填充 DCStretchBlt,hDcDest,XDest,YDest,Width,Height,hDcSource,XSrc,YSrc,WidthSrc,HeightSrc,dwRop 是拷贝并自动缩放大小你可以注意到它和 BitBlt 相比多了两个参数 WidthSrc 和 HeightSrc别的都是一样的。以上API 中的 dwRop 参数是最关键的它的值有 SRCCOPYSRCPAINTSRCANDDSTINVERT 等表示源DC 拷贝到目标DC后象素的计算方法SRCCOPY 表示用源DC覆盖目标DCSRCPAINT是执行 OR 操作SRCAND 是执行 AND 操作DSTINVERT 是取反举例说明如果源DC中的某一点是黑色目标DC对应的点是红色那么用 SRCCOPY后目标DC的点变成黑色用SRCPAINT 后还是红色因为黑 (000000) or 红(0000ff) 红(0000ff)。对应一般对屏幕或窗口进行图形操作的步骤如下。用GetDC 取得目标窗口的 DC用 CreateCompatibleDC 建立一个内存中的 DC用作缓冲区用 SelectObject 填充内存DC 或别的办法对内存DC进行操作一句话先把要显示的东西处理好用 BitBlt 把内存DC 拷贝到窗口 DC中完成屏幕刷新。本节的例子程序是一个屏幕放大镜它把鼠标移动到的地方的屏幕内容放大一倍显示到自己的窗口中。源程序 - 汇编源文件;; Programmed by 罗云彬, bigluotelekbird.com.cn; Website: http://asm.yeah.net; LuoYunBins Win32 ASM page (罗云彬的编程乐园);; 版本信息; 汇编教程附带源程序 - 屏幕放大器; V1.0 ------ 2000年7月1日;.386.model flat, stdcalloption casemap :none ; case sensitive;; Include 数据;include windows.incinclude user32.incinclude kernel32.incinclude comctl32.incinclude comdlg32.incinclude gdi32.incincludelib user32.libincludelib kernel32.libincludelib comctl32.libincludelib comdlg32.libincludelib gdi32.lib;; Equ 数据;DLG_MAIN equ 1000ID_BITMAP equ 1001;; 数据段;.data?hWinPic dd ?hDcMem dd ?hBitmap dd ?hWinDesktop dd ?hInstance dd ?szBuffer db 256 dup (?);; 子程序声明;_ProcDlgMain PROTO :DWORD,:DWORD,:DWORD,:DWORD.data;; 代码段;.codeinclude Win.asm;********************************************************************_ProcDlgMain proc uses ebx edi esi, \hWnd:DWORD,wMsg:DWORD,wParam:DWORD,lParam:DWORDlocal stPoint:POINTlocal hDcDesktop,hDcPicmov eax,wMsg.if eax WM_CLOSEinvoke EndDialog,hWnd,NULLinvoke KillTimer,hWnd,1invoke DeleteDC,hDcMeminvoke DeleteObject,hBitmap; *******************************************************************.elseif eax WM_INITDIALOGinvoke GetDlgItem,hWnd,ID_BITMAPmov hWinPic,eaxinvoke GetDesktopWindowmov hWinDesktop,eaxinvoke SetWindowPos,hWnd,HWND_TOPMOST,0,0,0,0,\SWP_NOMOVE or SWP_NOSIZE; *******************************************************************invoke GetDC,hWinDesktopmov hDcDesktop,eaxinvoke CreateCompatibleDC,hDcDesktopmov hDcMem,eaxinvoke CreateCompatibleBitmap,hDcDesktop,80,80mov hBitmap,eaxinvoke SelectObject,hDcMem,hBitmapinvoke ReleaseDC,hWinDesktop,hDcDesktopinvoke SetTimer,hWnd,1,100,NULL; *******************************************************************.elseif eax WM_TIMERinvoke GetCursorPos,addr stPointsub stPoint.x,20sub stPoint.y,20.if stPoint.x 0mov stPoint.x,0.endif.if stPoint.y 0mov stPoint.y,0.endifinvoke GetDC,hWinDesktopmov hDcDesktop,eaxinvoke GetDC,hWinPicmov hDcPic,eaxinvoke PatBlt,hDcMem,0,0,80,80,BLACKNESSinvoke StretchBlt,hDcMem,0,0,80,80,\hDcDesktop,stPoint.x,stPoint.y,40,40,SRCCOPYinvoke BitBlt,hDcPic,0,0,80,80,\hDcMem,0,0,SRCCOPYinvoke ReleaseDC,hWinDesktop,hDcDesktopinvoke ReleaseDC,hWinPic,hDcPic.else;********************************************************************; 注意对话框的消息处理后要返回 TRUE,对没有处理的消息; 要返回 FALSE;********************************************************************mov eax,FALSEret.endifmov eax,TRUEret_ProcDlgMain endp;********************************************************************start:invoke GetModuleHandle,NULLmov hInstance,eaxinvoke DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _ProcDlgMain,0invoke ExitProcess,NULLend start程序的分析和要点在程序的初始化中我们用GetDc 取的桌面的屏幕的 DC再用 CreateCompatibleDC 建立一个内存DC做缓冲区建立一个位图再用 SelectObject 把 hDcMem 设置为这个位图是为了是 hDcMem 的大小变为 80x80。invoke GetDC,hWinDesktopmov hDcDesktop,eaxinvoke CreateCompatibleDC,hDcDesktopmov hDcMem,eaxinvoke CreateCompatibleBitmap,hDcDesktop,80,80mov hBitmap,eaxinvoke SelectObject,hDcMem,hBitmapinvoke ReleaseDC,hWinDesktop,hDcDesktop然后在程序的每 0.1 秒一次的 WM_TIMER 定时器消息中我们先用 GetDC 取得桌面和对话框中文本框的句柄然后用 PatBlt 把内存DC清除为黑色再用 StretchBlt 从桌面DC中拷贝 40x40的区域到内存 DC 中新的大小是 80x80放大功能就是这样实现的拷贝的位置是用 GetCursorPos 取得的也就是鼠标的当前位置最后用 BitBlt 把内存DC 拷贝到对话框中。如果直接把桌面DC 拷贝到对话框中也可以但是当鼠标移动到屏幕边缘上时由于屏幕外的点是无效的所以对话框中的一部分会花屏大家可以改动程序试试。invoke GetCursorPos,addr stPointinvoke GetDC,hWinDesktopmov hDcDesktop,eaxinvoke GetDC,hWinPicmov hDcPic,eaxinvoke PatBlt,hDcMem,0,0,80,80,BLACKNESSinvoke StretchBlt,hDcMem,0,0,80,80,\