Kombonenten zur Laufzeit verändern



  • Ich schon wieder -.-

    jaja, ich weis, nich als anfänger gleich solche aufgaben vornehmen, aber wie bereits erwähnt is es dringend!

    Also:

    ich hab eine Form auf der ich durhc Button-Druck zur laufzeit neue Objekte erstellen soll!

    Das klappt, habs erst mit labels probiert und dann mit TabControls. Beides Hat funktioniert.

    Ich muss aber irgendwie hinbekommen, das ich jetzt diese erstellten Objekte zur laufzeit per maus verschieben kann!
    -.- wie bekomm ich das am besten hin und was is dazu sinnvoll? Ich benötige eine art "Box" in die ich wiederrum neue Elemte erzeugen kann..
    Diese Box muss ich zur laufzeit erstellen, verschieben und die grösse ändern können.
    Zudem muss der Name der "Box" angezeigt werden. ist das möglich?
    Kann ich keine Fenster erzeugen wie das der FOrm, nur ohne die zusätzlichen Icons oben?

    MfG Puccini



  • Hallo

    doch, du kannst neue Forms zur Laufzeit erzeugen und denen dann verschiedene BorderStyles zuweisen (z.B. bsNone für keine Titelleiste).

    Siehe auch TBorderIcons:

    Auszug aus der BCB-Hilfe zu TBorderIcons schrieb:

    The following code removes a form’s Maximize button when the user clicks a button:

    void __fastcall TForm1::Button1Click(TObject *Sender)

    {
    TBorderIcons tempBI = BorderIcons;
    tempBI >> biMaximize;
    BorderIcons = tempBI;
    }

    Zum verschieben von Komponenten zur Laufzeit mal hier lesen.

    mfg, Micha!



  • Thx für die Coole Site!

    Leider gibts ein Problem mit dem Code.
    Der Compiler meckert zwar nich, jedoch kann ich meine Buttons die ich auf der Form1 habe nicht verschieben!

    Woran könnte das jetzt liegen? An meiner Borland Version??
    Version 10.0.2151.25345

    Oder muss ich noch irgendetwas importieren um die API-Funktionalität zu nutzen??

    MfG Puccini



  • Hallo

    Ich gehe davon aus das der Quellcode vom Link korrekt ist. Also hast du etwas falsch gemacht bzw vergessen. Vermutlich vergessen die Events den Methoden zuzuweisen.

    bis bald
    akari



  • Die Events den Methonde zuweisen??

    o.O
    Wie mach ich das denn nun wieder?
    Mein Problem ist halt, das nach dem Laden der Form noch weiter Elemente durch Knopfdruck erzeugt werden können und diese Sollen verschoben werden.

    Also Events den Methoden zuweisen?

    Wäre cool wenn auch das noch wer mir erklären könnte 😃
    Ich hab mir den Quellcode des Progs mal angeschaut und keine Unterschiede feststellen..

    :<



  • Hallo

    Nehmen wir mal an du hast einen neuen Button erstell

    TButton* Button = new TButton(this);
    

    und willst dem nun den auszuführenden Quellcode zuweisen, der in

    void __fastcall TForm::ButtonClick(TObject* Sender)
    {
    }
    

    steht. Dann must du die Methode zu dem Event zuweisen :

    Button->OnClick = ButtonClick;
    

    Das kannst du auch mit allen anderen Events machen, solange die Methode dazu passt.

    /Edit : Code korrigiert.

    bis bald
    akari



  • Aha, alles klar. Klingt logisch ^^

    Aber:

    Das is ja nich das was die Methode mit dem verschieben betrifft! oder?
    Wenn ich mir die Beispielexe ansehe, kann ich entweder Verschieben, oder Klicken!

    Also wird doch das event des Buttons der verschoben werden soll bei Klick garnicht ausgelöst sonder die Methode MoveControls oder??



  • Hallo,

    siehe im Code des Beispiels...

    if(pControl != chkAllowMove && chkAllowMove->Checked) {...}
    

    Die Methode MoveControl wird also nur aufgerufen wenn die CheckBox chkAllowMove != 0 und das Control nicht selber die CheckBox ist.

    Wichtig ist im FormShow die Zeile

    Application->OnMessage = OnAppMessage; //Hier wird die Methode "OnAppMessage" dem Event "OnMessage" zugewiesen.
    

    mfg, Micha

    P.S. @akari

    TButton* Button = new wxButton(this); // ?  :D
    


  • Hmm, das hab ich alles!

    Das einzige was ich erstmal nich Übernommen habe sind die SPeichern- und Restoremethoden!

    :<
    Is doch komisch.....

    leider hab ich gleichfeierabend, aber ich werd mal den quellcode den ich habe post!

    vielleicht hiflt das ja dem einen oder anderen?
    Unit1.cpp

    //$$---- Form CPP ----
    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    #include <iostream>
    #include <string>
    using namespace std;
    #include "Unit1.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
    	: TForm(Owner)
    {
    	aktiveEbene="Erdgeschoss";
    	ebeneIndex=1;
    	anzraum[ebeneIndex]=0;
    	Etage1->Visible=false;
    	Etage2->Visible=false;
    	Erdgeschoss->Visible=true;
    	Untergeschoss->Visible=false;
    
    }
    void __fastcall TForm1::FormShow(TObject *Sender)
    {
    	//hilfspannel zum verschieben
    	pHelpPanel->Parent=this;
    	pHelpPanel->BorderStyle =bsNone;
    	pHelpPanel->BevelInner =bvNone;
    	pHelpPanel->BevelOuter =bvNone;
    	pHelpPanel->Caption ="";
    	pHelpPanel->FullRepaint =false;
    	pHelpPanel->Visible = false;
    	//Eigene Botschaftsroutine hinzufügen
    	Application->OnMessage=OnAppMessage;
    }
    void __fastcall TForm1::OnAppMessage(tagMSG &Message,bool &Handled)
    {
    	//Linke Maustaste abfragen
    	if(Message.message == WM_LBUTTONDOWN)
    	{
    		//Zeiger auf das Steuerelement unter demMauscursor
    		TControl * pControl=ControlAtPos(ScreenToClient(Message.pt),false,true);
    		//wenn Chekcbox "Elemente verschieben" angehackt ist
    		if (chkVerschieben->Checked)
    		{
    			//Steuerelement auf Unterobjekte überprüfen
    			if (pControl) {
    				TWinControl* pCmp=dynamic_cast<TWinControl*>(pControl);
    				TControl* pCtrl;
    				while(pCmp)
    				{
    					pCtrl=dynamic_cast<TControl*>(pCmp->ControlAtPos(pCmp->ScreenToClient(Message.pt),false,true));
    					pCmp=dynamic_cast<TWinControl*>(pCtrl);
    					if(pCmp) pControl=pCmp;
    					else if(pCtrl) pControl=pCtrl;
    				}
    			}
    			//Control verschieben
    			Form1->Close();
    			MoveControl(pControl);
    			Handled=true;
    		}
    	}
    }
    //Funktion zum verschieben:
    void __fastcall TForm1::MoveControl(TControl* pControl)
    {
    	//versuch Zeiger der Komponente in TWinControl umzucasten
    	TWinControl* pWinControl=dynamic_cast<TWinControl*>(pControl);
    	//falls Umwandlung erfolgreich
    	if(pWinControl)
    	{
    		//Verschieben-Modus aktivieren
    		ReleaseCapture();
    		pWinControl->Perform(WM_SYSCOMMAND, SC_MOVE+HTCAPTION,0);
    	}
    	//falls eine "Nicht-Fenster-Orientiere" Komponente verschoben werden soll
    	else if(pControl)
    	{
    		//Hilfspanel entsprechend anpassen
    		pHelpPanel->Parent=pControl->Parent;
    		pHelpPanel->Left=pControl->Left;
    		pHelpPanel->Top=pControl->Top;
    		pHelpPanel->Width=pControl->Width;
    		pHelpPanel->Height=pControl->Height;
    		//das zu verschiebende Steuerelement auf Hilfspannel plaziern
    		TWinControl* pSaveParent=pControl->Parent;
    		pControl->Parent=pHelpPanel;
    		pControl->Left=0;
    		pControl->Top=0;
    		pHelpPanel->Visible=true;
    		Application->ProcessMessages();
    
    		//Verschiebemodus aktiviren für Hilfspanel
    		ReleaseCapture();
    		pHelpPanel->Perform(WM_SYSCOMMAND,SC_MOVE+HTCAPTION,0);
    
    		//Nach dem verschieben das steuerelement wieder auf Formular platzieren
    		pControl->Parent=pSaveParent;
    		pControl->Left=pHelpPanel->Left;
    		pControl->Top=pHelpPanel->Top;
    		pHelpPanel->Visible=false;
        }
    }
    
    //---------------------------------------------------------------------------
    void __fastcall TForm1::bRaumClick(TObject *Sender)
    {
    	myTab=new TShape(this);
    	myTab->Parent=Form1;
    	myTab->Top=(anzraum[ebeneIndex]+1)*15;
    	myTab->Visible=true;
    	myTab->Name="Raum_"+ERaumName->Text+AnsiString(anzraum[ebeneIndex]);
    	myTab->Hint=ERaumName->Text;
    	myTab->ShowHint=true;
    	myTab->Height=50;
    	myTab->Width =50;
    
    	arrayraum[anzraum[ebeneIndex]][ebeneIndex][0]=1;
    	nameRaum[ebeneIndex][anzraum[ebeneIndex]]=ERaumName->Text;
    	anzraum[ebeneIndex]++;
    	Form1->Caption="Anzahl Räume auf Ebene "+aktiveEbene+": "+AnsiString(anzraum[ebeneIndex]);
    }
    

    unit1.h

    //$$---- Form HDR ----
    //---------------------------------------------------------------------------
    
    #ifndef Unit1H
    #define Unit1H
    //---------------------------------------------------------------------------
    #include <Classes.hpp>
    #include <Buttons.hpp>
    #include <Controls.hpp>
    #include <ExtCtrls.hpp>
    #include <jpeg.hpp>
    #include <Menus.hpp>
    #include <StdCtrls.hpp>
    #include <Forms.hpp>
    #include <ComCtrls.hpp>
    #include <Graphics.hpp>
    //---------------------------------------------------------------------------
    class TForm1 : public TForm
    {
    __published:	// IDE-managed Components
    	TImage *Etage1;
    	TImage *Etage2;
    	TImage *Erdgeschoss;
    	TBitBtn *button_1etage;
    	TBitBtn *button_2etage;
    	TBitBtn *button_erdgeschoss;
    	TBitBtn *button_untergeschuss;
    	TImage *Untergeschoss;
    	TMainMenu *MainMenu1;
    	TMenuItem *Datei1;
    	TMenuItem *Laden1;
    	TMenuItem *Speichern1;
    	TMenuItem *Schliessen1;
    	TMenuItem *N1;
    	TMenuItem *About1;
    	TMenuItem *Hilfe1;
    	TBitBtn *bRaum;
    	TEdit *ERaumName;
    	TCheckBox *chkVerschieben;
    
    	void __fastcall button_1etageClick(TObject *Sender);
    	void __fastcall button_untergeschussClick(TObject *Sender);
    	void __fastcall button_2etageClick(TObject *Sender);
    	void __fastcall button_erdgeschossClick(TObject *Sender);
    	void __fastcall UntergeschossClick(TObject *Sender);
    	void __fastcall RRaumClick(TObject *Sender);
    	void __fastcall RRechnerClick(TObject *Sender);
    	void __fastcall bRaumClick(TObject *Sender);
    	void __fastcall FormShow(TObject *Sender);
    	void __fastcall Schliessen1Click(TObject *Sender);
    	void __fastcall aktivTabMouseDown(TObject *Sender, TMouseButton Button,
              TShiftState Shift, int X, int Y);
    private:	// User declarations
    	TPanel *pHelpPanel;
    public:		// User declarations
    	void ebenewechseln();
    	void bild_klick();
    	//Zum verschieben der Komponenten zur laufzeit:
    	//Botschaftsbehandlung der Application
    	void __fastcall OnAppMessage(tagMSG &Message,bool &Handled);
    	//Funktion zum verschieben
    	void __fastcall MoveControl(TControl* Sender);
    	//Speichern
    	bool SaveControlsPositions(void);
    	//Laden
    	bool RestoreControlsPositions(void);
    	AnsiString aktiveEbene;
    	TShape *myTab;
    	TShape *aktivTab;	//ist der Aktuell angeklickte Raum
    	int ebeneIndex;     //0=Untergeschoss,1=Erdgeschoss,2=Erste Etage,3=Zweite Etage
    	int anzraum[6];		//Anzahl aller bereits Angelegten Räume pro Ebene
    	AnsiString nameRaum[6][500];	//Name der Räume pro Ebene (Ebene,Raumindex)
    	int arrayraum[500][6][4];	//Array aller Räume (max. 500),EbenenIndex,Positionierung(x,y,breit,hoch)
    	__fastcall TForm1(TComponent* Owner);
    };
    //---------------------------------------------------------------------------
    extern PACKAGE TForm1 *Form1;
    //---------------------------------------------------------------------------
    #endif
    

    Ein paar funktionenhab ich rausgeschnitten, um nich alzuviel paltz zu verbrauchen!

    Aber so wie es jetzt steth sollte es dohc auch funktionieren oder??
    Is meinermeinung nach genau das gleich! 😕
    pls help :<

    MfG Puccini



  • Hi!

    ich hab noch etwas rumgetüftetl und festgestellt, das meine Methode:
    OnAppMessage nie aufgerufen wird!!
    Woran könnte das liegen??

    Zudem hätte ich noch eine frage,

    Ich erstelle neue TShapes zur laufzeit welche alle auf die Selebe Funktion:
    aktivTabMouseDown bei Mausklick reagieren sollen. Das klappt auch!
    Nur wie ermittel ich innerhalb der Methode aktivTabMouseDown jetzt welches Shape ich gedrück habe??

    Wäre echt cool wenn einer hier helfen könnte! Ich bin glaub ich zu blöd zu sowas zu sehen -.- kenn mich eher mit anderen Programmiersprachen aus, welche keine Zeiger verwenden..

    MfG Puccini



  • Sorry für 3-Fach-Post, aber ich kann meine Beiträge nich editieren, da ich nich registriert bin!

    Das Problem mit "Komponente unter der Maus" hab ich hinbekommen!

    TPoint mauspos;
    ::GetCursorPos(&mauspos);
    TControl * unterMaus=ControlAtPos(mauspos,false,true);
    aktivTab=dynamic_cast<TShape*>(unterMaus);
    

    Damit hab ich die Komponente unter der Maus beim Anklicken in "aktivTab" übernommen und kann die so bearbeiten oder?
    Und das mit dem verschieben klapp immer noch net! Schade! keiner eine Idee?????????????


Anmelden zum Antworten