Autor Beitrag
CherryDT
Hält's aus hier
Beiträge: 4



BeitragVerfasst: 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:

ausblenden 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 user profile iconmatze: Code- durch Delphi-Tags ersetzt
dummzeuch
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 593
Erhaltene Danke: 5


Delphi 5 ent, Delphi 6 bis Delphi XE8 pro
BeitragVerfasst: So 19.04.09 21:39 
Moderiert von user profile iconNarses: 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 Threadstarter
Hält's aus hier
Beiträge: 4



BeitragVerfasst: 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):

ausblenden 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)


ausblenden volle Höhe 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:
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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 593
Erhaltene Danke: 5


Delphi 5 ent, Delphi 6 bis Delphi XE8 pro
BeitragVerfasst: Mo 20.04.09 07:34 
Hi,

user profile iconCherryDT hat folgendes geschrieben Zum zitierten Posting springen:
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:

ausblenden 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 Threadstarter
Hält's aus hier
Beiträge: 4



BeitragVerfasst: 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