Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Suche einen Fehlerfinder! (https://www.delphipraxis.net/133313-suche-einen-fehlerfinder.html)

himitsu 29. Apr 2009 16:00

Re: Suche einen Fehlerfinder!
 
Zitat:

Delphi-Quellcode:
TStringRecord=record
  var1:string[255];
end;

Sicher daß es nicht so sein sollte?
Delphi-Quellcode:
TStringRecord=record
  var1: array[1..255] of Char;
end;

wie ist denn das, was DllStructCreate erstellt intern aufgebaut?

LDericher 29. Apr 2009 16:03

Re: Suche einen Fehlerfinder!
 
Cool! Die Glaskugel will ich auch! :-P

Nur Leider gibt es jetzt Schwachsinn^^

Meine Senderfunktion:
Delphi-Quellcode:
function _SendData(vData, ReceiverTitle:string):boolean;
type
  TStringRecord=record
    var1:string;
  end;
  TlParamRecord=record
    none,
    count:DWord;
    Pointer:Pointer;
  end;
var
  CDString:TStringRecord;
  vs_cds:TlParamRecord;
  pCDString,
  pStruct:Pointer;
  strLen:integer;
  hwndRec:HWND;
const
  MHAdditionalIdentifier='_CAL987qwerty2468';
  WM_COPYDATA_MH=$4A;
begin
Result:=true;
if(Length(ReceiverTitle)=0)
  then Result:=false
  else begin
  ReceiverTitle:=ReceiverTitle+MHAdditionalIdentifier;
  strLen:=Length(vData);
  SetLength(CDString.var1, strLen);
  CDString.var1:=vData;
  pCDString:=@CDString;
  vs_cds.count:=strLen+1;
  vs_cds.Pointer:=pCDString;
  pStruct:=@vs_cds;
  hwndRec:=FindWindow('AutoIt v3 GUI', PAnsiChar(ReceiverTitle));
  if(hwndRec=0)
    then Result:=false
  else if(SendMessage(hWndRec, WM_COPYDATA_MH, 0, DWord(pStruct))<>0)
    then Result:=false;
  end;
end;
Die Original-Senderfunktion:
Code:
Func _SendData($vData,$ReceiverTitle)
   Local $strLen,$CDString,$vs_cds,$pCDString,$pStruct,$hwndRec
   
   If StringLen($ReceiverTitle) = 0 then Return SetError(1,1,0);Make sure the user has specified a title
   $ReceiverTitle&= $MHAdditionalIdentifier
   
   $strLen = StringLen($vData)
   $CDString = DllStructCreate("char var1[" & $strLen +1 & "]");the array to hold the string we are sending
   ;$CDString = DllStructCreate("char var1[255]");the array to hold the string we are sending
   DllStructSetData($CDString,1,$vData)
   
   $pCDString = DllStructGetPtr($CDString);the pointer to the string
   
   $vs_cds = DllStructCreate($StructDef_COPYDATA);create the message struct
   DllStructSetData($vs_cds,"count",$strLen + 1);tell the receiver the length of the string +1
   DllStructSetData($vs_cds,"pointer",$pCDString);the pointer to the string

   $pStruct = DllStructGetPtr($vs_cds)
   
   $hwndRec = WinGetHandle($ReceiverTitle)
   If $hwndRec = "" then
      $vs_cds = 0;free the struct
      $CDString = 0;free the struct
      Return SetError(1,2,0)
   EndIf
   

   DllCall("user32.dll", "lparam", "SendMessage", "hwnd", $hwndRec, "int", $WM_COPYDATA_MH, "wparam", 0, "lparam", $pStruct)
   If @error then
      $vs_cds = 0;free the struct
      $CDString = 0;free the struct
      return SetError(1, 3, 0) ;return 0 no data sent
   EndIf
   
   
   $vs_cds = 0;free the struct
   $CDString = 0;free the struct
   Return $strLen
EndFunc
Ja, wenn ich jetzt die Senderfunktion aufrufe und sage, er soll bitte "test" senden, wird nur "|)E" ausgegeben...
Also, ich probier jetz dann auch weiter, das Problem muss ja zu knacken sein ;)

LDer

LDericher 29. Apr 2009 16:18

Re: Suche einen Fehlerfinder!
 
Danke, himitsu: Das war's, der Keks geht an dich:
http://www.sinn-frei.com/zensiert/7324_27.jpg

Und nun habe ich aber das Gefühl, dass ich den folgenden Code vereinfachen kann:
Delphi-Quellcode:
  for I:=1 to strLen do
     CDString.var1[I]:=vData[I];
Ich wusste sogar mal, wie, aber hab das vergessen :wall: , wer mirs verrät, kriegt noch nen keks ;)

Gruß LDer

himitsu 29. Apr 2009 16:43

Re: Suche einen Fehlerfinder!
 
Zitat:

Zitat von Superwinger
Delphi-Quellcode:
function _SendData(vData, ReceiverTitle:string):boolean;
type
  TStringRecord=record
    var1:string;
  end;
Ja, wenn ich jetzt die Senderfunktion aufrufe und sage, er soll bitte "test" senden, wird nur "|)E" ausgegeben...

klar, weil du hier den Internen Pointer des Strings versendest ... drum auch das String[255]

und wenn dort immernoch ein Zeichen (also hier das Zeichen #4) vor dem "test" ankommt, dann nimm Array[1..255] of Char;

(oder probier es mal mit dem String "test56789012345678900123456789001234567890" ... denn vor dem String in String[255] versteckt sich noch ein Längenbyte und das wäre in dem letzen Fall "40 Zeichen", also #40 aka "(" )



[edit] OK, aber wo war die RedBox :shock:

ja, per Move bzw. MoveMemory/CopyMemory kopieren

Delphi-Quellcode:
MoveMemory(@CDString.var1, PChar(vData), Length(vData) + 1);
aber paß auf, daß der Text in vData nicht länger als 255 Zeichen ist

oder einfach notfalls abschneiden :stupid:
Delphi-Quellcode:
MoveMemory(@CDString.var1, PChar(vData), Min(Length(vData), 255) + 1);
und die +1 sind für die abschließende Null


[add2]
oder versuch mal ganz einfach direkt und ohne den Record darum :angel:
Delphi-Quellcode:
pCDString := PChar(vData);

LDericher 29. Apr 2009 16:54

Re: Suche einen Fehlerfinder!
 
Ja, Redbox :-D danke ;)

Du hast zwar schon deinen Keks aber ich halte meine Versprechen:

Kekse für die Ewigkeit: Ohrringe :lol:
http://www.porcelinazero.de/shop/images/CIMG1228.JPG

himitsu 29. Apr 2009 16:56

Re: Suche einen Fehlerfinder!
 
probier mal dieses hier :angel:
Delphi-Quellcode:
function _SendData(Const vData, ReceiverTitle: String): Boolean;
type
  TlParamRecord = packed Record
    none, count: DWord;
    Pointer: Pointer;
  end;
var
  vs_cds: TlParamRecord;
  hwndRec: HWND;
const
  MHAdditionalIdentifier = '_CAL987qwerty2468';
  WM_COPYDATA_MH = $4A;
begin
  if ReceiverTitle <> '' then begin
    vs_cds.count  := Length(vData);
    vs_cds.Pointer := PChar(vData);
    hwndRec := FindWindow('AutoIt v3 GUI', PChar(ReceiverTitle + MHAdditionalIdentifier));
    Result := (hwndRec <> 0) and (SendMessage(hWndRec, WM_COPYDATA_MH, 0, DWord(@vs_cds)) <> 0);
  end else Result := False;
end;

LDericher 30. Apr 2009 15:29

Re: Suche einen Fehlerfinder!
 
Funktioniert auch ;)

Also Danke nochmal, kann geschlossen werden und vllt. der CodeLib hinzugefügt werden :)

LDer

himitsu 30. Apr 2009 15:36

Re: Suche einen Fehlerfinder!
 
In Bezug auf eine Kompatibilität mit D2009+ sollten/könnten/müßten aber eventuell noch zwei Zeilen entsprechend geändert werden, also falls der Code auch dort mal laufen soll.
Delphi-Quellcode:
function _SendData(Const vData: AnsiString; Const ReceiverTitle: String): Boolean;

vs_cds.Pointer := PAnsiChar(vData);

du könntest die Lösung nun auch natürlich noch in das AutoIt-Forum rüberkopieren ... vielleicht braucht es da auch mal wer :angel:


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:58 Uhr.
Seite 2 von 2     12   

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz