Autor |
Beitrag |
CherryDT
Hält's aus hier
Beiträge: 4
|
Verfasst: So 19.04.09 15:15
Ich finde leider keinen wirklich treffenden Titel ^^
Also es geht um folgendes: Ich habe mir vor ein paar Tagen Delphi 5 besorgt. Ja, ganz bewusst diese alte Version, fragt aber bitte nicht wofür ^^ ist ziemlich kompliziert das ganze.
Ich brauche einige Funktionen, die für mich auf VCL-Controls zugreifen. Diese exportiere ich in einer DLL, die dann von meinem in einer anderen Sprache geschriebenen Programm geladen wird.
Als erstes brauche ich eine Funktion, die mir den Inhalt der ersten 3 Panels einer TStatusBar liefert. Ich habe nun folgendes gebastelt:
Delphi-Quelltext 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:
| library vclxchg;
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ComCtrls;
function RMGetStatusBarContent(control: TStatusBar; part1, part2, part3: PShortString; bufflen: Integer): Boolean; stdcall;
begin RMGetStatusBarContent := false; if control = nil then Exit; if control.Panels.Count < 3 then Exit; part1^ := copy(control.Panels.Items[0].Text, 0, bufflen); part2^ := copy(control.Panels.Items[1].Text, 0, bufflen); part3^ := copy(control.Panels.Items[2].Text, 0, bufflen); RMGetStatusBarContent := true; end;
exports
RMGetStatusBarContent;
{$R *.RES}
begin end. |
Funktioniert aber nicht. Es kommt eine Access Violation, dann meldet Windows, die Anwendung hätte ein Problem festgestellt. Klicke ich dann auf "Nicht senden", um das Programm zu beenden, kommt eine Messagebox "Corrupt String A" und die Problem-festgestellt-Meldung erscheint erneut.
Die Funktion SOLLTE:
in "control" einen Pointer auf eine TStatusBar-Struktur entgegennehmen
in "part1", "part2" und "part3" je einen Pointer auf einen (noch leeren) nullterminierten String entgegennehmen
in "bufflen" die Länge der 3 Strings (sie haben alle die selbe), also eigentlich die Größe des bereitgestellten Speichers, entgegennehmen
in den Speicher, auf den "part1", "part2" und "part3" zeigen, jeweils den Inhalt der Panels hineinschreiben
im Erfolgsfall true, sonst false zurückgeben.
Wäre sehr nett, wenn ihr mir helfen könntet.
mfG Cherry
Moderiert von matze: Code- durch Delphi-Tags ersetzt
|
|
dummzeuch
      
Beiträge: 593
Erhaltene Danke: 5
Delphi 5 ent, Delphi 6 bis Delphi XE8 pro
|
Verfasst: So 19.04.09 21:39
Moderiert von Narses: Komplett-Zitat des letzten Beitrags entfernt.
Ich wuerde an Deiner Stelle zunaechst mal die Strings auf Konstanten setzen, ohne dabei auf die TStatusBar zuzugreifen, um herauszufinden, welcher der Parameter das Problem ausloest. Meine Vermutung ist, dass gar keine PShortString uebergeben werden.
Ah, ich lese gerade, dass das aufrufende Programm von Dir stammt. Zeig doch mal den aufrufenden Code (und schreib dabei, welche Sprache das ist, falls das nicht eindeutig aus dem Source hervorgeht).
twm
|
|
CherryDT 
Hält's aus hier
Beiträge: 4
|
Verfasst: So 19.04.09 22:28
Naja, ich weiß nicht, wegen dem PShortString... Also ich hatte gehofft, dass es das ist. Es sollte ein Pointer auf einen Nullterminierten String sein. Ich dachte zuerst aber an PChar, bloß funktioniert da die Zuweisung nicht irgendwie.
Mein Code (FreeBASIC):
Quelltext 1: 2: 3:
| Var sb = VCLXChg.GetWinControl(awf.hWnd) ' in afw.hWnd steckt das Window Handle der Status Bar Dim As ZString * 255 p1, p2, p3 VCLXChg.RMGetStatusBarContent(sb, @p1, @p2, @p3, 255) |
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:
| Namespace VCLXChg Dim Shared Handle As Any Ptr Dim Shared RMGetStatusBarContent As Function StdCall (control As TStatusBar Ptr, part1 As ZString Ptr, part2 As ZString Ptr, part3 As ZString Ptr, bufflen As Integer) As Boolean Function Load() As Boolean Handle = LoadLibrary(*CPtr(ZString Ptr, @XChg.LoaderPath(0)) & "\vclxchg.dll") If Handle = NULL Then Return FALSE RMGetStatusBarContent = GetProcAddress(Handle, "RMGetStatusBarContent") If RMGetStatusBarContent = NULL Then Return FALSE Return TRUE End Function Function UnLoad() As Boolean Return FreeLibrary(Handle) End Function Private Function PropEnumProcEx1(hwnd As HWND, lpszString As LPTSTR, hData As Integer, dwData As ULONG_PTR) As BOOL If Left(*lpszString, 10) = "ControlOfs" Then *CPtr(Any Ptr Ptr, dwData) = hData Return FALSE EndIf Return TRUE End Function Function GetWinControl(hWnd As HWND) As TWinControl Ptr Dim ret As TWinControl Ptr EnumPropsEx(hWnd, @PropEnumProcEx1, @ret) Return ret End Function End Namespace |
|
|
dummzeuch
      
Beiträge: 593
Erhaltene Danke: 5
Delphi 5 ent, Delphi 6 bis Delphi XE8 pro
|
Verfasst: Mo 20.04.09 07:34
Hi,
CherryDT hat folgendes geschrieben : | Naja, ich weiß nicht, wegen dem PShortString... Also ich hatte gehofft, dass es das ist. Es sollte ein Pointer auf einen Nullterminierten String sein. Ich dachte zuerst aber an PChar, bloß funktioniert da die Zuweisung nicht irgendwie.
Mein Code (FreeBASIC):
|
Dann nimm mal wieder PChar und aendere die Zuweisung ab:
Delphi-Quelltext 1:
| StrPCopy(ZielPChar, Quellstring); |
Ob das funktioniert, haengt stark davon ab, wie FreeBasic die Strings uebergibt. Die Wahrscheinlichkeit, dass es ausgerechnet PShortString uebergibt, ist sehr gering, PChar ist wahrscheinlicher. Um das herauszufinden koenntest Du sie mal mit einem bekannten Text vorbelegen und sie in Delphi auslesen. Wenn Du Pech hast, ist ein Zeichen in FreeBasic nicht ein Byte lang sondern z.B. wg. Unicode 2 Zeichen, dann wird die Zuweisung komplizierter.
twm
|
|
CherryDT 
Hält's aus hier
Beiträge: 4
|
Verfasst: Mo 20.04.09 08:12
Vielen Dank, das scheint genau das zu sein, was ich gesucht habe. Ich kanns jetzt leider nicht gleich probieren, hoffe aber, dass auch die Art stimmt, wie ich die TStatusBar übergebe...
Ja, FreeBASIC übergibt in diesem Fall den Pointer (@) auf den ZString - nullterminierter ANSI-String, hier nur aus Nullen bestehend - , den ich 255 (inkl. Terminator 256) Bytes groß gemacht habe.
Danke!
mfG Cherry
|
|
|