Form schliessen



  • Hallo zusammen, ich rufe beim OnSho-event eines Forms eine funktion auf... wenn etwas bestimmtes in der Funktion passiert, möchte ich, dass das Form das angezeigt wird, wieder verschwindet... und alles im ursprünglichen zustand bleiobt. Form->Close(); scheint im OnShow()-Event nicht zu funktionieren... 😞
    Wie mach ich sowas?



  • // Application->ProcessMessages();	// Falls es Probleme geben sollte
    Application->Terminate();
    


  • Hallo,

    Damit schliesst er aber die gesamte Applikation. Ich weiss nicht ob er das will. Wenn die Form kurz angezeigt werden soll muss ja OnShow vollständig durchlaufen werden. Er könnte von seiner Funktion ja einen Timer starten welcher dann die Form schliesst.

    Ciao



  • Braunstein schrieb:

    Hallo,

    Damit schliesst er aber die gesamte Applikation. Ich weis nicht ob er das will. Wenn die Form kurz angezeigt werden soll muss ja OnShow vollständig durchlaufen werden. Er könnte von seiner Funktion ja einen Timer starten welcher dann die Form schliesst.

    Ciao

    richtig, ich will nicht die ganze Anwendung schliessen... und dein Vorschlag find' ich etwas unschön, geht das nicht schöner..?



  • geht das nicht schöner..?

    Doch, mach ne Schleife drum 😃

    Probier mal selbjenes:

    PostMessage(Handle, WM_CLOSE, 0, 0);
    


  • in so einem fall mache sende ich mit PostMessage(); aus dem OnShow Event eine x-belibeige benutzerdefienierte nachricht an das fenster selbst.
    die in der Behandlungsfunktion der Nachricht kann man dann je nach Situation Close(); aufrufen. dann wird ach das Fenster geschlossen.
    das liegt daran, das PostMessage() eine Nachricht schickt, ohne auf die Antwort zu warten, das heis dass OnShow() weiter ausgefürt und vollständig abgearbeitet wird.



  • Xqgene schrieb:

    in so einem fall mache sende ich ... eine x-belibeige benutzerdefienierte nachricht ...
    in der Behandlungsfunktion der Nachricht ...

    Jou, aber wenn Du gleich WM_CLOSE schickst brauchtst Du nichts weiter zu unternehmen 😉



  • Peter schrieb:

    geht das nicht schöner..?

    Doch, mach ne Schleife drum 😃

    Probier mal selbjenes:

    PostMessage(Handle, WM_CLOSE, 0, 0);
    

    Also...

    PostMessage(Parameterliste_Frm->Handle, WM_CLOSE, 0, 0);
    

    hat auch nicht funktioniert... 😞

    Xqgene schrieb:

    in so einem fall mache sende ich mit PostMessage(); aus dem OnShow Event eine x-belibeige benutzerdefienierte nachricht an das fenster selbst.
    die in der Behandlungsfunktion der Nachricht kann man dann je nach Situation Close(); aufrufen. dann wird ach das Fenster geschlossen.
    das liegt daran, das PostMessage() eine Nachricht schickt, ohne auf die Antwort zu warten, das heis dass OnShow() weiter ausgefürt und vollständig abgearbeitet wird.

    hm, ich möchte das Form eben während dem OnShow()-Event killen... da ich da viele Daten von einem Bus empfangen will und wenn nichts geht, sage ich: "Abrufen des Parameters misslungen Nummer:X!" und dann kann man abbrechen oder wiederholen drücken, bei abbrechen wird die funktion sofort beendet, bei wiederholen, wird nochmal versucht, zu lesen....



  • gehts nicht mit einer übergeordneten Funktion? Im Sinne von

    void TForm2::show_or_die(void)
    {
    
      bool bedingung = finde_raus_obs_geht();
    
      if(!bedingung)
      Show();
      else
      Close();
    }
    

    ?

    Statt Form2 -> Show(); müsstest du dann halt nur Form2 -> show_or_die(); aufrufen



  • @dreaddy
    Sollte so auch funktionieren, ist vielleicht sogar "schöner" ;). Allerdings braucht man dann das Close() in der if Abfrage nicht, da ja keine Form geshowed wurde.

    @others
    Man kann natürlich auch bei Torry nach ner entsprechenden Kompo suchen :D:D:D



  • dreaddy schrieb:

    gehts nicht mit einer übergeordneten Funktion? Im Sinne von

    void TForm2::show_or_die(void)
    {
     
      bool bedingung = finde_raus_obs_geht();
    
      if(!bedingung)
      Show();
      else
      Close();
    }
    

    ?

    Statt Form2 -> Show(); müsstest du dann halt nur Form2 -> show_or_die(); aufrufen

    hm, weiss nicht obs so wirklich geht, kann ja auch mal ein bisschen code zeigen...
    also, meine OnShow-Funktion:

    void __fastcall TParameterliste_Frm::FormShow(TObject *Sender)
    {
    Wait_Frm->Show();                                     // Warte Formular anzeigen, damit was passiert auf dem Screen während der Benutzer warten muss.
    Wait_Frm->Top = Screen->Height/2 - Wait_Frm->Height/2;// Form in der Mitte des Bildschirms platzieren
    Wait_Frm->Left = Screen->Width/2 - Wait_Frm->Width/2; // Form in der Mitte des Bildschirms platzieren
    Send_Btn->Enabled=false;                              // Send-Button disablen weil es noch nicht funktioniert...!
    Profi_p = new TProfibus(); //Instanz von TProfibus erstellen
    Main_Frm->StatusBar1->SimpleText="Parameterliste wird gestartet...";
    
      try{
      Tools::GetFormPos(this);
      }
      catch(...)
      {
      }
    if (Main_Frm->lan)
    {
    Grid->Cells[0][0]= "Nummer";
    Grid->Cells[1][0]= "Name";
    Grid->Cells[2][0]= "Wert (Hex)";
    
    }
    else
    {
    Grid->Cells[0][0]= "Number";
    Grid->Cells[1][0]= "Name";
    Grid->Cells[2][0]= "Value (Hex)";
    }
    Main_Frm->StatusBar1->SimpleText="Parameter aus INI-File einlesen...";
    
    ParamFile = new TIniFile(ExtractFileDir(ParamStr(0)) + "\\param.ini"); // Instanz auf IniFile
    Grid->ColWidths[0]=50;             // Breite der Spalten festlegen
    Grid->ColWidths[1]=250;            // Breite der Spalten festlegen
    Grid->ColWidths[2]=70;             // Breite der Spalten festlegen
    AnsiString AlreadyUsed_AS="";      // Variable deklariert in der der bereits gebrdauchte IND-String gespeichert wird
    for (int i=1; i<=1000; i++)
      {
      Grid->RowCount=Grid->RowCount+1; // ...eine Zeile hinzufügen
      Grid->FixedRows=1;               // fixed rows für die beschriftung festlegen
      Grid->Cells[1][Grid->RowCount]=ParamFile->ReadString("Parameters",i,"100000");// ^Parameter aus INI-File lesen und in Tabelle einfügen
      if (Grid->Cells[1][Grid->RowCount]=="100000")// Wenn beim auslesen aus Ini-File als Defaultwert 1000 eingefüllt wurde...
        Grid->RowCount=Grid->RowCount-1;// Eine Zeile löschen
      else
        Grid->Cells[0][Grid->RowCount]=i;// Parameternummer einfügen
      if (Grid->Cells[1][Grid->RowCount].Pos("(IND)")&&Grid->Cells[1][Grid->RowCount]!=AlreadyUsed_AS)// Wenn (IND) irgendwo im Parameter steht
        {
        AlreadyUsed_AS=Grid->Cells[1][Grid->RowCount];
        for (int IND_int=1; IND_int<=256; IND_int++)
          {
          Grid->RowCount=Grid->RowCount+1;// eine Zeile hinzufügen
          Grid->Cells[1][Grid->RowCount]=ParamFile->ReadString("Parameters",AnsiString(i)+"."+AnsiString(IND_int),"100000");// ^Parameter aus INI-File lesen und in Tabelle einfügen
          if (Grid->Cells[1][Grid->RowCount]=="100000")// Wenn beim auslesen aus Ini-File als Defaultwert 1000 eingefüllt wurde...
            {
            Grid->RowCount=Grid->RowCount-1;// Eine Zeile löschen
            break;
            }
          else
            Grid->Cells[0][Grid->RowCount]=AnsiString(i)+"."+AnsiString(IND_int);// Parameternummer einfügen à la system, das der IND-Wert hinter dem Punkt steht, z.B. 17.1
          }
        }
      }
    Main_Frm->StatusBar1->SimpleText="Parameterwerte aus Motor lesen...";
    PPO2 recStruct;
    for (int i=3; i<=Grid->RowCount;i++)
      {
      recStruct=ReceiveValues(i);
      Grid->Cells[2][i]=Tools::HexStringToShort(AnsiString(IntToHex(recStruct.PWE2,2)+IntToHex(recStruct.PWE1,0)));
      }
      Main_Frm->StatusBar1->SimpleText="fertig";
      Wait_Frm->Close(); // WarteFormular schliessen.
      }
    

    und die funktion, in der ich bestimmen will ob das formular geöffnet werden soll oder nicht:

    PPO2 __fastcall TParameterliste_Frm::ReceiveValues(int ActualRow)
    {
    PPO2 receivedStruct;
    int paramnum;
    AnsiString paramnumber_AS=Grid->Cells[0][ActualRow];
    if (paramnumber_AS.Pos("."))
      {
      AnsiString fullstring_AS=Grid->Cells[0][ActualRow];
      paramnum=paramnumber_AS.Delete(3,2).ToInt();
      receivedStruct.PKE=0x6000;
      receivedStruct.IND=(fullstring_AS.Delete(1,3).ToInt())<<8;       // vordere 2 zahlen und punkt löschen und dann in int wandeln
      }
    else
      {
      receivedStruct.IND=0;
      paramnum=paramnumber_AS.ToInt();
      receivedStruct.PKE=0x1000;
      }
    
    Profi_p->RecParam(&receivedStruct,paramnum);
    /****/
      int i;
      for (i=0; i<=20 && (Main_Frm->result.PKE &0x0fff) != paramnum; i++)
         {
         Profi_p->ReadSlave(Main_Frm->SlaveID_ED->Text.ToInt(),&Main_Frm->result);
         int result_int=Tools::HexStringToShort(AnsiString(IntToHex(Main_Frm->result.PWE2,2)+IntToHex(Main_Frm->result.PWE1,0)));
         Profi_p->RecParam(&receivedStruct,paramnum);
         Sleep(100);
         }
      if (i>20)
        {
        if (Main_Frm->lan)
          {// MSGBox zeigen und wert der Buttons in eine ver. schreiben.
          int ergebniss=Application->MessageBox(AnsiString("Abrufen des Parameters misslungen!\nNummer:"+AnsiString(paramnum)).c_str(),AnsiString(paramnum).c_str(),21);
          StatusBar1->SimpleText = "abrufen min. eines Parameters misslungen!";
          if (ergebniss==4)
          {
          // wiederholen
          i--;  // i um eins dekrementieren damit der selbe parametre nochmals abgefragt wird.
          }
          else if (ergebniss==2)
          {
          // abbrechen, hier sollte das Formular geschlossen werden....
          Parameterliste_Frm->Close();  // Form schliessen
          }
          }
        else
          {
          Application->MessageBox(AnsiString("Faild, getting the Parameter!\nNummer:"+AnsiString(paramnum)).c_str(),AnsiString(paramnum).c_str(),21);
          StatusBar1->SimpleText = "getting Parameters failed!";
          }
        }
    
    return  Main_Frm->result;
    }
    


  • Beeindruckend 🙄
    Meinst Du es hat jemand Bock sich durch den Quellcode zu ackern und das für Dich zu probieren ?



  • Peter schrieb:

    Beeindruckend 🙄
    Meinst Du es hat jemand Bock sich durch den Quellcode zu ackern und das für Dich zu probieren ?

    Nein, das sicher nicht, hab' nur gedacht so kann sich vielleicht jmd in etwa vorstelllen um was es etwa geht... :p



  • Fremden Code auf Anhieb zu verstehen ist wohl sicherlich nicht ganz so einfach. Wenn ich ne Menge Code sehe der mich eigentlich nicht ganz so brennend interessiert, wende ich mich meist ganz schnell wieder ab. Warum probierst Du nicht selber etwas rum ? Du kennst Deinen Code und die Logik die sich dahinter verbirgt am Besten 😉



  • *.h

    #define MSG_IMPPROGRESS   (WM_USER + 2314)
    ...
    
    private:
      void OnProgress(TMessage Msg);
    
    public:		// Anwender-Deklarationen
      __fastcall TForm1(TComponent* Owner);
    
    BEGIN_MESSAGE_MAP
      VCL_MESSAGE_HANDLER(MSG_IMPPROGRESS, TMessage, OnProgress);
    END_MESSAGE_MAP(TForm);
    

    in *.cpp

    void __fastcall TForm1::FormActivate(TObject *Sender)
    {
      PostMessage(Handle, MSG_IMPPROGRESS, 0, 0);
    }
    //---------------------------------------------------------------------------
    void TForm1::OnProgress(TMessage Msg)
    {
      if (iregendwas_nicht_stimmt)
        Close();
    }
    


  • Peter schrieb:

    Fremden Code auf Anhieb zu verstehen ist wohl sicherlich nicht ganz so einfach. Wenn ich ne Menge Code sehe der mich eigentlich nicht ganz so brennend interessiert, wende ich mich meist ganz schnell wieder ab. Warum probierst Du nicht selber etwas rum ? Du kennst Deinen Code und die Logik die sich dahinter verbirgt am Besten 😉

    also, hab's jetzt so probiert:
    (code des TParameterliste_Frm-Forms, das ich evt. nicht öffnen will)

    if (ergebniss==4)
          {
          // wiederholen
          i--;  // i um eins dekrementieren damit der selbe parametre nochmals abgefragt wird.
          }
          else if (ergebniss==2)
          {
          // abbrechen
          PostMessage(Main_Frm->Handle, 333, 0, 0);
    //      Parameterliste_Frm->Hide();  // Form schliessen
          }
    

    und in meinem Main_Frm steht das:

    void __fastcall TMain_Frm::AppOnMessage(MSG& msg, bool&)
    {
       [noch mehr *messageabarbeitcode*]
       if (msg.message == 333)
         {
         ShowMessage("Got Message!");// Message anzeigen wenn msg der paramliste angekommen ist.
         }
    
    }
    

    die message kommt aber nicht an... 😞



  • Ähhh, hast Du überhaupt gelesen (und probiert) was ich weiter vorne geschrieben habe (das mit WM_CLOSE) 🙄
    Nur zur Info, das habe ich nämlich zur Sicherheit bei mir an einem Popelprojekt ausprobiert und es hat funktioniert !



  • oder auch das, was ich geschrieben habe??



  • Oder vielleicht auch das was dreaddy geschrieben hat 🙄

    Ich gebs auf.
    Schönes Wochenende
    und Tschüss 🕶



  • Wieso nimmst du nicht einfach das "OnActivate"-Ereignis? Dann wird das Fenster bereits angezeigt, und du kannst es ganz in Ruhe schließen, allerdings nicht mit Close() glaub ich, da m,üsstest du dann halt Application->Terminate() benutzen.


Anmelden zum Antworten