ShellAnything
ShellAnything copied to clipboard
Right-click on a directory with Windows Explorer in the left panel shows the menus twice

I am unable to identify the cause of the issue. Anyone here can help?
The issue is still occurring in 0.9.0, branch feature-issue115, 22d3d87b4ec1c733d6990c3d5ed13061a18e0ed4.
Hint: Implement a ScopeLogger class in file LoggerHelper.h which job is to log (or vebose log) when the code enters/leave a scope. This will be much useful when trying to debug this issue.
EDIT: done : ScopeLogger.
I am uncertain why this is happening. Here are two log captures of the same use case : a user right-click on directory C:\Windows\Cursors" :
- right-panel.txt made by right-clicking on directory from the right-panel side (file list view).
- left-panel.txt made by right-clicking on directory from the left-panel side (directory tree view).
(both files were sanitized. See where I inserted ... for parts that were removed)
Investigations notes:
-
In left log, 2 instances of
CContextMenuare created. This is why we see ShellAnything menus rendered twice in the Context Menu.- The second instance is created and destroyed while the first instance is "in use".
- The first pass assigns a unique set of command ids to ShellAnything menus. The second instance reassign completely different command ids to ShellAnything menus (same instances). This overrides the previous command ids that were sets previously. When the system calls CContextMenu::GetCommandString() with the previous command ids, this creates tons of errors. For example :
E0824 17:46:38.655484 22964 CContextMenu.cpp:515] CContextMenu::GetCommandString(), unknown menu for command_id=1. QueryContextMenu() ended with m_FirstCommandId=143, target_command_id=144. See #31 for details.
-
Flags sent to
QueryContextMenu()in both log files are different.- left-panel: flags=0x00000414=(CMF_EXPLORE|CMF_CANRENAME|CMF_ASYNCVERBSTATE)
- right-panel: flags=0x00020494=(CMF_EXPLORE|CMF_CANRENAME|CMF_ITEMMENU|CMF_ASYNCVERBSTATE)
CMF_ITEMMENUis specified for right-panel. CMF_ITEMMENU means : 0x00000080. The calling application is invoking a shortcut menu on an item in the view (as opposed to the background of the view).
-
The shell extension is registering itself for multiple types :
*,Directory,Directory/Background,Folder, andDrive. Registering the shell extension forAllFilesystemObjectsis also discussed in #120. Maybe registering itself for multiple type is the reason why Windows File Explorer creates 2 instances ofCContextMenu?
The code has already been protected with a cheap patch for detecting calling CContextMenu::QueryContextMenu() twice for the same HMENU.
The fix requires the field CContextMenu::m_previousMenu to be declared static. It was implemented as such in v0.7.0. However, somewhere between v0.7.0 and v0.8.0, the fix was dropped during refactoring.