Bonjour,

Voici un petit tutorial expliquant comment intégrer le navigateur Chromium (Chrome) directement dans les fenêtres Windev, en lieu et place d'Internet Explorer et de l'activeX Shell.Explorer.
Cela est rendu possible par l'utilisation de la librairie CefSharp (pour Chromium Embedded Framework) (https://github.com/cefsharp/CefSharp) et d'un champ Windev de type .NET 2.0 (WinForm).
Les possibilités sont nombreuses et je ne présente donc ici que les fonctionnalités de base.

1/Fichiers nécessaires

Les sources pour Chromium en version 45 sont disponibles ici : https://mon-partage.fr/f/W22nIf8c/.
Il faut copier tous les éléments dans le répertoire de votre exécutable, et dans le répertoire "Exe" de votre projet Windev pour le mode test.

La dll WindevNet a été compilée par moi même pour permettre la récupération du résultat d'appels Javascript.

Les autres dlls sont issues d'un projet Visual Studio (Community) de test de CefSharp, compilé avec la dernière version des packages disponibles.
Des explications simples pour tester CefSharp avec Visual Studio sont disponibles ici : http://www.codeproject.com/Articles/...using-CefSharp.

2/Intégration dans Windev

Dans Windev, cliquez sur le menu Atelier/.NET/Utiliser un assemblage .NET dans votre projet.
Dans la fenêtre listant les assemblages disponibles, cliquez sur le bouton "Parcourir" et sélectionnez les dlls "CefSharp.Core.dll", "CefSharp.WinForms.dll", "WDNetHelpers.dll" et "WindevNet.dll", présentes dans le répertoire "Exe" de votre projet.

Dans la liste des assemblages, sélectionnez aussi l'assemblage "System.Windows.Forms".

Cliquez sur le bouton de validation pour importer les dlls dans votre projet.

2.1/Ajout du champ .NET 2.0 pour affichage du navigateur

Insérez sur votre fenêtre Windev un champ .NET 2.0 (WinForm)
Dans la description du champ, onglet "Général", sélectionnez la classe "System.Windows.Forms.Panel".

2.2/Code d'initialisation de la fenêtre

Dans le traitement d'initialisation de la fenêtre qui contient le champ .NET 2.0, ajoutez le code suivant, qui va permettre d'initialiser Cef et d'intercepter les événements du navigateur dans des procédures Windev.
La liste des événements gérés n'est pas exhaustive, mais j'ai souhaité dans un premier temps mettre en place l'interception de ceux qui me paraissaient les plus importants.

L'objet oWDJavascript va permettre d'intercepter l'événement de fin d'exécution asynchrone d'un code Javascript.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
SI PAS Cef.IsInitialized ALORS
	Cef.Initialize()
FIN

goBrowser est un ChromiumWebBrowser("http://google.com")

goBrowser.add_AddressChanged(DotNetDélégué(AdressChanged,"EventHandler<CefSharp.AddressChangedEventArgs>"))
goBrowser.add_ConsoleMessage(DotNetDélégué(ConsoleMessage,"EventHandler<CefSharp.ConsoleMessageEventArgs>"))
goBrowser.add_IsBrowserInitializedChanged(DotNetDélégué(IsBrowserInitializedChanged,"EventHandler<CefSharp.IsBrowserInitializedChangedEventArgs>"))
goBrowser.add_FrameLoadStart(DotNetDélégué(FrameLoadStart,"EventHandler<CefSharp.FrameLoadStartEventArgs>"))
goBrowser.add_FrameLoadEnd(DotNetDélégué(FrameLoadEnd,"EventHandler<CefSharp.FrameLoadEndEventArgs>"))
goBrowser.add_LoadError(DotNetDélégué(LoadError,"EventHandler<CefSharp.LoadErrorEventArgs>"))
goBrowser.add_LoadingStateChanged(DotNetDélégué(LoadingStateChanged,"EventHandler<CefSharp.LoadingStateChangedEventArgs>"))
goBrowser.add_StatusMessage(DotNetDélégué(StatusMessage,"EventHandler<CefSharp.StatusMessageEventArgs>"))
goBrowser.add_TitleChanged(DotNetDélégué(TitleChanged,"EventHandler<CefSharp.TitleChangedEventArgs>"))

oWDJavascript est un WindevNet.WDJavascript
oWDJavascript:add_EvaluateJsDone(DotNetDélégué(EvaluateJsDone,"EventHandler<EvaluateJsDoneEventArgs>"))

CAS EXCEPTION:
	Erreur(ExceptionInfo(errComplet))
2.3/Procédures de gestion des événements

Dans la fenêtre Windev, il faut maintenant créer les procédures correspondantes à celles déclarées dans la fonction DotNetDélégué() de l'étape 2.2 soit :

AdressChanged
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
 
PROCEDURE AdressChanged(_oBrowser est un ChromiumWebBrowser,_oArgs est CefSharp.AddressChangedEventArgs <utile>)
 
Trace("------------------------------")
Trace(dbgInfo(dbgTraitement))
Trace(_oBrowser:get_Address())
ConsoleMessage
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
 
PROCEDURE ConsoleMessage(_oBrowser est un ChromiumWebBrowser,_oArgs est CefSharp.ConsoleMessageEventArgs <utile>)
 
Trace("------------------------------")
Trace(dbgInfo(dbgTraitement))
Trace(_oBrowser:get_Address())
Trace(_oArgs.Line+" : "+_oArgs.Message)
IsBrowserInitializedChanged
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
 
PROCEDURE IsBrowserInitializedChanged(_oBrowser est un ChromiumWebBrowser,_oArgs est CefSharp.IsBrowserInitializedChangedEventArgs <utile>)
 
Trace("------------------------------")
Trace(dbgInfo(dbgTraitement))
Trace(_oBrowser:get_Address())
FrameLoadStart
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
 
PROCEDURE FrameLoadStart(_oBrowser est un ChromiumWebBrowser,_oArgs est CefSharp.FrameLoadStartEventArgs <utile>)
 
Trace("------------------------------")
Trace(dbgInfo(dbgTraitement))
Trace(_oBrowser:get_Address())
FrameLoadEnd
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
 
PROCEDURE FrameLoadEnd(_oBrowser est un ChromiumWebBrowser,_oArgs est CefSharp.FrameLoadEndEventArgs <utile>)
 
Trace("------------------------------")
Trace(dbgInfo(dbgTraitement))
Trace(_oBrowser:get_Address())
 
bMainFrame est un booléen
bMainFrame = _oArgs.Frame.IsMain
SI bMainFrame ALORS
	Trace("#############################")
FIN
Trace("Main Frame ? : "+bMainFrame)
Trace("Frame Url ? : "+_oArgs.Url)
LoadError
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
 
PROCEDURE LoadError(_oBrowser est un ChromiumWebBrowser,_oArgs est CefSharp.LoadErrorEventArgs <utile>)
 
Trace("------------------------------")
Trace(dbgInfo(dbgTraitement))
Trace(_oBrowser:get_Address())
LoadingStateChanged
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
 
PROCEDURE LoadingStateChanged(_oBrowser est un ChromiumWebBrowser,_oArgs est CefSharp.LoadingStateChangedEventArgs <utile>)
 
//https://github.com/cefsharp/CefSharp/blob/master/CefSharp/LoadingStateChangedEventArgs.cs
Trace("------------------------------")
Trace(dbgInfo(dbgTraitement))
Trace(_oBrowser:get_Address())
 
bIsLoading est un booléen
bIsLoading = _oArgs.get_IsLoading()
Trace("Loading : "+bIsLoading)
StatusMessage
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
 
PROCEDURE StatusMessage(_oBrowser est un ChromiumWebBrowser,_oArgs est CefSharp.StatusMessageEventArgs <utile>)
 
Trace("------------------------------")
Trace(dbgInfo(dbgTraitement))
Trace(_oBrowser:get_Address())
TitleChanged
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
 
PROCEDURE TitleChanged(_oBrowser est un ChromiumWebBrowser,_oArgs est CefSharp.TitleChangedEventArgs <utile>)
 
Trace("------------------------------")
Trace(dbgInfo(dbgTraitement))
Trace(_oBrowser:get_Address())
EvaluateJsDone
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
 
PROCEDURE EvaluateJsDone(_oWDJavascript est un WindevNet.WDJavascript <utile>,_oArgs est WindevNet.EvaluateJsDoneEventArgs)    
 
Info(_oArgs.sResult)
2.4/Fin d'initialisation de la fenêtre

Dans le traitement de fin d'initialisation, copier le code suivant (WinForm1 est le nom du champ .NET 2.0) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
 
goBrowser.Dock = DockStyle.Fill
//WinForm1 est le nom du champ .NET 2.0
WDHelpers.AddControlToControlCollection(goBrowser,WinForm1.Controls)
MaFenêtre..Titre += " : "+Cef.ChromiumVersion +"-"+ Cef.CefVersion+"-"+Cef.CefSharpVersion
2.5/Fermeture de la fenêtre

Cef.Shutdown()

3/Fonctions diverses

Charger une URL :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
 
goBrowser.Load("http://google.com")
Il est aussi possible d'accéder au DOM des documents et de le modifier à l'aide d'appels Javascript.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
sJavascript est une chaîne = [
	document.forms["%1"].submit();
]
sFormNom est une chaîne
sFormNom = "myform"
sJavascript = ChaîneConstruit(sJavascript,sFormNom)

WebBrowserExtensions.ExecuteScriptAsync(goBrowser,sJavascript)
Récupérer le résultat d'une fonction Javascript :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 
sJavascript est une chaîne
sVal est une chaîne
 
//Récupérer le contenu de la balise 'html' du document
sJavascript = [
document.getElementsByTagName('html')[0].innerHTML;
]
EvaluateJsAsync(goBrowser,sJavascript)
//La procédure Windev de gestion d'événement "EvaluateJsDone" est déclenchée lorsque le résultat est prêt.
 
//Récupérer le contenu de tous les formulaires du document
sJavascript = [
(function() { 
var elements = document.getElementsByTagName('form'); 
var elementsList = ''; 
for (var i = 0; i < elements.length; i++) { 
	var element = elements[i]; 
	elementsList += element.innerHTML; 
	if (i < elements.length-1) 
	{ 
		elementsList += '<RC>'; 
	} 
} 
return elementsList; })();
]
EvaluateJsAsync(goBrowser,sJavascript)
//La procédure Windev de gestion d'événement "EvaluateJsDone" est déclenchée lorsque le résultat est prêt.
La procédure Windev "EvaluateJsAsync" :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
 
PROCEDURE EvaluateJsAsync(_oBrowser est un ChromiumWebBrowser, LOCAL _sJavascript est une chaîne)
 
oFrame est CefFrameWrapper dynamique <- WebBrowserExtensions.GetMainFrame(_oBrowser)
oWDJavascript:EvaluateJsAsync(oFrame,_sJavascript,0)
La procédure Windev "EvaluateJsDone" :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
 
PROCEDURE EvaluateJsDone(_oWDJavascript est un WindevNet.WDJavascript <utile>,_oArgs est WindevNet.EvaluateJsDoneEventArgs)                         
 
Info(_oArgs.sResult)
Code C# de la dll WindevNet :

Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
 
using CefSharp;
using System;
using System.Threading.Tasks;
 
namespace WindevNet
{
    public class EvaluateJsDoneEventArgs : EventArgs
    {
        public int iID { get; set; }
        public string sResult { get; set; }
        public Task<JavascriptResponse> JavascriptResponse;
    }
 
    public class WDJavascript
    {
 
        public event EventHandler<EvaluateJsDoneEventArgs> EvaluateJsDone;
 
        protected virtual void OnEvaluateJsDone(EvaluateJsDoneEventArgs e)
        {
            EventHandler<EvaluateJsDoneEventArgs> handler = EvaluateJsDone;
            if (handler != null)
            {
                handler(this, e);
            }
        }
 
        public void EvaluateJsAsync(IFrame f, string sJavascript,int iID=0)
        {
            f.EvaluateScriptAsync(sJavascript).ContinueWith(t =>
            {
                var Response = t.Result;
                EvaluateJsDoneEventArgs args = new EvaluateJsDoneEventArgs();
                args.iID = iID;
                args.sResult = (string)Response.Result.ToString();
                args.JavascriptResponse = t;
                OnEvaluateJsDone(args);
            });
        }
 
    }
 
}

Code C# de test de CefSharp :

Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
 
using System;
using System.Windows.Forms;
using CefSharp;
using CefSharp.WinForms;
 
namespace CefTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            InitBrowser();
        }
 
        public ChromiumWebBrowser browser;
 
        public void InitBrowser()
        {
            Cef.Initialize(new CefSettings());
            browser = new ChromiumWebBrowser("www.google.com");
 
            browser.IsBrowserInitializedChanged -= new EventHandler<CefSharp.IsBrowserInitializedChangedEventArgs>(IsBrowserInitialized);
            browser.IsBrowserInitializedChanged += new EventHandler<CefSharp.IsBrowserInitializedChangedEventArgs>(IsBrowserInitialized);
 
            browser.FrameLoadEnd -= new EventHandler<CefSharp.FrameLoadEndEventArgs>(FrameLoadEnd);
            browser.FrameLoadEnd += new EventHandler<CefSharp.FrameLoadEndEventArgs>(FrameLoadEnd);
 
            browser.ConsoleMessage -= new EventHandler<CefSharp.ConsoleMessageEventArgs>(ConsoleMessage);
            browser.ConsoleMessage += new EventHandler<CefSharp.ConsoleMessageEventArgs>(ConsoleMessage);
 
            this.Controls.Add(browser);
            browser.Dock = DockStyle.Fill;
        }
 
        private void IsBrowserInitialized(object sender, IsBrowserInitializedChangedEventArgs e)
        {
            if (e.IsBrowserInitialized)
            {
                //Do something here
            }
        }
 
        public string EvaluateJsResponse;
 
        public void EvaluateJs(IFrame f, string Js)
        {
            f.EvaluateScriptAsync(Js).ContinueWith(x =>
            {
                var response = x.Result;
                if (response.Success && response.Result != null)
                {
                    EvaluateJsResponse = (string)response.Result.ToString();
                    //Do something here (To interact with the UI you must call BeginInvoke)
                }
            });
        }
 
        public void FrameLoadEnd(object sender, FrameLoadEndEventArgs e)
        {
            if (e.Frame.IsMain)
            {
                //string sJs = "document.getElementsByTagName('html')[0].innerHTML;";
                string sJs = "(function() { var body = document.body, html = document.documentElement; return  Math.max( body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight ); })();";
                EvaluateJs(e.Frame, sJs);
            }
        }
 
        public void ConsoleMessage(object sender, ConsoleMessageEventArgs e)
        {
            Console.WriteLine(e.Message);
        }
 
    }
}

En cas de problèmes d'intégration dans Windev, la solution peut être souvent de supprimer le répertoire .NET de votre projet, de vider son répertoire de compilation <NomProjet>.cpl et de recompiler le projet.

Merci aux intervenants de ce fil : http://www.developpez.net/forums/d14...cation-windev/ et à ochoteau en particulier pour les sources.

Bonne prog