Komponenten bewegen
-
bcb beischpiel: wenn man eine in bcb eine komponente zur entwicklungszeit auf der form verschiebt, wird zuerst nur ein frame gezeichnet. dieser frame wird dann mit der maus bewegt und erst, wenn die maustaste los gelassen wird, ändert die komp ihre koordinaten. das gleiche passiert auch beim ändern der grösse mit der maus.
und genau das möchte ich auch in meiner anwendung erreichen.
hat jemand einen einsaz?
wie bekomme ich so einen rechteck?
-
Du musst auf dem Canvas (Device Context) der Form malen mit einer XOR-Operation.
-
bei deinem vorschlag gibt es ein kleines problemchen
beim malen auf der form, wird mein frame von untergeordneten komponenten (panels, edits, etc.) verdeckt. also es wird nur auf freien stellen der form gezeichnet
-
Hast du das schon ausprobiert? Hast du auch GetWindowDC() ausprobiert?
-
habe gerade das mit GetDC() selbst gebastelt. ist echt klasse geworden
quellcode ist etwas umfangreich, aber bei interesse werde hier ausstellen.
[ Dieser Beitrag wurde am 26.03.2003 um 03:20 Uhr von Xqgene editiert. ]
-
Original erstellt von Xqgene:
**quellcode ist etwas umfangreich, aber bei interesse werde hier ausstellen.
**Ja, würde mich interessieren. Wollte sowas selbst immer schonmal machen, bin aber nie dazu gekommen. Wär echt super.
-
also. ich habe eine komp von TCustomPanel abgeleitet und die funktionalität da rein gepackt. zum testen einfach ein neues projekt erstellen und .cpp und .h mit meinem code überschreiben. ist unter bcb6 gemacht worden (anpassungen für bcb1-5 ???)
die unit1.h
//--------------------------------------------------------------------------- #ifndef Unit1H #define Unit1H //--------------------------------------------------------------------------- #include <Classes.hpp> #include <Controls.hpp> #include <StdCtrls.hpp> #include <Forms.hpp> #include <ExtCtrls.hpp> #define SM_NONE 0 #define SM_LEFT 1 #define SM_RIGHT 2 #define SM_UP 4 #define SM_DOWN 8 #define SM_MOVE 128 //--------------------------------------------------------------------------- class TPan : public TCustomPanel { private: int FSizeMode; TRect FOldRect; TPoint FOldMousePos; TRect FPRegion; HDC HScreenDC; HGDIOBJ HObj; protected: virtual void __fastcall Paint(void); DYNAMIC void __fastcall MouseMove(Classes::TShiftState Shift, int X, int Y); DYNAMIC void __fastcall MouseDown(TMouseButton Button, Classes::TShiftState Shift, int X, int Y); DYNAMIC void __fastcall MouseUp(TMouseButton Button, Classes::TShiftState Shift, int X, int Y); public: __fastcall TPan(TComponent* Owner); }; //--------------------------------------------------------------------------- class TForm1 : public TForm { __published: // Von der IDE verwaltete Komponenten void __fastcall FormCreate(TObject *Sender); private: // Anwender-Deklarationen public: // Anwender-Deklarationen __fastcall TForm1(TComponent* Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TForm1 *Form1; //--------------------------------------------------------------------------- #endif
die unit1.cpp
//--------------------------------------------------------------------------- #include <vcl.h> #pragma hdrstop #include "Unit1.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; void DrawFrame(HDC hdc, TRect Rect, TRect Region); __fastcall TPan::TPan(TComponent* Owner) : TCustomPanel(Owner) { Top = 100; Left = 100; FSizeMode = SM_NONE; } void __fastcall TPan::MouseDown(TMouseButton Button, Classes::TShiftState Shift, int X, int Y) { if (Button != mbLeft) return; // nur mit links ;-) FOldMousePos = TPoint(X, Y); if (Y >= Height - 2) FSizeMode |= SM_DOWN; else if (Y <= 2) FSizeMode |= SM_UP; if (X >= Width - 2) FSizeMode |= SM_RIGHT; else if (X <= 2) FSizeMode |= SM_LEFT; if (FSizeMode == SM_NONE) FSizeMode = SM_MOVE; HScreenDC = GetDC(0); // screen dc holen HPEN HPen = CreatePen(PS_SOLID, 2, ColorToRGB(clBlack)); // pen erstellen HObj = SelectObject(HScreenDC, HPen); // pen aktivieren SetROP2(HScreenDC, R2_NOTXORPEN); // XOR Modus setzen TPoint p = ClientToScreen(TPoint(0, 0)); FOldRect = TRect(p.x, p.y, p.x + Width, p.y + Height); // Rect in dem gezeichnent werden darf berechnen FPRegion = ((TControl*)Parent)->ClientRect; TPoint p1, p2; p1 = ((TControl*)Parent)->ClientToScreen(TPoint(FPRegion.Left, FPRegion.Top)); p2 = ((TControl*)Parent)->ClientToScreen(TPoint(FPRegion.Right, FPRegion.Bottom)); FPRegion.Left = p1.x; FPRegion.Top = p1.y; FPRegion.Right = p2.x; FPRegion.Bottom = p2.y; // markierungsrect zeichnen (XOR) DrawFrame(HScreenDC, FOldRect, FPRegion); } void __fastcall TPan::MouseUp(TMouseButton Button, Classes::TShiftState Shift, int X, int Y) { if (FSizeMode != SM_NONE) { // alten rect ausblenden (XOR) DrawFrame(HScreenDC, FOldRect, FPRegion); // aufräumen HGDIOBJ HObjOld = SelectObject(HScreenDC, HObj); // original object widerherstellen DeleteObject(HObjOld); // pen-object löschen ReleaseDC(0, HScreenDC); // Screen freigeben FSizeMode = SM_NONE; // neue koordinaten/grösse zuweisen // swap int a; if (FOldRect.Left > FOldRect.Right) { a=FOldRect.Left; FOldRect.Left=FOldRect.Right; FOldRect.Right=a; } if (FOldRect.Top > FOldRect.Bottom) { a=FOldRect.Top; FOldRect.Top=FOldRect.Bottom; FOldRect.Bottom=a; } TPoint NewPos = ((TControl*)Parent)->ScreenToClient(TPoint(FOldRect.left, FOldRect.top)); SetBounds(NewPos.x, NewPos.y, FOldRect.Width(), FOldRect.Height()); } } void __fastcall TPan::MouseMove(Classes::TShiftState Shift, int X, int Y) { if (FSizeMode != SM_NONE) { // alten rect ausblenden (XOR) DrawFrame(HScreenDC, FOldRect, FPRegion); // neuen rect zeichnen (XOR) if (FSizeMode != SM_MOVE) // bei gröseänderng { if (FSizeMode & SM_DOWN) FOldRect.bottom = FOldRect.top + Y; if (FSizeMode & SM_RIGHT) FOldRect.right = FOldRect.left + X; if (FSizeMode & SM_UP) FOldRect.top = FOldRect.bottom + Y - Height; if (FSizeMode & SM_LEFT) FOldRect.left = FOldRect.right + X - Width; } else // beim verschieben { OffsetRect(FOldRect, X - FOldMousePos.x, Y - FOldMousePos.y); FOldMousePos.x = X, FOldMousePos.y = Y; } DrawFrame(HScreenDC, FOldRect, FPRegion); } else if ((Y <= 2 && X <= 2) || (Y >= Height - 2 && X >= Width - 2)) Cursor = crSizeNWSE; else if ((Y <= 2 && X >= Width - 2) || (Y >= Height - 2 && X <= 2)) Cursor = crSizeNESW; else if ((Y >= Height - 2) || (Y <= 2)) Cursor = crSizeNS; else if ((X >= Width - 2) || (X <= 2)) Cursor = crSizeWE; else Cursor = crDefault; } void __fastcall TPan::Paint() { TCustomPanel::Paint(); } //--------------------------------------------------------------------------- void DrawFrame(HDC hdc, TRect Rect, TRect Region) { TPoint pp; // swap int a; if (Rect.Left > Rect.Right) { a=Rect.Left; Rect.Left=Rect.Right; Rect.Right=a; } if (Rect.Top > Rect.Bottom) { a=Rect.Top; Rect.Top=Rect.Bottom; Rect.Bottom=a; } if ((Rect.Left > Region.Right) || (Rect.Top > Region.Bottom) || (Rect.Right < Region.Left) || (Rect.Bottom < Region.Top)) return; bool l=true, r=true, t=true, b=true; if (Rect.Left < Region.Left) { l=false; Rect.Left = Region.Left; } if (Rect.Top < Region.Top) { t=false; Rect.Top = Region.Top; } if (Rect.Right > Region.Right) { r=false; Rect.Right = Region.Right; } if (Rect.Bottom > Region.Bottom) { b=false; Rect.Bottom = Region.Bottom; } if (t) { MoveToEx(hdc, Rect.left, Rect.top, &pp); LineTo(hdc, Rect.right, Rect.top); } else MoveToEx(hdc, Rect.right, Rect.top, &pp); if (r) LineTo(hdc, Rect.right, Rect.bottom ); else MoveToEx(hdc, Rect.right, Rect.bottom, &pp); if (b) LineTo(hdc, Rect.left, Rect.bottom ); else MoveToEx(hdc, Rect.left, Rect.bottom, &pp); if (l) LineTo(hdc, Rect.left, Rect.top ); } //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TForm1::FormCreate(TObject *Sender) { TPan* p = new TPan(this); p->Parent = this; } //---------------------------------------------------------------------------
[ Dieser Beitrag wurde am 26.03.2003 um 07:53 Uhr von Xqgene editiert. ]