Delphi-PRAXiS

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)

LDericher 29. Apr 2009 14:50


Suche einen Fehlerfinder!
 
Also, es geht um eine Übersetzung von AutoIt nach Delphi... Man sehe dazu HIER nach.

Wer den Fehler findet, kriegt einen Keks von mir!

MfG, Der LDer!

EWeiss 29. Apr 2009 14:53

Re: Suche einen Fehlerfinder!
 
Versuchs mal mit Packed Record

gruss Emil

hoika 29. Apr 2009 14:54

Re: Suche einen Fehlerfinder!
 
Hallo,

ist das VB ?
Dann musst du String[255] statt String verwenden.

*Keks haben wollen*


Heiko

EWeiss 29. Apr 2009 14:56

Re: Suche einen Fehlerfinder!
 
Zitat:

Zitat von hoika
Hallo,

ist das VB ?
Dann musst du String[255] statt String verwenden.

*Keks haben wollen*


Heiko

Kein VB!
Sieht mir eher nach PB - Powerbasic aus
Und da muss man den Record auf Packed setzen da hier das erste byte verschoben wird im Record.

gruss Emil

LDericher 29. Apr 2009 15:01

Re: Suche einen Fehlerfinder!
 
Bringt's leider beides nicht, aber danke für deine Idee schonmal

Das Zielprogramm reagiert noch nicht einmal mit Schwachsinn, und es ist AutoIt-Script, kein VB - denke aber, dass das recht ähnlich ist^^

Gruß vom LDer

nahpets 29. Apr 2009 15:16

Re: Suche einen Fehlerfinder!
 
Hallo,

ändere bitte mal den
Delphi-Quellcode:
TStringRecord=record
  var1:string;
end;
in
Delphi-Quellcode:
TStringRecord=record
  var1:string[255];
end;
und natürlich alles, was dann damit zusammenhängt.
Meine mich schwach daran erinnern zu können, bei Strings ohne Längenangabe in Records immer Probleme gehabt zu haben.

Einfacher werden die Änderungen vermutlich, wenn Du CDString in einen String änderst und auf var1 verzichtest.
Delphi-Quellcode:
function _SendData(vData, ReceiverTitle:string):boolean;
type
  // TStringRecord=record
  //   var1:string[255];
  // end;
  TlParamRecord=record
    none,
    count:word;
    Pointer:Cardinal;
  end;
var
  // CDString:TStringRecord;
  CDString:String;
  vs_cds:TlParamRecord;
  pCDString,
  pStruct:Cardinal;
  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);
  SetLength(CDString, strLen);
  // CDString.var1:=vData;
  CDString:=vData;
  pCDString:=integer(@CDString);
  vs_cds.count:=strLen+1;
  vs_cds.Pointer:=pCDString;
  pStruct:=integer(@vs_cds);
  hwndRec:=FindWindow('AutoIt v3 GUI', PAnsiChar(ReceiverTitle));
  if(hwndRec=0)
    then Result:=false
  else if(SendMessage(hWndRec, 74, 0, pStruct)=0)
    then Result:=false;
  end;
end;

LDericher 29. Apr 2009 15:21

Re: Suche einen Fehlerfinder!
 
Bringt auch nix... Meiner Meinung nach müsste das Empfängerprogramm doch wenigstens eine Ausgabe machen, da es ja eine Eingabe bekommen sollte per SendMessage...
Also zumindest irgendeine sinnfreie Zeichenkette ausspucken...? Oder nicht?

Na ja, ich bin hier langsam echt am verdreifeln -.-

LDer.

nahpets 29. Apr 2009 15:30

Re: Suche einen Fehlerfinder!
 
Hallo,

Empfängerprogramm: Welches Programm ist das? Wird es wirklich gefunden?
Sprich:
Delphi-Quellcode:
 
if(hwndRec=0) then begin
  ShowMessage('AutoIt v3 GUI wurde nicht gefunden.');
  Result:=false;
end else
if (SendMessage(hWndRec, 74, 0, pStruct)=0) then begin
  ShowMessage('SendMessage war erfolgreich');
  Result:=false;
end else begin
  ShowMessage('SendMessage war nicht erfolgreich!');
end;
Was bekommst Du hier zu sehen?

LDericher 29. Apr 2009 15:41

Re: Suche einen Fehlerfinder!
 
SendMessage liefert 0, kurz gesagt.

nahpets 29. Apr 2009 15:47

Re: Suche einen Fehlerfinder!
 
Hallo,

liegt der Fehler beim Empfänger?

An Stelle von
Delphi-Quellcode:
pCDString:=integer(@CDString);
vs_cds.count:=strLen+1;
vs_cds.Pointer:=pCDString;
pStruct:=integer(@vs_cds);
mal bitte das
Delphi-Quellcode:
pCDString:=DWord(@CDString);
vs_cds.count:=strLen+1;
vs_cds.Pointer:=pCDString;
pStruct:=DWord(@vs_cds);
Allerdings ist das was ich hier mache bestenfalls noch als :glaskugel: zu bezeichnen, 'ne vernünftige Idee zur Problemlösung habe ich nicht.

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:40 Uhr.

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