بالتأكيد هناك طريقة للحصول على المنظر الكامل المنسدلة لعرض المجلد الحالي؟

StackOverflow https://stackoverflow.com/questions/1836622

  •  11-09-2019
  •  | 
  •  

سؤال

تحفيز: إنشاء مربع حوار الملف الخاص بنا الذي يبدو وكأنه يشبه مربع الحوار STD الشائع

مشكلة: كيفية الحصول على عرض المنسد لأسفل لحاوية المجلد / شل الحالي

واضح طريق مسدود:

  • الاستعلام عن Ishellfolder ل ICONTEXTMENU <مؤشر واجهة NULL.
  • الاستعلام عن IshellView للحصول على ICONTEXTMENU <مؤشر واجهة NULL.
  • Ishellfolder :: CreateviewObject (iid_icontextmenu ...) <قائمة السياق المحدودة للغاية (جديد).
  • Ishellfolder :: getuiobjectof (iid_icontextmenu ...) <قائمة السياق المحدودة (فتح، استكشاف، ...).
  • تنفيذ IshellBrowser's Insertmenussb، Removemenussb، و SetMenusb <القائمة لا تتبع أبدا ما الذي أضعه

لقد قضيت بعض الوقت في القراءة تنفيذ عرض مجلد و كيفية استضافة ICONTEXTMENU. وبعد يبدو أن هذا يشير إلى أن النهج النهائي أعلاه (تنفيذ InsertMenusB، ...) يجب أن تعمل. يجب أن يكون ishellview ملء القائمة المشتركة للحصول على iShellBrowser، بما في ذلك Subsenu عرضها، مع العناصر المناسبة. ومع ذلك، حتى الآن، كل ما أحصل عليه من هذه قائمة فارغة (ما لم أتعفذها مع العناصر - في هذه الحالة، فقط أحصل على العناصر التي قمت بملءها بها).

بالتأكيد هناك طريقة للقيام بذلك. يصل مستكشف Windows إلى القائمة التي يعرضها (إذا قمت بالضغط على ALT على نظام التشغيل Vista أو أعلى) من مكان ما. ولا أستطيع أن أتخيل أن هذه القائمة مبنية قانونيا من قبل Explorer نفسه - إنها بالتأكيد تم إنشاؤها بشكل ديناميكي بطريقة أو بأخرى في حفل موسيقي مع ISHELLVIEVEN المعروض حاليا للسماح بملحقات Shell لعرض القائمة الصحيحة لخيارات العرض (وغيرها من خيارات القائمة).

لكن الوثائق على insertmenusb., removemenusb., ، و setmenusb. غير مربكة. يبدو أنه يشير إلى أنه، كخادم الحاوية، يجب أن أضعف المرفق olemenugroupwidths., "في العناصر 0، 2، و 4 لتعكس عدد عناصر القائمة التي قدمتها في مجموعات الملفات وعرضها ونوافذها."

لقد قمت بتطبيق ما يلي لمحاولة الوفاء بشكل صحيح بهذا العقد:

HRESULT STDMETHODCALLTYPE ShellBrowserDlgImpl::InsertMenusSB(__RPC__in HMENU hmenuShared, /* [out][in] */ __RPC__inout LPOLEMENUGROUPWIDTHS lpMenuWidths)
{
    TRACE("IShellBrowser::InsertMenusSB\n");

    // insert our main pull-downs
    struct  
    {
        UINT    id;
        LPCTSTR label;
    } pull_downs[] = {
        { FCIDM_MENU_FILE, "File" },
        { FCIDM_MENU_EDIT, "Edit" },
        { FCIDM_MENU_VIEW, "View" },
        { FCIDM_MENU_TOOLS, "Tools" },
        { FCIDM_MENU_HELP, "Help" },
    };
    for (size_t i = 0; i < countof(pull_downs); ++i)
    {
        VERIFY(AppendMenu(hmenuShared, MF_POPUP, pull_downs[i].id, pull_downs[i].label));
        ASSERT(GetMenuItemID(hmenuShared, i) == pull_downs[i].id);
    }

    // set the count of menu items we've inserted into each *group*
    lpMenuWidths->width[0] = 2; // FILE: File, Edit
    lpMenuWidths->width[2] = 2; // VIEW: View, Tools
    lpMenuWidths->width[4] = 1; // WINDOW: Help

    return S_OK;
}

هل قام أي شخص بتنفيذ مستكشف مثل المشروع الذي يكشف بشكل صحيح قوائم IshellView الحالية للمستخدم النهائي؟

هل هناك وثائق / أمثلة على ioleinpramefame. التنفيذات التي قد تسقط بعض الضوء على هذا الموضوع الحار؟

ugh! @ - أشعر أنني يجب أن أكون قريبا - ولكن ليس قريبا بما فيه الكفاية!

هل كانت مفيدة؟

المحلول

استخدم svgio_backgrounground للحصول على قائمة الخلفية للمجلد، والتي يجب أن يكون لها قائمة فرعية. قد يختلف المؤشر والاسم ومعرف الأمر من عنصر القائمة "عرض" بين إصدارات Windows واللغات المحلية، لذلك هذا نوع من الاختراق.

نصائح أخرى

بالنسبة لأولئك الذين قد يكونون مهتمين، إليك تنفيذ الإجابة المعطاة التي أستخدمها:

void ShellBrowserDlgImpl::ViewModeDropDown(const CPoint & pt)
{
    // ask the view for its context menu interface
    CComPtr<IContextMenu> pcm;
    if (FAILED(m_hresult = m_shell_view->GetItemObject(SVGIO_BACKGROUND, IID_PPV_ARGS(&pcm))) || !pcm)
        throw CLabeledException("Unable to query the context menu interface from the shell view: ");

    // create a blank menu to store it in
    CMenu menu;
    if (!menu.CreateMenu())
        throw CContextException("Unable to create an empty menu in which to store the context menu: ");

    // populate the context menu
    if (FAILED(m_hresult = pcm->QueryContextMenu(menu, 0, SCRATCH_QCM_FIRST, SCRATCH_QCM_LAST, CMF_NORMAL)))
        throw CLabeledException("Unable to query the context menu for the current folder");

    // obtain the "view" submenu to use as our drop-down menu
    //HACK: we assume that the view pop-up is the first entry (true in English)
    //TODO: We need some way to scan for the correct submenu
    // if we knew of a given command that exists under view - we could FindMenuContaining()
    // of if we could scan for an invariant command name using a similar technique
    // or we could possibly...?
    CMenu * pViewMenu = menu.GetSubMenu(0);

    // get the proper orientation for the drop-menu
    UINT uFlags = ::GetSystemMetrics(SM_MENUDROPALIGNMENT) ? TPM_RIGHTALIGN|TPM_HORNEGANIMATION : TPM_LEFTALIGN|TPM_HORPOSANIMATION;

    // display the menu to the user
    BOOL nCmdID = ::TrackPopupMenu(*pViewMenu, TPM_RETURNCMD|uFlags, pt.x, pt.y, 0, m_shell_view_hwnd, NULL);

    // check if the user canceled the menu
    if (!nCmdID)
        return;

    // create the command to execute
    CMINVOKECOMMANDINFO ici = {0};
    ici.cbSize = sizeof(ici);
    ici.hwnd = m_shell_view_hwnd;
    ici.lpVerb = MAKEINTRESOURCE(nCmdID-1); //NOTE: not sure if the -1 is due to the position of the submenu we're pulling out, or something else - might be invalid for other OSes or languages
    if (FAILED(m_hresult = pcm->InvokeCommand(&ici)))
        throw CLabeledException("Unable to execute your command");
}

أنت تقوم بإعادة تكوين سيطرة صعبة سيئة السمعة للحصول على صواب، ويعرف الكثيرون، وكثير من الناس يعرفون ويستخدمون منذ أن بدأوا في استخدام Windows. أي فشل في الحصول عليه بشكل صحيح سوف يزعج بعض مجموعة فرعية على الأقل من مستخدمي المستخدمين، وتعريف "اليمين تماما" سوف يتغير من إصدار Windows إلى إصدار Windows.

لماذا لا يمكنك استخدام واحد الافتراضي؟ ما الذي تنطبقه يضيف قيمة كبيرة إلى مربع الحوار هذا مفاده أن المعيار المستحيل استخدامه؟

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top