[C#][ActiveX][Thread][HTML/Javascript] Evénements OK mais pas dans tous les cas
Mediant
Messages postés2Date d'inscriptionmercredi 20 février 2008StatutMembreDernière intervention17 mars 2008
-
17 mars 2008 à 15:44
Mediant
Messages postés2Date d'inscriptionmercredi 20 février 2008StatutMembreDernière intervention17 mars 2008
-
17 mars 2008 à 20:31
Bonjour !
Voilà, j'au dû me mettre au C# il y a quelque jours afin de réaliser un composant ActiveX.
J'ai besoin que ce composant puisse m'envoyer des événements pouvant être "captés" depuis la page HTML qui l'utilisera.
Après avoir passer pas mal de temps à chercher de la doc sur la création d'activeX en C# et sur la gestion d'événements, jai pu arrivé à une solution (:aie:).
Lorsque j'appelle une méthode de mon objet intégré dans la page, cela lance bien un événement et arrive à bien être capté dans lapage HTML.
Mais pour les besoins que j'ai, ces évenements devront être lancés par un thread réalisant une tâche dépendante.
Et c'est là que le problème intervient. Lorsque depuis le thread, je fais appel la méthode de "l'objet parent" (si vous me permettez l'expression) cela me lève une Exception bien spécifique .. alors que cela fonctionne lorsqu'elle est appelée directement via la page HTML ??
Ainsi, pour les besoins de l'explication, j'ai tenté de vous proposer une version "light" de mon problème. Le composant repose sur un TextBox qui me permet de "tracer" différents messages.
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Threading;
using System.Reflection;
namespace ActiveXSourcingAutre {
public delegate void ClickEventHandlerThread(string a, string b);
[System.Runtime.InteropServices.GuidAttribute("9621A92C-3FBD-4be4-9153-51EEC1444507")]
[System.Runtime.InteropServices.InterfaceTypeAttribute(System.Runtime.InteropServices.ComInterfaceType.InterfaceIsIDispatch)]
public interface ControlEventsAutre
{
[System.Runtime.InteropServices.DispIdAttribute(0x60035000)]
void ClickEventThread(string a, string b);
}
[System.Runtime.InteropServices.InterfaceTypeAttribute(System.Runtime.InteropServices.ComInterfaceType.InterfaceIsIDispatch)]
public interface MonInterfaceAutre {
[System.Runtime.InteropServices.DispIdAttribute(0x60060003)]
void demandeLance();
[System.Runtime.InteropServices.DispIdAttribute(0x60060007)]
void FoncActiveThread(string a, string b);
}
public class MonThreadHandle {
MyWindowControlAutre mxcparent;
public MonThreadHandle(MyWindowControlAutre mxcparam) {
this.mxcparent = mxcparam;
}
public void AffichageInterp() {
mxcparent.FoncActiveThread("JOJO", "JUJU");
}
public void ThreadLoop() {
// .... Réalise différents traitements (attente de lectures asynchrones notamment ..)
// et dans un cas particulier fait appel à la fonction suivante
AffichageInterp();
}
}
[System.Runtime.InteropServices.ClassInterface(System.Runtime.InteropServices.ClassInterfaceType.None), System.Runtime.InteropServices.ComSourceInterfaces(typeof(ControlEventsAutre))]
public class MyWindowControlAutre : System.Windows.Forms.UserControl, MonInterfaceAutre //, ComInteropControlInterface
{
System.Windows.Forms.TextBox tx = new TextBox();
MonThreadHandle threadHandle;
Thread t;
event ActiveXSourcingAutre.ClickEventHandlerThread ClickEventThread;
private void InitializeComponent() {
this.Name = "MyWindowControlAutre";
}
public MyWindowControlAutre()
: base() {
initMyWindowControlAutre();
}
private void initMyWindowControlAutre() {
tx.Text = "";
Size = new System.Drawing.Size(700, 450);
tx.Size = this.Size;
tx.Multiline = true;
tx.ScrollBars = ScrollBars.Vertical;
tx.AcceptsReturn = true;
tx.AcceptsTab = true;
tx.WordWrap = true;
this.Controls.Add(tx);
}
public void demandeLance() {
Lance();
}
//[STAThread]
void Lance() {
threadHandle = null;
t = null;
try {
threadHandle = new MonThreadHandle(this);
t = new Thread(new ThreadStart(threadHandle.ThreadLoop));
t.Start();
}
catch {
traceFen("Thead non lance");
return;
}
}
public void FoncActiveThread(string a, string b) {
traceFen("Etape A : FoncActiveThread :: a=" + a + " b=" + b);
ClickEventThread = new ClickEventHandlerThread(ClickEventThread);
MonOpThread(a, b);
}
public void MonOpThread(string a, string b) {
try {
traceFen("Etape B : MonOpThread :: MonOpThread a=" + a + " b=" + b);
if (ClickEventThread != null) {
traceFen("Etape C : MonOpThread :: ClickEventThread diffrent null tente ClickEventThread");
ClickEventThread(a, b);
}
}
catch (TargetException te) {
traceFen("## Exception dans MonOpThread (TargetException):: Message [[" + te.Message + "]]");
}
catch (Exception e) {
traceFen("## Exception dans MonOpThread :: " + e.Message);
}
}
public void traceFen(string p) {
tx.Text += p + "\r\n";
}
}
}
Resultat obtenu :
Si depuis le navigateur, je lance un appel à la monObj.FoncActiveThread('CHAPI','CHAPO') , j'obtiens bien les traces suivantes :
Etape A : FoncActiveThread :: a =CHAPI b= CHAPO
Etape B : MonOpThread :: MonOpThread a=CHAPI b=CHAPO
Etape C : MonOpThread :: ClickEventThread diffrent null tente ClickEventThread
l'événement est bien lancé et ma page HTML le capte bien.. nickel. :yaisse2:
Mais lorsque, toujours depuis le navigateur, je fais appel à monObj.demandeLance() , le composant va bien lancer dans un processus différent l'execution de la méthode ThreadLoop() de mon objet de type MonThreadHandle.
Depuis ce processus, sera alors appelé la même méthode que précedement (FoncActiveThread()) de l'objet "parent".
Le positionnement du handler est alors réalisé, mais lorsque je fais appel au même bout de code qui me permettait de réaliser l'envoi de l'évenement, une exception de type TargetException est alors lancée, indiquant "L'objet ne correspond pas au type cible." :(
Etape A : FoncActiveThread :: a =JOJO b=JUJU
Etape B : MonOpThread :: MonOpThread a=JOJO b=JUJU
Etape C : MonOpThread :: ClickEventThread diffrent null tente ClickEventThread
## Exception dans MonOpThread (TargetException):: Message [[L'objet ne correspond pas au type cible.]]
Donc si quelqu'un aurait une petite explication sur l'erreur retournée, cela serait avec grand plaisir :) .. d'autant que là .. j'essaie différents moyens . mais cela ne passe toujours pas ..
Merci d'avance pour votre attention .. et surtout à ceux qui auront lu ce looooong post.
A voir également:
[C#][ActiveX][Thread][HTML/Javascript] Evénements OK mais pas dans tous les cas
Mediant
Messages postés2Date d'inscriptionmercredi 20 février 2008StatutMembreDernière intervention17 mars 2008 17 mars 2008 à 20:31
Bon .. je n'ai toujours pas compris ... :roll:
Mais j'ai trouvé un autre moyen de réaliser cette opération.
Pour ceux que cela pourrait intéresser, je me suis passé de la classe MonThreadHandle que j'utilisais, et ai tout repris dans MyWindowControlAutre
Voici le code :
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Threading;
using System.Reflection;
namespace ActiveXSourcingAutre {
public delegate void ClickEventHandlerThread(string a, string b);
[System.Runtime.InteropServices.GuidAttribute("9621A92C-3FBD-4be4-9153-51EEC1444507")]
[System.Runtime.InteropServices.InterfaceTypeAttribute(System.Runtime.InteropServices.ComInterfaceType.InterfaceIsIDispatch)]
public interface ControlEventsAutre
{
[System.Runtime.InteropServices.DispIdAttribute(0x60035000)]
void ClickEventThread(string a, string b);
}
[System.Runtime.InteropServices.InterfaceTypeAttribute(System.Runtime.InteropServices.ComInterfaceType.InterfaceIsIDispatch)]
public interface MonInterfaceAutre {
[System.Runtime.InteropServices.DispIdAttribute(0x60060003)]
void demandeLance();
[System.Runtime.InteropServices.DispIdAttribute(0x60060007)]
void FoncActiveThread(string a, string b);
}
[System.Runtime.InteropServices.ClassInterface(System.Runtime.InteropServices.ClassInterfaceType.None), System.Runtime.InteropServices.ComSourceInterfaces(typeof(ControlEventsAutre))]
public class MyWindowControlAutre : System.Windows.Forms.UserControl, MonInterfaceAutre //, ComInteropControlInterface
{
System.Windows.Forms.TextBox tx = new TextBox();
Thread t;
//[STAThread]
void Lance() {
t = null;
try {
t = new Thread(new ThreadStart(ThreadLoop));
t.Start();
}
catch {
traceFen("Thead non lance");
return;
}
}
public void FoncActiveThread(string a, string b) {
traceFen("Etape A : FoncActiveThread :: a=" + a + " b=" + b);
ClickEventThread = new ClickEventHandlerThread(ClickEventThread);
MonOpThread(a, b);
}
public void MonOpThread(string a, string b) {
try {
traceFen("Etape B : MonOpThread :: MonOpThread a=" + a + " b=" + b);
if (ClickEventThread != null) {
traceFen("Etape C : MonOpThread :: ClickEventThread diffrent null tente ClickEventThread");
ClickEventThread(a, b);
}
}
catch (TargetException te) {
traceFen("## Exception dans MonOpThread (TargetException):: Message [[" + te.Message + "]]");
}
catch (Exception e) {
traceFen("## Exception dans MonOpThread :: " + e.Message);
}
}
public void traceFen(string p) {
tx.Text += p + "\r\n";
}
public void AffichageInterp() {
object[] args = new object[2];
args[0] = "JOJO";
args[1] = "JUJU";
Invoke(ClickEventThread, args);
}