sysdata.asm
来自「这是一些例程」· 汇编 代码 · 共 429 行
ASM
429 行
;----------------------------------------------------------------------------;
; SYSDATA.ASM ;
;----------------------------------------------------------------------------;
; Sample program that accesses the SYSINFO.DLL functions. ;
;----------------------------------------------------------------------------;
.model small, pascal, nearstack
.286
?WINPROLOGUE = 1
include win.inc ; Converted from WINDOWS.H
include dll.inc ; SYSINFO.DLL definitions
include sysdata.inc ; equates for dialog controls
;----------------------------------------------------------------------------;
; Prototypes & External Definitions ;
;----------------------------------------------------------------------------;
NPBYTE TYPEDEF NEAR PTR BYTE
WinMain PROTO PASCAL, hInstance:HANDLE, hPrevInstance:HANDLE,
lpszCmdLine:LPSTR, nCmdShow:SWORD
WndProc PROTO FAR PASCAL, :HWND, :WORD, :SWORD, :SDWORD
SetDlg PROTO, :HWND
SetKeyb PROTO, :HWND
SetTime PROTO, :HWND
int2hex PROTO, :WORD, :NPBYTE
SetItem PROTO, :HWND, :WORD, :WORD
extern __astart:proc ; When Windows load an app, it expects astart
; to have the necessary start-up code. We get
; astart from APPENTRY.ASM
;----------------------------------------------------------------------------;
; Numeric Equates ;
;----------------------------------------------------------------------------;
TIMER_SECS EQU 1000t ; timer interval: 1000 mill = 1 second
fNUMLOCK EQU 020h ; Flags within the Keyboard Status word
fCAPLOCK EQU 040h ; that indicate different key modes
fSHIFTS EQU 003h
fCONTROL EQU 004h
;----------------------------------------------------------------------------;
; Data Segments ;
;----------------------------------------------------------------------------;
.const
szAppName SBYTE "SysData",0
szSysIcon SBYTE "SysIcon",0
szTooManyTimers SBYTE "Too many clocks or timers!",0
szError SBYTE "Error",0
szCoNotInst SBYTE "Not Found",0
szCoInst SBYTE "Found",0
szOff SBYTE "Off",0
szOn SBYTE "On",0
hex BYTE '0123456789ABCDEF' ; Table of hexadecimal digits
; for int2hex function
ProcTable NPBYTE sz8086
NPBYTE sz80186
NPBYTE sz80286
NPBYTE sz80386
NPBYTE sz80486
sz8086 SBYTE "8086",0
sz80186 SBYTE "80186",0
sz80286 SBYTE "80286",0
sz80386 SBYTE "80386",0
sz80486 SBYTE "80486",0
.data
HexValue BYTE "xxxxh",0
Initialized BYTE 0
;----------------------------------------------------------------------------;
; Code Segment ;
;----------------------------------------------------------------------------;
.code
;----------------------------------------------------------------------------;
; WinMain ;
;----------------------------------------------------------------------------;
; ;
; Main routine called by Windows in program start. If no previous instances, ;
; sets up a window class and registers it, then sets up the message loop. ;
; ;
;----------------------------------------------------------------------------;
WinMain PROC, hInstance:HANDLE, hPrevInstance:HANDLE,
lpszCmdLine:LPSTR, nCmdShow:SWORD
LOCAL msg:MSG, wndclass:WNDCLASS
; Local variables: msg: message to be used in the message loop
; wndclass: temp. to store window class
; x,y Start-Client: Size of Initial Window
;
;--- Check for previous instances
;
.IF (hPrevInstance == 0)
lea di, wndclass ; because we use a NEARSTACK,
ASSUME di:PTR WNDCLASS ; ss=ds
mov WORD PTR [di].lpfnWndProc, LROFFSET WndProc
mov WORD PTR [di].lpfnWndProc+2, SEG WndProc
mov [di].cbWndExtra, DLGWINDOWEXTRA
xor ax,ax
mov [di].style,ax
mov [di].cbClsExtra, ax
INVOKE LoadIcon, hInstance, ADDR szSysIcon
mov [di].hIcon, ax
mov ax, hInstance
mov [di].hInstance, ax
INVOKE LoadCursor, NULL, IDC_ARROW
mov [di].hCursor, ax
mov [di].hbrBackground, COLOR_WINDOW +1
xor ax, ax
mov WORD PTR [di].lpszMenuName, ax
mov WORD PTR [di].lpszMenuName+2, ax
mov WORD PTR [di].lpszClassName, OFFSET szAppName
mov WORD PTR [di].lpszClassName+2, ds
INVOKE RegisterClass, di
.IF (ax == 0)
mov ax, FALSE
jmp doRet
.ENDIF
ASSUME di:NOTHING
.ENDIF ;--- End of IF (hPrevInstance == 0)
INVOKE CreateDialog, hInstance, ADDR szAppName, 0, NULL
mov si, ax
INVOKE ShowWindow, si, nCmdShow
;---- Create Timer for Window
INVOKE SetTimer, si, 1, TIMER_SECS, NULL
.IF (ax == 0)
INVOKE MessageBox, si,ADDR szTooManyTimers,
ADDR szAppName,
MB_ICONEXCLAMATION OR MB_OK
mov ax, FALSE
INVOKE PostQuitMessage, 0 ; Quit.
.ENDIF
;---- Message Loop
.WHILE TRUE
INVOKE GetMessage, ADDR msg, NULL, 0, 0
.BREAK .IF (ax == 0)
INVOKE TranslateMessage, ADDR msg
INVOKE DispatchMessage, ADDR msg
.ENDW
mov ax, msg.wParam
doRet:
ret
WinMain ENDP
;----------------------------------------------------------------------------;
; SetTime ;
; ;
; Reads the System Time with GetSysTime, sets up the Dialog Item TIME_TEXT ;
; with the resulting string. Then does the same for DATE_TEXT. ;
;----------------------------------------------------------------------------;
SetTime PROC, hDlg:HWND
INVOKE GetSysTime
INVOKE SetDlgItemText, hDlg, TIME_TEXT, dx::ax
INVOKE GetSysDate
INVOKE SetDlgItemText, hDlg, DATE_TEXT, dx::ax
ret
SetTime ENDP
;----------------------------------------------------------------------------;
; SetKeyb ;
; ;
; Assumes DI has the keyboard status. Gets the control's text into buffer. ;
; If the control's status has changed (if buffer+1 is not what it would be ;
; set to) then set it to On or Off, otherwise return ;
;----------------------------------------------------------------------------;
SetItem PROC, hDlg:HWND, item:WORD, flag:WORD
LOCAL buffer[3]:BYTE
INVOKE GetDlgItemText, hDlg, item, ADDR buffer, 3
mov bx, di
and bx, flag
.IF bx
.IF (byte ptr buffer+1 != 'n') ; 'n' means we have 'On'
mov bx, OFFSET szOn
.ELSE
jmp doRet
.ENDIF
.ELSE
.IF (byte ptr buffer+1 != 'f') ; 'f' means we have 'Off'
mov bx, OFFSET szOff
.ELSE
jmp doRet
.ENDIF
.ENDIF
INVOKE SetDlgItemText, hDlg, item, ds::bx
doRet:
ret
SetItem ENDP
;----------------------------------------------------------------------------;
; SetKeyb ;
; ;
; Reads the keyboard status with GetSysInfo, then uses SetItem to set the ;
; appropiate controls in the dialog box. ;
;----------------------------------------------------------------------------;
SetKeyb PROC, hDlg:HWND
INVOKE GetSysInfo
mov es, dx
mov si, ax
ASSUME SI:PTR SYSINFO
mov di, es:[si].wKbStatus
INVOKE SetItem, hDlg, NUMLOCK,fNUMLOCK
INVOKE SetItem, hDlg, CAPLOCK,fCAPLOCK
INVOKE SetItem, hDlg, CONTROL,fCONTROL
INVOKE SetItem, hDlg, SHIFTS, fSHIFTS
ASSUME SI:NOTHING
ret
SetKeyb ENDP
;----------------------------------------------------------------------------;
; SetDlg ;
; ;
; Reads the System Time with GetSysTime, sets up the Dialog Item TIME_TEXT ;
; with the resulting string. Then does the same for DATE_TEXT. Then gets the ;
; other system information with GetSysInfo and sets the appropiate Dialog ;
; Items. Note that KEYBSTAT and VIDEOMODE take the hex of the value returned.;
; Since ES is not guaranteed to be preserved, have to restore it after every ;
; SetDlgItemInt or Text. A table is used to look up the processor type. ;
;----------------------------------------------------------------------------;
SetDlg PROC, hDlg:HWND
INVOKE SetTime, hDlg
INVOKE SetKeyb, hDlg
INVOKE GetSysInfo
mov di, dx
mov si, ax
ASSUME SI:PTR SYSINFO
lea ax, [si].szWinVer
INVOKE SetDlgItemText, hDlg, WINVERSION, di::ax
lea ax, [si].szDOSVer
INVOKE SetDlgItemText, hDlg, DOSVERSION, di::ax
lea ax, [si].szROM
INVOKE SetDlgItemText, hDlg, ROMBIOS, di::ax
mov es, di
mov al, es:[si].cFloppy
INVOKE SetDlgItemInt, hDlg, FLOPPIES, al, FALSE
mov es, di
mov bl, es:[si].cVidMode
INVOKE int2hex, bl, ADDR HexValue
INVOKE SetDlgItemText, hDlg, VIDEOMODE, ADDR HexValue
mov es, di
.IF es:[si].bCoproc
mov ax, OFFSET szCoInst
.ELSE
mov ax, OFFSET szCoNotInst
.ENDIF
INVOKE SetDlgItemText, hDlg, COPROC, ds::ax
mov es, di
mov bl, es:[si].cProcType
.IF (bl < 5)
xor bh, bh
shl bx, 1
mov ax, ProcTable[bx]
.ELSE
mov ax, OFFSET szError
.ENDIF
INVOKE SetDlgItemText, hDlg, PROCTYPE, ds::ax
ASSUME SI:NOTHING
ret
SetDlg ENDP
;----------------------------------------------------------------------------;
; int2hex
; Converts a WORD into its hexadecimal representation.
; Based on Chapter 4 of the MASM Programmer's guide
;----------------------------------------------------------------------------;
int2hex PROC NEAR USES ax bx si, number:WORD, string:NPBYTE
mov bx, OFFSET hex ; load table address
mov si, string
mov ax, number ; load value to convert
shr ax, 12 ; shift right to get into table index
and ax, 0000Fh ; remove all but least-significant byte
xlat ; translate
mov [si], al ; store as last byte
mov ax, number ; load value to convert
shr ax, 8 ; shift right to get into table index
and ax, 0000Fh ; remove all but least-significant byte
xlat ; translate
mov [si+1], al ; store as third to last byte
mov ax, number ; load value to convert
shr ax, 4 ; shift right to get into table index
and ax, 0000Fh ; remove all but least-significant byte
xlat ; translate
mov [si+2], al ; store as second to last byte
mov ax, number ; load value to convert
and ax, 0000Fh ; remove all but least-significant byte
xlat ; translate
mov [si+3], al ; store as last byte in string
ret
int2hex ENDP
;----------------------------------------------------------------------------;
; WndProc ;
; ;
; Because this is a Dialog Box/Window, we cannot intercept the WM_CREATE ;
; message to set up the initial values of the Dialog Box. We have to wait for;
; the timer or the keyboard status to change to set values. Initialized is a ;
; flag to determine if the other values need to be set. ;
; If we get a timer message, set the time and date. ;
; If we get a KEYDOWN or KEYUP message, set the Keyboard Status ;
; If we get a WININICHANGE, SETFOCUS, or SYSKEYUP, some data could change. ;
; Reset the dialog items ;
; A Close Window will get us out. ;
;----------------------------------------------------------------------------;
WndProc PROC FAR PASCAL, hWnd:HWND, iMessage:WORD, wParam:SWORD,
lParam:SDWORD
; Windows gives us: the handle of the Window, the Message ID,
; and two parameters for the message
.IF (iMessage == WM_TIMER)
.IF Initialized
INVOKE SetTime, hWnd
.ELSE
mov Initialized, TRUE
INVOKE SetDlg, hWnd
.ENDIF
.ELSEIF (iMessage == WM_KEYDOWN) || (iMessage == WM_KEYUP)
.IF Initialized
INVOKE SetKeyb, hWnd
.ELSE
mov Initialized, TRUE
INVOKE SetDlg, hWnd
.ENDIF
.ELSEIF (iMessage == WM_SETFOCUS) || (iMessage == WM_SYSKEYUP)\
|| (iMessage == WM_WININICHANGE)
INVOKE SetDlg, hWnd
jmp doDefault
.ELSEIF (iMessage==WM_DESTROY)
INVOKE KillTimer, hWnd, 1
INVOKE PostQuitMessage, 0
.ELSE
doDefault:
INVOKE DefWindowProc, hWnd, iMessage, wParam,lParam
jmp doRet
.ENDIF
mov ax, 0
cwd
doRet:
ret
WndProc ENDP
END __astart ; so that the code of the application will
; start with the Windows start-up code
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?