汇编创建简单的窗口
2007-11-13 09:32:32 来源:WEB开发网我们来仔细看一看这些的参数:
dwExStyle:附加的窗口风格。相对于旧的CreateWindow这是一个新的参数。在9X/NT中您可以使用新的窗口风格。您可以在Style中指定一般的窗口风格,但是一些特殊的窗口风格,如顶层窗口则必须在此参数中指定。如果您不想指定任何特别的风格,则把此参数设为NULL。
lpClassName:(必须)。ASCIIZ形式的窗口类名称的地址。可以是您自定义的类,也可以是预定义的类名。像上面所说,每一个应用程序必须有一个窗口类。
lpWindowName:ASCIIZ形式的窗口名称的地址。该名称会显示在标题条上。如果该参数空白,则标题条上什么都没有。
dwStyle:窗口的风格。在此您可以指定窗口的外观。可以指定该参数为零,但那样该窗口就没有系统菜单,也没有最大化和最小化按钮,也没有关闭按钮,那样您不得不按Alt+F4 来关闭它。最为普遍的窗口类风格是 WS_OVERLAPPEDWINDOW。 一种窗口风格是一种按位的掩码,这样您可以用“or”把您希望的窗口风格或起来。像 WS_OVERLAPPEDWINDOW 就是由几种最为不便普遍的风格或起来的。
X,Y: 指定窗口左上角的以像素为单位的屏幕坐标位置。缺省地可指定为 CW_USEDEFAULT,这样 Windows 会自动为窗口指定最合适的位置。
nWidth, nHeight: 以像素为单位的窗口大小。缺省地可指定为 CW_USEDEFAULT,这样 Windows 会自动为窗口指定最合适的大小。
hWndParent: 父窗口的句柄(如果有的话)。这个参数告诉 Windows 这是一个子窗口和他的父窗口是谁。这和 MDI(多文档结构)不同,此处的子窗口并不会局限在父窗口的客户区内。他只是用来告诉 Windows 各个窗口之间的父子关系,以便在父窗口销毁是一同把其子窗口销毁。在我们的例子程序中因为只有一个窗口,故把该参数设为 NULL。
hMenu: WINDOWS菜单的句柄。如果只用系统菜单则指定该参数为NULL。回头看一看WNDCLASSEX 结构中的 lpszMenuName 参数,它也指定一个菜单,这是一个缺省菜单,任何从该窗口类派生的窗口若想用其他的菜单需在该参数中重新指定。其实该参数有双重意义:一方面若这是一个自定义窗口时该参数代表菜单句柄,另一方面,若这是一个预定义窗口时,该参数代表是该窗口的 ID 号。Windows 是根据lpClassName 参数来区分是自定义窗口还是预定义窗口的。
hInstance: 产生该窗口的应用程序的实例句柄。
lpParam: (可选)指向欲传给窗口的结构体数据类型参数的指针。如在MDI中在产生窗口时传递 CLIENTCREATESTRUCT 结构的参数。一般情况下,该值总为零,这表示没有参数传递给窗口。可以通过GetWindowLong 函数检索该值。
mov hwnd,eax
invoke ShowWindow, hwnd,CmdShow
invoke UpdateWindow, hwnd
调用CreateWindowEx成功后,窗口句柄在eax中。我们必须保存该值以备后用。我们刚刚产生的窗口不会自动显示,所以必须调用 ShowWindow 来按照我们希望的方式来显示该窗口。接下来调用 UpdateWindow 来更新客户区。
.WHILE TRUE
invoke GetMessage, ADDR msg,NULL,0,0
.BREAK .IF (!eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.ENDW
这时候我们的窗口已显示在屏幕上了。但是它还不能从外界接收消息。所以我们必须给它提供相关的消息。我们是通过一个消息循环来完成该项工作的。每一个模块仅有一个消息循环,我们不断地调用 GetMessage 从 Windows 中获得消息。GetMessage 传递一个 MSG 结构体给 Windows ,然后 Windows 在该函数中填充有关的消息,一直到 Windows 找到并填充好消息后 GetMessage 才会返回。在这段时间内系统控制权可能会转移给其他的应用程序。这样就构成了Win16 下的多任务结构。如果 GetMessage 接收到 WM_QUIT 消息后就会返回 FALSE,使循环结束并退出应用程序。TranslateMessage 函数是一个是实用函数,它从键盘接受原始按键消息,然后解释成 WM_CHAR,在把 WM_CHAR 放入消息队列,由于经过解释后的消息中含有按键的 ASCII 码,这比原始的扫描码好理解得多。如果您的应用程序不处理按键消息的话,可以不调用该函数。DispatchMessage 会把消息发送给负责该窗口过程的函数。
mov eax,msg.wParam
ret
WinMain endp
如果消息循环结束了,退出码存放在 MSG 中的 wParam中,您可以通过把它放到 eax 寄存器中传给 Windows目前 Windows 没有利用到这个结束码,但我们最好还是遵从 Windows 规范已防意外。
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
是我们的窗口处理函数。您可以随便给该函数命名。其中第一个参数 hWnd 是接收消息的窗口的句柄。uMsg 是接收的消息。注意 uMsg 不是一个 MSG 结构,其实上只是一个 DWORD 类型数。Windows 定义了成百上千个消息,大多数您的应用程序不会处理到。当有该窗口的消息发生时,Windows 会发送一个相关消息给该窗口。其窗口过程处理函数会智能的处理这些消息。wParam 和 lParam 只是附加参数,以方便传递更多的和该消息有关的数据。
.IF uMsg==WM_DESTROY
invoke PostQuitMessage,NULL
.ELSE
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.ENDIF
xor eax,eax
ret
WndProc endp
上面可以说是关键部分。这也是我们写 Windows 程序时需要改写的主要部分。此处您的程序检查 Windows 传递过来的消息,如果是我们感兴趣的消息则加以处理,处理完后,在 eax 寄存器中传递 0,否则必须调用 DefWindowProc,把该窗口过程接收到的参数传递给缺省的窗口处理函数。所有消息中您必须处理的是 WM_DESTROY,当您的应用程序结束时 Windows 把这个消息传递进来,当您的应用程序解说到该消息时它已经在屏幕上消失了,这仅是通知您的应用程序窗口已销毁,您必须自己准备返回 Windows 。在此消息中您可以做一些清理工作,但无法阻止退出应用程序。如果您要那样做的话,可以处理 WM_CLOSE 消息。在处理完清理工作后,您必须调用 PostQuitMessage,该函数会把 WM_QUIT 消息传回您的应用程序,而该消息会使得 GetMessage 返回,并在 eax 寄存器中放入 0,然后会结束消息循环并退回 WINDOWS。您可以在您的程序中调用 DestroyWindow 函数,它会发送一个 WM_DESTROY 消息给您自己的应用程序,从而迫使它退出。
更多精彩
赞助商链接