salut
du momment que tu recupere la classe et que celle ci est connue il n'y a aucune limitation
@+ Phil
salut
du momment que tu recupere la classe et que celle ci est connue il n'y a aucune limitation
@+ Phil
Blaise PascalNous souhaitons la vérité et nous trouvons qu'incertitude. [...]
Nous sommes incapables de ne pas souhaiter la vérité et le bonheur, et sommes incapables ni de certitude ni de bonheur.
PS : n'oubliez pas le tag
OK, donc logiquement ça devrait fonctionnait mais voilà, ça bug ...
Voici le code :
Apparemment on ne peut pas transtyper de cette façon
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 procedure TForm1.Button1Click(Sender: TObject); var HandleParent:HWND; Handle : THandle; Titre,Classe:PChar; HandleEtTitre:string; begin HandleParent:=FindWindow(nil,'WebRadioPlayer'); Handle := GetWindow(HandleParent,GW_CHILD); Titre:=StrAlloc(256); Classe:=StrAlloc(256); GetWindowText(Handle,Titre,256); GetClassName(Handle,Classe,256); HandleEtTitre:=IntToStr(Handle)+' - '+Titre; if Classe='TPngBitBtn' then ShowMessage(TPngBitBtn(Handle).Hint); end;
ne pas confondre Handle de Classe Windows et Pointer d'Objet Delphi ...
Donc pour changer le Hint, hum, est-ce au moins accesible depuis l'extérieur ??? le Text oui, via un SendMessage(SET_TEXT) mais le hint ... ça sera pas interne delphi ...
Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
Attention Troll Méchant !
"Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
L'ignorance n'excuse pas la médiocrité !
L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
Il faut avoir le courage de se tromper et d'apprendre de ses erreurs
salut
as tu essaye de creer ton composant et de lui passer le handle
genre :
et ensuite voir si tu peut recuperer les info
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 MPngbutton := TPngbutton.create(); MPngbutton.handle := handle;
@+ Phil
Blaise PascalNous souhaitons la vérité et nous trouvons qu'incertitude. [...]
Nous sommes incapables de ne pas souhaiter la vérité et le bonheur, et sommes incapables ni de certitude ni de bonheur.
PS : n'oubliez pas le tag
A ShailLeTroll:
Hum, je veux juste récupérer le texte du Hint mais si je peux le changer, pourquoi pas lol. D'après ton message, ça a l'air assez complexe et j'avoue que c'est sûrement un trop gros poisson que de m'atteler à cette tâche.
A Anapurna:
J'avais déjà testé cette façon mais dès lors que l'on créer le composant, le Handle est créé et ne peut être modifié ... On peut juste le lire et le récupérer mais pas affecter un autre Handle au composant...
Pour conclure, si vous avez des liens intéressants qui justement permettraient d'avoir des infos supplémentaires à partir d'un Handle et d'une classe, je suis prenant!
Evidemment, si vous avez aussi des connaissances, n'hésitez, moi je prends tout ce qui me passe sous la main!
Merci bien
Il semble qu'en Delphi (voir Controls.pas et Form.pas, THintInfo, ...) tout est géré manuellement ... cela se voit en comparant le Hint et le Text
Simple variable FHint, sans manipulation ...
Code : Sélectionner tout - Visualiser dans une fenêtre à part property Hint: string read FHint write FHint stored IsHintStored;SetText appele SetTextBuf, et l'on voit le message windows puis son notify spécial delphi
Code : Sélectionner tout - Visualiser dans une fenêtre à part property Text: TCaption read GetText write SetText;
Récupéré le Hint me semple chose difficile, tu vois dans l'aide API, les ToolTips pour la ToolBar d'IE par exemple, mais tu ne vois rien sur celle du ShellTreeView32...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 procedure TControl.SetTextBuf(Buffer: PChar); begin Perform(WM_SETTEXT, 0, Longint(Buffer)); Perform(CM_TEXTCHANGED, 0, 0); end;
Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
Attention Troll Méchant !
"Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
L'ignorance n'excuse pas la médiocrité !
L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
Il faut avoir le courage de se tromper et d'apprendre de ses erreurs
Oué, je vois
J'essaierai de voir comment ça fontionne et comme ça peut être possible...
Dommage que l'histoire du transtypage de Handle ne fonctionne pas, ça aurait résolu pas mal de problème ...
Une question tout de même ... Lorsque l'on fait un transtypage, en paramètre, on passe bien un pointeur ??? (j'ai peur de dire une grosse bêtise là ....)
Merci
Ben un Objet un toujours passé sous la forme d'un pointeur, mais c'est juste pas la même chose, un pointeur c'est une adresse mémoire, un handle c'est un idenfiant logique d'un objet, ce n'est pas le même niveau d'abstraction ...
Sinon le Transtypage oui, il faut lui donner un pointer (typé ou non) pour l'interpréter comme un pointer typé, ... mais tu peux aussi transtyper d'autre chose, par exemple un Record, tu peux le transtyper d'un autre Record (si possible de même longueur) ... tient comme ce code ...
En fait, tu dis qu'une "zone mémoire" se lit de tel façon, si elles sont compatibles parce qu'il y a bien ce qu'il faut où il faut cela fonctionne, sinon soit ça plante, soit cela fait n'importe quoi !
Dans cette exemple, j'ai un fichier NX (format CCAM), qui contient des lignes qui font toujours 128+1 octets, donc je ne me suis pas fait chier, je lit les 129 octets que je mets dans une Structure avec le minimum d'info (TNXDataRecord) puis en fonction des 3 premiers octets, je suis capable de savoir qu'elle est le type de la ligne, donc au lieu de m'embêter à faire des cases complexes, je Transtype le TNXDataRecord en un autre Type de Record, et je peux accéder aux valeurs sans efforts, ... et cela pour un bon paquet de type (000 à 999 dont 150 existent actuellement, sans compter les sous variantes ...)
Code : Sélectionner tout - Visualiser dans une fenêtre à part CurrentNXRecord: TNXDataRecord;
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
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 // Type Utilisé pour faciliter le Découpage des buffers type TNXDataRecord = packed record TypeRecord: Array[1..3] of Char; Data: Array[1..NX_DATA_SIZE - NX_DATA_SIZE_TYPE] of Char; EndRecord: Char; // Toujours #$0A; end; // Type 091 type TNXData_091 = TNXData_Entete; type TNXData_091_01_CAC = packed record TypeRecord: Array[1..3] of Char; Rubrique: Array[1..2] of Char; Sequence: Array[1..2] of Char; CodeMenu: Array[1..6] of Char; CodePere: Array[1..6] of Char; Rang: Array[1..6] of Char; Libelle: Array[1..100] of Char; Spare: Array[1..3] of Char; EndRecord: Char; // Toujours #$0A end; // Type 999 type TNXData_999_TIP = packed record TypeRecord: Array[1..3] of Char; InfoNOEMIE: Array[1..49] of Char; NombreRecord: Array[1..8] of Char; NombreRefLPP: Array[1..6] of Char; Spare: Array[1..62] of Char; EndRecord: Char; // Toujours #$0A; end; type TNXData_999_CAM = packed record TypeRecord: Array[1..3] of Char; InfoNOEMIE: Array[1..49] of Char; NombreRecord: Array[1..8] of Char; NombreTables: Array[1..6] of Char; NombreActe: Array[1..6] of Char; NombreActeActivite: Array[1..6] of Char; NombreActeActivitePhase: Array[1..6] of Char; Spare: Array[1..44] of Char; EndRecord: Char; // Toujours #$0A; end; type TNXData_999_CAC = packed record TypeRecord: Array[1..3] of Char; InfoNOEMIE: Array[1..49] of Char; NombreRecord: Array[1..10] of Char; NombreTables: Array[1..6] of Char; NombreActe: Array[1..6] of Char; NombreActeActivite: Array[1..6] of Char; NombreActeActivitePhase: Array[1..6] of Char; Spare: Array[1..42] of Char; EndRecord: Char; // Toujours #$0A; end;Dans ce Code suivant je Transtype le TNXDataRecord en TNXData_091 puis en TNXData_091_01_CAC
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 //------------------------------------------------------------------------------ procedure TSPReaderFileNX.AnalyzeNXRecord; begin case StrToInt(CurrentNXRecord.TypeRecord) of 91 : AnalyzeNX_091(); 92 : AnalyzeNX_092(); 101 : AnalyzeNX_101(); 102..198 : Inc(Compteur.Actes); 199 : AnalyzeNX_199(); 201..298 : Inc(Compteur.Activites); 299 : AnalyzeNX_299(); 301..398 : Inc(Compteur.Phases); 399 : AnalyzeNX_399(); end; end;
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
29
30
31
32
33
34
35 //------------------------------------------------------------------------------ procedure TSPReaderFileNX.AnalyzeNX_091; var TmpNoteHierarchie : TRecNoteHierarchie; begin case StrToInt(TNXData_091(CurrentNXRecord).Rubrique) of 1 : begin with TmpNoteHierarchie do begin CodeMenu := StrToInt(TNXData_091_01_CAC(CurrentNXRecord).CodeMenu); CodePere := StrToInt(TNXData_091_01_CAC(CurrentNXRecord).CodePere); Rang := StrToInt(TNXData_091_01_CAC(CurrentNXRecord).Rang); Libelle := TNXData_091_01_CAC(CurrentNXRecord).Libelle; if StrToInt(TNXData_091(CurrentNXRecord).Sequence) = 1 then begin if Assigned(NoteHierarchie.Racine) then begin NoteHierarchie.Racine.AddItem(CodeMenu, CodePere, Rang, Libelle); end else begin // C'est la Première Note Hiérarchique NoteHierarchie.Racine := TNoteHierarchieItems.Create(CodeMenu, Rang, Libelle); end; end else begin if Assigned(NoteHierarchie.Racine) then begin if NoteHierarchie.Racine.Code = CodeMenu then begin NoteHierarchie.Racine.Libelle := NoteHierarchie.Racine.Libelle + Libelle; end else begin NoteHierarchie.Racine.UpdateItem(CodeMenu, Rang, Libelle); end; end else begin raise EOleError.Create('Erreur Interne 192 : Racine de la Hiérarchie Inexistante !'); end; end; end; end; end; end;tient voici, le code d'un collègue qui avait bossé sur le fichiers NX avant moi, je ne l'ai découvert qu'après et j'ai vu qu'il s'était bien fait chier ... et même pire son code est difficilement maintenable, car une modification du format nécessite de modifier tous les appels au Copy car c'est en valeur directe que sont notées les positions (même pas des constantes), alors qu'avec le Transtypage, il suffit de modifier la structure, et d'implémeter la partie métier ...
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 //------------------------------------------------------------------------------ procedure TSPReaderFileNX.AnalyzeNX_999; var NombreRecord: Integer; begin NombreRecord := 0; if Info.TypeFile = 'TIP' then NombreRecord := StrToInt(TNXData_999_TIP(CurrentNXRecord).NombreRecord); if Info.TypeFile = 'CAM' then NombreRecord := StrToInt(TNXData_999_CAM(CurrentNXRecord).NombreRecord); if Info.TypeFile = 'CAC' then NombreRecord := StrToInt(TNXData_999_CAC(CurrentNXRecord).NombreRecord); if RecordCount <> NombreRecord then begin raise EOleError.Create('Le Nombre Total d''Enregistrement Calculé ('+IntToStr(RecordCount)+') est différent du Nombre Total Prévu ('+IntToStr(NombreRecord)+')!'); end; end;
AnalyzeNX_091 et TypeEnr91 font exactement la même chose, simplement dans des tables différentes ...
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
29
30
31
32
33
34
35
36
37
38
39
40
41 Procedure TModuleDonneesNX.TypeEnr91(LEnregistrement : String; Ajout : Boolean); var Sequence : String; CodeMenu, CodePere, Rang : Integer; begin Sequence := copy(LEnregistrement, 6, 2); CodeMenu := strtoint(copy(LEnregistrement, 8, 6)); CodePere := strtoint(copy(LEnregistrement, 14, 6)); Rang := strtoint(copy(LEnregistrement, 20, 6)); if Sequence = '01' then begin ReqMenu.open; ReqMenu.Insert; ReqMenu.FieldByName('COD_MENU').AsInteger := CodeMenu; if CodePere <> 0 then ReqMenu.FieldByName('COD_PERE').asinteger := CodePere else ReqMenu.FieldByName('COD_PERE').Clear; ReqMenu.FieldByName('RANG').AsInteger := Rang; ReqMenu.FieldByName('LIBELLE').asstring := copy(LEnregistrement, 26, 100); try ReqMenu.RecurseApplyUpdates; except showmessage('Code : '+inttostr(CodeMenu)+' Codepapa : '+inttostr(CodePere)); ReqMenu.close; end; end else begin ReqMenu.Close; ReqMenu.ParamByName('COD_MENU').AsInteger := CodeMenu; ReqMenu.ParamByName('COD_PERE').asinteger := CodePere; ReqMenu.ParamByName('RANG').AsInteger := Rang; ReqMenu.Open; if not ReqMenu.IsEmpty then begin ReqMenu.Edit; ReqMenu.FieldByName('LIBELLE').asstring := ReqMenu.FieldByName('LIBELLE').asstring + copy(LEnregistrement, 28, 100); ReqMenu.RecurseApplyUpdates; end; end; end;
Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
Attention Troll Méchant !
"Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
L'ignorance n'excuse pas la médiocrité !
L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
Il faut avoir le courage de se tromper et d'apprendre de ses erreurs
Tu m'étonneras toujours
Tu as toujours tout sous la main! Franchement acquérir un niveau comme le tient ça serait bien (je vais arrêter les éloges ... lol)
Pour ce qui est du transtypage, j'ai posé la question car j'en étais plus trop sur ... Ton explication est claire!
En ce qui concerne mon problème, on pourrait essayer de récupérer le pointeur du Handle... et de faire le transtypage dans la bonne classe
Enfin, je pense que si c'était si simple on m'aurait déjà fait la remarque ...
Effectivement, tu as souvent entendre parler des echanges d'objet ou de string entre DLL, et bien entre programme c'est pareil ... tu peux échanger les pointeurs, lire les valeurs sur quelles ils pointent, les modifier c'est déjà plus tendu ... maintenant, autant un objet connait son handle comme propriété, autant windows qui a son handle, ne connait ni le type, ni le nom, ni même à quoi ressemble une classe delphi, VB, ... donc il sera bien incapable de faire la résolution ... ton problème de capture par handle vient surement que tu n'as pas la possibilité de modifier l'autre application (WebRadioPlayer), ... car si tu pouvais la modifier, tu pourrais avec toute sorte de lien (socket, pipe, DDE, message WM_DATA, ...), interragir sans soucis avec tes deux applications ... d'ailleurs, même si tu obtenais le pointeur de l'objet associé (c'est possible, il faudrait gérer toutes les formes avec un propriétaire Owner, application par exemple, et parcours récursivement tous les Owner/Components et trouver le WinControl qui contient ce Handle ^_^) ... mais même entre deux applications Delphi, si l'une et l'autre sont compilés avec deux Delphi différent, voire même juste des options de compilations différentes, il n'est pas garanti que la classe de ton programme aie la même structure que la classe de l'autre programme, il pourrait y manquer de nouvelle propriété ou méthode ...
J'espère BienEnvoyé par ero-sennin
Chut, normalement, je ne devrais pas ... loi et confidentialité vis à vis de mes anciens employeurs ...Envoyé par ero-sennin
Merci, je prends, maintenant, je vais fêter mes 8 ans d'XP (3 en apprentissage, 5 en CDI), et la chance d'avoir eux un EXCELLENT Maitre de Stage de DUT (un Ancien Horloger Militaire), et aussi ensuite un Patron suicidaire qui confiant à un Apprenti (Licence) un projet de trieuse industrielle (en fait ce n'était pas pour moi le projet, mais sur le 5 membres de l'équipe, je fut le seul à avoir réussi a faire communiquer deux programmes sur deux machines distantes, genre un chat, avec Windev 5.5, et à ce moment, ce langage ne possèdait pas de méthode TCP/IP simple, il fallait passer par du Remote Command FTP ... il fallu que l'on réclame les fonctions à PC Soft, et au final le projet fut fait avec Delphi 5 ...Envoyé par ero-sennin
Merci, Encore, Moi je n'ai jamais l'impression de l'être ...Envoyé par ero-sennin
Voir Ci-dessusEnvoyé par ero-sennin
Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
Attention Troll Méchant !
"Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
L'ignorance n'excuse pas la médiocrité !
L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
Il faut avoir le courage de se tromper et d'apprendre de ses erreurs
Oula, je vois mieux le niveau de difficulté ! Déjà qu'avant s'était pas si simple que ça mais la, avec ce que tu viens de me dire, je crais que je ne puisse récupérer que ce que qu'on a, c'est à dire le nom de classe et le texte du Handle...
Enfin, pour finir, WebRadioPlayer est un petit programme que j'ai réalisé avec Delphi et je voulais juste m'entraîner avec cet exemple...
Bon, hé bien je te remercie pour toutes ses infos et ces morceaux de code
Je tag donc résolu bien que ça aurait était intéressant de pousser les recherches encore plus loin
EDIT
Heu là c'était pas très clair ... Récupérer les Handles, ça je sais faire maintenant. Je sais même qui est le parent, qui sont les frères etc etc grâce à ton premier code. Par contre, quand tu parles de Owner c'est bien le propriétaire de l'objet, c'est à dire celui qui contient le contrôle ?Envoyé par ShailLeTroll
Par exemple, le Owner d'un bouton sur une form, c'est la form non?
Là j'avoue que niveau des compétences et du voc, je bloque ... On récupère le WinControl du Handle ...
Sachant que j'ai un Handle je peux pas "l'extraire" directement ...
Tu m'excuseras de ne pas avoir saisi tout du premier coup
Effectivement, si tu es l'auteur des deux programmes, tu peux t'amuser très loin, ... et l'échange d'objet peut se faire sans trop de problème, je pense ... fait des Recherches sur le forum sur DDE, DLL String PChar TStringList, ... sinon un code simple vite fait (je le tape direct sur forum sans test), et riche en violation d'accès ^_^
Cote Manager
Cote Client,
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 function TManagerForm.GetHintByHandle(HandleFormClient, HandleControl: THandle): string; var RLen: Longint; begin SetLength(Result, 255); RLen := SendMessage(HandleFormClient, UM_GET_HINT, HandleControl, @Result[1]); // UM_GET_HINT = WM_USER + 11111; par exemple, voir sinon RegisterWindowMessage, ensuite SendMessage ATTEND que le message soit traité ... très important SetLength(Result, RLen); end;
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 procedure TClientForm.SendHint(var message: TMessage); message UM_GET_HINT; var I: Integer; HintStr: String; begin for I := 0 to ComponentCount - 1 do begin if (Components[I] is TWinControl) and (TWinControl(Components[I]).Handle = message.wParam) then begin HintStr := TWinControl(Components[I]).Hint; message.Result := Min(255, Length(HintStr)); CopyMemory(Pointer(message.lParam), @HintStr[1], message.Result); end; end; end;
Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
Attention Troll Méchant !
"Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
L'ignorance n'excuse pas la médiocrité !
L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
Il faut avoir le courage de se tromper et d'apprendre de ses erreurs
Le Code du Format n'est pas complet, mais tu peux ajouter les segments qui manque, je peux t'envoyer le code d'un objet, communique ton email par MP, et ça sera envoyé en zip
Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
Attention Troll Méchant !
"Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
L'ignorance n'excuse pas la médiocrité !
L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
Il faut avoir le courage de se tromper et d'apprendre de ses erreurs
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager