用MasmPlus学习汇编语言 7
相关的例子:下载>>> 作者:Zoologist 于2008-3-16上传 

    我很喜欢使用Delphi,至少使用它编程的时候不用担心界面的问题,“拖拖拉拉”就能

完成一个Windows标准程序的界面。这次我将介绍如何使用汇编语言设计简单的界面。

一.如何使用 Static ?

    这个东西就是在界面上显示一行文字的东西,Delphi中叫做Label。创建的方法很简单,

和创建窗口差不多,就是使用 CreateWindowEx API,我们告诉系统,我要建立一种叫做static

的东西,这个东西放在我建立好的窗口上,窗口的handler是static,程序的handler是hInst,

于是写出来就是这个样子:

INVOKE CreateWindowEx, NULL, CTXT("static"), addr szText01,\
WS_CHILD or WS_VISIBLE or SS_NOTIFY,\
53, 66, 200, 69, hWnd, 2001, hInst, NULL

对照原形:

HWND CreateWindowEx(      
    DWORD dwExStyle,
    LPCTSTR lpClassName,
    LPCTSTR lpWindowName,
    DWORD dwStyle,
    int x,
    int y,
    int nWidth,
    int nHeight,
    HWND hWndParent,
    HMENU hMenu,
    HINSTANCE hInstance,
    LPVOID lpParam
);

   各个含义可以猜得八九不离十。

   下面的问题就是怎么向上面写字?我们使用   SetWindowText API,定义如下:

BOOL SetWindowText(      
    HWND hWnd,
    LPCTSTR lpString
);
   我们前面一直都在用,ShowMessage API 这个定义一看就清楚。
最后,我们要在上面写点什么呢?就写一下当前的时间吧。用 GetLocalTime API
可以获得当前的日期时间,不过需要留心一下,SYSTEMTIME 结构体中的成员都是WORD,
直接使用 invoke 压入进行格式转换会出现莫名其妙的错误,具体说来就是:
invoke wsprintf,addr szBuffer,CTXT("%u %u"),lpLocalTime.wYear,lpLocalTime.wMonth
这样用是不对的,运行起来除了第一个,其余的都不对。
    程序如下,我们将显示时间写在WM_SIZE消息中,每次改变窗口都会显示现在的时间。
		j1.JPG (8886 字节)
    惯例还要说点需要注意的问题:注意指定的长宽,要是显示不下,有可能出现字符截断
的情况,或者自己转到了下一行的情况哦。
参考:
1.CreateWindowEx http://msdn2.microsoft.com/en-us/library/ms632680(VS.85).aspx

2.SetWindowText    http://msdn2.microsoft.com/en-us/library/ms633546(VS.85).aspx

3.GetLocalTime  http://msdn2.microsoft.com/en-us/library/ms724338(VS.85).aspx

二. Button

    象上一个程序一样,button 也是使用CreateWindowEx建立的。比如,我们用下面的

语句就可以建立2个button,不同的地方是,这里我们特地定义了ButtonID1和ButtonID2。

简单的说,这个只是一个编号,使给我们后面响应命令用的。

INVOKE CreateWindowEx, NULL, CTEXT("button"), CTEXT("BT1"),\
WS_CHILD or WS_VISIBLE or WS_TABSTOP,\
15, 18, 80, 25, hWnd, ButtonID1, hInst, NULL
mov hButton1, eax


INVOKE CreateWindowEx, NULL, CTEXT("button"), CTEXT("BT2"),\
WS_CHILD or WS_VISIBLE or WS_TABSTOP,\
103, 19, 80, 25, hWnd, ButtonID2, hInst, NULL
mov hButton2, eax

    完整的程序:

;MASMPlus 代码模板 - 普通的 Windows 程序代码

.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

ButtonID1    equ    2003   
ButtonID2    equ    2004

    WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
    WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
   
.DATA
    szClassName db "MASMPlus_Class",0
   
.DATA?
    hInstance    dd ?
    hButton1        dd     ?
    hButton2        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,CS_HREDRAW or CS_VREDRAW or CS_BYTEALIGNWINDOW
    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
    invoke CreateWindowEx,NULL,ADDR szClassName,CTXT("http://www.aogosoft.com"),WS_OVERLAPPEDWINDOW,200,200,400,200,NULL,NULL,hInst,NULL
    mov hWnd,eax
   
INVOKE CreateWindowEx, NULL, CTEXT("button"), CTEXT("BT1"),\
WS_CHILD or WS_VISIBLE or WS_TABSTOP,\
15, 18, 80, 25, hWnd, ButtonID1, hInst, NULL
mov hButton1, eax

INVOKE CreateWindowEx, NULL, CTEXT("button"), CTEXT("BT2"),\
WS_CHILD or WS_VISIBLE or WS_TABSTOP,\
103, 19, 80, 25, hWnd, ButtonID2, hInst, NULL
mov hButton2, 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
    LOCAL szBuffer[10]    :BYTE
    .if uMsg==WM_CREATE
       
    .elseif uMsg == WM_DESTROY
        invoke PostQuitMessage,NULL
    .elseif uMsg == WM_COMMAND
        mov eax,wParam
       
.IF ax==ButtonID1    ;我们在这里响应按键的动作
shr eax,16
.IF ax==BN_CLICKED
        invoke    wsprintf,addr szBuffer,CTXT("%s"),CTEXT("Button1")
        invoke    MessageBox,hWin,addr szBuffer,NULL,NULL
.ENDIF
.ENDIF    

.IF ax==ButtonID2
shr eax,16
.IF ax==BN_CLICKED
        invoke    wsprintf,addr szBuffer,CTXT("%s"),CTEXT("Button2")
        invoke    MessageBox,hWin,addr szBuffer,NULL,NULL
.ENDIF
.ENDIF

    .else
        invoke DefWindowProc,hWin,uMsg,wParam,lParam
    .endif
    ret
WndProc endp

END START

wpe1.jpg (7840 字节)

参考:

1.Iczelion's Win32 Assembly 教程 Tutorial 9: Child Window Controls

三.透明效果的实现

    我们要实现透明窗口的效果,必须使得窗口拥有 WS_EX_LAYEDER 扩展属性,当然可以在创建的时候

直接指定,这里我们绕个弯,多讲一些,使用 GetWindowLong 取当前窗口的 GWL_EXSTYLE属性,加上

WS_EX_LAYERED 属性后再用 SetWindowLong设置回去。

    指定透明的API是 SetLayeredWindowAttributes 原形如下:

  第一个参数给定窗口的handler;第二个参数,给出一个眼色值;第三个参数给出透明度的值,

0是最透明,最大255是最不透明的;后面是标志位,

LWA_COLORKEY  =1 将crKey给出的颜色指定为透明色

LWA_ALPHA     =2    将 bAlpha 给出的透明度作为窗口的透明度

  我们的程序中只使用了透明的功能。

;MASMPlus 代码模板 - 普通的 Windows 程序代码

.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

ButtonID1    equ    2003   
ButtonID2    equ    2004

LWA_ALPHA    equ    2
LWA_COLORKEY equ 1
WS_EXD_LAYERED    equ    80000h
    WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
    WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
   
.DATA
    szClassName db "MASMPlus_Class",0
    bAlpha         dd     0FFh
   
.DATA?
    hInstance    dd ?
    hButton1        dd     ?
    hButton2        dd     ?
    hWnd              HWND ?
.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
   
   
    mov wc.cbSize,sizeof WNDCLASSEX
    mov wc.style,CS_HREDRAW or CS_VREDRAW or CS_BYTEALIGNWINDOW
    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
    invoke CreateWindowEx,NULL,ADDR szClassName,CTXT("http://www.aogosoft.com"),WS_OVERLAPPEDWINDOW,200,200,400,200,NULL,NULL,hInst,NULL
    mov hWnd,eax

INVOKE CreateWindowEx, NULL, CTEXT("button"), CTEXT("虚"),\
WS_CHILD or WS_VISIBLE or WS_TABSTOP,\
15, 18, 80, 25, hWnd, ButtonID1, hInst, NULL
mov hButton1, eax

INVOKE CreateWindowEx, NULL, CTEXT("button"), CTEXT("实"),\
WS_CHILD or WS_VISIBLE or WS_TABSTOP,\
103, 19, 80, 25, hWnd, ButtonID2, hInst, NULL
mov hButton2, eax

    invoke    GetWindowLong,hWnd,GWL_EXSTYLE
    or             eax,WS_EXD_LAYERED
    invoke    SetWindowLong,hWnd,GWL_EXSTYLE,eax
invoke     SetLayeredWindowAttributes,hWnd,0,bAlpha,LWA_ALPHA    

    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
    LOCAL szBuffer[10]    :BYTE
    .if uMsg==WM_CREATE

       
    .elseif uMsg == WM_DESTROY
        invoke PostQuitMessage,NULL
       
    .elseif uMsg == WM_COMMAND
        mov eax,wParam
       
.IF ax==ButtonID1         ;虚
shr eax,16
.IF ax==BN_CLICKED
        mov    eax,100
        mov    bAlpha,eax
.ENDIF
.ENDIF    

.IF ax==ButtonID2            ;实
shr eax,16
.IF ax==BN_CLICKED
        mov    eax,255
        mov    bAlpha,eax
.ENDIF
.ENDIF

invoke     SetLayeredWindowAttributes,hWnd,0,bAlpha,LWA_ALPHA     ;设置透明

    .else
        invoke DefWindowProc,hWin,uMsg,wParam,lParam
    .endif
    ret
WndProc endp

END START

   当点击 “虚” 按钮时,窗口会变得透明,当点击 “实” 按钮时,窗口会恢复。

wpe3.jpg (10744 字节)

   有兴趣的读者还可以试验一下更多的功能。需要注意的是

LWA_ALPHA LWA_COLORKEY    WS_EXD_LAYERED  在SDK中并没有定义,需要在程序中定义一下。

      根据上面的例子,我们还可以编写隐藏任务栏的小程序。同样是设置两个按钮,

一个是隐藏,一个是显示。然后在程序中加入下面的代码即可:

        invoke     FindWindow,CTXT('Shell_TrayWnd'),NULL
        mov         hDesktop,eax

.IF ax==ButtonID1         ;隐藏
    invoke    ShowWindow,hDesktop,SW_HIDE
.ENDIF    

.IF ax==ButtonID2            ;显示
    invoke    ShowWindow,hDesktop,SW_RESTORE
.ENDIF

       至于放到什么地方,请读者发挥自己的想象力~

参考:

1.SetLayeredWindowAttributes   http://msdn2.microsoft.com/en-us/library/ms633540(VS.85).aspx

SetLayeredWindowAttributes Function

The SetLayeredWindowAttributes function sets the opacity and transparency color key of a layered window.

Syntax

BOOL SetLayeredWindowAttributes(      
    HWND hwnd,
    COLORREF crKey,
    BYTE bAlpha,
    DWORD dwFlags
);

Parameters

hwnd
[in] Handle to the layered window. A layered window is created by specifying WS_EX_LAYERED when creating the window with the CreateWindowEx function or by setting WS_EX_LAYERED via SetWindowLong after the window has been created.
crKey
[in] COLORREF structure that specifies the transparency color key to be used when composing the layered window. All pixels painted by the window in this color will be transparent. To generate a COLORREF, use the RGB macro.
bAlpha
[in] Alpha value used to describe the opacity of the layered window. Similar to the SourceConstantAlpha member of the BLENDFUNCTION structure. When bAlpha is 0, the window is completely transparent. When bAlpha is 255, the window is opaque.
dwFlags
[in] Specifies an action to take. This parameter can be one or more of the following values.
LWA_COLORKEY
Use crKey as the transparency color.
LWA_ALPHA
Use bAlpha to determine the opacity of the layered window.

Return Value

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.



<<<上一篇
欢迎访问AoGo汇编小站:http://www.aogosoft.com
下一篇>>>