Menu enumeration

zhaozj2021-02-17  57

Menu enumeration

There is an MDI application that is now assumed to enumerate it to get the content of the system command to respond to all menu items: If the command ID, the resource name, the (child) handle, etc., and operate it. This article is a bit two or two, and it is expected to be in the depth of Han, and the only one is in the same place.

1, my confusion

These days have cultivated ENGLISH HELP, so that they have a little fruit, I hope to have a total of the world, and I don't know if it is effective, but it is Master-class:

The menu item can be a menu, and vice versa, the menu is called a submenu; if the menu item is not a menu, it is 'pure menu item'. I used to think that every item in the menu is a menu, therefore no need for menu items in my thinking. Maybe this is a rookie-level problem, but you may not have much mellow, then you may wish to talk on the paper, draw a picture of the simplest menu, and ponder.

2, menu enumeration algorithm

A, one of the menu abstract structures (tree type abstraction):

Now you have to access all of the leaf nodes of this 'tree' and processed, as described B.

B, enumeration algorithm (depth traversal, C syntax)

1.) Quality of the child nodes of the current node.

2.) Cycle query the current node i (0 <= i

If the sub-node i does not subtract the sub-node, then the sub-node I is the leaf junction. After processing, I = i 1, repeat this step;

Otherwise, the sub-node i is a branched node, and the lower sub-node is the current node, and turn to 1;

3. The traversal is over.

INT FindMenuItem (HMENU HMENU) // Parameter HMENU is identified for branch node resource

{

INT I, C;

Long res;

Char * s = new char [33];

Menuiteminfo MII;

Mii.cbsize = sizeof (menuiteminfo);

MII.FMASK = MIIM_DATA | MIIM_ID | MIIM_SUBMENU | MIIM_TYPE | MIIM_STATE | MIIM_CHECKMARKS;

mii.dewtypedata = s;

c = getMenuItemCount (HMENU); // Get all the number of menu items all of the current menu

For (i = 0; i

{

mii.cch = 32; // pay attention!

Res = GetMenuItemInfo (HMENU, I, True, & Mii);

IF (res == 0) {delete S; return -1;} // If the menu information failed

IF (mii.hsubmenu == NULL) //

{

// If the menu item is a non-submenu, it will be processed here.

}

Else

{

// If the menu item is a submenu,

Res = findMenuItem (mii.hsubmenu); // Direct recursive call

IF (res == - 1) {delete s; return -1;}

}

}

Delete S;

Return 0;

}

INT EnummenuendItems (HWND HWND) // Start Traverse Window menu item. The parameter hwnd is the form where the menu is located.

{

HMENU HMENU = GetMenu (hwnd);

IF (HMENU == Null) Return -1;

Return FindMenuItem (HMENU);

}

Note: The code here only describes the algorithm. If it is applied to it, according to different needs, the return value and node processing code of Function will change. Appendix 2 is a PB text of the above code, both slightly, with reference.

The Windows API and Struct used in the above code are slightly clicked.

3, in the development tool used in the development tools, the following Windows API and related struct (standard format):

HMENU GETMENU (HWND HWND); // Return Value: Menu handle of the window associated with HWND

HMENU GetSubmenu (HMENU HMENU, INT NPOS); // Return Value: The child of the nodes in the menu associated with HMENU

INT getMenuItemcount (HMENU HMENU); // Return Value: Number of menus items in the menu associated with HMENU

Bool WinAPi GetMenuItemInfo

Hmenu Hmenu,

Uint UItem,

BOOL FBYPOSITION, / / ​​This parameter determines that the command ID of the current menu item or the sort position number in the belonging menu

LpMenuItemInfo lpmii);

Bool DrawMenuBar (HWND HWND); / / Re-painting the menu of the window associated with HWND

Typedef struct tagmenuiteminfo {

Uint Cbsize; // This structure is physical size, based on byte, its value is actually 48

UINT FMASK; / / Determine what you want to query or set the menu item

Uint ftype; // menu format type

Uint fstate; // menu status: enabled, disabled or grayed

UINT WID; / / Command Identifier

HMENU HSUBMENU; // Submenu handle, if there is no submenu, null

Hbitmap hbmpchecked; // According to these two domain values, you can customize the marker when the menu item is selected.

Hbitmap hbmpunchecked; //, not necessarily '√' or blank

DWORD dwitemdata; // Translated from English as: Application defined value related to menu items (I don't understand)

LPTSTR DWTYPEDATA; // Menu Resource Content Pointer, pointing to String OR Bitmap or Separator resources

UINT CCH; // If the menu item is the MFT_String type, this is Dewtypedata length

Hbitmap hbmpitem; // found this one when debugging

Menuiteminfo, FAR * LPMENUITEMINFO;

Reference: MSDN98 (Microsoft) MS SDK HELP FILES / WIN32 Developer's References (Inprise / Borland)

(Appendix 1 is a declare text of the above API in PB)

Windows API functions related to MENU operations is also more, moderate reference, dynamic library: USER32.DLL.

4, other:

A, I call these Windows features in PB7, but when debugging to getMenuItemInfo, single-step running is stagnant, about

After 30 hours, I conducted the following:

A1, open a DOS window, run TDUMP C: /WINDOWS/SYSTEM/User32.dll> user32.txt (TDUMP.EXE is Inprise Application)

A2, return to Windows, open user32.txt with Notepad, found that there is no getMenuItemInfo, but there is GetMenuItemInfoa, if you call Win API in VB, you can speculate. A3, rewrite the GetMenuItemInfo (or alias) into getMenuiteminfoa, you will be OK!

B, menu item command identifier

After calling GetMenuItemInfoa, its value is saved in Menuiteminfo :: WID.

Setting Now, a menu item is now stored in the Menuiteminfo type Structural MII, and its part is:

mii.cbsize = 48

mii.dewtypedata = "Open File"

mii.wid = 10001

mii.fstate = enabled

mii.ftype = mft_string

Corresponding function reference identity command identifier WID

Openfile () 10001

Closefile () 10002

WID = 10001

C, when the above GetMenuItemInfoa is called, the following domains of Menuiteminfo are required:

Menuiteminfo :: CBSIZE

Menuiteminfo :: Fmask

Menuiteminfo :: DWTYPEDATA

Menuiteminfo :: cch

Where Menuiteminfo :: Fmask can be a combination of constant values ​​(it is difficult to find these constant values ​​in related materials)

MIIM_STATE (= 1) miim_id (= 2)

MIIM_SUBMENU (= 4) MIIM_CHECKMARKS (= 8)

MIIM_TYPE (= 16) MIIM_DATA (= 32)

Attachment:

1, related API and structural declare in PB

Function Long GetMenu (long hwnd) library "user32.dll"

Function Long GetSubmenu (long hmenu, long npos) library "user32.dll"

Function Long GetMenuItemcount (long hmenu) library "user32.dll"

Function Long Enablemenem (Long Hmenu, Ulong UidenableItem, Ulong Uenable) library "user32.dll"

Function Long Getmenuiteminfoa (Long Hmenu, Ulong UItem, Long FbyPosition, Ref Menuiteminfo MII) Library "User32.dll"

Function Long Drawmenubar (long hwnd) library "user32.dll"

Global Type Menuiteminfo from Structure

Unsignedlong CBSIZE

Unsignedlong Fmask

Unsignedlong ftype

Unsignedlong fstate

Unsignedlong WID

Long hsubmenu

Long HBMPCHECKED

Long hbmpunchecked

Long dwitemdata

String Dewtypedata

Unsignedlong Cch

Long HBmpItem

End Type

2, PB code, different from C code (excellent selection, modification) as needed

Public Function Int EnummenuendItems (Long Hwnd, Int INS_UPD)

Long hm

Constant int INS = 0

IF hwnd = 0 or isnull (hwnd) THEN RETURN 0

HM = GetMenu (Handle (WMDI))

IF INS_UPD = INS THEN

Delete from sec_fun using.

IF trans.sqlcode = -1 Then Goto Error

END IF

IF ismenu (hm) = 0 THEN RETURN -1

If Fun (hm, INS_UPD) = -1 Then Goto Error

IF trans.sqlcode = -1 Then Goto Error

Commits.

Delete from sec_auth where id_fun not in (select id_fun from sec_fun) using trans; //

If trans.sqlcode = -1 and INS_UPD = INS THEN messageBOX ("", "some operations may no longer exist, but users still have the operation permission, please delete manually!")

Return 0

Error:

Rollback.

Return -1

End fuction

Private function int FindMenuItem (HMENU HMENU, INT INS_UPD)

// INS = 0

// UPD = 1

INT I, C

Long HM, RES

Menuiteminfo MII

mii.cbsize = 48

mii.fmask = 54

Mii.FTYPE = 0

C = getMenuItemcount (HMENU)

For i = 0 to c -1

mii.dewtypedata = "" "

mii.cch = 63

IF not isvalid (mii) THEN RETURN -1

Res = GetMenuItemInfoa (HMenu, I, 255, MII)

if res = 0 THEN Continue

IF mii.hsubmenu = 0 THEN

IF not isnull (mii.dwtypedata) THEN

Choose Case INS_UPD

Case 0

INSERT INTO Sec_Fun (ID_FUN, DES_FUN, HANDLE) VALUES (: mii.wid,: mii.dwtypedata,: hmenu) using trans; // save the 'pure' menu item information

IF trans.sqlcode = -1 Then return -1

Case 1

Update sec_fun set handle =: hmenu where id_fun =: mii.wid sale trans;

IF trans.sqlcode = -1 Then Return -2nd choose

Else

Continue

END IF

Else

Res = FindMenuItem (MII.HSUBMENU, INS_UPD)

IF res <> 0 THEN RETURN RES

END IF

NEXT

Return 0

END FUNCTION

转载请注明原文地址:https://www.9cbs.com/read-30862.html

New Post(0)