Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Übersetzung Class MagneticWindow (https://www.delphipraxis.net/78689-uebersetzung-class-magneticwindow.html)

EWeiss 10. Okt 2006 21:41

Re: Übersetzung Class MagneticWindow
 
Zitat:

Zitat von Union
In der Standardkonfiguration heißt es result (extended Syntax). Das hat den Vorteil, dass man die Funktion umbenennen kann, ohne den evtl. verwendeten Namen 20 Mal ebenfalls ändern zu müssen. Und es ermöglicht Rekursion, wenn gewollt.

Danke habs geändert .. kann es aber noch nicht prüfen
da ich noch nicht bis hierher vordringen kann!

Die Klasse ist bis auf ein paar kleinigkeiten übersetzt.
Befinde mich nun in der Form und rufe diese mit diesen parametern auf.

Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
Var
  m_Magnetic: TMagnetic;
begin
  m_Magnetic := TMagnetic.Create;    // Class TMagnetic Initialisieren
  m_Magnetic.AddWindow(Form1.Handle); // Main Handle (Hauptanwendung) addieren

end;

end.
Beim ersten aufruf direkt der erste Fehler!

Delphi-Quellcode:
    // Validate windows
    If (IsWindow(Handle) And (IsWindow(hWndParent) Or (hWndParent = 0))) Then
        begin
        // Increase count
        inc(m_lWndCount);
        // Resize arrays
//        ReDim Preserve m_uWndInfo(0 To m_lWndCount);
//        ReDim Preserve m_rcWnd(0 To m_lWndCount);

        // Add info
        With m_uWndInfo[m_lWndCount] do
          begin
            hwnd := Handle;
            hWndParent := hWndParent;
          end;
Er springt bis hwnd := Handle; dann gibt es einen AV
Delphi-Quellcode:
m_uWndInfo   : array of TWND_INFO;
Delphi-Quellcode:
Type
 PWND_INFO = ^TWND_INFO;
    TWND_INFO = record
    hwnd      : Integer;
    hWndParent : Integer;
    Glue      : Boolean;
 end;
Das ist die Type welche angesprochen wird.
Dieser wird durch ReDim Preserve m_uWndInfo(0 To m_lWndCount); verursacht
Das Array wurde noch nicht redimensioniert!
Habe noch keine umsetzungs möglichkeit dafür gefunden!


Doch gerade!
Zitat:

REDIM
To allocate dynamic variables, use New or GetMem. For REDIM PRESERVE, allocate memory for the new variable and copy the old values to the new memory, and erase the old variable with Dispose or FreeMem. A ReAllocMem function is also available.
Wie müßte die funktion dann aussehen?
für ReDim Preserve m_uWndInfo(0 To m_lWndCount);


Gruß

EWeiss 10. Okt 2006 21:45

Re: Übersetzung Class MagneticWindow
 
Zitat:

Zitat von Muetze1
Du hast 100%ig zIdx nicht nochmal woanders verwendet bzw. deklariert? z.B. als Funktionsname?

Delphi-Quellcode:
function TMagnetic.zIdx(lng_hWnd: Integer; bAdd: Boolean = False): Integer;
//Get the sc_aSubData() array index of the passed hWnd
//Get the upper bound of sc_aSubData()
//If you get an error here, you're probably Subclass_AddMsg-ing before Subclass_Start

begin
    zIdx := UBound(sc_aSubData);
     While zIdx >= 0 Do                //Iterate through the existing sc_aSubData() elements
        With sc_aSubData[zIdx] do
        begin
            If (hwnd = lng_hWnd) Then  //If the hWnd of this element is the one we're looking for
            begin
              If (Not bAdd) Then       //If we're searching not adding
                Exit;                  //Found
              If (hwnd = 0) Then       //If this an element marked for reuse.
              begin
                If (bAdd) Then         //If we're adding
                    Exit;
              end;
            End;
        End;
        dec(zIdx);                     //Decrement the index

End;
zIdx ist die funktion in der ich mich befinde.
Ansonsten wird sie nur im Header als privat nochmal aufgeführt!
function zIdx(lng_hWnd: Integer; bAdd: Boolean = False): Integer;

Gruß

Muetze1 10. Okt 2006 23:35

Re: Übersetzung Class MagneticWindow
 
Zu deinem REDIM Problem: SetLength()
Delphi-Quellcode:
  SetLength(Array, NeueLänge); // danach hat das Array von Low(Array) bis High(Array) Einträge - bzw. da es dynamisch ist von 0 bis Length(Array)-1
Zitat:

Zitat von EWeiss
Zitat:

Zitat von Muetze1
Du hast 100%ig zIdx nicht nochmal woanders verwendet bzw. deklariert? z.B. als Funktionsname?

zIdx ist die funktion in der ich mich befinde.
Ansonsten wird sie nur im Header als privat nochmal aufgeführt!
function zIdx(lng_hWnd: Integer; bAdd: Boolean = False): Integer;

Dann ist es klar, warum er ein Handle will. Das hatte ich vorhin übersehen. Dadurch wird auch dei Rekursionshinweise der anderen erklärlich. Die Lösung mit der Verwendung von Result hast du ja nun schon.

xaromz 10. Okt 2006 23:42

Re: Übersetzung Class MagneticWindow
 
Hallo,

hierzu
Delphi-Quellcode:
WMSZ_LEFT, WMSZ_TOPLEFT, WMSZ_BOTTOMLEFT:
  begin
      case Abs(rcTmp.x1 - x1) < SnapWidth of True:
       rcWnd.x1 := x1;
      end;
      case Abs(rcTmp.x1 - x2) < SnapWidth of true:
       rcWnd.x1 := x2;
      End;
   End;
fällt mir noch was ein:
Warum benutzt Du überhaupt bei einer boolschen Abfrage case?
So ist es doch viel logischer und einfacher zu verstehen:
Delphi-Quellcode:
WMSZ_LEFT, WMSZ_TOPLEFT, WMSZ_BOTTOMLEFT:
begin
  if Abs(rcTmp.x1 - x1) < SnapWidth then
    rcWnd.x1 := x1;

  if Abs(rcTmp.x1 - x2) < SnapWidth then
    rcWnd.x1 := x2;
end;
Gruß
xaromz

EWeiss 11. Okt 2006 00:24

Re: Übersetzung Class MagneticWindow
 
Warum benutzt Du überhaupt bei einer boolschen Abfrage case?
So ist es doch viel logischer und einfacher zu verstehen:
Delphi-Quellcode:
WMSZ_LEFT, WMSZ_TOPLEFT, WMSZ_BOTTOMLEFT:
begin
  if Abs(rcTmp.x1 - x1) < SnapWidth then
    rcWnd.x1 := x1;

  if Abs(rcTmp.x1 - x2) < SnapWidth then
    rcWnd.x1 := x2;
end;

Werde mir den Vorschlag mal durch den Kopf gehen lassen
Bei Vb ist ein Case Anweisung schneller als eine IF abfrage.

gruß

EWeiss 11. Okt 2006 00:43

Re: Übersetzung Class MagneticWindow
 
Delphi-Quellcode:
  SetLength(Array, NeueLänge); // danach hat das Array von Low(Array) bis High(Array) Einträge - bzw. da es dynamisch ist von 0 bis Length(Array)-1
Supi läuft jetzt durch bis zum nächsten Fehler.
Danke

Zitat:

Dann ist es klar, warum er ein Handle will. Das hatte ich vorhin übersehen. Dadurch wird auch dei Rekursionshinweise der anderen erklärlich. Die Lösung mit der Verwendung von Result hast du ja nun schon.
Jo habe das mit dem Result übernommen aber soweit bin ich mit meinen
Durchlauf noch nicht gekommen.

gruß

EWeiss 11. Okt 2006 01:15

Re: Übersetzung Class MagneticWindow
 
Delphi-Quellcode:
    // Validate windows
    If (IsWindow(Handle) And IsWindow(hWndParent)) Or (hWndParent = 0) Then
        begin
        // Increase count
        inc(m_lWndCount);
        // Resize arrays
        SetLength(m_uWndInfo, m_lWndCount);
//        ReDim Preserve m_uWndInfo(0 To m_lWndCount);
        SetLength(m_rcWnd, m_lWndCount);
//        ReDim Preserve m_rcWnd(0 To m_lWndCount);

        // Add info
        With m_uWndInfo[m_lWndCount -1] do
          begin
            hwnd := Handle;
            hWndParent := hWndParent;
          end;
Läuft jetzt durch bis an dieser stelle!
Bei ReDim Preserve funktioniert diese anweisung
Delphi-Quellcode:
With m_uWndInfo[m_lWndCount] do
Bei
Delphi-Quellcode:
SetLength(m_rcWnd, m_lWndCount);
muss ich den counter wieder um eins herabsetzen
Delphi-Quellcode:
With m_uWndInfo[m_lWndCount -1] do
ansonsten werden mir keine Daten übergeben.

Ich denke mal wenn Length(Array)-1 wird das so in Ordnung sein.

gruß

Union 11. Okt 2006 07:56

Re: Übersetzung Class MagneticWindow
 
Das liegt daran, dass in Delphi dynamische Arrays immer mit Index 0 beginnen. Bei SetLength(Array, 10) geht dann z.b. der Index von 0..9

xaromz 11. Okt 2006 08:50

Re: Übersetzung Class MagneticWindow
 
Hallo,

Du hast hier
Delphi-Quellcode:
        // Add info
        With m_uWndInfo[m_lWndCount -1] do
          begin
            hwnd := Handle;
            hWndParent := hWndParent; <---------
          end;
ein Problem. Deine Variable im Record heißt genauso wie die Variable, die Du zuweisen willst. Delphi benutzt dann zwei mal den Record-Member (geringste Sichtbarkeit).
Meist ist es sowieso besser, with zu vermeiden, dann spart man sich viel Ärger beim Debuggen (der Debugger kann innerhalb eines solchen Blocks Variableninhalte nicht anzeigen :evil: ).
Also so:
Delphi-Quellcode:
// Add info
m_uWndInfo[m_lWndCount -1].hwnd := Handle;
m_uWndInfo[m_lWndCount -1].hWndParent := hWndParent;
Gruß
xaromz

Muetze1 11. Okt 2006 09:05

Re: Übersetzung Class MagneticWindow
 
Zitat:

Zitat von EWeiss
Ich denke mal wenn Length(Array)-1 wird das so in Ordnung sein.

Darauf habe ich dich extra hingewiesen mit meinem Kommentar hinter dem SetLength()! Ansonsten nutze die Funktion High()

xaromz 11. Okt 2006 09:14

Re: Übersetzung Class MagneticWindow
 
Hallo,

eine grundsätzliche Anmerkung habe ich noch. Du benutzt reichlich kryptische Variablennamen (m_uWndInfo ist so ein Beispiel). Wenn Du auch nach zwei Wochen noch verstehen willst, was Dein Programm macht, dann solltest Du Dir vielleicht aussagekräftigere Namen ausdenken. Diese sind dann automatisch Teil der Dokumentation des Programms, d. h. der Quellcode wird selbstbeschreibend. Und Unterstriche in Variablennamen sind in Delphi sowieso verpönt. Übrigens können wir Dir auch besser helfen, wenn wir verstehen, was Du da schreibst :wink: .

Hilfreich ist möglicherweise der Object Pascal Style Guide.

Gruß
xaromz

Muetze1 11. Okt 2006 10:59

Re: Übersetzung Class MagneticWindow
 
Wieso kryptisch? Ich habe (intuitiv) seine Variablen so verstanden:

- Wenn es ein Klassenmember ist, dann kommt vorne ein "m_" als Präfix vor.
- Dann folgt der Typ. So ist ein Boolean in einer Klasse deklariert: m_bXXX, ein Long und nicht als Member: lngXXX

Und der Name dahinter gibt den Inhalt an sich an, also die Bedeutung. Der Typ und Deklarationsort sind zuvor definiert. Was ist daran unklar? Ok, das mit dem Unterstrich. Grundlegend könnte ich an seinen bisherigen Benennungen nichts wirklich schlechtes vorwerfen - da gibt es genug andere Beispiel wo gar nichts in der Richtung gesagt wird.

EWeiss 11. Okt 2006 13:05

Re: Übersetzung Class MagneticWindow
 
Zitat:

Zitat von Muetze1
Wieso kryptisch? Ich habe (intuitiv) seine Variablen so verstanden:

- Wenn es ein Klassenmember ist, dann kommt vorne ein "m_" als Präfix vor.
- Dann folgt der Typ. So ist ein Boolean in einer Klasse deklariert: m_bXXX, ein Long und nicht als Member: lngXXX

Und der Name dahinter gibt den Inhalt an sich an, also die Bedeutung. Der Typ und Deklarationsort sind zuvor definiert. Was ist daran unklar? Ok, das mit dem Unterstrich. Grundlegend könnte ich an seinen bisherigen Benennungen nichts wirklich schlechtes vorwerfen - da gibt es genug andere Beispiel wo gar nichts in der Richtung gesagt wird.

absolut korrect.
Ich konnte im ersten moment die argumentation wegen der benennung
auch nicht nachvollziehen.

@xaromz
Habe aber nichts gegen einzuwenden ihn auf den Pascal Style zu konvertieren.
das könnte man zum schluss erledigen, wenn es komplett durchgelaufen ist.

gruß

EWeiss 11. Okt 2006 13:11

Re: Übersetzung Class MagneticWindow
 
Also so:
Delphi-Quellcode:
// Add info
m_uWndInfo[m_lWndCount -1].hwnd := Handle;
m_uWndInfo[m_lWndCount -1].hWndParent := hWndParent;
Gutes argument.
Werde es ändern. ;)

Das verändern der Variablen(Namen) möchte ich erst in angriff wenn der erste Durchlauf
mal erfolgreich war.

Gruß

EWeiss 11. Okt 2006 13:28

Re: Übersetzung Class MagneticWindow
 
Altes aber dennoch neues Problem.

Gerate bei der Übergabe einer neuen SnapWidth in eine Endlosschleife.
Kann also irgendetwas mit der Property SnapWidth noch nicht stimmen.

Habe beide Varianten versucht.
Delphi-Quellcode:
    property SnapWidth: Integer read FSnapWidth write SetSnapWidth;
Delphi-Quellcode:
    property SnapWidth: Integer read GetSnapWidth write SetSnapWidth;
Die eine verursacht eine endlosschleife, die andere einen AV.

Hat sich erledigt!


gruß

EWeiss 11. Okt 2006 15:18

Re: Übersetzung Class MagneticWindow
 
Original
Code:
        'Convert the string from hex pairs to bytes and store in the machine code buffer
        i = 1
        Do While j < CODE_LEN
            j = j + 1
            sc_aBuf(j) = CByte("&H" & Mid$(sSubCode, i, 2)) 'Convert a pair of hex characters to an eight-bit value and store in the static code buffer array
            i = i + 2
        Loop                                               'Next pair of hex characters
Übersetzt.
Delphi-Quellcode:
        //Convert the string from hex pairs to bytes and store in the machine code buffer
        i := 1;
         While j < CODE_LEN Do
            inc(j);
            sc_aBuf[j] := byte(MidStr('$' + sSubCode, i, 2)); //Convert a pair of hex characters to an
                                                              //eight-bit value and store in the static code buffer array
            i := i + 2;
Delphi-Quellcode:
function MidStr(Const Str: String; From, Size: Word): String;
begin
  MidStr := Copy(Str, From, Size)
end;
Fehler!
Zitat:

[Pascal Error] Magnetic.pas(850): E2089 Invalid typecast
Wie kann ich den String MidStr('$' + sSubCode, i, 2); nach byte convertieren ?

gruß

Muetze1 11. Okt 2006 16:01

Re: Übersetzung Class MagneticWindow
 
1. wieder Result
2. Mit StrToInt() kannst du Zahlen in hexadezimaler Schreibweise konvertieren, wenn diese mit einer "$" eingeleitet werden. Sonst würde er sie in dezimaler Schreibweise konvertieren..

EWeiss 11. Okt 2006 16:16

Re: Übersetzung Class MagneticWindow
 
Zitat:

Zitat von Muetze1
1. wieder Result
2. Mit StrToInt() kannst du Zahlen in hexadezimaler Schreibweise konvertieren, wenn diese mit einer "$" eingeleitet werden. Sonst würde er sie in dezimaler Schreibweise konvertieren..

Delphi-Quellcode:
function MidStr(Const Str: String; From, Size: Word): String;
begin
  Result := Copy(Str, From, Size)
end;
Ist gewohnheit muss mich dran gewöhnen das die rückgabe .. Result ist. :)

Delphi-Quellcode:
sc_aBuf    : array [1..CODE_LEN] of Byte;
sc_aBuf[j] := Byte(StrToInt(MidStr('$' + sSubCode, i, 2)));
Wie oben schneidet er mit einen Wert vom string ab
Sollte '$55' sein gibt aber '$5' aus .AV
sc_aBuf[j] ist ein Array of byte.

So funktioniert das nicht. :(

gruß

EWeiss 11. Okt 2006 16:55

Re: Übersetzung Class MagneticWindow
 
Geht jetzt!
Waren ein paar probleme mit der Schleife.

Delphi-Quellcode:
        //Convert the string from hex pairs to bytes and store in the machine code buffer
        i := 1;
        j := 0;

         While j < CODE_LEN Do
          begin
            inc(j);
            sc_aBuf[j] := Byte(StrToInt('$' + MidStr(sSubCode, i, 2))); //Convert a pair of hex characters to an
                                                   //eight-bit value and store in the static code buffer array
            i := i + 2;
          end;
gruß

EWeiss 11. Okt 2006 17:35

Re: Übersetzung Class MagneticWindow
 
Habe die aktuelle Version noch mal hochgeladen.
Fehlte noch eine 'end else' abfrage in Subclass_Start.

Jetzt wird es mal wieder schwierig.

Delphi-Quellcode:
PATCH_0A = 186; //Address of the owner object
Delphi-Quellcode:
zPatchVal(VarPtr(sc_aBuf(1)), PATCH_0A, ObjPtr(Me))
VarPtr ??? , ObjPtr ???

und

Delphi-Quellcode:
procedure TMagnetic.zPatchVal(nAddr: Integer; nOffset: Integer; nValue: Integer);
//Patch the machine code buffer at the indicated offset with the passed value
begin
    RtlMoveMemory(nAddr + nOffset, nValue, 4);
End;
RtlMoveMemory ???

Edit:
Scheint das gleiche wie CopyMemory zu sein!
Code:
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (xDest As Any, xSource As Any, ByVal nbytes As Long)
gruß

EWeiss 11. Okt 2006 19:38

Re: Übersetzung Class MagneticWindow
 
Push..

:duck:
Niemand eine Idee ?

Vielleicht hilft das noch etwas!

Zitat:

Die Funktionen VarPtr, ObjPtr und StrPtr. Während erstere die Adresse einer Variablen zurückgibt,
liefert die ObjPtr-Funktion die Adresse einer Objektvariablen.
Über StrPtr greifen Sie direkt auf einen String zu, was auch nützlich sein kann,
wenn Sie beim Aufruf einer API-Funktion die Umwandlung von ANSI in Unicode vermeiden möchten.
gruß

Muetze1 11. Okt 2006 19:42

Re: Übersetzung Class MagneticWindow
 
Diese Anweisung fummelt im Arbeitsspeicher rum und ändert Bytes. Da die Compiler bestimmt nicht gleich sind (VB <-> Delphi), ist die Frage ob dieser Code überhaupt noch funktioniert. Daher ist eher die Frage, was soll der Code bewirken? Weil so kannst du ihn wohl nicht übernehmen. Daher müssen wir nach einer anderen Lösung mit gleichem Effekt suchen...

EWeiss 11. Okt 2006 19:48

Re: Übersetzung Class MagneticWindow
 
Zitat:

Zitat von Muetze1
Diese Anweisung fummelt im Arbeitsspeicher rum und ändert Bytes. Da die Compiler bestimmt nicht gleich sind (VB <-> Delphi), ist die Frage ob dieser Code überhaupt noch funktioniert. Daher ist eher die Frage, was soll der Code bewirken? Weil so kannst du ihn wohl nicht übernehmen. Daher müssen wir nach einer anderen Lösung mit gleichem Effekt suchen...

Korrekt deshalb oben die beschreibung was die pointer machen ;)
Die Variable VarPtr zeigt(gibt) die adresse von sc_aBuf(1)) zurück.

ObjPtr zeigt auf die Adresse von der erstellen 'object instance' wäre in VB die cMagnetic ob
es nun in Delphi die hInstance der Classe ist kann ich auch nicht sagen.

Deshalb schwierig ;)

Gruß

Muetze1 11. Okt 2006 20:13

Re: Übersetzung Class MagneticWindow
 
Zitat:

Zitat von EWeiss
Korrekt deshalb oben die beschreibung was die pointer machen ;)

Die Bedeutung war mir von der Benennung vorhin schon klar. Das Problem ist der Objektpointer. Der Code als gesamtes liest oder schreibt etwas von oder in die Objektinstanz. An der Stelle wo er dies tut klappt das vielleicht bei VB, aber ich denke wirklich nicht, dass es 1:1 übersetzt auch nur ansatzweise in Delphi klappen wird.

Daher die Frage: Nicht was machen die verwendeten Funktionen sondern, was soll der Code als gesamtes bewirken?

EWeiss 11. Okt 2006 20:30

Re: Übersetzung Class MagneticWindow
 
Zitat:

Zitat von Muetze1
Zitat:

Zitat von EWeiss
Korrekt deshalb oben die beschreibung was die pointer machen ;)

Die Bedeutung war mir von der Benennung vorhin schon klar. Das Problem ist der Objektpointer. Der Code als gesamtes liest oder schreibt etwas von oder in die Objektinstanz. An der Stelle wo er dies tut klappt das vielleicht bei VB, aber ich denke wirklich nicht, dass es 1:1 übersetzt auch nur ansatzweise in Delphi klappen wird.

Daher die Frage: Nicht was machen die verwendeten Funktionen sondern, was soll der Code als gesamtes bewirken?

Wenn du die Zeile meinst!
Delphi-Quellcode:
Call zPatchVal(VarPtr(sc_aBuf(1)), PATCH_0A, ObjPtr(Me))
Patscht die adresse von der erstellten Objekt Instanz in einen statischen Maschinencode Buffer.

Ich kann zwar die werte auslesen aber nicht so wie in Delphi dir genau sagen was sie bewirken
Das kann man in vb nicht debuggen.

Selbst von MS gibt es keine Documentation über diese Pointer was sie eigentlich tun.
Habe aber hier einen Link!

Hmm ! Nicht das die ganze sache jetzt hier scheitert.
wäre schade.

gruß

EWeiss 11. Okt 2006 20:45

Re: Übersetzung Class MagneticWindow
 
Die Function wir in AddWindow aufgerufen!

Zitat:

'-- Start subclassing
Call Subclass_Start(hWnd)
Call Subclass_AddMsg(hWnd, WM_ENTERSIZEMOVE)
Call Subclass_AddMsg(hWnd, WM_SIZING, [MSG_BEFORE])
Call Subclass_AddMsg(hWnd, WM_MOVING, [MSG_BEFORE])
Call Subclass_AddMsg(hWnd, WM_EXITSIZEMOVE)
Call Subclass_AddMsg(hWnd, WM_SYSCOMMAND)
Call Subclass_AddMsg(hWnd, WM_COMMAND)
Da bin ich zur zeit 'Subclass_Start'
Hier wird die Winproc gestartet und anschließend über Subclass_AddMsg
die Messagen addiert.

Ich muß nur noch durch die Subclass_Start dann ist die Classe funktions tüchtig.

Ansonsten wie im Thread 1
Die Classe emuliert die exakten Dockeigenschaften wie sie auch
in Winamp zur verfügung stehen.


EDIT:
ObjPtr übergibt die Klasseninstanz gibt es eine solche in Delphi ?
Die Adresse des aktuellen Objektes.

gruß

EWeiss 11. Okt 2006 23:09

Re: Übersetzung Class MagneticWindow
 
Habe nochmal im VB Forum nachgefragt wie man das Problem lösen könnte!

Hier die Antwort!

Code:
'Sub/Function....
'...
'Call zPatchVal(VarPtr(sc_aBuf(1)), PATCH_0A, ObjPtr(Me))
'...
'end Sub/Function

'VarPtr
'Die VarPtr-Funktion liefert Ihnen die Startadresse des Speicherbereichs zurück,
'in dem eine Variable (nicht notwendigerweise ihr Inhalt) gespeichert wird.

'ObjPtr
'Die ObjPtr-Funktion liefert Ihnen einen Zeiger auf das Interface eines instanzierten Objekts zurück.

'Hier ein Auszug aus der Offline MSDN (Me in der IDE tippen und F1)
'Das Schlüsselwort Me verhält sich wie eine implizit deklarierte Variable.
'Es steht allenProzeduren in einemKlassenmodul automatisch zur Verfügung.
'Wenn eine Klasse mehrere Instanzen haben kann, stellt Me eine Möglichkeit dar,
'um sich auf die jenige Instanz der Klasse zu beziehen, in der Code ausgeführt wird.

'Private Declare Sub RtlMoveMemory Lib "kernel32.dll" ( _
'                               ByRef Destination As Any, _
'                               ByRef Source As Any, _
'                               ByVal Length As Long)
'
'Private Sub zPatchVal(ByVal nAddr As Long, ByVal nOffset As Long, ByVal nValue As Long)
''Patch the machine code buffer at the indicated offset with the passed value
'   Call RtlMoveMemory(ByVal nAddr + nOffset, nValue, 4)
'End Sub
Code:
Es sieht so aus als würde ein Zeiger auf die aktuelle Instanz deiner Klasse in das Array sc_aBuf(), dessen Datentyp ich nicht kenne der aber vermutlich Long[4 byte] je Element ist, an die in PATCH_0A angegebene Byteposition kopiert wird.
Wie ich das nun in Delphi vernünfig umsetzen kann ?
Kein Ahnung..

gruß

Muetze1 12. Okt 2006 00:04

Re: Übersetzung Class MagneticWindow
 
Das bringt uns alles nicht weiter. Du kopierst einen Wert aus der Instanz in die Variable - das ist mir klar. Aber das können wir so nicht umsetzen - wie oft denn noch. Die Frage ist was der Code im Endeffekt bewirken soll. Was er da macht ist mir klar, aber die Frage ist: Was steht am Offset PATCH_0A der Instanz in VB? Was kopiert er da? Das ist die Frage. Selbst Me hatte ich mir schon gedacht. Ich kann dir den Code hier so in Delphi hinschreiben, da es für alles einen entsprechenden Code gibt - den würde ich hier auch ohne Probleme hinbekommen, aber er würde nix bewirken - naja. oder wahrscheinlich schon: einen Absturz. Die Frage, um das nochmals zu wiederholen, ist: Was bewirkt der Code im Endeffekt. Wozu braucht er den (unbekannten) Wert am Offset PATCH_0A der Instanz der Klasse. Was macht dieser Code? Hat es was mit den zuvor genannten Windows-Botschaften Behandlungsroutinen zu tun? Wenn ja, dann sag es, weil diese kannst du in Delphi einfach bedienen und handeln.

Nochmals zusammen gefasst: Der reine Code ist 1:1 so kovertierbar, aber er würde nicht das gleiche bewirken. Irgendwelche Offset Adressen die im internen Speicheraufbau der Instanzen rumwurschteln klappen so vllt. in VB, aber 120% nicht in Delphi, da hier an der Stelle was anderes steht. Daher ist die Frage: was steht an der Stelle in VB bzw. was soll der Code im ganzen bewirken (und damit meine ich nicht deine Klasse an sich als gesamtes).

EWeiss 12. Okt 2006 01:28

Re: Übersetzung Class MagneticWindow
 
Ich versuche es zu erklären und hoffe das es das ist was du meinst.

Es wird ein statischer MaschinenCode Buffer erstellt. sSubCode : string;
Die länge des String als Const declariert ist CODE_LEN = 197;

Am anfang der Function werden feste Positionen im Array festgelegt.

Delphi-Quellcode:
    PATCH_02                = 68;                 //Address of the previous WndProc
PATCH_03                = 78;                 //Relative address of SetWindowsLong
PATCH_06                = 116;                //Address of the previous WndProc
PATCH_07                = 121;                //Relative address of CallWindowProc
PATCH_0A               = 186;                //Address of the owner object
Bedeutet PATCH_0A befindet sich im sSubCode an der CODE_LEN Position (186). wert an dieser stelle in byte = 184
sc_aBuf(1) zeigt auf den speicheranfang vom sSubCode HEX = '$55' byte 85
der ObjPtr zeigt auf die Klasseninstanz.

Nun muß der wert der Klasseninstanz an die Position (sc_aBuf(1) + PATCH_0A) mit einer länge von 4 copiert werden.

Delphi-Quellcode:
procedure TMagnetic.zPatchVal(nAddr: Integer; nOffset: Integer; nValue: Integer);
//Patch the machine code buffer at the indicated offset with the passed value
begin
    // nAddr=sc_aBuf(1) + nOffset=PATCH_0A, ObjPtr=Klasseninstanz, 4
    CopyMemory(Pointer(nAddr + nOffset), Pointer(nValue), 4);
End;
Mit den anderen verhält es sich genauso sind festangelegte werte welche den Index im Array(sc_aBuf) repräsentieren.

Ich hoffe das reicht dir als erklärung..
Sorry das ich nicht verstanden habe was du eigentlich wolltest ;)

Edit:
Alle oben aufgeführte funktionen selbst die Winproc existieren nicht als code
in der Classe sondern als MaschinenCode im speicher.
Lediglich die Messagen werden im Code verwaltet.

gruß

Muetze1 12. Okt 2006 09:09

Re: Übersetzung Class MagneticWindow
 
Zitat:

Zitat von EWeiss
Alle oben aufgeführte funktionen selbst die Winproc existieren nicht als code
in der Classe sondern als MaschinenCode im speicher.
Lediglich die Messagen werden im Code verwaltet.

Wozu brauchst du dies? Wozu legst du Maschinencode hier in diesem Array ab und patcht die Instanzenadressen. Die Messagebehandlung und überschreiben der WndProc geht bei Delphi mit einfachsten OOP Mitteln, da brauchen wir sowas nicht. Ich möchte daher im ganz allgemeinen Worten wissen, was der Code bewirken soll. Was er macht und wie und wo er irgendwelche Daten hin- und herschreibt, das sehe ich am VB Code. Die Frage ist, wozu du den Code brauchst. Warum ist es nötig gewesen diesen Code bei deinem VB Programm einzufügen?

Elvis 12. Okt 2006 09:19

Re: Übersetzung Class MagneticWindow
 
Zitat:

Zitat von Muetze1
Zitat:

Zitat von EWeiss
Alle oben aufgeführte funktionen selbst die Winproc existieren nicht als code in der Classe sondern als MaschinenCode im speicher.
Lediglich die Messagen werden im Code verwaltet.

Wozu brauchst du dies? Wozu legst du Maschinencode hier in diesem Array ab und patcht die Instanzenadressen. Die Messagebehandlung und überschreiben der WndProc geht bei Delphi mit einfachsten OOP Mitteln, da brauchen wir sowas nicht.

Weshalb ich ihm empfahl sich erst mit der Sprache vertraut zu machen, bevor er ein VB Projekt portiert. ;)
Zitat:

Ich möchte daher im ganz allgemeinen Worten wissen, was der Code bewirken soll. Was er macht und wie und wo er irgendwelche Daten hin- und herschreibt, das sehe ich am VB Code. Die Frage ist, wozu du den Code brauchst. Warum ist es nötig gewesen diesen Code bei deinem VB Programm einzufügen?
Weil er ihn vllt. von irgendwo kopiert hat?
Oder weil die Pastamaschine VB tatsächlich solchen Krempel benötigt um irgendetwas hinzukriegen, das komplexer als eine Hello-world-MsgBox hinter einem ButtonClick ist?
Keine Ahnung ich sehe da nur kryptische Hieroglyphen und da vergeht mir ganz schnell die Lust weiter zu lesen, bin hier ganz xaromz' Meinung. ;)

EWeiss 12. Okt 2006 10:06

Re: Übersetzung Class MagneticWindow
 
Zitat:

Zitat von Muetze1
Zitat:

Zitat von EWeiss
Alle oben aufgeführte funktionen selbst die Winproc existieren nicht als code
in der Classe sondern als MaschinenCode im speicher.
Lediglich die Messagen werden im Code verwaltet.

Wozu brauchst du dies? Wozu legst du Maschinencode hier in diesem Array ab und patcht die Instanzenadressen. Die Messagebehandlung und überschreiben der WndProc geht bei Delphi mit einfachsten OOP Mitteln, da brauchen wir sowas nicht. Ich möchte daher im ganz allgemeinen Worten wissen, was der Code bewirken soll. Was er macht und wie und wo er irgendwelche Daten hin- und herschreibt, das sehe ich am VB Code. Die Frage ist, wozu du den Code brauchst. Warum ist es nötig gewesen diesen Code bei deinem VB Programm einzufügen?

Weil es in Vb mit Konventionellen mitteln in der IDE nicht möglich ist sein
Programm zu debuggen wenn sich eine solche Funktion 'Subclass' im Code befindet.
Deshalb der umweg über Maschinensprache damit man weiterhin an seinen Programm innerhalb
der IDE arbeiten kann... ohne sich mit abstürzen rumplagen zu müssen.

Er emuliert das Subclasing(Address of @WinProc) im Speicher das einzigste
was im Code ausgeführt wird ist die überprüfugn der Messagen.
Deshalb kommt es auch nicht mehr zu Abstürzen.

Delphi braucht das nicht da die Winproc in der IDE während des Programmierens
Debuggen nicht zum Absturz von Delphi führt.

gruß

EWeiss 12. Okt 2006 10:28

Re: Übersetzung Class MagneticWindow
 
Zitat:

Weil er ihn vllt. von irgendwo kopiert hat?
Oder weil die Pastamaschine VB tatsächlich solchen Krempel benötigt um irgendetwas hinzukriegen, das komplexer als eine Hello-world-MsgBox hinter einem ButtonClick ist?
Keine Ahnung ich sehe da nur kryptische Hieroglyphen und da vergeht mir ganz schnell die Lust weiter zu lesen, bin hier ganz xaromz' Meinung.
Klar habe ich den MaschinenCode String kopiert!
Woher soll er denn sonst kommen :-D

Du machst nur unterstellungen..
Lästerst über etwas wovon du nichts verstehst.
Hast noch nichts kreatives zum Thema beigetragen.

Deshalb PLONK.!
Keine weiteren Kommentare.

gruß

Muetze1 12. Okt 2006 11:24

Re: Übersetzung Class MagneticWindow
 
Zitat:

Zitat von EWeiss
Delphi braucht das nicht da die Winproc in der IDE während des Programmierens
Debuggen nicht zum Absturz von Delphi führt.

Ok, mit anderen Worten: Delphi braucht es nicht, es muss nicht portiert werden und es funktioniert mit den Delphi Hausmitteln. Ok, dann sollte sich das Problem somit in Luft aufgelöst haben.

EWeiss 12. Okt 2006 11:43

Re: Übersetzung Class MagneticWindow
 
Zitat:

Zitat von Muetze1
Zitat:

Zitat von EWeiss
Delphi braucht das nicht da die Winproc in der IDE während des Programmierens
Debuggen nicht zum Absturz von Delphi führt.

Ok, mit anderen Worten: Delphi braucht es nicht, es muss nicht portiert werden und es funktioniert mit den Delphi Hausmitteln. Ok, dann sollte sich das Problem somit in Luft aufgelöst haben.

Diese Hinterfragungen waren doch nur auf dieses Ergebnis deinerseits aus oder ?

Habe das Projekt jemanden geschickt der beide Sprachen beherrscht.
Denke das sich ein weg finden wird es trotzdem auf die art weiterzuführen.

Auch Delphi arbeitet schneller mit MachinenCode als mit seiner Scriptsprache
welche vom compiler auch erst mal in Mc übersetzt werden muss.

Warum sonst verwendet Borland ASM innerhalb seiner bereitgestellten Units.

Trotzdem Danke für deine Hilfe.

Gruß

Muetze1 12. Okt 2006 11:58

Re: Übersetzung Class MagneticWindow
 
Zitat:

Zitat von EWeiss
Diese Hinterfragungen waren doch nur auf dieses Ergebnis deinerseits aus oder ?

Ja

Zitat:

Zitat von EWeiss
Denke das sich ein weg finden wird es trotzdem auf die art weiterzuführen.

Wie haben gerade festgestellt, dass es nicht mehr nötig ist.

Zitat:

Zitat von EWeiss
Auch Delphi arbeitet schneller mit MachinenCode als mit seiner Scriptsprache

Delphi ist keine Interpretersprache. Alles wird in Maschinensprache übersetzt vor der Ausführung. Es wird kein "Script" mehr interpretiert zur Laufzeit (so lange du es nicht explizit mit der .NET Technik machst).

Zitat:

Zitat von EWeiss
welche vom compiler auch erst mal in Mc übersetzt werden muss.

Dies geschieht vor der Ausführung deines Programmes - da ist dies schon alles erledigt. Wenn dein Programm startet, dann liegt es nur noch in Maschinencode vor.

Zitat:

Zitat von EWeiss
Warum sonst verwendet Borland ASM innerhalb seiner bereitgestellten Units.

Weil es an manchen Stellen Vorteile bringt - ABER: Borland weiss um die Umgebung und wie die Internas aufgebaut ist.

sailxia 12. Okt 2006 13:13

Re: Übersetzung Class MagneticWindow
 
Liste der Anhänge anzeigen (Anzahl: 1)
in delphi, SXMagnet is a very goog VCL component about MagneticWindow like winamp. but it's a share-ware.(http://www.spoonworx.com/Main.htm)

in VB, cMagneticWnd is very good class about MagneticWindow like winamp. and it's open source.

EWeiss 13. Okt 2006 23:19

Re: Übersetzung Class MagneticWindow
 
Muss trotzdem noch was loswerden.
An die welche etwas mehr von Delphi verstehen wie meinereins.

Warum funktioniert denn nun der VBHack nicht unter Delphi ?
Ich weiss es ;) Ihr auch ?

Es wurde mir mit einen Super Beispiel dokumentiert.
Schaut es euch selber an! VarPtrObjPtrInDelphi

Könnt selbst ihr noch etwas von lernen.
So hätte ich mir die Hilfe hier gern gewünscht. ;)
Will aber nicht undankbar sein!
War schon in Ordnung so ..

gruß

xaromz 14. Okt 2006 00:09

Re: Übersetzung Class MagneticWindow
 
Hallo,
Zitat:

Zitat von EWeiss
Könnt selbst ihr noch etwas von lernen.

Ich habe mir den Link mal angesehen.
So ganz hab' ich aber immer noch nicht verstanden, wozu ich das brauchen soll. VarPtr gibt also die Adresse einer Variablen zurück, also Addr() bzw @ in Delphi. Aber was ObjPtr soll, hab ich in meiner abendlichen Bierseligkeit nicht begriffen. Kann mich da jemand aufklären?

Gruß
xaromz

EWeiss 14. Okt 2006 00:59

Re: Übersetzung Class MagneticWindow
 
Zitat:

Zitat von xaromz
Hallo,
Zitat:

Zitat von EWeiss
Könnt selbst ihr noch etwas von lernen.

Ich habe mir den Link mal angesehen.
So ganz hab' ich aber immer noch nicht verstanden, wozu ich das brauchen soll. VarPtr gibt also die Adresse einer Variablen zurück, also Addr() bzw @ in Delphi. Aber was ObjPtr soll, hab ich in meiner abendlichen Bierseligkeit nicht begriffen. Kann mich da jemand aufklären?

Gruß
xaromz

Es hat niemand gesagt das du es brauchen sollst!
Sondern in dem Beispiel wird am Objekt(Sample) erklärt das auch
mit Pointern unter VB gearbeitet werden kann.

Zitat:

Dieses Tutorial soll klären wie man mit Hilfe der Funktionen VarPtr und ObjPtr aus VB6
die gleiche Funktionalität bekommt wie in anderen Programmiersprachen,
hier am Beispiel von Delphi.
Auszug aus meiner Mail!
Zitat:

Deine Frage war:
Wie man das in VB gebräuchliche ObjPtr(Me) nach Delphi übersetzt.
dabei hast du es eigentlich schon fast richtig gemacht
"Me" ist in Delphi einfach "Self"
Das Object ist die Instanz deiner Klasse, Quasi 'Self'
Obj ist deine Klasse 'Self' + ptr wäre quasi '@' ergebnis müßte dieses sein '@Self'

Warum die übersetzung von der Classe nicht funktioniert ist diese.

die Private Variable mValue im Delphi Beispiel ist 4 Bytes über dem Objekt
die Private Variable mValue im VBasic Beispiel ist 52Bytes über dem Objekt
damit wird klar, daß die Objekte in VB und Delphi unterschiedlich aufgebaut
sind.

Der VisualBasic-Hack ist also nur für VB zu gebrauchen.

Ich muss diesen nur weglassen lenke um auf eine Standard
WinProc und schon läuft die Classe.

Gruß


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:01 Uhr.
Seite 2 von 3     12 3      

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