天天看點

MASM32程式設計示範程式在視窗模式和全屏模式間切換

當我們設定的強制休息時間到了,我們需要讓強制休息程式視窗在頂層全屏顯示,暫時把螢幕擋住,阻止使用者操作。

讓視窗全屏顯示的一般步驟是:

1、用GetWindowPlacement()擷取并儲存視窗目前尺寸、位置資訊

2、用GetWindowLong()取得用視窗屬性,用SetWindowLong()去除視窗标題欄屬性WS_CAPTION

3、用GetDeviceCaps()擷取螢幕尺寸

4、用SetWindowPos()設定視窗全屏顯示

還原到視窗模式的一般步驟是:

1、用GetWindowLong()取得用視窗屬性,用SetWindowLong()為視窗加上标題欄屬性WS_CAPTION

2、用SetWindowPlacement()将視窗恢複到全屏前的尺寸、位置

完整的示範程式可參考:

用MASM32編寫全屏視窗程式​

由于我們強制休息程式視窗使用了WS_POPUP風格,沒有标題欄,實作起來就更簡捷一些。

下面的示範程式允許使用者在視窗上點選滑鼠左鍵來進行視窗模式和全屏模式間的切換:

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Function: 點選滑鼠左鍵讓示範程式在視窗模式和全屏模式間切換
;   Author: PurpleEndurer
;   DevEnv: Win XP SP2 + MASM32 v7
;   log
; ----------------------------------------------------
; 2008-09-27 Created!
;
;參考: 用MASM32編寫全屏視窗程式
;javascript:void(0)
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

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

include /masm32/include/kernel32.inc
includelib /masm32/lib/kernel32.lib

include /masm32/include/user32.inc
includelib /masm32/lib/user32.lib

include /masm32/include/gdi32.inc
includelib /masm32/lib/gdi32.lib

WinMain proto :DWORD,  :DWORD, :DWORD, :DWORD
SetWinToScrRightDown proto
SetFullScrMode proto
SetWinMode proto

;.const
c_isFullMode equ 1b     ;視窗處于全屏模式标志

.data
g_szTimeWinClsName db "TimeWinCls", 0
g_szAppName  db "定時強制休息!", 0

g_dwFlag dd 0

;.data?
g_hHInstance HINSTANCE ?
g_hWndMain   HWND  ?
g_stOriginPos WINDOWPLACEMENT <>        ;用于儲存視窗模式時位置

.code
start:
    invoke GetModuleHandle,  NULL
    mov    g_hHInstance, eax
    invoke WinMain,  g_hHInstance, 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

    mov   wc.cbSize, SIZEOF WNDCLASSEX
    mov   wc.style,  CS_HREDRAW or CS_VREDRAW
    mov   wc.lpfnWndProc,  OFFSET WndProc
    mov   wc.cbClsExtra, NULL
    mov   wc.cbWndExtra, NULL
    push  g_hHInstance
    pop   wc.hInstance
    mov   wc.hbrBackground, 25
    mov   wc.lpszMenuName, NULL
    mov   wc.lpszClassName, OFFSET g_szTimeWinClsName
    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_szTimeWinClsName, ADDR g_szAppName/
       , WS_POPUP, 100,100, 500, 200, 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


;///
; 功能:讓以g_hWndMain為句柄的視窗全屏顯示
; 輸入: 無
; 輸出: 若失敗,eax=0;若成功,eax !=0
;///
SetFullScrMode PROC ;hWnd: HWND
    LOCAL dwHorzres, dwVertres: DWORD
    LOCAL hDC:  HDC

    ;--- 儲存視窗目前位置以便恢複
    invoke GetWindowPlacement, g_hWndMain, ADDR g_stOriginPos

    invoke GetDC, g_hWndMain
    mov hDC, eax

    ;--- 取螢幕尺寸
    invoke GetDeviceCaps, hDC, HORZRES
    mov dwHorzres, eax

    invoke GetDeviceCaps, hDC, VERTRES
    mov dwVertres, eax

    invoke ReleaseDC, g_hWndMain, hDC

    ;--- 全屏顯示
    xor eax, eax
    invoke SetWindowPos, g_hWndMain, HWND_TOPMOST/
        , eax, eax, dwHorzres, dwVertres, SWP_SHOWWINDOW
    ret
SetFullScrMode ENDP


;/
; 功能: 恢複以g_hWndMain為句柄的視窗顯示
; 輸入: 無
; 輸出: 若失敗,eax=0;若成功,eax !=0
;/
SetWinMode PROC ;hWnd: HWND
    invoke SetWindowPlacement, g_hWndMain, ADDR g_stOriginPos
    ret
SetWinMode ENDP

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

    .ELSEIF uMsg==WM_CREATE
        mov eax, hWnd
        mov g_hWndMain, eax

    .ELSEIF uMsg==WM_LBUTTONDOWN
        test g_dwFlag, c_isFullMode   ;視窗處于全屏模式嗎?
        .if ZERO?
            invoke SetFullScrMode      ; 否則置為全屏
            or g_dwFlag, c_isFullMode  ; 置全屏标志
        .else
            invoke SetWinMode          ;是則傳回視窗模式
            and g_dwFlag, not c_isFullMode ;取消全屏标志
        .endif
    .ELSE
        invoke DefWindowProc, hWnd, uMsg, wParam, lParam  
        ret
    .ENDIF

    xor eax, eax
    ret
WndProc endp
end