2010-03-19 40 views
0

我正在为Windows资源管理器实现一个shell上下文菜单,并已成功创建菜单。我遇到的问题是IContextMenu :: GetCommandString方法,当您将鼠标悬停在所选菜单项上时,会在状态栏中显示帮助文本。IContextMenu :: GetCommandString在Windows资源管理器中未显示帮助文本

当我将鼠标悬停在每个项目没有显示,但什么奇怪的是,一些我没有创造,如其他项目 - 开或打印有他们的帮助文本变成垃圾..

这里是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_SEPARATOR | 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; 
     } 
    } 

有没有人有什么建议?我已阅读了大量关于如何构建外壳扩展的文章,并且也一直在阅读MSDN。

谢谢。

+0

你不应该在.NET中创建shell扩展 – Anders 2010-03-21 01:01:50

+0

嘿,你有没有发布你的任何环绕接口? – divinci 2011-06-17 21:33:47

回答

1

您对GetCommandString的声明不正确 - GetCommandString将自己的缓冲区传递到应该复制字符串的地方。在这种情况下,我认为你不能把它声明为StringBuilder。将其声明为IntPtr,然后使用Encoding.Unicode.GetBytes和Marshal.Copy将您的字符串复制到缓冲区 - 确保添加空终止符。

0

为了准确,您还需要验证GetCommandString flags。即使pszName被声明为LPSTR,也要检查GCS _...常量是A(ansi)还是W(unicode)。
例如,如果uFlags是GCS_VERBA,那么pszName是LPSTR(char *),并且您需要传递ANSI字符串中的复制cch字符。
如果uFlags是GCS_VERBW,那么pszName是LPWSTR类型(wchar_t *)(即使声明为LPSTR),并且您需要从Unicode字符串复制cch字符。
我不记得这里的cchMax文档是否正确(可能是字节数而不是字符数)。

相关问题