IContextMenu::GetCommandString Not showing help text in Windows Explorer
i am implementing a shell context menu for windows explorer and have successfully created the menu's. What i am having trouble with is the IContextMenu::GetCommandString method that displays the help text in the status bar when you hover over the selected menu item.
When i do hover over each item nothing is displayed, but whats weird is that some of the other items that i didnt create, eg - open, or print have had their help text turned into garbage..
Here is a code sample of IContextMenu::QueryContextMenu & IContextMenu::GetCommandString..
int ShellExtLib.IContextMenu.QueryContextMenu(IntPtr hMenu, uint indexMenu, uint idCmdFirst, uint idCmdLast, uint uFlags)
{
uint idCmd = idCmdFirst;
StringBuilder sb = new StringBuilder(1024);
try
{
if ((uFlags & 0xf) == 0 || (uFlags & (uint)ShellExtLib.CMF.CMF_EXPLORE) != 0)
{
uint selectedFileCount = Helpers.DragQueryFile(m_hDrop, 0xffffffff, null, 0);
if (selectedFileCount == 1)
{
Helpers.DragQueryFile(m_hDrop, 0, sb, sb.Capacity + 1);
Documents.Add(sb.ToString());
}
else
{
// MULTIPLE FILES SELECTED.
for (uint i = 0; i < selectedFileCount; i++)
{
Helpers.DragQueryFile(m_hDrop, i, sb, sb.Capacity + 1);
Documents.Add(sb.ToString());
}
}
Helpers.InsertMenu(hMenu, indexMenu++, ShellExtLib.UFLAGS.MF_SEPARATOR | ShellExtLib.UFLAGS.MF_BYPOSITION, 0, null);
IntPtr hSubMenu = Helpers.CreateMenu();
if (hSubMenu != IntPtr.Zero)
{
Helpers.InsertMenu(hSubMenu, 0, ShellExtLib.UFLAGS.MF_STRING | ShellExtLib.UFLAGS.MF_BYPOSITION, idCmd++, "Item 1");
Helpers.InsertMenu(hSubMenu, 1, ShellExtLib.UFLAGS.MF_STRING | ShellExtLib.UFLAGS.MF_BYPOSITION, idCmd++, "Item 2");
Helpers.InsertMenu(hSubMenu, 2, ShellExtLib.UFLAGS.MF_SEPARATOR | ShellExtLib.UFLAGS.MF_BYPOSITION, idCmd++, null);
Helpers.InsertMenu(hSubMenu, 3, ShellExtLib.UFLAGS.MF_STRING | ShellExtLib.UFLAGS.MF_BYPOSITION, idCmd++, "Item 3");
Helpers.InsertMenu(hSubMenu, 4, ShellExtLib.UFLAGS.MF_SEPARATOR | ShellExtLib.UFLAGS.MF_BYPOSITION, idCmd++, null);
Helpers.InsertMenu(hSubMenu, 5, ShellExtLib.UFLAGS.MF_STRING | ShellExtLib.UFLAGS.MF_BYPOSITION, idCmd++, "Item 4");
Helpers.InsertMenu(hSubMenu, 6, ShellExtLib.UFLAGS.MF_STRING | ShellExtLib.UFLAGS.MF_BYPOSITION, idCmd++, "Item 5");
}
Helpers.InsertMenu(hMenu, indexMenu++, ShellExtLib.UFLAGS.MF_STRING | ShellExtLib.UFLAGS.MF_BYPOSITION | ShellExtLib.UFLAGS.MF_POPUP, (uint)hSubMenu, "Main Menu");
Helpers.InsertMenu(hMenu, indexMenu++, ShellExtLib.UFLAGS.MF_SEP开发者_如何学GoARATOR | ShellExtLib.UFLAGS.MF_BYPOSITION, 0, null);
return (int)(idCmd - idCmdFirst);
}
}
catch { }
return 0;
}
void ShellExtLib.IContextMenu.GetCommandString(int idCmd, uint uFlags, int pwReserved, StringBuilder commandString, int cchMax)
{
switch (uFlags)
{
case (uint)ShellExtLib.GCS.VERB:
commandString = new StringBuilder("x");
break;
case (uint)ShellExtLib.GCS.HELPTEXTA:
commandString = new StringBuilder("y");
break;
}
}
Does anyone have any suggestions? I have read a number of articles on how to build shell extensions and have also been reading MSDN as well..
Thanks.
Your declaration of GetCommandString is incorrect - GetCommandString passes its own buffer where you are supposed to copy the string. I don't think you can declare it as StringBuilder in this case. Declare it as IntPtr and then use Encoding.Unicode.GetBytes and Marshal.Copy to copy your string to the buffer - be sure to add the null terminator.
To be accurate, you need to verify also the GetCommandString flags. Even if the pszName is declared as LPSTR, check if the GCS_... constants are A (ansi) or W (unicode).
If, for example, uFlags is GCS_VERBA, then pszName is a LPSTR (char*) and you need to pass copy cch characters from an ANSI string.
If uFlags is GCS_VERBW, then pszName is a LPWSTR type (wchar_t*) (even if declared as LPSTR) and you need to copy cch characters from an Unicode string.
I don't remember if the documentation is correct here for cchMax (might be a byte count and not a character count).
精彩评论