Précédent   Forum du club des développeurs et IT Pro > Environnements de développement > Delphi
Delphi Environnement de développement RAD avec compilateur Natif. Avant de poster -> La FAQ Delphi
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Actualité déjà publiée
 
Outils de la discussion
Publicité
'
Vieux 06/12/2012, 12h50   #1
Andnotor
Rédacteur/Modérateur
 
Avatar de Andnotor
 
Inscription : septembre 2008
Messages : 2 857
Détails du profil
Informations forums :
Inscription : septembre 2008
Messages : 2 857
Points : 5 967
Points : 5 967
Par défaut [Tutoriel] Envoyer des chaînes et structures par PostMessage

Bonjour à tous !

Je vous propose aujourd'hui un nouveau tutoriel sur l'envoi de chaînes ou de structures par PostMessage en utilisant la table d'atomes.

N'hésitez pas à faire part de vos réactions

Bonne lecture !
__________________
Mes tutoriels Delphi
Andnotor est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 07/12/2012, 05h01   #2
Paul TOTH
Expert Confirmé Sénior
 
Avatar de Paul TOTH
 
Homme Paul TOTH
Freelance
Inscription : novembre 2002
Messages : 4 427
Détails du profil
Informations personnelles :
Nom : Homme Paul TOTH
Âge : 43
Localisation : Réunion

Informations professionnelles :
Activité : Freelance
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : novembre 2002
Messages : 4 427
Points : 10 833
Points : 10 833
Bonjour,

Personnellement j'utilise un autre approche que je trouve bcp plus simple

Code :
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
 
type
  TMessageData = class
    UnEntier: Integer;
    UneChaine: string;
    UnStream: TStream;
    NImporteQuoi: TNImportQuoi;
  end;
 
  TDataMessage = record
    Msg: Integer;
    Null: Integer;
    Data: TMessageData;
   Result : Integer;
  end;
 
procedure SendInfos(HWnd, Msg: Integer; UnEntier, UneChaine...);
var
  data: TMessageData;
begin
  data := TMessageData.Create;
  data.UnEntier := UnEntier;
  data.UneChaine := UneChaine;
  ...
  PostMessage(HWnd, Msg, 0, Integer(@data));
end;
le destinataire du message est responsable de la suppression de "data", mais il est possible d'ajouter ces objets à une ThreadList globale qu'on purge le cas échéant quand c'est nécessaire.
__________________
Developpez.com: Mes articles, forum FlashPascal
Entreprise: Execute SARL
Produits : UPnP, RemoteOffice, FlashPascal
Embarcadero : Ile de la Réunion, Dephi, C++Builder, RADPHP...TVA à 8,5%
Paul TOTH est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 07/12/2012, 10h24   #3
Andnotor
Rédacteur/Modérateur
 
Avatar de Andnotor
 
Inscription : septembre 2008
Messages : 2 857
Détails du profil
Informations forums :
Inscription : septembre 2008
Messages : 2 857
Points : 5 967
Points : 5 967
C'est possible en effet

Par record, il faudra prendre soin de faire appel à GetMem/FreeMem (New/Dispose) et pas simplement déclarer une variable locale à la fonction !
Mon approche se veut cependant plus universelle et autorise l'envoi entre processus
__________________
Mes tutoriels Delphi
Andnotor est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/12/2012, 14h19   #4
ShaiLeTroll
Expert Confirmé Sénior
 
Avatar de ShaiLeTroll
 
Homme
Développeur C++\Delphi
Inscription : juillet 2006
Messages : 9 199
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 32
Localisation : France

Informations professionnelles :
Activité : Développeur C++\Delphi
Secteur : High Tech - Électronique et micro-électronique

Informations forums :
Inscription : juillet 2006
Messages : 9 199
Points : 13 251
Points : 13 251
J'ai jamais eu le temps de m'occuper de [QR] Comment passer une string dans un message Windows ? qui utilise WM_COPYDATA qui fonctionnee en inter-processus
__________________
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

Halte à la ségrégation des Cinémas, VO sur Paris, VF en Banlieue, Abonnement résilié !
ShaiLeTroll est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/12/2012, 14h24   #5
Andnotor
Rédacteur/Modérateur
 
Avatar de Andnotor
 
Inscription : septembre 2008
Messages : 2 857
Détails du profil
Informations forums :
Inscription : septembre 2008
Messages : 2 857
Points : 5 967
Points : 5 967
...mais qui est obligatoirement synchrone par SendMessage
__________________
Mes tutoriels Delphi
Andnotor est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/12/2012, 22h55   #6
BuzzLeclaire
Membre Expert
 
Avatar de BuzzLeclaire
 
Homme
Dev/For/Vte/Ass
Inscription : août 2008
Messages : 1 499
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Dev/For/Vte/Ass

Informations forums :
Inscription : août 2008
Messages : 1 499
Points : 1 059
Points : 1 059
@AndNotY,

Salut, j'ai parcouru tout ton article, et à la fin je me suis demandé à quoi cela peut servir en cas réel ? (je préfère passer pour un idiot, mais je pose quand même la question...)

Est-ce un moyen de transmettre des données (tableau, chaîne, nombre) entre 2 applications ?

BuzzLeclaire est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/12/2012, 13h09   #7
Andnotor
Rédacteur/Modérateur
 
Avatar de Andnotor
 
Inscription : septembre 2008
Messages : 2 857
Détails du profil
Informations forums :
Inscription : septembre 2008
Messages : 2 857
Points : 5 967
Points : 5 967
Tu peux envoyer tout ce que tu veux, entre threads ou entre processus

Voici deux exemples.

Rediriger la sortie d'une application console.
Admettons que cycliquement, tu lances en tâche de fond une application console invisible pour de la maintenance (backup, mise à jour...). Tu aimerais cependant que l'utilisateur soit informé de l'avancement ou d'une éventuelle erreur. Tu pourrais bien sûr :
  • utiliser CreateProcess et rediriger la sortie sur un Pipe. Un travail conséquent ;
  • lancer ShellExecuteEx depuis un thread et attendre la fin pour contrôler le code de sortie (ExitCode), mais pas de notification d'avancement ;
  • envoyer WM_COPYDATA mais SendMessage est bloquant et dû à la structure de taille fixe, le texte risque d'être tronqué (ou alors il faut surdimentionner le buffer).
Ici, rien de tout cela ! Il suffit de redéfinir WriteLn et d'envoyer PostTextMessage
Code :
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
program Project1;
 
{$APPTYPE CONSOLE}
 
{$R *.res}
 
uses
  SysUtils, Windows, Messages, MessagesEx;
 
procedure WriteLn(aText :string);
begin
  PostTextMessage(FindWindow('ClassName', 'WindowName'), WM_USER, aText);
end;
 
begin
  ClearTableOnExit := FALSE;
 
  try
    WriteLn('BlaBla');
    WriteLn('BlaBla');
 
  except
    on E: Exception do
      WriteLn(E.Message);
  end;
end.

Hook.
Tu aimerais intercepter le retour de traitement d'un message par une fenêtre quelconque. Tu vas pour cela injecter une DLL dans les processus par SetWindowsHookEx. Mais un hook peut être très pénalisant pour le système et le ralentir considérablement si le traitement à effectuer est long.
Jusqu'à Windows XP, on privilégiait le passage d'info par fichier mappé. Les lectures et écritures devant bien sûr être synchronisées par mutex. Depuis Vista et l'UAC, C'est fini ! La DLL injectée dans une application de niveau d'intégrité inférieur (par exemple Internet Explorer en mode protégé) n'aura pas accès au fichier mappé. Une violation est générée et c'est le deadlock assuré de l'application cible.
On pourrait à nouveau utiliser WM_COPYDATA, mais il faudra que notre application soit très réactive. Imagine un hook souris tellement pénalisant que le curseur avance par saccade !
Router simplement les informations par PostMessage ? Bien sûr si peu d'informations nous intéressent et tiennent dans WParam/LParam. Mais il ne faut pas espérer en récupérer plus par la suite par AttachThreadInput (UAC quand tu nous tiens...).

Intercepter le retour d'un message se fait en plaçant un hook de type WH_CALLWNDPROCRET. Un pointeur est passé dans LParam correspondant à la structure suivante :
Code :
1
2
3
4
5
6
7
8
type
  TCwpRetStruct = record
    lResult :LRESULT;
    lParam  :LPARAM;
    wParam  :WPARAM;
    message :UINT;
    hwnd    :HWND;
  end;
Nous n'aurons donc plus qu'à faire :

Code :
1
2
3
4
5
6
7
function CWPRetProc(aCode: integer; aWParam: WPARAM; aLParam: LPARAM):LRESULT; stdcall;
begin
  if (aCode = HC_ACTION) then
    PostBufferMessage(FindWindow('ClassName', 'WindowName'), WM_USER, aLParam, SizeOf(TCwpRetStruct));
 
  Result := CallNextHookEx(0, aCode, aWParam, aLParam);
end;
Est-ce plus clair ?
__________________
Mes tutoriels Delphi
Andnotor est déconnecté   Envoyer un message privé Réponse avec citation 40
Vieux 14/12/2012, 18h30   #8
ShaiLeTroll
Expert Confirmé Sénior
 
Avatar de ShaiLeTroll
 
Homme
Développeur C++\Delphi
Inscription : juillet 2006
Messages : 9 199
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 32
Localisation : France

Informations professionnelles :
Activité : Développeur C++\Delphi
Secteur : High Tech - Électronique et micro-électronique

Informations forums :
Inscription : juillet 2006
Messages : 9 199
Points : 13 251
Points : 13 251
Citation:
Envoyé par Andnotor Voir le message
envoyer WM_COPYDATA mais SendMessage est bloquant et dû à la structure de taille fixe, le texte risque d'être tronqué (ou alors il faut surdimentionner le buffer).
WM_COPYDATA est bloquant, cela a un avantage car son retour permet de vérifier la bonne reception\compréhension du message par le receveur

Sinon WM_COPYDATA utilise une structure COPYDATASTRUCT de taille fixe mais permet justement de gérer un buffer de longueur variable via se membres cbData et lpData
On peut donc strictement définir un buffer de la taille exacte de la donnée devant être envoyé

Sinon, pourquoi ne pas avoir utiliser BinToHex qui aurait fait le travail de conversion en Hexa bien plus rapidement que les nombreuses réallocation\concaténation de Data.Bytes même si FastMM le gère bien mieux que l'ancien gestionnaire de mémoire

Tient, j'ai fait un petit dev hier que l'on m'a réclamé pour simplifier la vie de l'utilisateur
un programme A doit lancer un programme B
A étant déjà loggué, B est lancé en mode "AutoLogin" pour que l'utilisateur n'est pas retapé son Login+PW
Dans d'autres programmes qui font la même chose, le login est passé sur la ligne de commande, en clair pour certaines et d'autres en chiffré
Cela reste une jolie faille de sécurité puisque cela permet un login sans PW
Mon prédecesseur n'avait pas du tout conscience de la sécurité !

Je passe un HWND qui servirait ensuite pour un échange entre A et B d'un GUID servant d'ID de session qui aboutit à l'authentification, c'est déjà plus difficile à choper (un hook)

je viens d'en extraire une petite classe plus générique, on voit tout de suite qu'avec un peu d'effort que l'on pourrait hériter d'un TStream et utiliser un TBinaryReader\TBinaryWriter dessus

la Version C++, si j'ai le temps, je la tenterais en Delphi

Code c++ :
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
//---------------------------------------------------------------------------
typedef bool __fastcall (__closure *TShaiCopyDataMessagerReadEvent)(TObject* Sender, HWND DataSender, void *Data, int DataLen);
 
//---------------------------------------------------------------------------
//                          TShaiCopyDataMessager                           -
//---------------------------------------------------------------------------
class TShaiCopyDataMessager : public TObject
{
private:
  // Membres Privés
  HWND FSenderHandle;
  HWND FRecipientHandle;
  COPYDATASTRUCT FRawData;
  TShaiCopyDataMessagerReadEvent FOnRead;
 
  // Accesseurs
  HWND __fastcall GetSenderHandle();
 
  // Méthodes Privées
  void __fastcall WndProc(Messages::TMessage &Message);
  bool DoRead(HWND DataSender, void *Data, int DataLen);
 
public:
  // Constructeurs Publiques
  /*constructor*/__fastcall TShaiCopyDataMessager();
  /*destructor*/virtual __fastcall ~TShaiCopyDataMessager();
 
  // Méthodes Publiques
  void BeginWrite();
  void WriteInteger(int Value);
  void WriteString(String Value);
  void WriteBuffer(void *Data, int DataLen);
  bool EndWrite();
  void CancelWrite();
 
  int ReadInteger(void *Data, /*out*/int &Value);
  int ReadString(void *Data, /*out*/String &Value);
 
  // Propriétés Publiques
  __property HWND SenderHandle = {read=GetSenderHandle};
  __property HWND RecipientHandle = {read=FRecipientHandle, write=FRecipientHandle};
  __property TShaiCopyDataMessagerReadEvent OnRead = {read=FOnRead, write=FOnRead};
};

Code c++ :
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
//---------------------------------------------------------------------------
//                          TShaiCopyDataMessager                           -
//---------------------------------------------------------------------------
/*constructor*/__fastcall TShaiCopyDataMessager::TShaiCopyDataMessager()
{
 
}
 
//---------------------------------------------------------------------------
/*destructor*/__fastcall TShaiCopyDataMessager::~TShaiCopyDataMessager()
{
  CancelWrite();
 
  if (FSenderHandle != 0)
  {
    DeallocateHWnd(FSenderHandle);
    FSenderHandle = 0;
  }
}
 
//---------------------------------------------------------------------------
HWND __fastcall TShaiCopyDataMessager::GetSenderHandle()
{
  if ( ! FSenderHandle)
    FSenderHandle = AllocateHWnd(WndProc);
 
  return FSenderHandle;
}
 
//---------------------------------------------------------------------------
void TShaiCopyDataMessager::BeginWrite()
{
  CancelWrite();
}
 
//---------------------------------------------------------------------------
void TShaiCopyDataMessager::WriteInteger(int Value)
{
  WriteBuffer(&Value, sizeof(Value));
}
 
//---------------------------------------------------------------------------
void TShaiCopyDataMessager::WriteString(String Value)
{
  int Len = Value.Length();
  WriteInteger(Len);
 
  if (Len > 0)
  {
    int Size = Len * sizeof(Char); // gère que la table BMP de UTF-16
    WriteBuffer(Value.c_str(), Size);
  }
}
 
//---------------------------------------------------------------------------
void TShaiCopyDataMessager::WriteBuffer(void *Data, int DataLen)
{
  int Position = FRawData.cbData;
  FRawData.cbData += DataLen;
  if (Position > 0)
    ReallocMemory(FRawData.lpData, FRawData.cbData);
  else
    FRawData.lpData = GetMemory(FRawData.cbData);
  CopyMemory((Byte*)FRawData.lpData + Position, Data, DataLen);
}
 
//---------------------------------------------------------------------------
bool TShaiCopyDataMessager::EndWrite()
{
  bool Result = SendMessage(FRecipientHandle, WM_COPYDATA, (WPARAM)FSenderHandle, (LPARAM)&FRawData);
  CancelWrite();
  return Result;
}
 
//---------------------------------------------------------------------------
void TShaiCopyDataMessager::CancelWrite()
{
  FreeMemory(FRawData.lpData);
  ZeroMemory(&FRawData, sizeof(FRawData));
}
 
//---------------------------------------------------------------------------
int TShaiCopyDataMessager::ReadInteger(void *Data, /*out*/int &Value)
{
  int Result = -1;
  if ( ! IsBadReadPtr(Data, sizeof(Value)))
  {
    Value = *(int*)Data;
    Result = sizeof(Value);
  }
  return Result;
}
 
//---------------------------------------------------------------------------
int TShaiCopyDataMessager::ReadString(void *Data, /*out*/String &Value)
{
  int Result = -1;
  int Len = 0;
  int TmpResult = ReadInteger(Data, Len);
  if (TmpResult > 0)
  {
    Result = TmpResult;
    if (Len > 0)
    {
      Value = UnicodeString((WideChar*)((Byte*)Data + TmpResult), Len);
      int Size = Len * sizeof(Char); // gère que la table BMP de UTF-16
      Result += Size;
    }
    else
      Value = "";
  }
  return Result;
}
 
//---------------------------------------------------------------------------
void __fastcall TShaiCopyDataMessager::WndProc(Messages::TMessage &Message)
{
  if (Message.Msg == WM_COPYDATA)
  {
    PCOPYDATASTRUCT PRawData = (PCOPYDATASTRUCT)Message.LParam;
    if (PRawData && PRawData->cbData)
      Message.Result = DoRead((HWND)Message.WParam, PRawData->lpData, PRawData->cbData);
    else
      Message.Result = false;
  }
  else
    Message.Result = DefWindowProc(FSenderHandle, Message.Msg, Message.WParam, Message.LParam);
}
 
//---------------------------------------------------------------------------
bool TShaiCopyDataMessager::DoRead(HWND DataSender, void *Data, int DataLen)
{
  bool Result = false;
  if (FOnRead)
    Result = FOnRead(this, DataSender, Data, DataLen);
 
  return Result;
}

//---------------------------------------------------------------------------

Code c++ :
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
void __fastcall TSystemManipForm::BtnCopyDataWhoIAmClick(TObject *Sender)
{
  if ( ! FCopyDataMessager)
  {
    FCopyDataMessager = new TShaiCopyDataMessager();
    FCopyDataMessager->OnRead = CopyDataMessagerReadEventHandler;
  }
 
  EditCopyDataWhoIAm->Text = UIntToStr((unsigned)FCopyDataMessager->SenderHandle);
}
 
//---------------------------------------------------------------------------
bool __fastcall TSystemManipForm::CopyDataMessagerReadEventHandler(TObject *Sender, HWND DataSender, void *Data, int DataLen)
{
  bool Result = false;
 
  TShaiCopyDataMessager* Messager = dynamic_cast<TShaiCopyDataMessager*>(Sender);
  if (Messager)
  {
    String S1, S2, S3;
 
    int OffSet = Messager->ReadString(Data, S1);
    Data = (Byte*)Data + OffSet;
    OffSet = Messager->ReadString(Data, S2);
    Data = (Byte*)Data + OffSet;
    OffSet = Messager->ReadString(Data, S3);
 
    MemoCopyDataRecv->Lines->Add(S1 + S2 + S3);
    Result = Pos("bad", S2) <= 0;
  }
 
  return Result;
}
 
//---------------------------------------------------------------------------
void __fastcall TSystemManipForm::BtnCopyDataSendToClick(TObject *Sender)
{
  if ( ! FCopyDataMessager)
  {
    FCopyDataMessager = new TShaiCopyDataMessager();
    FCopyDataMessager->OnRead = CopyDataMessagerReadEventHandler;
  }
 
  FCopyDataMessager->RecipientHandle = (HWND)StrToInt(EditCopyDataSendTo->Text);
  FCopyDataMessager->BeginWrite();
  FCopyDataMessager->WriteString("La Chaine est : \"");
  FCopyDataMessager->WriteString(EditCopyDataSendToText->Text);
  FCopyDataMessager->WriteString("\" !");
  if ( ! FCopyDataMessager->EndWrite())
    MemoCopyDataRecv->Lines->Add("bad est refusé");
}
//---------------------------------------------------------------------------

Code dfm :
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
object BtnCopyDataWhoIAm: TButton
  Left = 3
  Top = 3
  Width = 75
  Height = 25
  Caption = 'Who I Am ?'
  TabOrder = 0
  OnClick = BtnCopyDataWhoIAmClick
end
object EditCopyDataWhoIAm: TEdit
  Left = 84
  Top = 5
  Width = 121
  Height = 21
  Alignment = taRightJustify
  NumbersOnly = True
  ReadOnly = True
  TabOrder = 1
  Text = '?'
end
object BtnCopyDataSendTo: TButton
  Left = 3
  Top = 34
  Width = 75
  Height = 25
  Caption = 'Send To'
  TabOrder = 2
  OnClick = BtnCopyDataSendToClick
end
object EditCopyDataSendTo: TEdit
  Left = 84
  Top = 36
  Width = 121
  Height = 21
  Alignment = taRightJustify
  NumbersOnly = True
  TabOrder = 3
  Text = '?'
end
object EditCopyDataSendToText: TEdit
  Left = 211
  Top = 36
  Width = 121
  Height = 21
  TabOrder = 4
  Text = 'Bonjour !'
end
object MemoCopyDataRecv: TMemo
  Left = 3
  Top = 65
  Width = 329
  Height = 274
  Lines.Strings = (
    'Receive :')
  ReadOnly = True
  ScrollBars = ssBoth
  TabOrder = 5
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

Halte à la ségrégation des Cinémas, VO sur Paris, VF en Banlieue, Abonnement résilié !
ShaiLeTroll est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 14/12/2012, 19h21   #9
Andnotor
Rédacteur/Modérateur
 
Avatar de Andnotor
 
Inscription : septembre 2008
Messages : 2 857
Détails du profil
Informations forums :
Inscription : septembre 2008
Messages : 2 857
Points : 5 967
Points : 5 967
Citation:
Envoyé par ShaiLeTroll Voir le message
WM_COPYDATA est bloquant, cela a un avantage car son retour permet de vérifier la bonne reception\compréhension du message par le receveur
C'est clair qu'à partir du moment où un dialogue est nécessaire, cette technique n'est pas applicable. Ce n'est pas pour rien que j'ai pris l'exemple de WH_CALLWNDPROCRET dont la donnée ne peut être modifiée

Maintenant, mon but était vraiment de faire de l'asynchrone...

Citation:
Envoyé par ShaiLeTroll Voir le message
Sinon, pourquoi ne pas avoir utiliser BinToHex qui aurait fait le travail de conversion en Hexa bien plus rapidement que les nombreuses réallocation\concaténation de Data.Bytes
J'aurais pu Comme j'aurais pu aussi définir une chaîne de 2x la taille de la donnée et travailler sur l'index du caractère.
Mais je suis un pervers et au départ je comptais convertir un octet sur 10 bits (actuellement 16 bits) pour utiliser au mieux les 255 octets à disposition. Puisqu'une des contraintes est : pas de byte à "0" son codage aurait été 1000010000 (en ajoutant toujours "1"). Mais ça devenait un peu compliqué et le tuto n'aurait plus été "Confirmé", mais "Expert"

Mais j'aurais dû plus simplifier !

Citation:
Envoyé par ShaiLeTroll Voir le message
Je passe un HWND qui servirait ensuite pour un échange entre A et B d'un GUID servant d'ID de session qui aboutit à l'authentification, c'est déjà plus difficile à choper (un hook)
J'ai aussi utiliser ce genre de technique en envoyant un message que l'application ne sait pas gérer (RegisterWindowMessage, donc inconnu par la cible)
mais récupéré par hook pour exécuter du code dans le processus cible
__________________
Mes tutoriels Delphi
Andnotor est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/12/2012, 18h29   #10
MIWAN
Membre du Club
 
Inscription : mars 2007
Messages : 96
Détails du profil
Informations forums :
Inscription : mars 2007
Messages : 96
Points : 64
Points : 64
c'est Noël
Dans l'endroit et au bon moment que ce tutoriel car je passais des heures pour apprendre quelques choses sur les HOOK(s).

Merci pour ce tutoriel et les interventions des chères membres
MIWAN est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Actualité déjà publiée
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 17h21.


 
 
 
 
Partenaires

Hébergement Web