📄 见招拆招《windows程序设计》(九) .txt
字号:
程序10-4 MENUDEMO
MENUDEMO.ASM
;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
ID_TIMER equ 1
IDM_FILE_NEW equ 40001
IDM_FILE_OPEN equ 40002
IDM_FILE_SAVE equ 40003
IDM_FILE_SAVE_AS equ 40004
IDM_APP_EXIT equ 40005
IDM_EDIT_UNDO equ 40006
IDM_EDIT_CUT equ 40007
IDM_EDIT_COPY equ 40008
IDM_EDIT_PASTE equ 40009
IDM_EDIT_CLEAR equ 40010
IDM_BKGND_WHITE equ 40011
IDM_BKGND_LTGRAY equ 40012
IDM_BKGND_GRAY equ 40013
IDM_BKGND_DKGRAY equ 40014
IDM_BKGND_BLACK equ 40015
IDM_TIMER_START equ 40016
IDM_TIMER_STOP equ 40017
IDM_APP_HELP equ 40018
IDM_APP_ABOUT equ 40019
ID_MENUITEM40020 equ 40020
.DATA
szAppName TCHAR "MenuDemo",0
idColor DD WHITE_BRUSH, LTGRAY_BRUSH, GRAY_BRUSH,DKGRAY_BRUSH, BLACK_BRUSH
iSelection DD IDM_BKGND_WHITE
.DATA?
.CODE
START:
invoke GetModuleHandle,NULL
invoke WinMain,eax,NULL,NULL,SW_SHOWDEFAULT
invoke ExitProcess,0
WinMain proc hInstance:DWORD,hPrevInst:DWORD,szCmdLine: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 hInstance
pop wndclass.hInstance
invoke LoadIcon,hInstance,IDI_APPLICATION
mov wndclass.hIcon,eax
invoke LoadCursor,NULL,IDC_ARROW
mov wndclass.hCursor,eax
invoke GetStockObject,WHITE_BRUSH
mov wndclass.hbrBackground,EAX
lea eax,szAppName
mov wndclass.lpszMenuName,eax
mov wndclass.lpszClassName,eax
mov wndclass.hIconSm,0
invoke RegisterClassEx, ADDR wndclass
.if (eax==0)
invoke MessageBox,NULL,CTXT("This program requires Windows NT!"),szAppName, MB_ICONERROR
ret
.endif
invoke CreateWindowEx,NULL,
ADDR szAppName, ;window class name
CTXT("Menu Demonstration"),
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,uMsg:DWORD,wParam :DWORD,lParam :DWORD
LOCAL hMenu:HMENU
.if uMsg==WM_COMMAND
invoke GetMenu,hwnd
mov hMenu,eax
mov eax,wParam
.if (eax==IDM_FILE_NEW) || \
(eax==IDM_FILE_OPEN) || \
(eax==IDM_FILE_SAVE) || \
(eax==IDM_FILE_SAVE_AS)
invoke MessageBeep,0
xor eax,eax
ret
.elseif (eax==IDM_APP_EXIT)
invoke SendMessage,hwnd,WM_CLOSE,0,0
xor eax,eax
ret
.elseif (eax==IDM_EDIT_UNDO) || \
(eax==IDM_EDIT_CUT) || \
(eax==IDM_EDIT_COPY) || \
(eax==IDM_EDIT_PASTE) ||\
(eax==IDM_EDIT_CLEAR)
xor eax,eax
ret
.elseif (eax==IDM_BKGND_WHITE) || \
(eax==IDM_BKGND_LTGRAY) ||\
(eax==IDM_BKGND_GRAY) || \
(eax==IDM_BKGND_DKGRAY) ||\
(eax==IDM_BKGND_BLACK)
invoke CheckMenuItem,hMenu,iSelection,MF_UNCHECKED
mov eax,wParam
and eax,0FFFFh
mov iSelection,eax
invoke CheckMenuItem,hMenu,iSelection,MF_CHECKED
mov eax,wParam
and eax,0FFFFh
sub eax,IDM_BKGND_WHITE
mov ebx,idColor[eax*4]
invoke GetStockObject,ebx
invoke SetClassLong,hwnd,GCL_HBRBACKGROUND,eax
invoke InvalidateRect,hwnd,NULL,TRUE
xor eax,eax
ret
.elseif (eax== IDM_TIMER_START)
invoke SetTimer,hwnd,ID_TIMER,1000,NULL
.if (eax!=0)
invoke EnableMenuItem,hMenu, IDM_TIMER_START, MF_GRAYED
invoke EnableMenuItem,hMenu, IDM_TIMER_STOP, MF_ENABLED
.endif
xor eax,eax
ret
.elseif (eax==IDM_TIMER_STOP)
invoke KillTimer,hwnd,ID_TIMER
invoke EnableMenuItem,hMenu, IDM_TIMER_START, MF_ENABLED
invoke EnableMenuItem,hMenu, IDM_TIMER_STOP, MF_GRAYED
xor eax,eax
ret
.elseif (eax==IDM_APP_HELP)
invoke MessageBox,hwnd,CTXT("Help not yet implemented!"),addr szAppName, MB_ICONEXCLAMATION or MB_OK
xor eax,eax
ret
.elseif (eax==IDM_APP_ABOUT)
invoke MessageBox,hwnd,CTXT("Menu Demonstration Program"),CTXT("(c) Charles Petzold, 1998"),MB_ICONINFORMATION or MB_OK
xor eax,eax
ret
.endif
.elseif uMsg == WM_TIMER
invoke MessageBeep,0
xor eax,eax
ret
.elseif uMsg == WM_DESTROY
invoke PostQuitMessage,NULL
xor eax,eax
ret
.endif
invoke DefWindowProc,hwnd,uMsg,wParam,lParam
ret
WndProc endp
END START
MENUDEMO.RC
#define IDM_FILE_NEW 40001
#define IDM_FILE_OPEN 40002
#define IDM_FILE_SAVE 40003
#define IDM_FILE_SAVE_AS 40004
#define IDM_APP_EXIT 40005
#define IDM_EDIT_UNDO 40006
#define IDM_EDIT_CUT 40007
#define IDM_EDIT_COPY 40008
#define IDM_EDIT_PASTE 40009
#define IDM_EDIT_CLEAR 40010
#define IDM_BKGND_WHITE 40011
#define IDM_BKGND_LTGRAY 40012
#define IDM_BKGND_GRAY 40013
#define IDM_BKGND_DKGRAY 40014
#define IDM_BKGND_BLACK 40015
#define IDM_TIMER_START 40016
#define IDM_TIMER_STOP 40017
#define IDM_APP_HELP 40018
#define IDM_APP_ABOUT 40019
#define ID_MENUITEM40020 40020
MENUDEMO MENU DISCARDABLE
BEGIN
POPUP "&File"
BEGIN
MENUITEM "&New", ID_MENUITEM40020
MENUITEM "&Open", IDM_FILE_OPEN
MENUITEM "&Save", IDM_FILE_SAVE
MENUITEM "Save &As...", IDM_FILE_SAVE_AS
MENUITEM SEPARATOR
MENUITEM "E&xit", IDM_APP_EXIT
END
POPUP "&Edit"
BEGIN
MENUITEM "&Undo", IDM_EDIT_UNDO
MENUITEM SEPARATOR
MENUITEM "C&ut", IDM_EDIT_CUT
MENUITEM "&Copy", IDM_EDIT_COPY
MENUITEM "&Paste", IDM_EDIT_PASTE
MENUITEM "De&lete", IDM_EDIT_CLEAR
END
POPUP "&Background"
BEGIN
MENUITEM "&White", IDM_BKGND_WHITE, CHECKED
MENUITEM "&Light Gray", IDM_BKGND_LTGRAY
MENUITEM "&Gray", IDM_BKGND_GRAY
MENUITEM "&Dark Gray", IDM_BKGND_DKGRAY
MENUITEM "&Black", IDM_BKGND_BLACK
END
POPUP "&Timer"
BEGIN
MENUITEM "&Start", IDM_TIMER_START
MENUITEM "S&top", IDM_TIMER_STOP, GRAYED
END
POPUP "&Help"
BEGIN
MENUITEM "&Help...", IDM_APP_HELP
MENUITEM "&About MenuDemo...", IDM_APP_ABOUT
END
END
MENUDEMO.RC资源描述档给了您定义菜单的提示。菜单的名称为「MenuDemo」。大多数项目有底线字母,这就是说您必须在字母前键入『&』。MENUITEM SEPARATOR叙述是在「Menu Item Properties」对话框中选中「Separator」框产生的。注意菜单中有一个项目具有「 Checked」选项,另一个具有「Grayed」选项。还有,「 Background」弹出式菜单中的五个项目应该按顺序输入,确保标识符是以数值的顺序,本程序需要这样。所有菜单项的标识符定义在RESOURCE.H中。
当收到弹出式菜单「File」和「Edit」各项有关的WM_COMMAND消息时,MENUDEMO程序只使系统发出哔声。「 Background」弹出式菜单列出MENUDEMO用来给背景着色的五种现有画刷。在MENUDEMO.RC资源描述档中,「 White」菜单项(菜单ID为IDM_BKGND_WHITE)被标以「 CHECKED」,它在菜单项旁边设定选中标记。在MENUDEMO.C中,iSelection的值被初始化为IDM_BKGND_WHITE。
「Background」弹出式菜单上的五种画刷相互排斥。当MENUDEMO.C收到一个WM_COMMAND消息,而该消息中的wParam是「 Background」弹出式菜单上的五项之一时,它必须从先前选中的背景颜色中除掉选中标记,并把标记加到新的背景颜色上。为此,首先要得到菜单句柄:
hMenu = GetMenu (hwnd) ;
CheckMenuItem函数用来取消目前被选中的项目:
CheckMenuItem (hMenu, iSelection, MF_UNCHECKED) ;
iSelection的值被设定为wParam的值,新的背景颜色被选中:
iSelection = wParam ;
CheckMenuItem (hMenu, iSelection, MF_CHECKED) ;
窗口类别中的背景颜色于是被
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -