Instantly share code, notes, and snippets.
Last active
April 13, 2021 03:09
-
Star
(0)
0
You must be signed in to star a gist -
Fork
(0)
0
You must be signed in to fork a gist
-
Save CarlTBarnes/e2902bb0280fe25554aa67b2e9292c51 to your computer and use it in GitHub Desktop.
Menu Open Message WM_INITMENU to modify menus before opening
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
!Often right when Menus are being opened you want to change the Menus | |
!based on the other variables and things. | |
!Simple example of SubClass Window to get a WM_INITMENU Message before Menus display | |
!This adds Time to an Item text to show it changing at time it opens | |
!It also adds Time when closed, you get a Message when window close also WM_EXITMENULOOP | |
PROGRAM | |
INCLUDE 'TplEqu.CLW' | |
INCLUDE 'KeyCodes.CLW' | |
MAP | |
MenuOpenTest PROCEDURE() | |
DB PROCEDURE(STRING DebugMessage) | |
DBClear PROCEDURE() !Clear DebugView Buffer | |
MODULE('RTL') | |
ClaFieldNameRTL PROCEDURE(LONG pFEQ),CSTRING,RAW,NAME('Cla$FIELDNAME'),DLL(dll_mode) | |
ClaEventNameRTL PROCEDURE(LONG EventPlusA000h),*CSTRING,RAW,NAME('WslDebug$MsgName'),DLL(dll_mode) | |
END | |
MODULE('api') | |
CallWindowProc(LONG lpPrevWndProc,UNSIGNED hWnd,UNSIGNED MsgNo,UNSIGNED wParam,LONG lParam),LONG,RAW,PASCAL,NAME('CallWindowProcA'),DLL(1) | |
OutputDebugString(*CSTRING cMsg),PASCAL,DLL(1),RAW,NAME('OutputDebugStringA') | |
GetLastError(),LONG,PASCAL,DLL(1) | |
END | |
END | |
CODE | |
MenuOpenTest() | |
RETURN | |
!---------------------------- | |
MenuOpenTest PROCEDURE | |
MAP | |
SubClassMain PROCEDURE(UNSIGNED hWnd,UNSIGNED Msg,UNSIGNED wParam,LONG lParam),LONG,PASCAL | |
END | |
LongStack LONG !A Local STACK variable CANNOT be accessed in Subclass Call Back | |
LongThread LONG,THREAD !This Thread variable CAN be accessed in Subclass Call Back | |
Window WINDOW('Menu Open Hook'),AT(,,254,138),CENTER,GRAY,IMM,SYSTEM,STATUS,FONT('Segoe UI',9),RESIZE | |
MENUBAR,USE(?MENUBAR1) | |
MENU('&Menu1'),USE(?Menu1) | |
ITEM('Item 1'),USE(?Menu1Item1) | |
ITEM('Item 2'),USE(?Menu1Item2) | |
ITEM(''),SEPARATOR,USE(?SEPARATOR1) | |
MENU('Print Sub Menu'),USE(?Menu1PrintSubMenu) | |
ITEM('&Print...<9>Ctrl+P'),USE(?PrintPrint) | |
ITEM('Printer Set&up...'),USE(?PrintPrinterSetup) | |
ITEM('Page &Layout...'),USE(?PrintPageLayout) | |
ITEM('Print Pre&view'),USE(?PrintPreview) | |
END | |
ITEM('Item 3'),USE(?Menu1Item3) | |
ITEM('Item 4'),USE(?Menu1Item4) | |
END | |
MENU('&SheetMenu'),USE(?SheeMenu) | |
ITEM('Tab 1 Sub Menu'),USE(?SheeMenuTab1),DISABLE | |
ITEM('Tab 2 Sub Menu'),USE(?SheeMenuTab2),DISABLE | |
ITEM('Tab 3 Sub Menu'),USE(?SheeMenuTab3),DISABLE | |
END | |
END | |
SHEET,AT(117,18,133,40),USE(?SHEET1) | |
TAB('Tab 1'),USE(?TAB1) | |
END | |
TAB('Tab 2'),USE(?TAB2) | |
END | |
TAB('Tab 3'),USE(?TAB3) | |
END | |
END | |
STRING('Sheet Menu items Enable based on Tab'),AT(123,38),USE(?STRING1) | |
CHECK('Print Menu Disabled '),AT(4,54),USE(?PrintDisabled) | |
BUTTON('Popup Menu'),AT(4,74),USE(?PopupBtn),TIP('Will this get Menu Events?') | |
END | |
Prior_WndProc LONG,STATIC !WndProc Must be Static | |
CODE | |
LongThread=1001 | |
DBClear() ; DB('Menu Open Event Test') | |
OPEN(WINDOW) | |
display !; message('before subclass') | |
Prior_WndProc = Window{PROP:WndProc} | |
Window{PROP:WndProc}=ADDRESS(SubClassMain) | |
0{PROP:text}=clip(0{PROP:text}) &' - Library ' & system{PROP:LibVersion,2} &'.'& system{PROP:LibVersion,3} | |
ACCEPT | |
CASE EVENT() | |
OF EVENT:OpenWindow | |
OF EVENT:CloseWindow | |
OF EVENT:PreAlertKey | |
OF EVENT:AlertKey | |
OF EVENT:Timer | |
END | |
CASE ACCEPTED() | |
OF ?PopupBtn ; p#=POPUP('One|Two|Three') | |
END | |
CASE FIELD() | |
END | |
END | |
CLOSE(WINDOW) | |
!========================================================================== | |
!SubClassMain is in the Local Map so has scope of the Proceduure symbols. | |
!Local Variables are on the Stack and are not going to work in this Call Back | |
!Define Thread, Static, Module, Global variables. | |
!Window properties can also work like new {'User Defined'} added in C10 | |
!Or Windows API Props | |
!The FEQ ?symbols are simply long number constants so they work | |
SubClassMain PROCEDURE(UNSIGNED hWnd,UNSIGNED MsgNo,UNSIGNED wParam,LONG lParam)!,LONG,PASCAL | |
WM_ENTERMENULOOP EQUATE(0211h) !1st message when menus open. Called w/o W/L parms | |
WM_INITMENU EQUATE(0116h) !next, passes wParam as hMenu to menubar http://msdn.microsoft.com/en-us/library/ms646344(VS.85).aspx | |
WM_INITMENUPOPUP EQUATE(0117h) !next, passed hSubMenu to menu activated http://msdn.microsoft.com/en-us/library/ms646347(VS.85).aspx | |
WM_EXITMENULOOP EQUATE(0212h) !last message menus closing. | |
CODE | |
CASE MsgNo | |
!Notifies an application's main window procedure that a menu modal loop has been entered | |
OF WM_ENTERMENULOOP ; db('SubClassMain WM_ENTERMENULOOP wParam=' & wParam & ' lParam=' & lParam ) | |
!Called when menus are about to open | |
!wParam=True if TrackPopupMenu i.e. Popup() Menu. Not sure if see | |
!------------------------------------------------------------------------------ | |
!This message comes once for the first menu click, it passes wParm as the Menu Bar handle | |
!Sent when a menu is about to become active. It occurs when the user clicks an | |
!item on the menu bar or presses a menu key. This allows the application to | |
!modify the menu before it is displayed. | |
!wParam - A handle to the menu to be initialized. | |
OF WM_INITMENU ; db('SubClassMain WM_INITMENU wParam=' & wParam & ' lParam=' & lParam ) | |
?Menu1Item1{PROP:Text}='Menu Opened ' & FORMAT(CLOCK(),@t4) | | |
&' - LT#'& LongThread | |
LongThread + =1 | |
! LongStack += 1 This will hang or crash | |
?Menu1PrintSubMenu{PROP:Disable}=?PrintDisabled{PROP:Checked} | |
DISABLE(?SheeMenuTab1,?SheeMenuTab3) | |
CASE ?SHEET1{PROP:ChoiceFEQ} | |
OF ?Tab1 ; Enable(?SheeMenuTab1) | |
OF ?Tab2 ; Enable(?SheeMenuTab2) | |
OF ?Tab3 ; Enable(?SheeMenuTab3) | |
END | |
!------------------------------------------------------------------------------ | |
!Each menu accessed passed hSubMenu to menu activated | |
OF WM_INITMENUPOPUP ; db('SubClassMain WM_INITMENUPOPUP wParam=' & wParam & ' lParam=' & lParam ) | |
!------------------------------------------------------------------------------ | |
!Menus Closing - Notifies an application's main window procedure that a menu modal loop has been exited. | |
OF WM_EXITMENULOOP ; db('SubClassMain WM_EXITMENULOOP wParam=' & wParam & ' lParam=' & lParam ) | |
?Menu1Item4{PROP:Text}='Last Closed ' & FORMAT(CLOCK(),@t4) | |
END | |
RETURN(CallWindowProc(Prior_WndProc,hWnd,MsgNo,wParam,lParam)) | |
!=============================== | |
DB PROCEDURE(STRING xMessage) | |
Prfx EQUATE('MenuOpen: ') | |
sz CSTRING(SIZE(Prfx)+SIZE(xMessage)+1),AUTO | |
CODE | |
sz = Prfx & CLIP(xMessage) | |
OutputDebugString( sz ) | |
!------------------ | |
DBClear PROCEDURE() | |
DbgClear CSTRING('DBGVIEWCLEAR') !Message to Clear the buffer. Must UPPER and first i.e. without a Prefix | |
CODE | |
OutputDebugString(DbgClear) !Cannot have Prefix, must be first .. so call API directly | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
!Windows Menu API Functions | |
MENUITEMINFO GROUP,TYPE !http://msdn.microsoft.com/en-us/library/ms647578(VS.85).aspx | |
cbSize UNSIGNED !Size of structure, in bytes. Caller must = size(MENUITEMINFO) | |
fMask UNSIGNED !Mask of Members to retrieve or set. MIIM_XXXX equates MIIM_STATE MIIM_TYPE MIIM_FTYPE | |
fType UNSIGNED !Menu item type MFT_XXXX some require fMask to be MIIM_FTYPE | |
fState UNSIGNED !Menu item state MFS_CHECKED MFS_DISABLED+MFS_GRAYED MFS_ENABLED | |
wID UNSIGNED !Application-defined 16-bit value that identifies the menu item. Set fMask to MIIM_ID to use wID. | |
hSubMenu UNSIGNED !Handle to the drop-down menu or submenu associated with the menu item. Null if not a SubMenu | |
hBmpChecked UNSIGNED !Handle to the bitmap to display next to the item if it is selected. | |
hBmpUnchecked UNSIGNED !Handle to the bitmap to display next to the item if it is not selected. | |
dwItemData ULONG !Application-defined value associated with the menu item. Set fMask to MIIM_DATA to use dwItemData. | |
dwTypeData LONG !Content of the menu item. The meaning of this member depends on the value of fType and is used only if the MIIM_TYPE flag is set in the fMask member. | |
cch UNSIGNED !Length of menu item text in TCHARs, for menu item of the MFT_STRING type, only used if fMask=MIIM_TYPE | |
hBmpItem UNSIGNED !Handle to the bitmap to be displayed | |
END | |
WM_ENTERMENULOOP EQUATE(0211h) !1st message,once, wParm=1 if TrackPopupMenu i.e. POPUP() http://msdn.microsoft.com/en-us/library/ms647595(VS.85).aspx | |
! The WM_ENTERMENULOOP message informs an application's main window procedure that a menu modal loop has been entered. | |
WM_INITMENU EQUATE(0116h) !next,once, passes wParam as hMenu to menubar http://msdn.microsoft.com/en-us/library/ms646344(VS.85).aspx | |
! The WM_INITMENU message is sent when a menu is about to become active. It occurs when the user clicks an item on the menu bar or presses a menu key. This allows the application to modify the menu before it is displayed. | |
WM_INITMENUPOPUP EQUATE(0117h) !next,each, passed hSubMenu to menu activated http://msdn.microsoft.com/en-us/library/ms646347(VS.85).aspx | |
WM_EXITMENULOOP EQUATE(0212h) !last message,once | |
MF_UNCHECKED EQUATE(00000000h) !MF_UNCHECKED 0x00000000L | |
MF_CHECKED EQUATE(00000008h) !MF_CHECKED 0x00000008L | |
MF_BYCOMMAND EQUATE(00000000h) !MF_BYCOMMAND 0x00000000L | |
MF_BYPOSITION EQUATE(00000400h) !MF_BYPOSITION 0x00000400L | |
MF_SEPARATOR EQUATE(00000800h) !MF_SEPARATOR 0x00000800L | |
MF_ENABLED EQUATE(00000000h) !MF_ENABLED 0x00000000L | |
MF_GRAYED EQUATE(00000001h) !MF_GRAYED 0x00000001L | |
MF_DISABLED EQUATE(00000002h) !MF_DISABLED 0x00000002L | |
MF_USECHECKBITMAPS EQUATE(00000200h) !MF_USECHECKBITMAPS 0x00000200L | |
MF_STRING EQUATE(00000000h) !MF_STRING 0x00000000L | |
MF_BITMAP EQUATE(00000004h) !MF_BITMAP 0x00000004L | |
MF_OWNERDRAW EQUATE(00000100h) !MF_OWNERDRAW 0x00000100L | |
MF_POPUP EQUATE(00000010h) !MF_POPUP 0x00000010L | |
MF_MENUBARBREAK EQUATE(00000020h) !Puts menu item in a new column, or on new line (for a menu bar). A vertical line separates the new column from the old. | |
MF_MENUBREAK EQUATE(00000040h) !same as MF_MENUBARBREAK without Vert BAR | |
MF_UNHILITE EQUATE(00000000h) !MF_UNHILITE 0x00000000L | |
MF_HILITE EQUATE(00000080h) !MF_HILITE 0x00000080L | |
MF_DEFAULT EQUATE(00001000h) !MF_DEFAULT 0x00001000L | |
MF_SYSMENU EQUATE(00002000h) !MF_SYSMENU 0x00002000L | |
MF_HELP EQUATE(00004000h) !MF_HELP 0x00004000L | |
MF_RIGHTJUSTIFY EQUATE(00004000h) !MF_RIGHTJUSTIFY 0x00004000L | |
MF_MOUSESELECT EQUATE(00008000h) !MF_MOUSESELECT 0x00008000L | |
MFT_STRING EQUATE(MF_STRING) !MFT_STRING MF_STRING | |
MFT_BITMAP EQUATE(MF_BITMAP) !MFT_BITMAP MF_BITMAP | |
MFT_MENUBARBREAK EQUATE(MF_MENUBARBREAK) !MFT_MENUBARBREAK MF_MENUBARBREAK | |
MFT_MENUBREAK EQUATE(MF_MENUBREAK) !MFT_MENUBREAK MF_MENUBREAK | |
MFT_OWNERDRAW EQUATE(MF_OWNERDRAW) !MFT_OWNERDRAW MF_OWNERDRAW | |
MFT_RADIOCHECK EQUATE(00000200h) !MFT_RADIOCHECK 0x00000200L | |
MFT_SEPARATOR EQUATE(MF_SEPARATOR) !MFT_SEPARATOR MF_SEPARATOR | |
MFT_RIGHTORDER EQUATE(00002000h) !MFT_RIGHTORDER 0x00002000L | |
MFT_RIGHTJUSTIFY EQUATE(MF_RIGHTJUSTIFY) !MFT_RIGHTJUSTIFY MF_RIGHTJUSTIFY | |
! Menu flags for Add/Check/EnableMenuItem() */ | |
MFS_GRAYED EQUATE(00000003h) !MFS_GRAYED 0x00000003L | |
MFS_DISABLED EQUATE(MFS_GRAYED) !MFS_DISABLED MFS_GRAYED | |
MFS_CHECKED EQUATE(MF_CHECKED) !MFS_CHECKED MF_CHECKED | |
MFS_HILITE EQUATE(MF_HILITE) !MFS_HILITE MF_HILITE | |
MFS_ENABLED EQUATE(MF_ENABLED) !MFS_ENABLED MF_ENABLED | |
MFS_UNCHECKED EQUATE(MF_UNCHECKED) !MFS_UNCHECKED MF_UNCHECKED | |
MFS_UNHILITE EQUATE(MF_UNHILITE) !MFS_UNHILITE MF_UNHILITE | |
MFS_DEFAULT EQUATE(MF_DEFAULT) !MFS_DEFAULT MF_DEFAULT | |
MIIM_STATE EQUATE(00000001h) !MIIM_STATE 0x00000001 | |
MIIM_ID EQUATE(00000002h) !MIIM_ID 0x00000002 | |
MIIM_SUBMENU EQUATE(00000004h) !MIIM_SUBMENU 0x00000004 | |
MIIM_CHECKMARKS EQUATE(00000008h) !MIIM_CHECKMARKS 0x00000008 | |
MIIM_TYPE EQUATE(00000010h) !MIIM_TYPE 0x00000010 | |
MIIM_DATA EQUATE(00000020h) !MIIM_DATA 0x00000020 Win9x way to get Menu String :( | |
MIIM_STRING EQUATE(00000040h) !MIIM_STRING 0x00000040 #if(WINVER >= 0x0500) i.e. Win2K ! | |
MIIM_BITMAP EQUATE(00000080h) !MIIM_BITMAP 0x00000080 #if(WINVER >= 0x0500) | |
MIIM_FTYPE EQUATE(00000100h) !MIIM_FTYPE 0x00000100 #if(WINVER >= 0x0500) | |
MAP | |
module('api') | |
! GetlastError(),SIGNED,PASCAL,DLL(1) | |
GetMenu(SIGNED HWND),SIGNED,PASCAL,DLL(1) !returns hMenu | |
GetSubMenu(SIGNED HMENU, SIGNED nPos),SIGNED,PASCAL,DLL(1) !returns hMenu to Submenu | |
IsMenu(SIGNED HMenu),BOOL,PASCAL,DLL(1) !The IsMenu function determines whether a handle is a menu handle. | |
GetMenuItemCount(SIGNED hMenu),SIGNED,PASCAL,DLL(1) !returns no of items, -1 = failed then GetLastError | |
GetMenuItemID(SIGNED hMenu, SIGNED nPos),UNSIGNED,PASCAL,DLL(1) !ID of menu Item | |
CheckMenuItem(SIGNED hMenu, UNSIGNED uIDCheckItem, UNSIGNED uCheck),PASCAL,RAW,SIGNED,DLL(1) !,name('CheckMenuItemA') | |
GetMenuString(SIGNED hMenu, UNSIGNED uIDItem, *CSTRING lpString, UNSIGNED nMaxCount, UNSIGNED uFlag),SIGNED,PROC,PASCAL,DLL(1),RAW,NAME('GetMenuStringA') | |
GetMenuItemInfo(SIGNED hMenu, UnSIGNED uItem, BOOL fByPosition=0, LONG InOutLPMENUITEMINFO),BOOL,PASCAL,DLL(1),RAW,NAME('GetMenuItemInfoA') !0=failed then getlasterror() | |
SetMenuItemInfo(SIGNED hMenu, UnSIGNED uItem, BOOL fByPosition=0, LONG InOutLPMENUITEMINFO),BOOL,PASCAL,DLL(1),RAW,NAME('SetMenuItemInfoA') !0=failed then getlasterror() | |
DrawMenuBar(SIGNED hndWnd2redraw),BOOL,PROC,PASCAL,DLL(1) !If menu BAR changes after Window created this function must be called to draw the changed menu bar. | |
GetSystemMenu(SIGNED HWND, BOOL bRevert=0),SIGNED,PASCAL,DLL(1) !returns hMenu to System Menu | |
DestroyMenu(SIGNED hMenu),BOOL,PASCAL,DLL(1) !0=failed | |
CallWindowProc(LONG lpPrevWndProc,UNSIGNED hWnd,UNSIGNED MsgNo,UNSIGNED wParam,LONG lParam),LONG,RAW,PASCAL,NAME('CallWindowProcA'),DLL(1) | |
!SubClassMain PROCEDURE(UNSIGNED hWnd,UNSIGNED Msg,UNSIGNED wParam,LONG lParam),LONG,PASCAL | |
end | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment