ikj78i 發表於 2024-12-4 22:03:14

功能表

Windows應用程式中的功能表(menu)有三種:
1.主功能表:位於標題欄下方,並非每個應用程式都有。
2.系統功能表:以滑鼠左鍵點擊位於標題欄最左邊的圖示才出現。
3.快捷功能表:以滑鼠右鍵點擊工作區才出現,但並非每個應用程式都有。
這一篇要討論如何製作主功能表,製作主功能表的方式有許多種,這裏採用在資源描述檔中描述
功能表的方式。在資源描述檔中描述功能表的語法如下:MenuID MENU

BEGIN
MENUITEM text, ID [,option]
POPUP text
  BEGIN
   ...
  END
...
END這裡的MENU是關鍵字,說明在這之後是功能表的描述
1.MenuID是1~65535之間的整數,是功能表識別碼。
2.optional-statements:與https://bingfong.com/forum.php?m ... 1&extra=#pid5469926
 中對話盒的一樣。
3.在BEGIN/END之間的是選項或子功能表,假如是選項就用MENUITEM,如果使子功能表用POPUP,
 也可以用「MENUITEM SEPARATOR」畫出分隔線。
 A.MENUITEM:代表選項,的text會顯示在功能表的選項上。ID是選項識別碼,在1~65535之間
  的正整數。
 B.POPUP:表示子功能表。
例如底下的資源描述檔,MENU.RC:#include "C:\MASM32\INCLUDE\RESOURCE.H"
#define IDD_DLG   1000
#define IDM_MENU  1001
#define IDS_MENU  1002
#define IDB_QUIT  1003
#define IDM_OPEN  1004
#define IDM_SAVE  1005
#define IDM_QUIT  1006
#define IDM_COPY  1007
#define IDM_PASTE 1008
#define IDM_HELP  1009

IDM_MENU MENU
BEGIN
POPUP "檔案"
{
   MENUITEM "開啟",IDM_OPEN
   MENUITEM "儲存",IDM_SAVE
   MENUITEM SEPARATOR
   MENUITEM "離開",IDM_QUIT
}
POPUP "編輯"
{
   MENUITEM "複製",IDM_COPY
   MENUITEM "貼上",IDM_PASTE
}
MENUITEM "說明",IDM_HELP
END

IDD_DLG DIALOG 340,150,120,50
CAPTION "功能表"
FONT 10,"細明體"
STYLE WS_VISIBLE|WS_OVERLAPPEDWINDOW
MENU  IDM_MENU
BEGIN
LTEXT "",IDS_MENU,2,30,72,10
PUSHBUTTON "離開",IDB_QUIT,75,30,40,15
END底下是MENU.ASM的內容:.586
.MODEL  FLAT,STDCALL
OPTION  CASEMAP:NONE
IDD_DLG   EQU 1000
IDM_MENU  EQU 1001
IDS_MENU  EQU 1002
IDB_QUIT  EQU 1003
IDM_OPEN  EQU 1004
IDM_SAVE  EQU 1005
IDM_QUIT  EQU 1006
IDM_COPY  EQU 1007
IDM_PASTE EQU 1008
IDM_HELP  EQU 1009
INCLUDE    c:\masm32\include\windows.inc
INCLUDE    c:\masm32\include\kernel32.inc
INCLUDE    c:\masm32\include\user32.inc
INCLUDELIB c:\masm32\lib\kernel32.lib
INCLUDELIB c:\masm32\lib\user32.lib
;*******************************************************************************
.DATA
hInst   DD ?
hMenu   DD ? ;主功能表
hFile   DD ? ;檔案子功能表
hEdit   DD ? ;編輯子功能表
sYouPre DB "你按下"
buffer  DB 20h DUP (0)
;*******************************************************************************
.CODE
;-------------------------------------------------------------------------------
DlgProc PROC    hDlg:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
.IF uMsg==WM_COMMAND
        mov     edx,wParam
        mov     eax,wParam
        shr     edx,10h    ;DX=通知碼
        and     eax,0ffffh ;AX=控制元件識別碼
  .IF ax==IDB_QUIT
        jmp     quit
  .ELSEIF ax==IDM_OPEN
        INVOKE  GetMenuString,hFile,eax,OFFSET buffer,SIZEOF buffer,MF_BYCOMMAND
  .ELSEIF ax==IDM_SAVE
        INVOKE  GetMenuString,hFile,eax,OFFSET buffer,SIZEOF buffer,MF_BYCOMMAND
  .ELSEIF ax==IDM_QUIT
        jmp     quit
  .ELSEIF ax==IDM_COPY
        INVOKE  GetMenuString,hEdit,eax,OFFSET buffer,SIZEOF buffer,MF_BYCOMMAND
  .ELSEIF ax==IDM_PASTE
        INVOKE  GetMenuString,hEdit,eax,OFFSET buffer,SIZEOF buffer,MF_BYCOMMAND
  .ELSEIF ax==IDM_HELP
        INVOKE  GetMenuString,hMenu,eax,OFFSET buffer,SIZEOF buffer,MF_BYCOMMAND
  .ENDIF
        INVOKE  SetDlgItemText,hDlg,IDS_MENU,OFFSET sYouPre

.ELSEIF uMsg==WM_INITDIALOG
        INVOKE  GetMenu,hDlg
        mov     hMenu,eax
        INVOKE  GetSubMenu,hMenu,0
        mov     hFile,eax
        INVOKE  GetSubMenu,hMenu,1
        mov     hEdit,eax

.ELSEIF uMsg==WM_CLOSE
quit:   INVOKE  EndDialog,hDlg,0

.ELSE   ;其他未處理的訊息返回0,通知系統此訊息未處理
        xor     eax,eax
        ret

.ENDIF  ;已處理的訊息返回1,通知系統此訊息已處理
        mov     eax,1
        ret
DlgProc ENDP
;-------------------------------------------------------------------------------
main    PROC
        INVOKE  GetModuleHandle,0
        mov     hInst,eax
        INVOKE  DialogBoxParam,hInst,IDD_DLG,0,OFFSET DlgProc,0
        INVOKE  ExitProcess,0
main    ENDP
;*******************************************************************************
END     main把MENU.ASM、MENU.RC放在同一資料夾,開啟命令提示字元,切換到該資料夾,輸入下面指令即可。path c:\masm32\bin;%path%
rc menu.rc
ml /coff menu.asm /link menu.res /subsystem:windows執行結果:
頁: [1]
查看完整版本: 功能表