Je cherche à envoyer à une instance d'application en cours d'exécution
un message indiquant qu'une autre instance vient de démarrer avec un nom
de fichier passé en argument. Le but est évidemment d'éviter d'avoir
deux fois la même application à l'écran, ce qui fonctionne bien, mais
aussi de signaler à celle qui tourne déjà qu'elle doit ouvrir un fichier.
Le programme contient le code suivant au début du main() :
COPYDATASTRUCT CopyData;
CopyData.dwData=0;
CopyData.cbData=strlen(ArgFile)+1;
CopyData.lpData=&ArgFile[0];
SendMessage(hWnd,WM_COPYDATA,0,(LPARAM)&CopyData);
hWnd est le handle sur l'instance déjà en cours, trouvée avec
FindWindow() et GetClassName(). Pas de problème de ce côté, ça marche
bien puisque ça donne le focus à l'instance existante avec
SetForegroundWindow(hWnd).
Côté réception, le programme contient une surcharge de DefWindowProc()
dans laquelle je fais le test suivant :
if(Msg==WM_COPYDATA)
...
Problème : le seul message que reçoit l'instance déjà en cours, c'est le
WM_SETFOCUS généré par SetForegroundWindow(). Elle ne reçoit rien
d'autre. Je suppose donc que le message n'est pas posté. Est-ce que
c'est parce que j'ai un argument WParam nul ? Si c'est bien le cas,
qu'est-ce que je dois mettre puisque je n'ai pas de handle à passer ? Le
programme appelant n'a pas le temps de créer une instance : il quitte
juste après avoir envoyé le message à celle déjà en cours.
C'est pourtant bien ce que je fais : "Window passing the data", c'est bien celle qui envoie le message, non ? Et dans mon cas, il n'y a pas de fenêtre puisqu'on est au tout début du main(). Donc je mets 0 faute de mieux.
C'est pourtant bien ce que je fais : "Window passing the data", c'est
bien celle qui envoie le message, non ? Et dans mon cas, il n'y a pas de
fenêtre puisqu'on est au tout début du main(). Donc je mets 0 faute de
mieux.
C'est pourtant bien ce que je fais : "Window passing the data", c'est bien celle qui envoie le message, non ? Et dans mon cas, il n'y a pas de fenêtre puisqu'on est au tout début du main(). Donc je mets 0 faute de mieux.
J'ai pas le temps alors, j'ai fait rapidos : une boîte de dialogue en mémoire qui attends un WM_COPYDATA et affiche dans sa barre de titre la donnée reçue. Et voici le client, sans fenêtre, comme toi :
J'ai pas le temps alors, j'ai fait rapidos : une boîte de dialogue en
mémoire qui attends un WM_COPYDATA et affiche dans sa barre de titre la
donnée reçue.
Et voici le client, sans fenêtre, comme toi :
J'ai pas le temps alors, j'ai fait rapidos : une boîte de dialogue en mémoire qui attends un WM_COPYDATA et affiche dans sa barre de titre la donnée reçue. Et voici le client, sans fenêtre, comme toi :
Chez moi, ça marche sans problème. Si le serveur tourne, il reçoit bien la donnée. Inspire-toi de cet exemple.
-- Arnold McDonald (AMcD) - Help #38/2006
http://arnold.mcdonald.free.fr/
Caliban
Arnold McDonald (AMcD) wrote:
Bon. J'ai codé un rapide petit exemple.
Ben, ça marche pas mieux. J'avoue que j'ai pas codé ta partie serveur puisque mon appli contient déjà ce qu'il faut pour intercepter les messages, et que de toute façon c'est là-dedans que ça devra tourner. Dans WindowProc(), au lieu de DialogProc() donc, j'ai le code suivant (j'utilise l'encapsulation Borland de l'API et donc la surcharge de WindowProc, mais ça revient au même) : TResult TWin::WindowProc(UINT uMsg, WPARAM wPrm, LPARAM lPrm) { switch(uMsg) { case WM_SETFOCUS: ... // Breakpoint ici break; case WM_COPYDATA: ... // Breakpoint ici aussi break; } return TWindow::WindowProc(uMsg,wPrm,lPrm); }
Côté client, j'ai codé la même chose que toi, et même avec des valeurs identiques : COPYDATASTRUCT CopyData; int Data55; HWND hWnd=FindWindow(PrgmClassName,0); if(hWnd) { SetForegroundWindow(hWnd); CopyData.dwData0; CopyData.cbData=sizeof(int); CopyData.lpData=&Data; SendMessage(hWnd,WM_COPYDATA,(WPARAM)0,(LPARAM)(LPVOID)&CopyData); }
1er test : une instance de l'appli tourne, que je couvre avec une autre fenêtre. Je lance le programme depuis l'IDE : dès que ça passe sur SetForegroundWindow() l'appli réapparaît (même si elle perd aussitôt le focus puisque je trace dans l'IDE). Ce qui veut dire que hWnd est ok. Ca passe sur SendMessage() puis le programme s'arrête.
2ème test : je lance une instance de l'appli depuis l'IDE, et une fois qu'elle est à l'écran, peinte et tout le tintouin, je pose deux breakpoints dans WindowProc(), l'un après case WM_SETFOCUS et l'autre après case WM_COPYDATA. Ensuite je lance une 2ème instance. Le breakpoint après case WM_SETFOCUS réagit immédiatement. Je relance : le second breakpoint après case WM_COPYDATA ne réagit pas.
3ème test : je mets mon code côté serveur dans DefWindowProc() au lieu de WindowProc() parce que je suis pas sûr d'avoir pas compris la différence profonde entre les deux, et je mets un breakpoint tout en haut de la fonction une fois que l'appli est lancée. Quand je lance la 2ème instance, le breakpoint réagit sur un message WM_SETFOCUS, puis sur un WM_KILLFOCUS (puisque l'IDE a repris le focus entretemps à cause du 1er break). Il n'y a AUCUN autre message qui arrive dans DefWindowProc() après ces deux-là.
Je conclus sans en être tout à fait sûr que c'est côté client que ça coince et que SendMessage() n'a pas fonctionné. Pourtant, hWnd n'a pas changé entre le moment où j'appelle SetForegroundWindow() et SendMessage(), j'ai vérifié. D'ailleurs, si j'appelle SetForegroundWindow() APRES SendMessage(), le focus est toujours bien donné à la 1ère instance. Donc hWnd est ok.
Déroutant, non ?
Arnold McDonald (AMcD) wrote:
Bon. J'ai codé un rapide petit exemple.
Ben, ça marche pas mieux. J'avoue que j'ai pas codé ta partie serveur
puisque mon appli contient déjà ce qu'il faut pour intercepter les
messages, et que de toute façon c'est là-dedans que ça devra tourner.
Dans WindowProc(), au lieu de DialogProc() donc, j'ai le code suivant
(j'utilise l'encapsulation Borland de l'API et donc la surcharge de
WindowProc, mais ça revient au même) :
TResult TWin::WindowProc(UINT uMsg, WPARAM wPrm, LPARAM lPrm)
{
switch(uMsg) {
case WM_SETFOCUS:
... // Breakpoint ici
break;
case WM_COPYDATA:
... // Breakpoint ici aussi
break;
}
return TWindow::WindowProc(uMsg,wPrm,lPrm);
}
Côté client, j'ai codé la même chose que toi, et même avec des valeurs
identiques :
COPYDATASTRUCT CopyData;
int Data55;
HWND hWnd=FindWindow(PrgmClassName,0);
if(hWnd)
{
SetForegroundWindow(hWnd);
CopyData.dwData0;
CopyData.cbData=sizeof(int);
CopyData.lpData=&Data;
SendMessage(hWnd,WM_COPYDATA,(WPARAM)0,(LPARAM)(LPVOID)&CopyData);
}
1er test : une instance de l'appli tourne, que je couvre avec une autre
fenêtre. Je lance le programme depuis l'IDE : dès que ça passe sur
SetForegroundWindow() l'appli réapparaît (même si elle perd aussitôt le
focus puisque je trace dans l'IDE). Ce qui veut dire que hWnd est ok. Ca
passe sur SendMessage() puis le programme s'arrête.
2ème test : je lance une instance de l'appli depuis l'IDE, et une fois
qu'elle est à l'écran, peinte et tout le tintouin, je pose deux
breakpoints dans WindowProc(), l'un après case WM_SETFOCUS et l'autre
après case WM_COPYDATA. Ensuite je lance une 2ème instance. Le
breakpoint après case WM_SETFOCUS réagit immédiatement. Je relance : le
second breakpoint après case WM_COPYDATA ne réagit pas.
3ème test : je mets mon code côté serveur dans DefWindowProc() au lieu
de WindowProc() parce que je suis pas sûr d'avoir pas compris la
différence profonde entre les deux, et je mets un breakpoint tout en
haut de la fonction une fois que l'appli est lancée. Quand je lance la
2ème instance, le breakpoint réagit sur un message WM_SETFOCUS, puis sur
un WM_KILLFOCUS (puisque l'IDE a repris le focus entretemps à cause du
1er break). Il n'y a AUCUN autre message qui arrive dans DefWindowProc()
après ces deux-là.
Je conclus sans en être tout à fait sûr que c'est côté client que ça
coince et que SendMessage() n'a pas fonctionné. Pourtant, hWnd n'a pas
changé entre le moment où j'appelle SetForegroundWindow() et
SendMessage(), j'ai vérifié. D'ailleurs, si j'appelle
SetForegroundWindow() APRES SendMessage(), le focus est toujours bien
donné à la 1ère instance. Donc hWnd est ok.
Ben, ça marche pas mieux. J'avoue que j'ai pas codé ta partie serveur puisque mon appli contient déjà ce qu'il faut pour intercepter les messages, et que de toute façon c'est là-dedans que ça devra tourner. Dans WindowProc(), au lieu de DialogProc() donc, j'ai le code suivant (j'utilise l'encapsulation Borland de l'API et donc la surcharge de WindowProc, mais ça revient au même) : TResult TWin::WindowProc(UINT uMsg, WPARAM wPrm, LPARAM lPrm) { switch(uMsg) { case WM_SETFOCUS: ... // Breakpoint ici break; case WM_COPYDATA: ... // Breakpoint ici aussi break; } return TWindow::WindowProc(uMsg,wPrm,lPrm); }
Côté client, j'ai codé la même chose que toi, et même avec des valeurs identiques : COPYDATASTRUCT CopyData; int Data55; HWND hWnd=FindWindow(PrgmClassName,0); if(hWnd) { SetForegroundWindow(hWnd); CopyData.dwData0; CopyData.cbData=sizeof(int); CopyData.lpData=&Data; SendMessage(hWnd,WM_COPYDATA,(WPARAM)0,(LPARAM)(LPVOID)&CopyData); }
1er test : une instance de l'appli tourne, que je couvre avec une autre fenêtre. Je lance le programme depuis l'IDE : dès que ça passe sur SetForegroundWindow() l'appli réapparaît (même si elle perd aussitôt le focus puisque je trace dans l'IDE). Ce qui veut dire que hWnd est ok. Ca passe sur SendMessage() puis le programme s'arrête.
2ème test : je lance une instance de l'appli depuis l'IDE, et une fois qu'elle est à l'écran, peinte et tout le tintouin, je pose deux breakpoints dans WindowProc(), l'un après case WM_SETFOCUS et l'autre après case WM_COPYDATA. Ensuite je lance une 2ème instance. Le breakpoint après case WM_SETFOCUS réagit immédiatement. Je relance : le second breakpoint après case WM_COPYDATA ne réagit pas.
3ème test : je mets mon code côté serveur dans DefWindowProc() au lieu de WindowProc() parce que je suis pas sûr d'avoir pas compris la différence profonde entre les deux, et je mets un breakpoint tout en haut de la fonction une fois que l'appli est lancée. Quand je lance la 2ème instance, le breakpoint réagit sur un message WM_SETFOCUS, puis sur un WM_KILLFOCUS (puisque l'IDE a repris le focus entretemps à cause du 1er break). Il n'y a AUCUN autre message qui arrive dans DefWindowProc() après ces deux-là.
Je conclus sans en être tout à fait sûr que c'est côté client que ça coince et que SendMessage() n'a pas fonctionné. Pourtant, hWnd n'a pas changé entre le moment où j'appelle SetForegroundWindow() et SendMessage(), j'ai vérifié. D'ailleurs, si j'appelle SetForegroundWindow() APRES SendMessage(), le focus est toujours bien donné à la 1ère instance. Donc hWnd est ok.
Déroutant, non ?
Caliban
J'ajoute si ça peut aider que SendMessage() retourne 0.
J'ajoute si ça peut aider que SendMessage() retourne 0.
J'ajoute si ça peut aider que SendMessage() retourne 0.
Arnold McDonald \(AMcD\)
Caliban wrote:
Arnold McDonald (AMcD) wrote:
Bon. J'ai codé un rapide petit exemple.
Ben, ça marche pas mieux.
Ha si, désolé, ça marche très bien chez moi.
J'avoue que j'ai pas codé ta partie serveur puisque mon appli contient déjà ce qu'il faut pour intercepter les messages, et que de toute façon c'est là-dedans que ça devra tourner.
En informatique, il n'y a pas de "toute façon" ; si un problème existe, il faut le corriger non ? Si c'est le serveur qui foire, faudra bien le recoder !
Dans WindowProc(), au lieu de DialogProc() donc, j'ai le code suivant (j'utilise l'encapsulation Borland de l'API et donc la surcharge de WindowProc, mais ça revient au même) :
Oui, Dialogproc() appelle un WindowProc() en interne, c'est strictement la même chose.
Côté client, j'ai codé la même chose que toi, et même avec des valeurs identiques : COPYDATASTRUCT CopyData; int Data55; HWND hWnd=FindWindow(PrgmClassName,0); if(hWnd) { SetForegroundWindow(hWnd); CopyData.dwData0; CopyData.cbData=sizeof(int); CopyData.lpData=&Data; SendMessage(hWnd,WM_COPYDATA,(WPARAM)0,(LPARAM)(LPVOID)&CopyData); }
Non, ce n'est pas du tout pareil que moi. D'abord, je n'utilise pas de SetForeground(). Ensuite, moi, je cherche avec le titre de la fenêtre, pas avec le nom de la classe de fenêtre. Si tu cherches qu'avec la classe de fenêtre, il est très possible, surtout avec des produits daubesques comme Delphi et autres, que plusieurs applications aient cette classe de fenêtre, donc, difficile d'être sûr que ce soit la bonne qui recevra ton WM_COPYDATA...
Le mieux, pour gérer l'unicité des instances, c'est d'utiliser des mutex.
Je conclus sans en être tout à fait sûr que c'est côté client que ça coince et que SendMessage() n'a pas fonctionné.
Ce qui serait une première depuis que Windows existe :-).
Déroutant, non ?
Je pense que tu cherches "mal" ton serveur et que le message n'est pas envoyé à qui de droit. Enfin, il faudrait un code plus détaillé, parce qu'avec ce que tu donnes, difficile de faire de la précision.
-- Arnold McDonald (AMcD)
http://arnold.mcdonald.free.fr/
Caliban wrote:
Arnold McDonald (AMcD) wrote:
Bon. J'ai codé un rapide petit exemple.
Ben, ça marche pas mieux.
Ha si, désolé, ça marche très bien chez moi.
J'avoue que j'ai pas codé ta partie serveur
puisque mon appli contient déjà ce qu'il faut pour intercepter les
messages, et que de toute façon c'est là-dedans que ça devra tourner.
En informatique, il n'y a pas de "toute façon" ; si un problème existe, il
faut le corriger non ? Si c'est le serveur qui foire, faudra bien le recoder
!
Dans WindowProc(), au lieu de DialogProc() donc, j'ai le code suivant
(j'utilise l'encapsulation Borland de l'API et donc la surcharge de
WindowProc, mais ça revient au même) :
Oui, Dialogproc() appelle un WindowProc() en interne, c'est strictement la
même chose.
Côté client, j'ai codé la même chose que toi, et même avec des valeurs
identiques :
COPYDATASTRUCT CopyData;
int Data55;
HWND hWnd=FindWindow(PrgmClassName,0);
if(hWnd)
{
SetForegroundWindow(hWnd);
CopyData.dwData0;
CopyData.cbData=sizeof(int);
CopyData.lpData=&Data;
SendMessage(hWnd,WM_COPYDATA,(WPARAM)0,(LPARAM)(LPVOID)&CopyData);
}
Non, ce n'est pas du tout pareil que moi. D'abord, je n'utilise pas de
SetForeground(). Ensuite, moi, je cherche avec le titre de la fenêtre, pas
avec le nom de la classe de fenêtre. Si tu cherches qu'avec la classe de
fenêtre, il est très possible, surtout avec des produits daubesques comme
Delphi et autres, que plusieurs applications aient cette classe de fenêtre,
donc, difficile d'être sûr que ce soit la bonne qui recevra ton
WM_COPYDATA...
Le mieux, pour gérer l'unicité des instances, c'est d'utiliser des mutex.
Je conclus sans en être tout à fait sûr que c'est côté client que ça
coince et que SendMessage() n'a pas fonctionné.
Ce qui serait une première depuis que Windows existe :-).
Déroutant, non ?
Je pense que tu cherches "mal" ton serveur et que le message n'est pas
envoyé à qui de droit. Enfin, il faudrait un code plus détaillé, parce
qu'avec ce que tu donnes, difficile de faire de la précision.
J'avoue que j'ai pas codé ta partie serveur puisque mon appli contient déjà ce qu'il faut pour intercepter les messages, et que de toute façon c'est là-dedans que ça devra tourner.
En informatique, il n'y a pas de "toute façon" ; si un problème existe, il faut le corriger non ? Si c'est le serveur qui foire, faudra bien le recoder !
Dans WindowProc(), au lieu de DialogProc() donc, j'ai le code suivant (j'utilise l'encapsulation Borland de l'API et donc la surcharge de WindowProc, mais ça revient au même) :
Oui, Dialogproc() appelle un WindowProc() en interne, c'est strictement la même chose.
Côté client, j'ai codé la même chose que toi, et même avec des valeurs identiques : COPYDATASTRUCT CopyData; int Data55; HWND hWnd=FindWindow(PrgmClassName,0); if(hWnd) { SetForegroundWindow(hWnd); CopyData.dwData0; CopyData.cbData=sizeof(int); CopyData.lpData=&Data; SendMessage(hWnd,WM_COPYDATA,(WPARAM)0,(LPARAM)(LPVOID)&CopyData); }
Non, ce n'est pas du tout pareil que moi. D'abord, je n'utilise pas de SetForeground(). Ensuite, moi, je cherche avec le titre de la fenêtre, pas avec le nom de la classe de fenêtre. Si tu cherches qu'avec la classe de fenêtre, il est très possible, surtout avec des produits daubesques comme Delphi et autres, que plusieurs applications aient cette classe de fenêtre, donc, difficile d'être sûr que ce soit la bonne qui recevra ton WM_COPYDATA...
Le mieux, pour gérer l'unicité des instances, c'est d'utiliser des mutex.
Je conclus sans en être tout à fait sûr que c'est côté client que ça coince et que SendMessage() n'a pas fonctionné.
Ce qui serait une première depuis que Windows existe :-).
Déroutant, non ?
Je pense que tu cherches "mal" ton serveur et que le message n'est pas envoyé à qui de droit. Enfin, il faudrait un code plus détaillé, parce qu'avec ce que tu donnes, difficile de faire de la précision.
-- Arnold McDonald (AMcD)
http://arnold.mcdonald.free.fr/
Caliban
Arnold McDonald (AMcD) wrote:
Ha si, désolé, ça marche très bien chez moi.
Je n'en doute pas, mais malheureusement c'est chez moi que ça coince. J'aurais préféré l'inverse ;-)
Non, ce n'est pas du tout pareil que moi. D'abord, je n'utilise pas de SetForeground().
Cet appel à SetForegroundWindow() me sert entre autres à vérifier que j'ai bien chopé la bonne fenêtre. Comme elle réapparaît, je me sens à peu près en position d'affirmer que c'est bien elle. De toute façon, cette fonction n'altère pas hWnd et si je l'enlève, ça va pas mieux.
Ensuite, moi, je cherche avec le titre de la fenêtre, pas avec le nom de la classe de fenêtre.
Je l'ai fait aussi, bien que si je vérifie quelle fenêtre je tiens dans mon hWnd, je sais que c'est la bonne (je peux lire son titre). De toute façon, c'est pas mieux avec FindWindow(0,"Machin").
Si tu cherches qu'avec la classe de fenêtre, il est très possible, surtout avec des produits daubesques comme Delphi et autres, que plusieurs applications aient cette classe de fenêtre,
Bon, j'utilise pas Delphi mais Borland C++. Ensuite, je n'ai que 2 applications avec fenêtre : mon IDE et l'appli qui tourne. Enfin, dans la GetClassName(), je retourne le nom du programme avec son chemin d'accès, c'est à dire l'Arg[0] du main(). La possibilité de confusion me paraît limitée de ce côté.
Le mieux, pour gérer l'unicité des instances, c'est d'utiliser des mutex.
Ok, mais ça marche bien comme ça pour empêcher de lancer 2 instances de la même appli correspondant au même programme. Si les 2 sont dans les répertoires différents, alors elles ont le droit de cohabiter. Je vais pas recoder un truc qui marche bien et de toute façon c'est pas le problème.
Je pense que tu cherches "mal" ton serveur et que le message n'est pas envoyé à qui de droit. Enfin, il faudrait un code plus détaillé, parce qu'avec ce que tu donnes, difficile de faire de la précision.
J'ai essayé d'utiliser WM_COPYDATA cette fois entre deux applis différentes : marche pas mieux, mais il semble y avoir un temps de traitement de SendMessage() - qui retourne 0 après 1 seconde. A mon avis, le hWnd et le SendMessage() sont bons, mais c'est côté réception que ça déraille. J'en conclus donc maintenant que quelque chose hooke le message avant que je le chope dans WindowProc(). C'est curieux, parce que, encore une fois, je reçois bien le WM_SETFOCUS correspondant à l'appel de SetForegroundWindow(hWnd) et le WM_KILLFOCUS correspondant au retour dans mon IDE à cause du breakpoint.
Bon, ne nous énervons pas, hein. J'ai sûrement une connerie quelque part, ok. Mais franchement, je vois pas où.
Arnold McDonald (AMcD) wrote:
Ha si, désolé, ça marche très bien chez moi.
Je n'en doute pas, mais malheureusement c'est chez moi que ça coince.
J'aurais préféré l'inverse ;-)
Non, ce n'est pas du tout pareil que moi. D'abord, je n'utilise pas de
SetForeground().
Cet appel à SetForegroundWindow() me sert entre autres à vérifier que
j'ai bien chopé la bonne fenêtre. Comme elle réapparaît, je me sens à
peu près en position d'affirmer que c'est bien elle. De toute façon,
cette fonction n'altère pas hWnd et si je l'enlève, ça va pas mieux.
Ensuite, moi, je cherche avec le titre de la fenêtre, pas
avec le nom de la classe de fenêtre.
Je l'ai fait aussi, bien que si je vérifie quelle fenêtre je tiens dans
mon hWnd, je sais que c'est la bonne (je peux lire son titre). De toute
façon, c'est pas mieux avec FindWindow(0,"Machin").
Si tu cherches qu'avec la classe de fenêtre, il est très possible, surtout
avec des produits daubesques comme Delphi et autres, que plusieurs
applications aient cette classe de fenêtre,
Bon, j'utilise pas Delphi mais Borland C++. Ensuite, je n'ai que 2
applications avec fenêtre : mon IDE et l'appli qui tourne. Enfin, dans
la GetClassName(), je retourne le nom du programme avec son chemin
d'accès, c'est à dire l'Arg[0] du main(). La possibilité de confusion me
paraît limitée de ce côté.
Le mieux, pour gérer l'unicité des instances, c'est d'utiliser des mutex.
Ok, mais ça marche bien comme ça pour empêcher de lancer 2 instances de
la même appli correspondant au même programme. Si les 2 sont dans les
répertoires différents, alors elles ont le droit de cohabiter. Je vais
pas recoder un truc qui marche bien et de toute façon c'est pas le problème.
Je pense que tu cherches "mal" ton serveur et que le message n'est pas
envoyé à qui de droit. Enfin, il faudrait un code plus détaillé, parce
qu'avec ce que tu donnes, difficile de faire de la précision.
J'ai essayé d'utiliser WM_COPYDATA cette fois entre deux applis
différentes : marche pas mieux, mais il semble y avoir un temps de
traitement de SendMessage() - qui retourne 0 après 1 seconde. A mon
avis, le hWnd et le SendMessage() sont bons, mais c'est côté réception
que ça déraille. J'en conclus donc maintenant que quelque chose hooke le
message avant que je le chope dans WindowProc(). C'est curieux, parce
que, encore une fois, je reçois bien le WM_SETFOCUS correspondant à
l'appel de SetForegroundWindow(hWnd) et le WM_KILLFOCUS correspondant au
retour dans mon IDE à cause du breakpoint.
Bon, ne nous énervons pas, hein. J'ai sûrement une connerie quelque
part, ok. Mais franchement, je vois pas où.
Je n'en doute pas, mais malheureusement c'est chez moi que ça coince. J'aurais préféré l'inverse ;-)
Non, ce n'est pas du tout pareil que moi. D'abord, je n'utilise pas de SetForeground().
Cet appel à SetForegroundWindow() me sert entre autres à vérifier que j'ai bien chopé la bonne fenêtre. Comme elle réapparaît, je me sens à peu près en position d'affirmer que c'est bien elle. De toute façon, cette fonction n'altère pas hWnd et si je l'enlève, ça va pas mieux.
Ensuite, moi, je cherche avec le titre de la fenêtre, pas avec le nom de la classe de fenêtre.
Je l'ai fait aussi, bien que si je vérifie quelle fenêtre je tiens dans mon hWnd, je sais que c'est la bonne (je peux lire son titre). De toute façon, c'est pas mieux avec FindWindow(0,"Machin").
Si tu cherches qu'avec la classe de fenêtre, il est très possible, surtout avec des produits daubesques comme Delphi et autres, que plusieurs applications aient cette classe de fenêtre,
Bon, j'utilise pas Delphi mais Borland C++. Ensuite, je n'ai que 2 applications avec fenêtre : mon IDE et l'appli qui tourne. Enfin, dans la GetClassName(), je retourne le nom du programme avec son chemin d'accès, c'est à dire l'Arg[0] du main(). La possibilité de confusion me paraît limitée de ce côté.
Le mieux, pour gérer l'unicité des instances, c'est d'utiliser des mutex.
Ok, mais ça marche bien comme ça pour empêcher de lancer 2 instances de la même appli correspondant au même programme. Si les 2 sont dans les répertoires différents, alors elles ont le droit de cohabiter. Je vais pas recoder un truc qui marche bien et de toute façon c'est pas le problème.
Je pense que tu cherches "mal" ton serveur et que le message n'est pas envoyé à qui de droit. Enfin, il faudrait un code plus détaillé, parce qu'avec ce que tu donnes, difficile de faire de la précision.
J'ai essayé d'utiliser WM_COPYDATA cette fois entre deux applis différentes : marche pas mieux, mais il semble y avoir un temps de traitement de SendMessage() - qui retourne 0 après 1 seconde. A mon avis, le hWnd et le SendMessage() sont bons, mais c'est côté réception que ça déraille. J'en conclus donc maintenant que quelque chose hooke le message avant que je le chope dans WindowProc(). C'est curieux, parce que, encore une fois, je reçois bien le WM_SETFOCUS correspondant à l'appel de SetForegroundWindow(hWnd) et le WM_KILLFOCUS correspondant au retour dans mon IDE à cause du breakpoint.
Bon, ne nous énervons pas, hein. J'ai sûrement une connerie quelque part, ok. Mais franchement, je vois pas où.
Arnold McDonald \(AMcD\)
Caliban wrote:
Bon, ne nous énervons pas, hein. J'ai sûrement une connerie quelque part, ok. Mais franchement, je vois pas où.
J'ai testé différentes versions, même une où le programme se ferme directement après avoir envoyé le WM_COPYDATA au serveur. Pas de problème, le serveur le reçoit quand même ! Quel que soit le truc testé, ça marche toujours.
Alors, désolé, mais je peux plus rien pour toi :-).
-- Arnold McDonald (AMcD)
http://arnold.mcdonald.free.fr/
Caliban wrote:
Bon, ne nous énervons pas, hein. J'ai sûrement une connerie quelque
part, ok. Mais franchement, je vois pas où.
J'ai testé différentes versions, même une où le programme se ferme
directement après avoir envoyé le WM_COPYDATA au serveur. Pas de problème,
le serveur le reçoit quand même ! Quel que soit le truc testé, ça marche
toujours.
Alors, désolé, mais je peux plus rien pour toi :-).
Bon, ne nous énervons pas, hein. J'ai sûrement une connerie quelque part, ok. Mais franchement, je vois pas où.
J'ai testé différentes versions, même une où le programme se ferme directement après avoir envoyé le WM_COPYDATA au serveur. Pas de problème, le serveur le reçoit quand même ! Quel que soit le truc testé, ça marche toujours.
Alors, désolé, mais je peux plus rien pour toi :-).