您的位置:首页 > 移动开发

[07-04] 用MASM32编写全屏窗口程序

2006-07-03 22:01 375 查看
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; 文件名: FullScr.asm
; 作  者:Purple Endurer(purpleendurer@163.com)
; 功 能: 演示程序在窗口模式和全屏模式间切换
; Date         log
;-------------------------------------------------
;2006-07-04   对代码作了一些优化
;2006-07-03    利用SetTimer()和GetAsyncKeyState()增加Esc键
;              作为从全屏切换回窗口模式的热键!
;              在全屏模式下,窗口接收不到WM_KEYDOWN消息
;2006-06-30    创建!可在全屏和窗口模式间切换!
;              在一个国外MASM32论坛上,看到有网友讨论如何用
;              MASM32编写全屏窗口程序。于是在
;              用VC 6.0写flash播放器——5、全屏播放
;              (http://blog.csdn.net/purpleendurer/archive/2005/12/07/545717.aspx)
;              的代码基础上改写。
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

.386
.model flat, stdcall
option casemap:none
include /masm32/include/windows.inc

include /masm32/include/user32.inc
include /masm32/include/gdi32.inc
include /masm32/include/kernel32.inc
include /masm32/include/shell32.inc

includelib /masm32/lib/user32.lib
includelib /masm32/lib/gdi32.lib
includelib /masm32/lib/kernel32.lib
includelib /masm32/lib/shell32.lib

WinMain proto :DWORD, :DWORD, :DWORD, :DWORD
SetFullScr PROTO :HWND
SetWinMode PROTO :HWND
SwitchMode PROTO :HWND

m_m2m MACRO d1, d2
    push d2
    pop d1
ENDM

;.const
c_ButtonID equ 1
c_TimerID equ 1

.data
g_szWinClsName db "DemoWinClass", 0
g_szAppName  db "全屏显示演示程序 by PurpleEndurer", 0
g_szBtnClsName db "button", 0
g_szFullScr db "全屏显示!", 0
g_szSetWinMode db "窗口显示! 按Esc键返回!", 0
g_szFailWinMode db "设置为窗口模式失败!", 0
g_szFailFullScrMode db "设置为全屏模式失败!", 0

g_bIsFull dword FALSE

.data?
g_hInstance HINSTANCE ?
g_hwndButton HANDLE ?
g_stOriginPos WINDOWPLACEMENT <>

.code
start:
    invoke GetModuleHandle, NULL
    mov    g_hInstance, eax
    invoke WinMain, g_hInstance, NULL, NULL, SW_SHOWDEFAULT
    invoke ExitProcess, eax

WinMain proc hInst:HINSTANCE, hPrevInst:HINSTANCE, CmdLine:LPSTR, CmdShow:DWORD
    LOCAL wc:WNDCLASSEX
    LOCAL msg:MSG
    LOCAL hwnd:HWND
    m_m2m   wc.cbSize, SIZEOF WNDCLASSEX
    m_m2m   wc.style, CS_HREDRAW or CS_VREDRAW
    m_m2m   wc.lpfnWndProc, OFFSET WndProc
    m_m2m   wc.cbClsExtra, NULL
    m_m2m   wc.cbWndExtra, NULL
    m_m2m   wc.hInstance, g_hInstance
    m_m2m   wc.hbrBackground, COLOR_WINDOW+1
    m_m2m   wc.lpszMenuName, NULL
    m_m2m   wc.lpszClassName, OFFSET g_szWinClsName
    invoke LoadIcon, NULL, IDI_APPLICATION
    mov   wc.hIcon, eax
    mov   wc.hIconSm, eax
    invoke LoadCursor, NULL, IDC_ARROW
    mov   wc.hCursor, eax
    invoke RegisterClassEx, addr wc
    INVOKE CreateWindowEx, NULL, ADDR g_szWinClsName, ADDR g_szAppName, /
           WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, /
           CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, /
           hInst, NULL
    mov   hwnd, eax
    invoke ShowWindow, hwnd, SW_SHOWNORMAL
    invoke UpdateWindow, hwnd
    .WHILE TRUE
        invoke GetMessage, ADDR msg, NULL, 0, 0
        .BREAK .IF (!eax)
        invoke TranslateMessage, ADDR msg
        invoke DispatchMessage, ADDR msg
    .ENDW
    mov eax, msg.wParam
    ret
WinMain endp

WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
    .IF uMsg==WM_DESTROY
         invoke PostQuitMessage, NULL

    .ELSEIF uMsg==WM_CREATE
        ;创建按钮
        invoke CreateWindowEx, NULL, ADDR g_szBtnClsName, ADDR g_szFullScr, /
                        WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON,/
                        25, 25, 560, 50, hWnd, c_ButtonID, g_hInstance, NULL
        mov  g_hwndButton, eax

    .ELSEIF uMsg==WM_COMMAND
        mov eax, wParam
        .IF lParam!=0
            .IF ax==c_ButtonID
                shr eax, 16
                .IF ax==BN_CLICKED
                        invoke SwitchMode, hWnd
                .ENDIF
            .ENDIF
        .ENDIF

    .ELSEIF uMsg==WM_TIMER
        invoke GetAsyncKeyState, VK_ESCAPE;Esc键
        test eax, 08000h
        jz @F
          invoke SwitchMode, hWnd

        @@:
    .ELSE
        invoke DefWindowProc, hWnd, uMsg, wParam, lParam
        ret
    .ENDIF
    xor eax, eax
    ret
WndProc endp

SwitchMode proc hWnd: HWND
    .if g_bIsFull==TRUE
        invoke KillTimer, hWnd, c_TimerID   ;清除定时器
        invoke SetWinMode, hWnd ;设置为窗口模式
        .IF eax==0
            invoke MessageBox, hWnd, ADDR g_szFailWinMode, ADDR g_szAppName, MB_ICONERROR
            ret
        .ENDIF
        m_m2m g_bIsFull, FALSE

        invoke SetWindowText, g_hwndButton, ADDR g_szFullScr    ;修改按钮的文本
    .else
        invoke SetFullScr, hWnd ;设置为全屏模式
        .IF eax==0
            invoke MessageBox, hWnd, ADDR g_szFailFullScrMode, ADDR g_szAppName, MB_ICONERROR
            ret
        .ENDIF
        m_m2m g_bIsFull, TRUE

        invoke SetTimer, hWnd, c_TimerID, 100, NULL ;启动定时器,以捕获Esc键
        invoke SetWindowText, g_hwndButton, ADDR g_szSetWinMode ;修改按钮的文本
    .endif

    ret
SwitchMode endp

;////////////////////////////////////////////////////////////////////////////
; 返回值:若失败,eax=0;若成功,eax !=0
;////////////////////////////////////////////////////////////////////////////
SetFullScr PROC hWnd: HWND
    LOCAL hDC: HWND
    LOCAL dwHorzres, dwVertres: DWORD
    invoke GetWindowPlacement, hWnd, ADDR g_stOriginPos
    invoke GetWindowLong, hWnd, GWL_STYLE

    xor eax, WS_CAPTION ;     push edi
                                             ;     mov edi, WS_CAPTION
                                             ;     not edi
                                             ;     and eax, edi
                                             ;     push edi
    
    invoke SetWindowLong, hWnd, GWL_STYLE, eax;//去掉标题栏
    invoke GetDC, hWnd
    mov hDC, eax
    invoke GetDeviceCaps, hDC, HORZRES
    mov dwHorzres, eax
    invoke GetDeviceCaps, hDC, VERTRES
    mov dwVertres, eax
    xor eax, eax
    invoke MoveWindow, hWnd, eax, eax, dwHorzres, dwVertres, TRUE
    xor eax, eax
    invoke SetWindowPos, hWnd, HWND_TOPMOST, eax, eax, dwHorzres, dwVertres, SWP_SHOWWINDOW ;全屏显示
    ret
SetFullScr ENDP

;////////////////////////////////////////////////////////////////////////////
; 返回值:若失败,eax=0;若成功,eax !=0
;////////////////////////////////////////////////////////////////////////////
SetWinMode PROC hWnd: HWND
    invoke GetWindowLong, hWnd, GWL_STYLE
    or eax, WS_CAPTION
    invoke SetWindowLong, hWnd, GWL_STYLE, eax  ;//恢复标题栏
    invoke ShowWindow, hWnd, SW_HIDE
    invoke SetWindowPlacement, hWnd, ADDR g_stOriginPos
    ret
SetWinMode ENDP

end start
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息