IContextMenu :: GetCommandString Не показывать текст справки в проводнике Windows - PullRequest
1 голос
/ 20 марта 2010

Я реализую контекстное меню оболочки для Windows Explorer и успешно создал меню. У меня возникли проблемы с методом IContextMenu :: GetCommandString, который отображает текст справки в строке состояния при наведении курсора на выбранный элемент меню.

Когда я наводю указатель мыши на каждый элемент, ничего не отображается, но странно, что некоторые другие элементы, которые я не создал, например, - открыть или распечатать, превратили текст справки в мусор.

Вот пример кода 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.

Спасибо.

Ответы [ 2 ]

1 голос
/ 20 марта 2010

Ваше объявление GetCommandString неверно - GetCommandString передает свой собственный буфер, куда вы должны копировать строку. Я не думаю, что вы можете объявить его как StringBuilder в этом случае. Объявите его как IntPtr, а затем используйте Encoding.Unicode.GetBytes и Marshal.Copy, чтобы скопировать строку в буфер - обязательно добавьте нулевой терминатор.

0 голосов
/ 15 мая 2015

Чтобы быть точным, вам необходимо проверить также GetCommandString flags . Даже если pszName объявлено как LPSTR, проверьте, являются ли константы GCS _... A (ansi) или W (unicode).
Если, например, uFlags - это GCS_VERBA, то pszName - это LPSTR (char *), и вам нужно передать символы cch копирования из строки ANSI.
Если uFlags - GCS_VERBW, то pszName - это тип LPWSTR (wchar_t *) (даже если он объявлен как LPSTR), и вам необходимо скопировать символы cch из строки Unicode.
Я не помню, правильная ли здесь документация для cchMax (может быть число байтов, а не количество символов).

...