2009-07-08 8 views
1

J'héberge un contrôle de navigateur Web et je souhaite fournir mon propre menu contextuel.ajouter un menu contextuel personnalisé au contrôle du navigateur Web hébergé

Idéalement, je souhaite présenter mon propre menu contextuel, qui contient le menu contextuel du navigateur d'origine (avec tous les addins, etc.) en tant que sous-menu.

Si ce n'est pas possible/difficile, je serais d'accord, par exemple. normalement en affichant mon menu contextuel et en affichant le menu d'origine lorsque l'utilisateur appuie sur MAJ. J'ai besoin de mettre en œuvre IDocHostUIHandler? Si oui, comment puis-je spécifier un menu contextuel personnalisé, comment puis-je forcer l'original? Comment puis-je obtenir le contrôle pour utiliser ma mise en œuvre?

Le contrôle est créé en tant que telle (gestion des erreurs omise):

HRESULT hr=AtlAxCreateControlEx(
    L"Shell.Explorer",m_wndWebCtrl.m_hWnd, 
    NULL,NULL,(IUnknown**)&unk, 
    IID_IWebBrowser2, NULL); // (IPersistStreamInit*)this); 

hr = AtlAdviseSinkMap(this, true); 

IUnknownPtr unk; 
AtlAxGetControl(m_wndWebCtrl.m_hWnd, &unk); 

IWebBrowser2Ptr browser2 = unk; 

Répondre

1

Oui, vous avez besoin de mettre en œuvre IDocHostUIHandler. Ok, je suppose que vous pourriez intercepter les clics droits, les frappes au clavier, et cet autre message qui affichera normalement un menu contextuel ... Mais ça va probablement mal tourner tôt ou tard; à tout le moins, je m'attends à ce que cela brise l'accessibilité. Une fois que vous avez intercepté IDocHostUIHandler::ShowContextMenu(), vous avez la possibilité de retourner le S_OK pour annuler le menu intégré après avoir affiché le vôtre. Vous pouvez utiliser les routines de menu Win32 normales à cet effet, un contrôle personnalisé ou même HTML sophistiqué si c'est ce qu'il fait pour vous. Selon la documentation, suffisamment de contexte est fourni pour vous permettre de déterminer quel contexte d'élément est demandé, et quel est le menu contextuel par défaut .

Malheureusement, je ne connais aucun moyen de maîtriser le menu intégré. Vous pourriez probablement truquer en montrant votre menu contextuel et en retournant S_FALSE si l'utilisateur a choisi l'option "original", mais même alors il n'y a aucun moyen de joindre le menu résultant à un menu contextuel existant (qui devrait vraiment être parti au moment où vous retourner quand même si vous utilisez la boucle modale commune à ces popups). Il est possible de add options to the built-in menus.

Vous devriez pouvoir utiliser GetKeyboardState() pour déterminer l'état de la touche Maj lorsque le menu a été demandé.


En supposant que vous voulez seulement un sous-ensemble de la fonctionnalité du navigateur normal de toute façon, vous pourriez être mieux servis par tout réimplémenter les options que vous voulez (arrière, avant, impression) et invoquer la commande appropriée si la l'utilisateur les choisit. Alternativement, si vous voulez seulement des menus normaux dans un scénario très spécifique (par exemple: éditer des commandes dans une zone de texte), utilisez les arguments ShowContextMenu() pour l'identifier et seulement ensuite retournez S_FALSE pour déclencher le défaut. J'ai eu beaucoup de chance avec cette dernière technique; après tout, ils sont censés être contexte menus ...

+0

Merci Shog :) Je ne veux tout simplement pas couper complètement l'utilisateur de la fonctionnalité par défaut, donc je suppose que GetKeyboardState fera l'affaire. Est-ce que je sais aussi comment je dis à ATL d'utiliser mon IDocHostUIHandler dans la mise en œuvre de son site client? – peterchen

+0

Je ne peux pas vous le dire, j'ai peur ... Je n'ai jamais essayé en utilisant ATL moi-même. Peut-être que cela va aider? http://support.microsoft.com/kb/274202 – Shog9

1

J'ajoute les informations suivantes comment « injecter » votre propre implémentation DocHostUI dans le contrôle du navigateur:

Le chemin par défaut est de implémenter IOleClientSite et prendre en charge le IDocHostUIHandler sur l'objet d'implémentation.

Il existe un moyen plus simple: Dans le gestionnaire DocumentComplete, interrogez le IHTMLDocumennt pour ICustomDoc, ce qui vous permet de fournir votre interface à partir d'un objet autonome. Cela vous permet de conserver l'implémentation de IOleClientSite fournie par votre environnement.

Plus de détails peuvent être trouvés here.

Questions connexes