Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IContextMenu::QueryContextMenu return not relevant menu

Network connection shortcut (Ethernet, Wi-Fi, etc.) have different context menus depending on the connection state (connected/disconnected). I use the following code (Delphi) to retrieve and display this menu.

var pidl, child: PItemIdList;
    pFolder: IShellFolder;
    pMenu: IContextMenu;
    menu: HMENU;
begin
  SHParseDisplayName(PChar('%USERPROFILE%\Desktop\eth0.lnk'), nil, pidl, 0, PDWORD(nil)^);
  SHBindToParent(pidl, IID_IShellFolder, Pointer(pFolder), child);
  CoTaskMemFree(pidl);
  pFolder.GetUIObjectOf(0, 1, child, IID_IContextMenu, nil, pMenu);
  menu := CreatePopupMenu;
  pMenu.QueryContextMenu(menu, 0, 0, $7fff, CMF_NORMAL);
  TrackPopupMenuEx(menu, TPM_LEFTBUTTON, 0, 0, Handle, nil);
  DestroyMenu(menu);
end;

But after changing the connection state, I keep getting the old menu. After restarting the app I sometimes get the correct menu, however, most of the time I don't.

Why it happens and how to fix it?

OS: both 32- and 64-bit Windows 7/8/10

C++ code:

PIDLIST_ABSOLUTE pidl;
if SUCCEEDED(SHParseDisplayName(L"%USERPROFILE%\\Desktop\\eth0.lnk", NULL, &pidl, 0, NULL))
{
  PCUITEMID_CHILD child;
  CComQIPtr<IShellFolder> pFolder;
  if SUCCEEDED(SHBindToParent(pidl, IID_IShellFolder, (void**)&pFolder, &child))
  {
    CComQIPtr<IContextMenu> pMenu;
    if SUCCEEDED(pFolder->GetUIObjectOf(0, 1, &child, IID_IContextMenu, NULL, (void**)&pMenu))
    {
      HMENU menu = CreatePopupMenu();
      if SUCCEEDED(pMenu->QueryContextMenu(menu, 0, 0, 0x7fff, CMF_NORMAL))
        TrackPopupMenuEx(menu, TPM_LEFTBUTTON, 0, 0, hWnd, NULL);
      DestroyMenu(menu);
    }
  }
  CoTaskMemFree(pidl);
}

Add: Maybe it Windows bug. Any examples from internet and file managers like Explorer (XYPlorer, Explorer++, etc.) have the same problem. Now I see the same issue on Windows 10 Explorer. If you make a shortcut, by Drag & Drop, to a network connection from "Control Panel\All Control Panel Items\Network and Sharing Center\Change adapter settings\adapter_name" on your Desktop, you'll see the same issue.

like image 633
Asaq Avatar asked Sep 05 '25 08:09

Asaq


1 Answers

I think the issue is related to the context menu information for the network connection shortcut being cached, windows might not automatically refresh the cached information when you change the connection state.

You may need to manually refresh the cache by calling the function SHChangeNotify, it will notify the system of an event that an application has performed and trigger a cache refresh.
Here's an example in Delphi:

begin
// ... your code here ...

SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nil, nil);
end;

And in C++:

SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);

To ensure that the context menu is up-to-date, try calling SHChangeNotify before you display.

like image 161
Lemonina Avatar answered Sep 07 '25 22:09

Lemonina