Файл dmenu.asm
Ideal
P586
Radix 16
Model flat
struc WndClassEx
cbSize dd 0
style dd 0
lpfnWndProc dd 0
cbClsExtra dd 0
cbWndExtra dd 0
hInstance dd 0
hIcon dd 0
hCursor dd 0
hbrBackground dd 0
lpszMenuName dd 0
lpszClassName dd 0
hIconSm dd 0
ends WndClassEx
struc Point
left dd 0
top dd 0
right dd 0
bottom dd 0
ends Point
struc msgStruc
hwnd dd 0
message dd 0
wParam dd 0
lParam dd 0
time dd 0
pt Point <>
ends msgStruc
MyMenu = 0065
ID_OPEN = 9C41
ID_SAVE = 9C42
ID_EXIT = 9C43
CS_VREDRAW = 0001
CS_HREDRAW = 0002
IDI_APPLICATION = 7F00
IDC_ARROW = 7F00
COLOR_WINDOW = 5
WS_EX_WINDOWEDGE = 00000100
WS_EX_CLIENTEDGE = 00000200
WS_EX_OVERLAPPEDWINDOW = WS_EX_WINDOWEDGE OR WS_EX_CLIENTEDGE
WS_OVERLAPPED = 00000000
WS_CAPTION = 00C00000
WS_SYSMENU = 00080000
WS_THICKFRAME = 00040000
WS_MINIMIZEBOX = 00020000
WS_MAXIMIZEBOX = 00010000
WS_OVERLAPPEDWINDOW = WS_OVERLAPPED OR \
WS_CAPTION OR \
WS_SYSMENU OR \
WS_THICKFRAME OR \
WS_MINIMIZEBOX OR \
WS_MAXIMIZEBOX
CW_USEDEFAULT = 80000000
SW_SHOW = 5
WM_COMMAND = 0111
WM_DESTROY = 0002
WM_CLOSE = 0010
MB_OK = 0
PROCTYPE ptGetModuleHandle stdcall \
lpModuleName :dword
PROCTYPE ptLoadIcon stdcall \
hInstance :dword, \
lpIconName :dword
PROCTYPE ptLoadCursor stdcall \
hInstance :dword, \
lpCursorName :dword
PROCTYPE ptLoadMenu stdcall \
hInstance :dword, \
lpMenuName :dword
PROCTYPE ptRegisterClassEx stdcall \
lpwcx :dword
PROCTYPE ptCreateWindowEx stdcall \
dwExStyle :dword, \
lpClassName :dword, \
lpWindowName :dword, \
dwStyle :dword, \
x :dword, \
y :dword, \
nWidth :dword, \
nHeight :dword, \
hWndParent :dword, \
hMenu :dword, \
hInstance :dword, \
lpParam :dword
PROCTYPE ptShowWindow stdcall \
hWnd :dword, \
nCmdShow :dword
PROCTYPE ptUpdateWindow stdcall \
hWnd :dword
PROCTYPE ptGetMessage stdcall \
pMsg :dword, \
hWnd :dword, \
wMsgFilterMin :dword, \
wMsgFilterMax :dword
PROCTYPE ptTranslateMessage stdcall \
lpMsg :dword
PROCTYPE ptDispatchMessage stdcall \
pmsg :dword
PROCTYPE ptSetMenu stdcall \
hWnd :dword, \
hMenu :dword
PROCTYPE ptPostQuitMessage stdcall \
nExitCode :dword
PROCTYPE ptDefWindowProc stdcall \
hWnd :dword, \
Msg :dword, \
wParam :dword, \
lParam :dword
PROCTYPE ptSendMessage stdcall \
hWnd :dword, \
Msg :dword, \
wParam :dword, \
lParam :dword
PROCTYPE ptMessageBox stdcall \
hWnd :dword, \
lpText :dword, \
lpCaption :dword, \
uType :dword
PROCTYPE ptExitProcess stdcall \
exitCode :dword
extrn GetModuleHandleA :ptGetModuleHandle
extrn LoadIconA :ptLoadIcon
extrn LoadCursorA :ptLoadCursor
extrn RegisterClassExA :ptRegisterClassEx
extrn LoadMenuA :ptLoadMenu
extrn CreateWindowExA :ptCreateWindowEx
extrn ShowWindow :ptShowWindow
extrn UpdateWindow :ptUpdateWindow
extrn GetMessageA :ptGetMessage
extrn TranslateMessage :ptTranslateMessage
extrn DispatchMessageA :ptDispatchMessage
extrn SetMenu :ptSetMenu
extrn PostQuitMessage :ptPostQuitMessage
extrn DefWindowProcA :ptDefWindowProc
extrn SendMessageA :ptSendMessage
extrn MessageBoxA :ptMessageBox
extrn ExitProcess :ptExitProcess
UDataSeg
hInst dd ?
hWnd dd ?
IFNDEF VER1
hMenu dd ?
ENDIF
DataSeg
msg msgStruc <>
classTitle db 'Menu demo', 0
wndTitle db 'Demo program', 0
msg_open_txt db 'You selected open', 0
msg_open_tlt db 'Open box', 0
msg_save_txt db 'You selected save', 0
msg_save_tlt db 'Save box', 0
CodeSeg
Start: call GetModuleHandleA, 0 ; не обязательно, но желательно
mov [hInst],eax
sub esp,SIZE WndClassEx ; отведём место в стеке под структуру
mov [(WndClassEx esp).cbSize],SIZE WndClassEx
mov [(WndClassEx esp).style],CS_HREDRAW or CS_VREDRAW
mov [(WndClassEx esp).lpfnWndProc],offset WndProc
mov [(WndClassEx esp).cbWndExtra],0
mov [(WndClassEx esp).cbClsExtra],0
mov [(WndClassEx esp).hInstance],eax
call LoadIconA, 0, IDI_APPLICATION
mov [(WndClassEx esp).hIcon],eax
call LoadCursorA, 0, IDC_ARROW
mov [(WndClassEx esp).hCursor],eax
mov [(WndClassEx esp).hbrBackground],COLOR_WINDOW
IFDEF VER1
mov [(WndClassEx esp).lpszMenuName],MyMenu
ELSE
mov [(WndClassEx esp).lpszMenuName],0
ENDIF
mov [(WndClassEx esp).lpszClassName],offset classTitle
mov [(WndClassEx esp).hIconSm],0
call RegisterClassExA, esp ; зарегистрируем класс окна
add esp,SIZE WndClassEx ; восстановим стек
; и создадим окно
IFNDEF VER2
call CreateWindowExA, WS_EX_OVERLAPPEDWINDOW, \ extended window style
offset classTitle, \ pointer to registered class name
offset wndTitle,\ pointer to window name
WS_OVERLAPPEDWINDOW, \ window style
CW_USEDEFAULT, \ horizontal position of window
CW_USEDEFAULT, \ vertical position of window
CW_USEDEFAULT, \ window width
CW_USEDEFAULT, \ window height
0, \ handle to parent or owner window
0, \ handle to menu, or child-window identifier
[hInst], \ handle to application instance
0 ; pointer to window-creation data
ELSE
call LoadMenu, hInst, MyMenu
mov [hMenu],eax
call CreateWindowExA, WS_EX_OVERLAPPEDWINDOW, \ extended window style
offset classTitle, \ pointer to registered class name
offset wndTitle, \ pointer to window name
WS_OVERLAPPEDWINDOW, \ window style
CW_USEDEFAULT, \ horizontal position of window
CW_USEDEFAULT, \ vertical position of window
CW_USEDEFAULT, \ window width
CW_USEDEFAULT, \ window height
0, \ handle to parent or owner window
eax, \ handle to menu, or child-window identifier
[hInst], \ handle to application instance
0 ; pointer to window-creation data
ENDIF
mov [hWnd],eax
call ShowWindow, eax, SW_SHOW ; show window
call UpdateWindow, [hWnd] ; redraw window
IFDEF VER3
call LoadMenuA, [hInst], MyMenu
mov [hMenu],eax
call SetMenu, [hWnd], eax
ENDIF
msg_loop:
call GetMessageA, offset msg, 0, 0, 0
or ax,ax
jz exit
call TranslateMessage, offset msg
call DispatchMessageA, offset msg
jmp msg_loop
exit: call ExitProcess, 0
public stdcall WndProc
proc WndProc stdcall
arg @@hwnd: dword, @@msg: dword, @@wPar: dword, @@lPar: dword
mov eax,[@@msg]
cmp eax,WM_COMMAND
je @@command
cmp eax,WM_DESTROY
jne @@default
call PostQuitMessage, 0
xor eax,eax
jmp @@ret
@@default:
call DefWindowProcA, [@@hwnd], [@@msg], [@@wPar], [@@lPar]
@@ret: ret
@@command:
mov eax,[@@wPar]
cmp eax,ID_OPEN
je @@open
cmp eax,ID_SAVE
je @@save
call SendMessageA, [@@hwnd], WM_CLOSE, 0, 0
xor eax,eax
jmp @@ret
@@open: mov eax, offset msg_open_txt
mov edx, offset msg_open_tlt
jmp @@mess
@@save: mov eax, offset msg_save_txt
mov edx, offset msg_save_tlt
@@mess: call MessageBoxA, 0, eax, edx, MB_OK
xor eax,eax
jmp @@ret
endp WndProc
end Start