2010-03-19 108 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文檔是否正確(可能是字節數而不是字符數)。

相關問題