Bonjour,
Je tourne en rond, je ne vois pas où ça buggue !!!
Voilà, j'ai développé un truc en Win32 pur (j'utilise MSVS.NET C++ 2003)
J'ai emprunté une source trouvée sur le site concernant une utilisation simple de iwebvowser2, celle-ci :
http://www.cppfrance.com/dlzip.zipnix?ID=29171&accept=1Depuis mon dialogue principal, je veux simplement afficher dans un dialogue modal un fichier HTML présent sur le disque:
La ressource contient:
- un contrôle Edit (IDC_CONTENEUR) qui hébergera le contrôle ActiveX pour afficher la page HTML
- un contrôle Edit (IDC_EDITHTML) pour afficher le code HTML pour info.
- un bouton de fermeture (ID_OK)
------------------------------------------------------------------------------------
J'ai bien mis le:
#include <exdisp.h>
J'ai déclaré ces variables globales:
IWebBrowser2 * pIWeb; // objet Browser utilisé dans preview
HINSTANCE hDLL; // instance atl.dll
------------------------------------------------------------------------------------
Dans WinMain, je crée une instance du Browser une fois pour toutes...
// Charger la DLL "atl.dll" pour le WebBrowser
hDLL = LoadLibrary("atl.dll");
// Initialiser la librairie COM pour le programme:
CoInitialize(0);
// Créer une instance de l'objet WebBrowser et de l'interface IWebBrowser2:
CoCreateInstance(CLSID_WebBrowser,0,CLSCTX_ALL,IID_IWebBrowser2,(void**)&pIWeb);
Puis j'appelle le dialogue principal:
// créer le dialogue principal
hDlg=CreateDialog(hInstance,(LPCTSTR)IDD_MAIN_DIALOG,NULL,(DLGPROC)MainProc);
// le centrer et l'afficher
CenterWindow(hDlg);
ShowWindow(hDlg,SW_SHOW);
Ensuite la boucle des messages...
// boucle messages
MSG msg;
while(GetMessage(&msg,NULL,0,0)==TRUE)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
Et je libère l'interface:
// Libérer l'interface IWebBrowser2:
pIWeb->Release();
// Fermer la librairie COM pour le programme:
CoUninitialize();
// Fermer la DLL "atl.dll"
FreeLibrary(hDLL);
------------------------------------------------------------------------------------
Dans le dialogue principal, un bouton appelle le dialogue "WebBrowser" inclus dans les ressources:
DialogBoxParam(hInst,MAKEINTRESOURCE(IDD_WEBDLG), MainDlg,(DLGPROC)WebProc, (LPARAM)st.c_str());
(st est une string contenant le code HTML)
Et voilà la procédure callback du dialogue "WebBrowser":
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
// procédure callback messages WebBrowser
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
LRESULT CALLBACK WebProc(HWND hwnd, UINT message,WPARAM wParam,LPARAM lParam)
{
// test message
switch(message)
{
case WM_INITDIALOG:
{
hPreview=hwnd; // utilisé dans la procédure OnSize()
CenterWindow(hwnd);
// afficher l'icône système
SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon(hInst,
MAKEINTRESOURCE(IDI_MAINICON)));
SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)LoadIcon(hInst,
MAKEINTRESOURCE(IDI_MAINICON)));
// LPARAM pointe sur la chaîne contenant le code HTML
// Il est mis dans l'edit pour info
SendDlgItemMessage(hwnd, IDC_EDITHTML, WM_SETTEXT, 0, (LPARAM)lParam);
// Définir le type de pointeur pour la fonction "AtlAxAttachControl":
typedef HRESULT (WINAPI *PAttachControl)(IUnknown*, HWND,IUnknown**);
// Récupérer l'adresse de la fonction "AtlAxAttachControl":
PAttachControl AtlAxAttachControl = (PAttachControl) GetProcAddress(hDLL, "AtlAxAttachControl");
// Attacher l'objet WebBrowser à notre EDIT conteneur:
AtlAxAttachControl(pIWeb,GetDlgItem(hwnd, IDC_CONTENEUR),0);
// mise en forme URL
WCHAR url[256];
char buff[256];
strcpy(buff,sAppPath.c_str());
strcat(buff, "\\html.htm");
MultiByteToWideChar (CP_ACP, 0,buff, -1, url, 256);
// Lancer la navigation:
pIWeb->Navigate(url,0,0,0,0);
// Sauter la procédure originale:
return true;
}
/*
j'ai essayé ça, mais c'est pareil !...
case WM_DESTROY:
VARIANT_BOOL pBool;
if ((pIWeb->get_Busy(&pBool))==S_OK)
if (pBool==VARIANT_TRUE)
pIWeb->Stop();
return true;
*/
case WM_SIZE:
OnSize(wParam, LOWORD(lParam), HIWORD(lParam));
return true;
case WM_COMMAND:
switch(HIWORD(wParam))
{
case BN_CLICKED:
switch(LOWORD(wParam))
{
case IDOK:
// Quitter le dialogue
EndDialog(hwnd, LOWORD(wParam));
return true;
}
}
case WM_SYSCOMMAND:
if ((wParam & 0xFFF0) == SC_CLOSE)
{
EndDialog(hwnd,LOWORD(wParam));
return true;
}
default:
return false;
}
}
Je ne vois pas où est l'erreur ???
Au début, j'avais mis les initilisations/libérations de l'interface dans WM_INITDIALOG de la fenêtre "Webbrowser", mais le résultat est le même et ça prend du temps : ça recharge la DLL à chaque appel !
Le problème :
Tout a l'air de fonctionner normalemenr.
Mais... si dans le texte HTML, il y a par exemple ceci : <IMG src="http://machintruc"></IMG>, au premier appel du dialogue la fenêtre de connexion apparaît, ce qui est normal.
Si je refuse la connexion, l'image est représentée par le carré rouge, toujours normal.
Mais quand je referme le dialogue et que je le réouvre deux ou trois fois, ça "plante" à la fermeture comme si quelque chose n'était pas libéré...
Le dialogue se ferme, mais ne rend pas la main à la proceduré principale !
Je dois passer par "Le programme ne répond pas, terminer maintenant, envoyer le rapport etc....."
De plus le comportement est assez erratique !
Parfois, ça marche mais ça ne repropose pas la connexion !...
Il me semble que l'appel au dialogue (le DialogBoxParam plus haut...) attend indéfiniment su'une fonction appelée se termine.
Je suis dans le brouillard.
Je suis prêt à adopter une autre solution... mais pour faire aussi court ?!...
Merci pour votre aide.