爱爱小说网 > 其他电子书 > windows环境下32位汇编语言程序设计 >

第35章

windows环境下32位汇编语言程序设计-第35章

小说: windows环境下32位汇编语言程序设计 字数: 每页3500字

按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!




。if         ax    IDM_BACK1

                mov     dwNowBack;IDB_BACK1

                invoke  CheckMenuRadioItem;hMenu;IDM_BACK1;IDM_BACK2;IDM_BACK1;NULL

。elseif     ax    IDM_BACK2

                mov     dwNowBack;IDB_BACK2

                invoke  CheckMenuRadioItem;hMenu;IDM_BACK1;IDM_BACK2;IDM_BACK2;NULL

。elseif     ax    IDM_CIRCLE1

                mov     dwNowCircle;IDB_CIRCLE1

                invoke  CheckMenuRadioItem;hMenu;IDM_CIRCLE1;IDM_CIRCLE2;

                        IDM_CIRCLE1;NULL

。elseif     ax    IDM_CIRCLE2

                mov     dwNowCircle;IDB_CIRCLE2

                invoke  CheckMenuRadioItem;hMenu;IDM_CIRCLE1;IDM_CIRCLE2;

                        IDM_CIRCLE2;NULL

。elseif     ax    IDM_EXIT

        call        _Quit

        xor     eax;eax

        ret

。endif

;********************************************************************

; 恢复源代码缩进格式

;********************************************************************

                    invoke  _DeleteBackGround

                    invoke  _CreateBackGround

                    invoke  _CreateClockPic

                    invoke  InvalidateRect;hWnd;NULL;FALSE

            。elseif eax   WM_CLOSE

                    call        _Quit

;********************************************************************

; 按下右键时弹出一个POPUP菜单

;********************************************************************

            。elseif eax   WM_RBUTTONDOWN

                    invoke  GetCursorPos;addr @stPos

                    invoke  TrackPopupMenu;hMenu;TPM_LEFTALIGN;

                            @stPos。x;@stPos。y;NULL;hWnd;NULL

;********************************************************************

; 由于没有标题栏,下面代码用于按下左键时移动窗口

; UpdateWindow:即时刷新,否则要等到放开鼠标时窗口才会重画



 
来源:电子工业出版社 作者:罗云彬 上一页         回书目         下一页          
上一页         回书目         下一页          
  


第7章 图形操作


7。3 创建和使用位图(4)

    
;********************************************************************

            。elseif eax   WM_LBUTTONDOWN

                    invoke  SetCursor;hCursorMove

                    invoke  UpdateWindow;hWnd

                    invoke  ReleaseCapture

                        invoke   SendMessage;hWnd;WM_NCLBUTTONDOWN;HTCAPTION;0

                    invoke  SetCursor;hCursorMain

;********************************************************************

            。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  LoadCursor;hInstance;IDC_MOVE

                mov     hCursorMove;eax

                invoke  LoadCursor;hInstance;IDC_MAIN

                mov     hCursorMain;eax

;********************************************************************

; 注册窗口类

;********************************************************************

                invoke  RtlZeroMemory;addr @stWndClass;sizeof @stWndClass

                invoke  LoadIcon;hInstance;ICO_MAIN

                mov     @stWndClass。hIcon;eax

                mov     @stWndClass。hIconSm;eax

                push        hCursorMain

                pop     @stWndClass。hCursor

                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;NULL;

                        offset szClassName;offset szClassName;

                        WS_POPUP or WS_SYSMENU;

                        100;100;CLOCK_SIZE;CLOCK_SIZE;

                        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

首先简单分析一下程序的结构,主程序中先用RegisterClassEx注册窗口类,再用CreateWindowEx建立窗口的过程,这是标准的创建窗口的代码,惟一的特殊之处是建立窗口使用的窗口风格是WS_POPUP或WS_SYSMENU,这样建立的窗口没有标题栏,以便以后实现圆形的窗口。

程序中的坐标算法和7。2节的Clock。asm是一样的,所以有些子程序沿用了上一个程序中的相关子程序,如计算坐标的_CalcX和_CalcY,绘画指针的_DrawLine子程序等。

在窗口过程的WM_CREATE消息中,程序用CreatePopupMenu创建了一个Popup菜单,用来在按下右键的时候弹出该菜单,并多次调用AppendMenu创建需要的菜单项(相关内容见第5章的“菜单”一节)。然后,程序用CreateEllipticRgn建立一个区域,并用SetWindowRgn函数把窗口设置成圆形,这两个函数在本章的最后一节介绍。接下来,程序用SetWindowPos函数把窗口设置为“总在最前面”。在WM_CREATE消息的最后,程序调用_CreateBackGround和_CreateClockPic创建背景位图和时钟位图,这是这一节中要详细介绍的内容。和前面简单的时钟程序类似,本程序也建立了一个周期为1s的定时器用来刷新屏幕。

在选择菜单后的WM_MAND消息中,程序调用_DeleteBackGround子程序先删除原有的位图,再调用_CreateBackGround和_CreateClockPic子程序产生新的背景位图和时钟位图,最后调用InvalidateRect函数产生WM_PAINT消息重新绘画客户区。

程序有个特殊之处是对WM_LBUTTONDOWN消息的处理,由于建立的窗口没有标题栏,所以无法用拖动标题栏的方法移动窗口,为了在窗口客户区拖动鼠标就能够移动窗口,必须欺骗Windows,让它认为是在拖动标题栏,所以在WM_LBUTTONDOWN消息中,程序发送位置为HTCAPTION的WM_NCLBUTTONDOWN消息,这样就相当于告诉Windows用户按下的是标题栏。头尾处的两个SetCursor函数是为了按下鼠标时让光标变成一个抓住东西的手的形状。

整个程序的结构采用图7。1中的B结构,也就是说窗口客户区的绘画代码和产生时钟位图的代码是分开的,程序中建立了两个位图当做缓冲数据,第一个位图是背景位图,在_CreateBackGround子程序中建立,只有在程序初始化以及在菜单中选择了不同的背景和边框后才需要调用这个子程序,以便建立新的背景图片;第二个位图是要输出到屏幕的时钟位图,它在_CreateClockPic子程序中建立,时钟位图是通过将背景位图拷贝过来,再根据当前时间画上指针得到的,程序在WM_TIMER消息中每秒重画一次新的时钟图片,并用InvalidateRect函数产生一个WM_PAINT消息将这个位图拷贝到屏幕上,当其他原因产生WM_PAINT消息时,程序并不从头开始产生背景位图和时钟位图等图片,而是直接从时钟图片中拷贝数据到屏幕上。

好了,接下来继续分析_CreateBackGround和_CreateClockPic子程序是如何对位图进行处理的。

7。3。2  创建和使用位图

所有绘图函数的操作对象都是“设备环境”,对位图操作也不例外。为了对位图使用GDI函数,需要使用CreatepatibleDC函数为位图建立一个DC,然后使用SelectObject函数将位图选入这个DC中,这样,所有对这个DC的绘图操作实际上就是在操作这个位图。每一个需要操作的位图都需要单独为它创建一个DC。

程序中常常使用在资源中预定义的位图,但也有使用未初始化的位图的情况,如例子程序的背景位图和时钟位图一开始就是未初始化的,它们是程序开始运行后才被创建的。

为了建立一个未初始化的位图,可以使用以下的函数:

    invoke  CreatepatibleBitmap,hDC,dwWidth,dwHeight

    mov hBitmap1;eax        ;方法1

    invoke  CreateBitmap,dwWidth,dwHeight,dwPlanes,dwBitsPerPel,NULL

    mov hBitmap2;eax        ;方法2



 
来源:电子工业出版社 作者:罗云彬 上一页         回书目         下一页          
上一页         回书目         下一页          
  


第7章 图形操作


7。3 创建和使用位图(5)

    
创建一个位图需要的参数是高度、宽度以及颜色深度,要创建位图必须得知这些参数。使用CreatepatibleBitmap创建位图的时候,参数中有一个hDC,这是个参考hDC,也就是说,新位图的颜色深度和hDC对应的“设备环境”的颜色深度相同(注意:有个hDC参数的意思并不是将创建的位图选入这个hDC中)。CreateBitmap函数则直接在参数dwPlanes和dwBitsPerPel中指定了颜色深度。两个函数的dwWidth和dwHeight参数指定创建的位图的宽度和高度。

在例子程序的_CreateBackGround子程序中,为了建立背景图片和时钟图片,需要建立两个未初始化的位图和操作它们的DC,所以程序一开始用GetDC函数获取主窗口的hDC来当做参考DC,然后用CreatepatibleDC函数建立了两个DC(句柄放在全局变量hDcBack和hDcClock中),并用CreatepatibleBitmap建立了两个位图(句柄放入hBmpBack和hBmpClock中),接下来用SelectObject将这两个位图选入新建的hDC中。

创建背景图片的过程中还要用到资源中的背景图片、边框图片和边框的遮掩图片,对于这些图片,程序用LoadBitmap函数装入,并使用CreatepatibleDC为每个图片建立一个DC。

对于不再使用的位图,要用DeleteObject函数将它们删除。所以在子程序的最后,使用DeleteObject函数将临时使用的位图句柄删除,并使用DeleteDC将操作这些位图的hDC删除。

操作未初始化位图需要用到CreatepatibleDC和CreatepatibleBitmap函数,初学者常犯的错误是用CreatepatibleDC返回的hDC当做CreatepatibleBitmap函数的参考hDC,这样的结果是建立的位图是单色的,正确的做法是两个函数的参考hDC都使用窗口客户区的hDC。

7。3。3  使用设备无关位图

设备无关位图简称为DIB,这在5。3。1小节中已经有所介绍。DIB一般是存放在磁盘上的以bmp为扩展名的位图文件,使用DIB的关键是如何将DIB中的数据转化为一个内存中的位图并返回一个位图句柄。

bmp文件的文件结构是这样定义的:文件的开始是一个BITMAPFILEHEADER结构,这个结构定义如下:

BITMAPFILEHEADER STRUCT

  bfType           WORD       ?    ;文件标识,必须是“BM”

  bfSize           DWORD     ?    ;文件长度

  bfReserved1      WORD      ?    ;0

  bfReserved2      WORD      ?    ;0

  bfOffBits        DWORD     ?    ;位图像素数据在文件中的起始位置

BITMAPFILEHEADER   ENDS

BITMAPFILEHEADER结构的后面要么是BITMAPCOREHEADER结构,要么是BITMAPINFOHEADER结构和索引色表,这两种结构的定义如下:

BITMAPCOREHEADER STRUCT

  bcSize            DWORD     ?    ;本结构长度

  bcWidth          WORD      ?    ;位图宽度

  bcHeight         WORD      ?    ;位图高度

  bcPlanes          WORD      ?    ;位图的色平面数

  bcBitCount        WORD      ?    ;位图的颜色深度

BITMAPCOREHEADER   ENDS

 

BITMAPINFOHEADER STRUCT

  bcSize            DWORD     ?    ;本结构长度

  bcWidth          

返回目录 上一页 下一页 回到顶部 2 2

你可能喜欢的