Probleme de Handles

Mxbug Messages postés 47 Date d'inscription mercredi 27 avril 2005 Statut Membre Dernière intervention 9 janvier 2006 - 27 nov. 2005 à 01:06
Mxbug Messages postés 47 Date d'inscription mercredi 27 avril 2005 Statut Membre Dernière intervention 9 janvier 2006 - 2 déc. 2005 à 22:22
Yop
voila j'essaye de faire une ptite application d'auto message sur msn ( msn plus avec tout ses sons fait *** ) .
le code est le suivant avec quelques commentaires vite fait :
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, MessengerAPIEvents, StdCtrls, WinSkinData;

type
TForm1 = class(TForm)
MessengerAPIDMessengerEvents1: TMessengerAPIDMessengerEvents;
Button1: TButton;
Edit1: TEdit;
Memo1: TMemo;
SkinData1: TSkinData;
procedure Button1Click(Sender: TObject);
procedure MessengerAPIDMessengerEvents1IMWindowCreated(Sender: TObject;
const pIMWindow: IDispatch);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1; // la form
Window: String; //
Handle: THandle; // le handle
Msg: Tmsg;
IMessage: String = ('je teste fais pas attention , merci ');
hwin:Hwnd ;
Wnd:Hwnd; //le handle de la fenetre msn
Tableau: array of Integer;
i : integer ;
implementation

{$R *.dfm}

Function TrimRight(Const S: String): String; // fonction pour avoir le titre
Var
I: Integer;
Begin
I := Length(S);
While (I > 0) And (S[I] <= ' ') Do Dec(I);
Result := Copy(S, 1, I);
end;

Function ActiveHandle: THandle; // fonction pour avoir le handle active
Begin
Result := GetForeGroundWindow;
End;

Function ActiveCaption: String; // fonction pour avoir le titre active
Var
Handle: THandle; // handle qu'on donnera a la conversation ouverte
Len: LongInt;
Title: String; // titre
Begin
hWin := FindWindowA(PChar('IMWindowClass'), Nil); // on trouve la conversation
Handle := hwin; // c ici qu'on donne le handle a la conversation
Len := GetWindowTextLength(Handle) + 1;
SetLength(Title, Len);
GetWindowText(Handle, pChar(Title), Len);
ActiveCaption := TrimRight(Title);
End;

Procedure SendKeys(Const text: String); // pour envoyer le message
Var
i: Integer;
shift: Boolean;
vk, scancode: Word;
ch: Char;
c, s: Byte;
Const
vk_keys: Array[0..9] Of Byte =
(VK_HOME, VK_END, VK_UP, VK_DOWN, VK_LEFT,
VK_RIGHT, VK_PRIOR, VK_NEXT, VK_INSERT,
VK_DELETE);
vk_shft: Array[0..2] Of Byte =
(VK_SHIFT, VK_CONTROL, VK_MENU);
flags: Array[false..true] Of Integer =
(KEYEVENTF_KEYUP, 0);
Begin
shift := false;
For i := 1 To Length(text) Do
Begin
ch := text[i];
If ch >= #250 Then
Begin
s := Ord(ch) - 250;
shift := Not Odd(s);
c := vk_shft[s Shr 1];
scancode := MapVirtualKey(c, 0);
Keybd_Event(c, scancode, flags[shift], 0);
End
Else
Begin
vk := 0;
If ch >= #240 Then
c := vk_keys[Ord(ch) - 240]
Else If ch >= #228 Then
c := Ord(ch) - 116
Else If ch < #32 Then
c := Ord(ch)
Else
Begin
vk := VkKeyScan(ch);
c := LoByte(vk);
End;
scancode := MapVirtualKey(c, 0);
If Not shift And (Hi(vk) > 0) Then
Keybd_Event(VK_SHIFT, $2A, 0, 0);
Keybd_Event(c, scancode, 0, 0);
Keybd_Event(c, scancode,
KEYEVENTF_KEYUP, 0);
If Not shift And (Hi(vk) > 0) Then
Keybd_Event(VK_SHIFT,
$2A, KEYEVENTF_KEYUP, 0);
End;
End;
End;

function TimerFunc (H: hwnd;uMsg : UINT;idEvent : UINT;dwTime : DWORD ): BOOL; stdcall; // pouyr finir l'envoi de message
begin
If (Handle <> ActiveHandle) Then
If (Window <> ActiveCaption) Then
Begin
Window := ActiveCaption;
If Window = ActiveCaption then
Begin
SendKeys(Pchar('Automessage : ' + IMessage + #13));

End;
End;
end;

procedure SwitchToThisWindow(h1: hWnd; x: bool); stdcall; // fonction pour mettre la fenetre en premier plan
external user32 Name 'SwitchToThisWindow';




procedure TForm1.FormCreate(Sender: TObject);
begin
setlength(tableau,10000000);
SetTimer(wnd,0,1000,@TimerFunc); // chaque 1 seconde on revient a la fonction qui envoi le message c a dire timerfunc
SetTimer(form1.handle,0,1000,@TForm1.MessengerAPIDMessengerEvents1IMWindowCreated); // chaque 1 seconde on revient a la fonction qui regarde si quelqun nous a parlé
end;


procedure TForm1.MessengerAPIDMessengerEvents1IMWindowCreated(Sender: TObject;
const pIMWindow: IDispatch); //la fonction qui regarde si quelqun nous a parlé
begin
wnd:=FindWindowA(PChar('IMWindowClass'), Nil); // on recherche encore la fenetre et on la donne a wnd
for i:=0 to tableau[10000000] do //on parcour le tableau
if i=integer(wnd) then
break // on arrette la boucle
else //sinon
SwitchToThisWindow(wnd, True); // on met la fenetre au premier plan ( a ce moment timerfunc va envoyer le message )
tableau[i+1]:=integer(wnd) // on stocke dans une cellule du tableau le handle
end;




procedure TForm1.Button1Click(Sender: TObject);
begin
imessage:=edit1.text;
end;

end.


le probleme vient du code en rouge , avec mon code le programme est supposé a chaque ouverture de fenetre voir si c une fenetre msn , puis envoyer le message si s'en est une , puis stocker la valeur de son handle dans un tableau et puis reparcourir el tableau si il trouve le handle de la fenetre il la laisse tranquille et ne la met pas au premier plan , sinon il la met au premier plan et envoi le message et puis stock encore son handle dans le tableau .
le probleme ici c'est qu'elle devient toujours au premier plan meme si le handle a été inscrit sur le tableau :?.
voila merci esperant avoir été clair .

22 réponses

Mxbug Messages postés 47 Date d'inscription mercredi 27 avril 2005 Statut Membre Dernière intervention 9 janvier 2006
27 nov. 2005 à 01:11
desolé , je reecris le code ici :

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, MessengerAPIEvents, StdCtrls, WinSkinData;

type
TForm1 = class(TForm)
MessengerAPIDMessengerEvents1: TMessengerAPIDMessengerEvents;
Button1: TButton;
Edit1: TEdit;
Memo1: TMemo;
SkinData1: TSkinData;
procedure Button1Click(Sender: TObject);
procedure MessengerAPIDMessengerEvents1IMWindowCreated(Sender: TObject;
const pIMWindow: IDispatch);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1; // la form
Window: String; //
Handle: THandle; // le handle
Msg: Tmsg;
IMessage: String = ('je teste fais pas attention , merci ');
hwin:Hwnd ;
Wnd:Hwnd; //le handle de la fenetre msn
Tableau: array of Integer;
i : integer ;
implementation

{$R *.dfm}

Function TrimRight(Const S: String): String; // fonction pour avoir le titre
Var
I: Integer;
Begin
I := Length(S);
While (I > 0) And (S[I] <= ' ') Do Dec(I);
Result := Copy(S, 1, I);
end;

Function ActiveHandle: THandle; // fonction pour avoir le handle active
Begin
Result := GetForeGroundWindow;
End;

Function ActiveCaption: String; // fonction pour avoir le titre active
Var
Handle: THandle; // handle qu'on donnera a la conversation ouverte
Len: LongInt;
Title: String; // titre
Begin
hWin := FindWindowA(PChar('IMWindowClass'), Nil); // on trouve la conversation
Handle := hwin; // c ici qu'on donne le handle a la conversation
Len := GetWindowTextLength(Handle) + 1;
SetLength(Title, Len);
GetWindowText(Handle, pChar(Title), Len);
ActiveCaption := TrimRight(Title);
End;

Procedure SendKeys(Const text: String); // pour envoyer le message
Var
i: Integer;
shift: Boolean;
vk, scancode: Word;
ch: Char;
c, s: Byte;
Const
vk_keys: Array[0..9] Of Byte =
(VK_HOME, VK_END, VK_UP, VK_DOWN, VK_LEFT,
VK_RIGHT, VK_PRIOR, VK_NEXT, VK_INSERT,
VK_DELETE);
vk_shft: Array[0..2] Of Byte =
(VK_SHIFT, VK_CONTROL, VK_MENU);
flags: Array[false..true] Of Integer =
(KEYEVENTF_KEYUP, 0);
Begin
shift := false;
For i := 1 To Length(text) Do
Begin
ch := text[i];
If ch >= #250 Then
Begin
s := Ord(ch) - 250;
shift := Not Odd(s);
c := vk_shft[s Shr 1];
scancode := MapVirtualKey(c, 0);
Keybd_Event(c, scancode, flags[shift], 0);
End
Else
Begin
vk := 0;
If ch >= #240 Then
c := vk_keys[Ord(ch) - 240]
Else If ch >= #228 Then
c := Ord(ch) - 116
Else If ch < #32 Then
c := Ord(ch)
Else
Begin
vk := VkKeyScan(ch);
c := LoByte(vk);
End;
scancode := MapVirtualKey(c, 0);
If Not shift And (Hi(vk) > 0) Then
Keybd_Event(VK_SHIFT, $2A, 0, 0);
Keybd_Event(c, scancode, 0, 0);
Keybd_Event(c, scancode,
KEYEVENTF_KEYUP, 0);
If Not shift And (Hi(vk) > 0) Then
Keybd_Event(VK_SHIFT,
$2A, KEYEVENTF_KEYUP, 0);
End;
End;
End;

function TimerFunc (H: hwnd;uMsg : UINT;idEvent : UINT;dwTime : DWORD ): BOOL; stdcall; // pouyr finir l'envoi de message
begin
If (Handle <> ActiveHandle) Then
If (Window <> ActiveCaption) Then
Begin
Window := ActiveCaption;
If Window = ActiveCaption then
Begin
SendKeys(Pchar('Automessage : ' + IMessage + #13));

End;
End;
end;

procedure SwitchToThisWindow(h1: hWnd; x: bool); stdcall; // fonction pour mettre la fenetre en premier plan
external user32 Name 'SwitchToThisWindow';




procedure TForm1.FormCreate(Sender: TObject);
begin
setlength(tableau,10000000);
SetTimer(wnd,0,1000,@TimerFunc); // chaque 1 seconde on revient a la fonction qui envoi le message c a dire timerfunc
SetTimer(form1.handle,0,1000,@TForm1.MessengerAPIDMessengerEvents1IMWindowCreated); // chaque 1 seconde on revient a la fonction qui regarde si quelqun nous a parlé
end;


procedure TForm1.MessengerAPIDMessengerEvents1IMWindowCreated(Sender: TObject;
const pIMWindow: IDispatch); //la fonction qui regarde si quelqun nous a parlé
begin
wnd:=FindWindowA(PChar('IMWindowClass'), Nil); // on recherche encore la fenetre et on la donne a wnd
for i:=0 to tableau[10000000] do //on parcour le tableau
if i=integer(wnd) then
break // on arrette la boucle
else //sinon
SwitchToThisWindow(wnd, True); // on met la fenetre au premier plan ( a ce moment timerfunc va envoyer le message )
tableau[i+1]:=integer(wnd) // on stocke dans une cellule du tableau le handle
end;




procedure TForm1.Button1Click(Sender: TObject);
begin
imessage:=edit1.text;
end;

end.
0
cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
27 nov. 2005 à 07:48
Tu as écrit : "le probleme vient du code en rouge".

Serions-nous tous subitement devenus daltoniens ?

<hr color="#008000">Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
0
Mxbug Messages postés 47 Date d'inscription mercredi 27 avril 2005 Statut Membre Dernière intervention 9 janvier 2006
27 nov. 2005 à 11:15
yop
desolé c'est un copier coller d'un autre forum oui je n'ai pas eu de reponse voila le code en rouge :
procedure TForm1.MessengerAPIDMessengerEvents1IMWindowCreated(Sender: TObject;
const pIMWindow: IDispatch); //la fonction qui regarde si quelqun nous a parlé
begin
wnd:=FindWindowA(PChar('IMWindowClass'), Nil); // on recherche encore la fenetre et on la donne a wnd
for i:=0 to tableau[10000000] do //on parcour le tableau
if i=integer(wnd) then
break // on arrette la boucle
else //sinon
SwitchToThisWindow(wnd, True); // on met la fenetre au premier plan ( a ce moment timerfunc va envoyer le message )
tableau[i+1]:=integer(wnd) // on stocke dans une cellule du tableau le handle
end;
0
Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 50
27 nov. 2005 à 11:36
Bonjour MxBug,
je suppose que c'est "MessengerAPIDMessengerEvents1IMWindowCreated" qui pose problème, donc ce qui est en Rouge à été modifier ou ajouté

Au passage tu déclares un tableau dinamique et tu lui fixes sa longueur à "10000000"
l'intérêt du tableau dinamique c'est justement de pouvoir adapter sa taille au besoin.
et " hwnd et THandle " sont de type Integer donc pas besoin de transtyper.


Et pour finir évite de déclarer une variable nomé handle qui pourrait être confondue par le compilateur avec le handle de la form où d'un composent renome le en aHandle par Ex.
procedure TForm1.FormCreate(Sender: TObject);
begin
setlength(tableau,0);
SetTimer(wnd,0,1000,@TimerFunc); // chaque 1 seconde on revient a la fonction qui envoi le message c a dire timerfunc
SetTimer(form1.handle,0,1000,@TForm1.MessengerAPIDMessengerEvents1IMWindowCreated); // chaque 1 seconde on revient a la fonction qui regarde si quelqun nous a parlé
end;

procedure TForm1.MessengerAPIDMessengerEvents1IMWindowCreated(Sender: TObject;
const pIMWindow: IDispatch); //la fonction qui regarde si quelqun nous a parlé
Var
Found : Boolean;
begin
Found := False;
wnd:=FindWindowA(PChar('IMWindowClass'), Nil); // on recherche encore la fenetre et on la donne a wnd
If wnd <> 0 Then
for i:=0 to High(tableau) do //on parcour le tableau (Tableau[1000000] = 38)
if Tableau[i] = wnd then
Begin
Found := True;
break;// on arrette la boucle
End;
If not Found Then //sinon
Begin
SetLength(Tableau, Length(Tableau)+1); //on ajoute une entrée au Tableau
SwitchToThisWindow(wnd, True); // on met la fenetre au premier plan ( a ce moment timerfunc va envoyer le message )
tableau[High(Tableau)] := wnd // on stocke dans une cellule du tableau le handle
End;
end;
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Mxbug Messages postés 47 Date d'inscription mercredi 27 avril 2005 Statut Membre Dernière intervention 9 janvier 2006
27 nov. 2005 à 12:12
yop
merci a toi cirec ca marche ;) .
0
Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 50
27 nov. 2005 à 12:20
Content que ca fonctionne
et dans l'évenement onClose de ta form tu peux mettre ceci
Finalize(Tableau); // libère le tableau dinamique
et je me demande si il ne faut pas liberé ton timer, d'ailleur pourquoi n'utilises tu pas un TTimer

voilà c'est tout
Bon dimanche
@+
Cirec
0
Mxbug Messages postés 47 Date d'inscription mercredi 27 avril 2005 Statut Membre Dernière intervention 9 janvier 2006
27 nov. 2005 à 20:08
yop
j'ai un nouveau ptit probleme ici :
function TimerFunc (H: hwnd;uMsg : UINT;idEvent : UINT;dwTime : DWORD ): BOOL; stdcall; // pouyr finir l'envoi de message
begin
If (Handle <> ActiveHandle) Then
If (Window <> ActiveCaption) Then
Begin
Window := ActiveCaption;
If Window = ActiveCaption then
Begin

SendKeys(Pchar('Automessage : ' + IMessage + #13));

End;
End;
end;

apres le sendkeys j'ai essayé de reduire la fenetre car sinon le prog ne prend pas en compte les autres fenetres , mais je n'y arrive pas elle ne se reduit pas j'ai essayé : showwindow et setwindowpos ,SetForegroundWindow ,en vain :( .
autre idée ??
0
Mxbug Messages postés 47 Date d'inscription mercredi 27 avril 2005 Statut Membre Dernière intervention 9 janvier 2006
27 nov. 2005 à 23:06
un ptit Up !
0
Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 50
28 nov. 2005 à 10:10
Pour ton petit souci :
ShowWindow(handle de la Fenêtre , ShowCommand);


{ ShowWindow() Commands }
SW_HIDE = 0;
SW_SHOWNORMAL = 1
SW_NORMAL = 1;
SW_SHOWMINIMIZED = 2;
SW_SHOWMAXIMIZED = 3;
SW_MAXIMIZE = 3;
SW_SHOWNOACTIVATE = 4;
SW_SHOW = 5;
SW_MINIMIZE = 6;
SW_SHOWMINNOACTIVE = 7;
SW_SHOWNA = 8;
SW_RESTORE = 9;
SW_SHOWDEFAULT = 10;
SW_MAX = 10;


Donc pour réduire : ShowWindow(Form1.Handle, SW_MINIMIZE );

et pour la restaurer: ShowWindow(Form1.Handle, SW_RESTORE);
0
Mxbug Messages postés 47 Date d'inscription mercredi 27 avril 2005 Statut Membre Dernière intervention 9 janvier 2006
28 nov. 2005 à 10:42
yop
c'est pas ma form que je veux minimize mais l'autre fenetre , et ca marche toujours pas avec showminimized , ni minimize , ni showminnoactive :( .
0
Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 50
28 nov. 2005 à 12:31
Il faut remplacer le handle de ta form par celui de la form à fermer dans ton cas il me semble que la fenêtre à fermer est celle qui correspond au Handle "Wnd" donc il faut adapter :
Tu mets ShowWindow(Wnd ,SW_MINIMIZE ); // pour réduire
et ShowWindow(Wnd , SW_RESTORE); // pour restaurer



@+
Cirec
0
Mxbug Messages postés 47 Date d'inscription mercredi 27 avril 2005 Statut Membre Dernière intervention 9 janvier 2006
28 nov. 2005 à 13:23
yop
bien sur que j'ai modifié le handle , je ne suis pas un adepte du copier coller ^^ .
toujours sans resultat .
0
Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 50
28 nov. 2005 à 13:58
le sw_Hide Fonctionne t-il



@+
Cirec
0
Mxbug Messages postés 47 Date d'inscription mercredi 27 avril 2005 Statut Membre Dernière intervention 9 janvier 2006
28 nov. 2005 à 14:30
yop
oui le SW_HIDE fonctionne mais ce n'est pas ce que je veux ,enfaite j'ai remarqué que cela :
disons qu'il ya deux fenetres msn reduites , quand je lance mon prog il en ouvre une ( la premiere )et ecris son message ,et ne touche pas a la deuxieme :s mais si je reduit la premier fenetre ( manuellement ) il ouvre l'autre de suite donc je me suis dit que s i apres avoir posté le message il reduisait la fenetre il ouvrirais l'autre .
si vous avez une autre idée pour faire cela je suis prenant
0
Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 50
28 nov. 2005 à 15:24
Essaye ceci :
SendMessage(Wnd ,WM_SHOWWINDOW ,0,SW_PARENTCLOSING);



@+
Cirec
0
Mxbug Messages postés 47 Date d'inscription mercredi 27 avril 2005 Statut Membre Dernière intervention 9 janvier 2006
28 nov. 2005 à 19:23
yop
j'ai mit
function TimerFunc (H: hwnd;uMsg : UINT;idEvent : UINT;dwTime : DWORD ): BOOL; stdcall; // pouyr finir l'envoi de message
begin
If (Handle <> ActiveHandle) Then
If (Window <> ActiveCaption) Then
Begin
Window := ActiveCaption;
If Window = ActiveCaption then
Begin

SendKeys(Pchar('Automessage : ' + IMessage + #13));
SendMessage(Wnd ,WM_SHOWWINDOW,0,SW_PARENTCLOSING);;
End;
End;
end;

et ca me fait otujours la meme chose , j'ai essayé WM_SHOWWINDOW par SW_SHOWMINNOACTIVE et SW_MINIMIZE mais ca ne reduit pas la fenetre ...
merci de ton aide
0
Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 50
28 nov. 2005 à 20:44
Essaye encore de remplacer le Handle "Wnd" par "Tableau[High(tableau)]" le dernier Handle valide enregistrer



@+
Cirec
0
Mxbug Messages postés 47 Date d'inscription mercredi 27 avril 2005 Statut Membre Dernière intervention 9 janvier 2006
28 nov. 2005 à 20:52
nope meme chose :( :( , je comprend pas.
0
Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 50
28 nov. 2005 à 20:59
moi non plus désolé
0
Mxbug Messages postés 47 Date d'inscription mercredi 27 avril 2005 Statut Membre Dernière intervention 9 janvier 2006
28 nov. 2005 à 21:59
ok pas grave , sinon une autre idée pour ecrire dans d'autres fenetres a part celle que j'utilise ??
0
Rejoignez-nous