TMagnetic Pascal Unit für C++Builder 2009?
-
Hallo. Ich möchte gern wie bei Winamp realisieren das die Forms meiner Anwendung bei Näherung wie magnetisch angezogen werden und dann an der anderen Form kleben und sich mit bewegen.
Ich habe dafür günstigerweise bei torry die Komponente TMagnetic Class (2009) gefunden. Diese besteht jedoch nur aus einer .pas Datei und .dcu. Wie erhalte ich daraus eine .hpp? Gibt es gar eine einfache C++Builder2009 Lösung?
-
.pas-Datei zum Projekt hinzufügen.
-
Oh so einfach. Danke schön!
Ich habe es entsprechend dem Beispiel umgesetzt, scheitre aber scheinbar ein einer Funktion, da dort in der Funktion als Parameter eine Funktion aufgerufen wird.
Pascal steht das
// Code aus der Unit Magnet.pas TSubClass_Proc = function(lng_hWnd: HWND; uMsg: Integer; var Msg: TMessage; var bHandled: Boolean) : boolean; MagneticWndProc: TSubClass_Proc; TMagnetic = class public function AddWindow(Handle: HWND; hWndParent: HWND; [b][u]var FuncPointer : TSubClass_Proc[/u][/b]): Boolean; end; // Ende // Beispielform verwendet das dann so procedure TfrmParent.FormShow(Sender: TObject); begin if Assigned(MagneticWnd) then begin // Register main window as a serviced window of TMagnetic Class MagneticWnd.AddWindow(Self.Handle, 0, MagneticWndProc); end; end;
ich mache dies dann ebenfalls so:
// In Magnet.hpp steht dann bool __fastcall AddWindow(HWND Handle, HWND hWndParent, TSubClass_Proc &FuncPointer); // In meiner Form steht das TSubClass_Proc MagneticWndProc; void __fastcall TForm1::FormShow(TObject *Sender) { if (MagneticWnd) { MagneticWnd->AddWindow(Handle, 0, MagneticWndProc); } }
Er sagt mir dann allerdings
[ILINK32 Fehler] Error: Nicht auflösbares externes '__fastcall Magnetic::TMagnetic::AddWindow(void *, void , bool __fastcall ()(void *, int, Messages::TMessage&, bool&)&)' referenziert von UNIT1.OBJ
Kann mir jemand helfen wie man das realisieren kann?
-
Wenn es eine Komponente, wäre es doch ratsamer, diese erstmal zu installieren:
- Neues Package erstellen.
- Zu diesen die pas Datei hinzufügen.
- In den Optionen muss noch eingestellt werden, das auch die C++ Dateien erzeugt werden sollen. Weiss aber aus dem Kopf nicht, wo genau das ist , aber diese Einstellung gibt es (selbst schon benutzt, ev. beim Linker).
- Package installieren.
-
Es ist keine visuelle Komponente. Es ist eine Klasse die man einbindet und dann damit arbeitet. In der Komponente und im beiliegenden Beispiel wird gezeigt wie man dann seine TForm aufbereiten muss, damit es funktioniert.
Es wird kein Code wie so etwas verwendet:
initialization RegisterClasses([TComponentenName]); finalization end.
Frage besteht damit weiterhin. Wie übergebe ich der Funktion AddWindow() als Parameter die Funktion MagneticWndProc().
-
TM schrieb:
Kann mir jemand helfen wie man das realisieren kann?
Das ist ein Mangling-Problem. Ersetze in den Projektoptionen das Makro NO_STRICT durch STRICT.
-
Oh, ja das scheint zu helfen, vielen Dank!
Ich komme mit dieser Funktion aber nicht ganz klar
var MagneticWndProc : TSubClass_Proc; // procedure to subclass form's window procedure for magnetic effect. procedure TfrmChild3.WndProc(var Msg_ : TMessage); var Handled: boolean; begin if not Assigned(MagneticWndProc) then begin inherited WndProc(Msg_); exit; end; if (Msg_.Msg = WM_SYSCOMMAND) or (Msg_.Msg = WM_ENTERSIZEMOVE) or (Msg_.Msg = WM_EXITSIZEMOVE) or (Msg_.Msg = WM_WINDOWPOSCHANGED) or (Msg_.Msg = WM_COMMAND)then begin inherited WndProc(Msg_); MagneticWndProc(Self.Handle, Msg_.Msg, Msg_, Handled); end else if (Msg_.Msg = WM_MOVING) or (Msg_.Msg = WM_SIZING) then begin MagneticWndProc(Self.Handle, Msg_.Msg, Msg_, Handled); if not Handled then inherited WndProc(Msg_); end else inherited WndProc(Msg_); end;
Da C++Builder2009 zu "MagneticWndProc : TSubClass_Proc;" doppelten Bezeichner meint, da dieser auch global in TForm1 vorhanden ist, habe ich dies in TForm2 zu "MagneticWndProc Sub" umbenannt.
So habe ich das dann realisiert
void __fastcall TForm2::WndProc(Messages::TMessage &Message) { bool Handled; if (!MagneticWndProcSub) { TForm::WndProc(Message); return; } if ((Message.Msg == WM_SYSCOMMAND) || (Message.Msg == WM_ENTERSIZEMOVE) || (Message.Msg == WM_EXITSIZEMOVE) || (Message.Msg == WM_WINDOWPOSCHANGED) || (Message.Msg == WM_COMMAND)) { TForm::WndProc(Message); MagneticWndProcSub(Handle, Message.Msg, Message, Handled); return; } else if ((Message.Msg == WM_MOVING) || (Message.Msg = WM_SIZING)) { MagneticWndProcSub(Handle, Message.Msg, Message, Handled); if (!Handled) { TForm::WndProc(Message); return; } } TForm::WndProc(Message); }
Wenn ich die TForm2 aber aufrufe, dann erhalte ich ein "Zugriffsverletzung bei Adresse 500451D in Modul 'rtl120.bpl'. LEsen von Adresse 00000008."
Kann mir jemand vielleicht gar meinen Fehler sagen?
-
Erledigt, habe die Funktion nochmal neu geschrieben und nun klappt alles