2009-11-16 15 views
0

Création d'un remplacement de boîte de dialogue d'ouverture de fichier. Une grande partie de cela fonctionne maintenant, mais je voudrais générer le menu déroulant mode de vue pour la barre d'outils directement à partir de l'objet vue de l'interpréteur de commandes.Comment puis-je obtenir le IContextMenu qui est affiché dans un menu contextuel IShellView?

En regardant IShellView2, je peux voir IShellView2 :: GetView() me donnera le FOLDERVIEWMODE pris en charge. Cependant, cela ne me donne pas les noms de ces modes, ni ne formate ce menu contextuel pour moi, ni me donne immédiatement un moyen de définir un de ces modes (il semblerait qu'il soit nécessaire de détruire la fenêtre de vue shell et de créer un remplacement pour le dossier actuel et spécifiez le nouveau FOLDERVIEWMODE souhaité ... yeesh). Quoi qu'il en soit, si l'on clique avec le bouton droit sur une fenêtre IShellView, on obtient un menu contextuel, dont le premier sous-menu est exactement ce que je veux placer dans mon bouton de la barre d'outils déroulante (par exemple -out menu (par exemple petites icônes, icônes moyennes, etc.)).

Il semble qu'il devrait y avoir un moyen de récupérer ce sous-menu directement à partir de IShellView, plutôt que de devoir coder en dur mes valeurs (et ainsi, si une instance donnée d'IShellView prend en charge des modes d'affichage supplémentaires, De même, ceux qui devraient être désactivés le seraient, puisque tout serait sous le contrôle de IShellView).

J'ai lu l'excellent How to host an IContextMenu de Raymond Chen. Malheureusement, cela me donne juste un menu contextuel très simpliste - celui du dossier lui-même, ou pour un fichier dans un dossier donné, mais PAS le menu contextuel pour la fenêtre de vue shell de IShellView (à partir de laquelle je pourrais obtenir la vue fly-out).

J'ai essayé ce qui suit, basé sur l'article de Chen:

CComQIPtr<IContextMenu> pcm(m_shell_view); // <<-- FAIL resulting pointer is NULL <<< 

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

// obtain the full popup menu we need 
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"); 

// display the menu to the user 
// menu.getsubmenu 
::TrackPopupMenu(menu, ::GetSystemMetrics(SM_MENUDROPALIGNMENT)|TPM_TOPALIGN|TPM_LEFTBUTTON, pt.x, pt.y, 0, m_shell_view_hwnd, NULL); 

Malheureusement, la tentative d'interroger le m_shell_view (qui est un IShellView *) pour son interface IContextMenu échoue. Ce "fonctionne":

// retrieve our current folder's PIDL 
PidlUtils::Pidl pidl(m_folder); 

// get the context menu for the current folder 
CComPtr<IContextMenu> pcm; 
if (FAILED(m_hresult = GetUIObjectOf(m_owner->m_hWnd, pidl, IID_PPV_ARGS(&pcm)))) 
    throw CLabeledException("Unable to obtain the PIDL for the current folder"); 

Mais ici je reçois seulement très peu d'options dans le menu contextuel (Open, Explorer, ...). Pas le menu contextuel détaillé que je reçois si je fais simplement un clic droit sur la vue du shell elle-même.

Je n'ai plus d'idées sur la façon de procéder. Aidez-moi?! ;)

Répondre

1

Essayez IShellView :: GetItemObject avec SVGIO_BACKGROUND comme uItem pour obtenir un IContextMenu sur l'objet de la vue: http://msdn.microsoft.com/en-us/library/bb774832%28VS.85%29.aspx

+0

Je ne pense pas que vous ayez des idées sur la façon de m'assurer que je peux obtenir le sous-menu de vue indépendamment du système d'exploitation sous lequel je cours (version et langue). – Mordachai

+0

Désolé. Je doute vraiment que ce soit possible, le tout construit le menu win32 pour énumérer les options semble très bas niveau. Il semble que ce soit construit dans le but de construire des menus, pas de les fourrer dedans (mais je peux me tromper) –

0

Il est le SHCreateDefaultContextMenu (Vista un haut) qui peut être utile. Bjarke Viksoe site contient également d'excellentes informations.
SVGIO_BACKGROUND vous obtiendra le menu contextuel en arrière-plan de la vue shell. Vous devrez peut-être appeler à plusieurs reprises pShellView-> SelectItem pour chaque PIDL que vous pourriez avoir, puis faire l'appel GetUIObjectOf (puis QI pour IContextMenu, créer un menu, appeler IContextMenu (3) :: QueryContextMenu et enfin l'afficher avec TrackPopupMenu).