Win32 desktop application API to enumerate all menu items with id from another GUI window

Usage

Think about if you have ten millions of menus, submenus.

// https://docs.microsoft.com/en-us/windows/win32/menurc/menus
// https://*.com/questions/2862883/is-it-possible-to-enumerate-menu-items-of-other-programs-on-windows
// https://blog.csdn.net/greless/article/details/83143465
// https://blog.csdn.net/seele52/article/details/17542265

// Check
// https://*.com/questions/18589385/retrieve-list-of-menu-items-in-windows-in-c
// https://blog.csdn.net/liangzhonglin/article/details/5603792
// https://*.com/questions/20012990/how-can-i-access-menu-items-of-a-given-program?noredirect=1&lq=1
// http://zetcode.com/gui/winapi/menus/

// idea
//  display tree like `tree` commands, thinking menu as file inside folder.

#include <stdio.h>
#include <windows.h>

TCHAR _szMenuString[128] = {NULL};

void getMenuString(HMENU hMenu, int nPos) {
  GetMenuStringA(hMenu, nPos, _szMenuString, 128, MF_BYPOSITION);
}

void printMenu(HMENU hMenu, int nPos, int level) {
  TCHAR fmt_string[128] = {NULL};
  for (int col=0; col<level*2; col++)
    fmt_string[col] = ‘ ‘;

  getMenuString(hMenu, nPos);
  UINT menuId = GetMenuItemID(hMenu, nPos);

  if (menuId != -1) {
    strcpy(fmt_string + level*2, "id, name: %5d, %s\n");
    printf(fmt_string, menuId, _szMenuString);
  } else {
    strcpy(fmt_string + level*2, "menu: %s\n");
    printf(fmt_string, _szMenuString);
  }
}

int main(int argc, char *argv[]) {
  LPCTSTR lpClassName = argc-1 > 0 ? argv[1] : "notepad";

  HWND hWnd = FindWindowA(lpClassName, NULL);
  printf("hWnd: %d\n", hWnd);

  HMENU hmenuMain = GetMenu(hWnd);
  printf("\nhmenuMain: %d\n", hmenuMain);

  int menuCount = GetMenuItemCount(hmenuMain);
  for (int nPos=0; nPos<menuCount; nPos++) {
    printMenu(hmenuMain, nPos, 0);

    HMENU hSubMenu = GetSubMenu(hmenuMain, nPos);
    int subMenuItemCount = GetMenuItemCount(hSubMenu);
    for (int subMenu_nPos=0; subMenu_nPos<subMenuItemCount; subMenu_nPos++) {
      printMenu(hSubMenu, subMenu_nPos, 1);
    }
  }

  UINT menuId = 65; // Pickup your menuId
  // PostMessage(hWnd, WM_COMMAND, menuId, 0);

  return 0;
}

Run

cmd> g++ main.cpp
cmd> a.exe
hWnd: 266060

hmenuMain: 310841463
menu: &File
  id, name:     1, &New Ctrl+N
  id, name:     8, New &Window  Ctrl+Shift+N
  id, name:     2, &Open...     Ctrl+O
  id, name:     3, &Save        Ctrl+S
  id, name:     4, Save &As...  Ctrl+Shift+S
  id, name:     0,
  id, name:     5, Page Set&up...
  id, name:     6, &Print...    Ctrl+P
  id, name:     0,
  id, name:     7, E&xit
menu: &Edit
  id, name:    16, &Undo        Ctrl+Z
  id, name:     0,
  id, name:   768, Cu&t Ctrl+X
  id, name:   769, &Copy        Ctrl+C
  id, name:   770, &Paste       Ctrl+V
  id, name:   771, De&lete      Del
  id, name:     0,
  id, name:    28, &Search with Bing... Ctrl+E
  id, name:    21, &Find...     Ctrl+F
  id, name:    22, Find &Next   F3
  id, name:    29, Find Pre&vious       Shift+F3
  id, name:    23, &Replace...  Ctrl+H
  id, name:    24, &Go To...    Ctrl+G
  id, name:     0,
  id, name:    25, Select &All  Ctrl+A
  id, name:    26, Time/&Date   F5
menu: F&ormat
  id, name:    32, &Word Wrap
  id, name:    33, &Font...
menu: &View
  menu: &Zoom
  id, name:    27, &Status Bar
menu: &Help
  id, name:    64, View &Help
  id, name:    66, Send &Feedback
  id, name:     0,
  id, name:    65, &About Notepad
cmd> a.exe | findstr /I about
  id, name:    65, &About Notepad

TODO:

- Add support to enumerate nested sub-submenu item
  File menu
    Align submenu
      Align to left sub-submenu item
      Align to right sub-submenu item
      ...

Win32 desktop application API to enumerate all menu items with id from another GUI window

上一篇:Android之同步与异步


下一篇:Linux 文件、文件夹的复制、移动、删除