用MasmPlus学习汇编语言(8)
相关的例子:下载>>> 作者:Zoologist 于2008-4-14上传 

一.单选按钮

    Radio button 中文名称 “单选按钮”。从名称看就能知道是一种特殊的按钮。与之相对,

还有一种可以多选的,叫做 Check Box。今天我们的就编写一个选择更换桌面墙纸的程序。

更换墙纸,我们使用SystemParametersInfo API,这个函数我们在前面多次使用过。与前面

不同,这次我们使用的是 SPI_SETDESKWALLPAPER 这个参数。有一点需要注意的是,2003/XP/2000

操作系统下这个参数后面给出的桌面墙纸不能是 jpg 格式。说明如下:

SPI_SETDESKWALLPAPER Sets the desktop wallpaper. The value of the pvParam parameter determines the new wallpaper. To specify a wallpaper bitmap, set pvParam to point to a NULL-terminated string containing the full path to the bitmap file. Setting pvParam to "" removes the wallpaper. Setting pvParam to SETWALLPAPER_DEFAULT or NULL reverts to the default wallpaper.

The pvParam parameter can specify a .jpg file.

Windows Server 2003 and Windows XP/2000:  The pvParam parameter cannot specify a .jpg file.

程序如下:

;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

   
    RadioID01        equ     2001
    RadioID02        equ     2002
    RadioID03        equ     2003   
    ButtonID             equ     2004
   
    WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
    WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
   
.DATA
    szClassName db "MASMPlus_Class",0
    num             dd 0abH
    szBuffer        db     100 dup (0)   
   
    szWallPaper01 db    "Wall1",0
    szWallPaper02 db     "Wall2",0
    szWallPaper03 db    "Wall3",0

    WallPaper    dd    0
   
.DATA?
    hInstance    dd ?
    hRadio01        dd     ?
    hRadio02        dd     ?
    hRadio03        dd     ?
    hButton        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,300,200,NULL,NULL,hInst,NULL
    mov hWnd,eax
   
;---------- [Create Radio] ----------
INVOKE CreateWindowEx, NULL, CTXT("button"), addr szWallPaper01,\
WS_CHILD or WS_VISIBLE or WS_TABSTOP or BS_AUTORADIOBUTTON,\
16, 16, 100, 39, hWnd, RadioID01, hInst, NULL
mov hRadio01, eax

;---------- [Create Radio] ----------
INVOKE CreateWindowEx, NULL, CTXT("button"), addr szWallPaper02,\
WS_CHILD or WS_VISIBLE or WS_TABSTOP or BS_AUTORADIOBUTTON,\
16, 64, 100, 47, hWnd, RadioID02, hInst, NULL
mov hRadio02, eax

;---------- [Create Radio] ----------
INVOKE CreateWindowEx, NULL, CTXT("button"), addr szWallPaper03,\
WS_CHILD or WS_VISIBLE or WS_TABSTOP or BS_AUTORADIOBUTTON,\
16, 112, 100, 55, hWnd, RadioID03, hInst, NULL
mov hRadio03, eax   

;---------- [Create the Control Window] ----------
INVOKE CreateWindowEx, NULL, CTXT("button"), CTXT("Change"),\
WS_CHILD or WS_VISIBLE or WS_TABSTOP,\
129, 25, 115, 120, hWnd, ButtonID, hInst, NULL
mov hButton, 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

.elseif uMsg == WM_COMMAND
mov eax,wParam
       
        .IF ax==RadioID01 ;我们在这里响应按键的动作
        shr eax,16
        .IF ax==BN_CLICKED
            mov     WallPaper,1
        .ENDIF
        .ENDIF
       
        .IF ax==RadioID02
        shr eax,16
        .IF ax==BN_CLICKED
            mov     WallPaper,2
        .ENDIF
        .ENDIF

        .IF ax==RadioID03
        shr eax,16
        .IF ax==BN_CLICKED
            mov     WallPaper,3
        .ENDIF
        .ENDIF

        .IF ax==ButtonID
        shr eax,16
        .IF ax==BN_CLICKED
            .if         WallPaper==1
                invoke     SystemParametersInfo,SPI_SETDESKWALLPAPER,NULL,CTXT("F:\汇编通讯\MasmPlus\1.bmp"),1
            .elseif      WallPaper==2
                invoke     SystemParametersInfo,SPI_SETDESKWALLPAPER,NULL,CTXT("F:\汇编通讯\MasmPlus\2.bmp"),1
            .elseif     WallPaper==3   
                invoke     SystemParametersInfo,SPI_SETDESKWALLPAPER,NULL,CTXT("F:\汇编通讯\MasmPlus\3.bmp"),1                
            .endif    
        .ENDIF
        .ENDIF
       
    .elseif uMsg == WM_DESTROY
        invoke PostQuitMessage,NULL
    .else
        invoke DefWindowProc,hWin,uMsg,wParam,lParam
    .endif
    ret
WndProc endp

END START 

   运行结果:

r1.PNG (5519 字节)

    选择你想要的,然后点Change按钮,即可更换。

二.光渗视幻觉

    最近在读《数学趣闻集锦(上)》,上面提到了“光渗视幻觉”。

   “视幻觉是由于人们的注意力和眼睛的构造两者造成的.当我们观察一个具有明暗对象的区域时,

不固定的东西在我们眼睛中是不完全清楚的,光线进入位于我们眼 后的视网膜时扩散了.结果明亮的

光线或亮的区域便溢出,并渗入到视网膜上影像的暗区.这样一来,亮的区域就显得比同等大小的暗的

区域要大一些,就像下图所 示的那样.这也解释了为什么穿暗色的衣服,特别是黑的,比起你穿亮丽的

衣服或同等式样的白色衣服,会使你显得更为瘦长.这种幻觉称为光渗,它是由19世纪德国的物理学家和

生理学家赫尔姆霍兹(Herman LFvon Helmholtz18211894)发现的.” 【参考1

    下面这个图片中心的方块,哪个看起来大一点呢?

 

    下面我们就设计一个程序来验证这个问题,结合我们前面所学的绘图和获取键盘消息的知识,

 ;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
   
    WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
    WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD


.DATA
    szAppName db "Herman's",0
grRight        db    0h
grLeft        db    0h
rectwhole    RECT <0>

.DATA?
    hInstance    dd ?
    cxClient        dd ?
    cyClient        dd     ?
rectright    RECT    <>
rectleft        RECT    <>

.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,iCmdShow:DWORD
    LOCAL wndclass :WNDCLASSEX
    LOCAL msg         :MSG
    local hWnd         :HWND
    mov wndclass.cbSize,sizeof WNDCLASSEX   
    mov wndclass.style,CS_HREDRAW or CS_VREDRAW   
    mov wndclass.lpfnWndProc,offset WndProc

    mov wndclass.cbClsExtra,0
    mov wndclass.cbWndExtra,0
   
    push hInst
    pop wndclass.hInstance
   
    invoke LoadIcon,NULL,IDI_APPLICATION
    mov wndclass.hIcon,eax   
   
    invoke LoadCursor,NULL,IDC_ARROW
    mov wndclass.hCursor,eax   
   
    invoke GetStockObject,WHITE_BRUSH
    mov wndclass.hbrBackground,EAX
   
    mov wndclass.lpszMenuName,NULL
    mov wndclass.lpszClassName,offset szAppName

    mov wndclass.hIconSm,0
   
    invoke RegisterClassEx, ADDR wndclass
    .if (EAX==0)
        invoke MessageBox,NULL,CTXT("This program requires Windows NT!"),addr szAppName,MB_ICONERROR         
        ret
    .endif

    invoke CreateWindowEx,
                    NULL,
                    ADDR szAppName,                          ;window class name
                    CTXT("halo effect"), ;window caption
                    WS_OVERLAPPEDWINDOW,                     ;window style
                    CW_USEDEFAULT,                             ;initial x position
                    CW_USEDEFAULT,                             ;initial y position
                    CW_USEDEFAULT,                          ;initial x size
                    CW_USEDEFAULT,                             ;initial y size
                    NULL,                                         ;parent window handle
                    NULL,                                         ;window menu handle
                    hInstance,                                 ;program instance handle
                    NULL                                         ;creation parameters
    mov hWnd,eax
   
    invoke ShowWindow,hWnd,iCmdShow
    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 hwnd:DWORD,message:DWORD,wParam :DWORD,lParam :DWORD

    LOCAL hdc                  :HDC
    LOCAL tmpx,tmpy        :DWORD
    LOCAL ps                  :PAINTSTRUCT
    LOCAL szBuffer[256]    :BYTE
   
    .if message == WM_SIZE
        mov         eax,lParam             ;cxClient = LOWORD (lParam)
        and         eax,0FFFFh
        mov         cxClient,eax
        mov    rectwhole.right,eax
       
        mov         eax,lParam
        shr         eax,16
        mov         cyClient,eax         ;cyClient = HIWORD (lParam)
        mov         rectwhole.bottom,eax
            ret         

        .elseif message == WM_KEYDOWN
                .if     wParam == VK_UP
                        add         grRight,5
                .elseif wParam == VK_DOWN
                        sub         grRight,5
                .elseif wParam == VK_LEFT
                        add         grLeft,5
                .elseif wParam == VK_RIGHT
                        sub         grLeft,5
                .endif        
                invoke     InvalidateRect,hwnd,addr rectwhole,FALSE
    .elseif message == WM_PAINT
        invoke    BeginPaint,hwnd,addr ps
        mov         hdc,eax

        xor         edx,edx
        mov         eax,cxClient   
        mov         ecx,9
        div         ecx
        mov         tmpx,eax         ;tmpx = cxClient / 9

        xor         edx,edx
        mov         eax,cyClient   
        mov         ecx,5
        div         ecx
        mov         tmpy,eax         ;tmpy = cyClient / 5
       
        mov         eax,tmpy
        mov         ecx,4
        mul         ecx
        push         eax             ;eax = 4 * cyClient / 5
        mov         rectleft.bottom,eax
       
        mov         eax,tmpx
        mov         ecx,4
        mul         ecx
        push         eax             ;eax = 4 * cxClient / 9
        mov         rectleft.right,eax
       
        mov         eax,tmpy
        push         eax
        mov         rectleft.top,eax
       
        mov         eax,tmpx
        push         eax
        mov         rectleft.left,eax
       
        push         hdc
        call         Rectangle    ;绘制左边大长方形

        xor         eax,eax
        mov         al,grLeft
        shl         eax,8
        mov         al,grLeft
        shl         eax,8
        mov         al,grLeft
        mov         ebx,eax
    invoke    CreateSolidBrush,eax
        mov         ebx,eax
    invoke    FillRect,hdc,addr rectleft,ebx
   
        mov         eax,tmpy
        mov         ecx,3
        mul         ecx
        push         eax             ;eax = 3 * cyClient / 9
       
        mov         eax,tmpx
        mov         ecx,3
        mul         ecx
        push         eax             ;eax = 3 * cxClient / 5

        mov         eax,tmpy
        add         eax,eax
        push         eax

        mov         eax,tmpx
        add         eax,eax
        push         eax
       
        push         hdc
        call         Rectangle    ;绘制左边小长方形    

   
        push         tmpy
       
        mov         eax,tmpx
        mov         ecx,5
        mul         ecx
        push         eax             ;eax = 5 * cxClient / 9

        mov         eax,tmpy
        mov         ecx,4
        mul         ecx
        push         eax

        mov         eax,tmpx
        mov         ecx,8
        mul         ecx
        push         eax
       
        push         hdc
        call         Rectangle    ;绘制右边大长方形        

        mov         eax,tmpy
        mov         ecx,3
        mul         ecx
        push         eax
        mov         rectright.bottom,eax
       
        mov         eax,tmpx
        mov         ecx,7
        mul         ecx
        push         eax             ;eax = 8 * cxClient / 9
        mov         rectright.right,eax
       
        mov         eax,tmpy
        mov         ecx,2
        mul         ecx
        push         eax
        mov         rectright.top,eax
       
        mov         eax,tmpx
        mov         ecx,6
        mul         ecx
        push         eax
        mov         rectright.left,eax
       
        push         hdc
        call         Rectangle    ;绘制右边小长方形
       
        xor         eax,eax
        mov         al,grRight
        shl         eax,8
        mov         al,grRight
        shl         eax,8
        mov         al,grRight
    invoke    CreateSolidBrush,eax
        mov         ebx,eax
    invoke    FillRect,hdc,addr rectright,ebx

        invoke    EndPaint,hwnd,addr ps
        ret
    .elseif message == WM_DESTROY
       
        invoke PostQuitMessage,NULL        
    ret   
    .endif   
   
    invoke DefWindowProc,hwnd, message, wParam, lParam
    ret
   
WndProc endp
END START

    运行结果:

p2.PNG (12445 字节)

    你可以使用光标上下左右调整明暗。试试看什么时候感觉差别最大。

    江湖传闻:据说美国码头搬运军火的装运工曾经因为箱子太沉太重而罢工。后来心理学家给军方一个建议,

就是使用绿色的箱子装军火,而原来的箱子都是黑色的。改变颜色之后,装运工普遍觉得箱子“轻了”。

    个人观点:在目前所有的科学研究中,人类在心理学方面成就不大,思维是非线性不容易量化的,并且

出于道德伦理上面的限制,科学家也无法做过多的试验,而实验是科学的基础。很多时候,心理学的实验凭借

受试者的“感觉”,也是非常不精确的。

参考:

1.        http://www.bioon.com/popular/math/305225.shtml

2.        http://zhidao.baidu.com/question/2311680.html

色彩的膨胀与收缩感

据说法兰西国旗一开始是由面积完全相等的红、白、蓝三色制成的,但是旗帜升到空中后在感觉是三色的面积并不相等,

于是召集了有关色彩专家进行专门研究,最后把三色的比例调整到红35%、白33%、蓝37%的比例时才感觉到面积相等。

这究竟是什么原因呢?

因为当各种不同波长的光同时通过水晶体时,聚集点并不完全在视网膜的一个平面上,因此在视网膜上的影像的清晰度

就有一定差别。长波长的暖色影像似焦距不准 确,因此在视网膜上所形成的影像模糊不清,似乎具有一种扩散性;短波长

的冷色影像就比较清晰,似乎具有某种收缩性。所以,我们平时在凝视红色的时候,时间 长了会产生眩晕现象,景物形象

模糊不清似有扩张运动的感觉。如果我们改看青色,就没有这种现象了。如果我们将红色与蓝色对照着看,由于色彩同时

对比的作 用,其面积错视现象就会更加明显。

色彩的膨胀、收缩感不仅与波长有关,而且还与明度有关。由于球面像差物理原理,光亮的物体在视网膜上所成影像

的轮廓外似乎有一圈光圈围绕着,使物体在 视网膜上的影像轮廓扩大了,看起来就觉得比实物大一些,如通电发亮的电灯

钨丝比通电前的钨丝似乎要粗得多,生理物理学上称这种现象为光渗现象。歌德在 《论颜色的科学》一文中指出:

两个圆点同样面积大小,在白色背景上的黑圆点比黑色背景上的白圆点要小15同一个人。日出和日落时,地平线上

仿佛出现一个凹陷似的,这也是光渗作 用而引起的视觉现象。

宽度相同的印花黑白条纹布,感觉上白条子总比黑条子宽;同样大小的黑白方格子布,白方格子要比黑方格略大一些。超市中,

小商品、小包装若要使它显眼一些, 宜采用鲜艳的浅色;如果要它显得高贵精致,宜采用沉着的深色或黑色。为了扩大建筑

或交通工具的室内空间感,色彩设计宜采用乳白、浅米、象牙等淡雅明快的色 调,像卫生间等特别狭小的空间还可以利用

镜子作墙面,利用镜子的反射来增加面积的宽畅度和明亮度。



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