Sorry, schon wieder ein kleines Problem
-
Hallo,
ich hab schon wieder ein kleines Problem zu lösen.
Ich versuche nun ein erstes kleines Projekt zu erstellen in dem später ein Callback bestimmte werte aus einem anderen Programm auslesen soll.
Das aber erst VIEL später.
Derzeit hab ich das Problem das ich nicht genau weiß wie ich die Labels ( wo die Werte später angezeigt werden sollen ) ändern kann.
Einfach den Text ändern geht, schon klar, aber es muss aus einer funktion geschehen die nicht in der classendefinition der form steht.
Um dies zu verdeutlichen hab ich mal was einfaches erstellt und im Kommentar die stelle reingeschrieben wo ich den Label ändern müsste:// Zugriff_auf_Form.cpp: Hauptprojektdatei. #include "stdafx.h" #include "Form1.h" using namespace NSForm1; // Callback dummy void ChangeLabel() { // Hier ist das Problem Form1^ f; f->lblToChange->Text = L"Hallo"; } System::Void Form1::btnStart_Click(System::Object^ sender, System::EventArgs^ e) { // Soll jetzt mal das Callback demonstrieren. // Diese funktion wird als immer wieder aufgerufen ChangeLabel(); } [STAThreadAttribute] int main(array<System::String ^> ^args) { // Aktivieren visueller Effekte von Windows XP, bevor Steuerelemente erstellt werden Application::EnableVisualStyles(); Application::SetCompatibleTextRenderingDefault(false); // Hauptfenster erstellen und ausführen Application::Run(gcnew Form1()); return 0; }
Form1.h :
#pragma once namespace NSForm1 { using namespace System; using namespace System::ComponentModel; using namespace System::Collections; using namespace System::Windows::Forms; using namespace System::Data; using namespace System::Drawing; /// <summary> /// Zusammenfassung für Form1 /// /// Warnung: Wenn Sie den Namen dieser Klasse ändern, müssen Sie auch /// die Ressourcendateiname-Eigenschaft für das Tool zur Kompilierung verwalteter Ressourcen ändern, /// das allen RESX-Dateien zugewiesen ist, von denen diese Klasse abhängt. /// Anderenfalls können die Designer nicht korrekt mit den lokalisierten Ressourcen /// arbeiten, die diesem Formular zugewiesen sind. /// </summary> public ref class Form1 : public System::Windows::Forms::Form { public: Form1(void) { InitializeComponent(); // //TODO: Konstruktorcode hier hinzufügen. // } protected: /// <summary> /// Verwendete Ressourcen bereinigen. /// </summary> ~Form1() { if (components) { delete components; } } private: System::Windows::Forms::Button^ btnStart; public: System::Windows::Forms::Label^ lblToChange; protected: private: /// <summary> /// Erforderliche Designervariable. /// </summary> System::ComponentModel::Container ^components; #pragma region Windows Form Designer generated code /// <summary> /// Erforderliche Methode für die Designerunterstützung. /// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden. /// </summary> void InitializeComponent(void) { this->btnStart = (gcnew System::Windows::Forms::Button()); this->lblToChange = (gcnew System::Windows::Forms::Label()); this->SuspendLayout(); // // btnStart // this->btnStart->Location = System::Drawing::Point(36, 22); this->btnStart->Name = L"btnStart"; this->btnStart->Size = System::Drawing::Size(162, 23); this->btnStart->TabIndex = 0; this->btnStart->Text = L"Start"; this->btnStart->UseVisualStyleBackColor = true; this->btnStart->Click += gcnew System::EventHandler(this, &Form1::btnStart_Click); // // lblToChange // this->lblToChange->Location = System::Drawing::Point(252, 22); this->lblToChange->Name = L"lblToChange"; this->lblToChange->Size = System::Drawing::Size(252, 23); this->lblToChange->TabIndex = 1; this->lblToChange->Text = L"label1"; this->lblToChange->TextAlign = System::Drawing::ContentAlignment::MiddleRight; // // Form1 // this->AutoScaleDimensions = System::Drawing::SizeF(6, 13); this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font; this->ClientSize = System::Drawing::Size(635, 246); this->Controls->Add(this->lblToChange); this->Controls->Add(this->btnStart); this->Name = L"Form1"; this->Text = L"Form1"; this->ResumeLayout(false); } #pragma endregion private: System::Void btnStart_Click(System::Object^ sender, System::EventArgs^ e); }; // Class } // NS
Was mach ich da falsch ?
Ich bekomme einen Fehler das ich ein Objekt mit new erstellen soll in der zeile :
f->lblToChange->Text = L"Hallo";Aber Form1^ f; ist doch richtig oder ?
Mit From1 ^f = gcnew Form1; würde ich ja ein neues Form1 Objekt erstellen und das will ich ja nicht. Ich muss ja an dieser stelle nur auf die Form1->lblToChange->Text eigenschaft zugreifen.Hilfe ..... Danke
Matthias
-
STF-DIR schrieb:
Hallo,
Was mach ich da falsch ?
Ich bekomme einen Fehler das ich ein Objekt mit new erstellen soll in der zeile :
f->lblToChange->Text = L"Hallo";Aber Form1^ f; ist doch richtig oder ?
Mit From1 ^f = gcnew Form1; würde ich ja ein neues Form1 Objekt erstellen und das will ich ja nicht. Ich muss ja an dieser stelle nur auf die Form1->lblToChange->Text eigenschaft zugreifen.Hilfe ..... Danke
Matthias
Das Problem liegt darin, dass dein f zwar ein Verweis des richtigen Typs ist, der Verweis aber eben auf nichts verweist. Du greifst mit f-> ins Nichts.
Du musst der Methode z.B. über einen Parameter das konkrete, bereits existierende Form1-Objekt übergeben, dann funktioniert auch der Zugriff.Nid.
-
Das Stichwort für die Grundlagen lautet: "Instanziieren, instanzen und Objekte"
Btw wäre es empfehlenswert wenn Du ein property oder eine Methode in Form1 implementierst. Du kannst mit diesem kleinen Mehraufwand später viel arbeit und Probleme sparen, da Form1 am besten weiß wo es angezeigt werden soll und der Aufrufer unabhängig davon wird.
-
Hallo,
das mit den Propertys hattest Du mir ja schon mal erklärt.
Könnte man so machen, nicht das thema.
Aber wie ist es mit einer Textbox, die brauch ich auch noch später ?Danke
MatthiasPS.: Ich weiss nicht ob Ihr damit was anfangen könnt, aber das hier muss ich so umsetzen das ich das ganze in einer Form habe und die ganzen printF sollen dann in Textboxen oder Labels ausgegeben werden. Dazu muss ich natürlich auch in der Form Werte setzen und das ist das Problem :
#include <windows.h> #include <tchar.h> #include <stdio.h> #include <strsafe.h> #include "SimConnect.h" int quit = 0; HANDLE hSimConnect = NULL; struct Struct1 { char title[256]; double kohlsmann; double altitude; double latitude; double longitude; }; static enum EVENT_ID{ EVENT_SIM_START, }; static enum DATA_DEFINE_ID { DEFINITION_1, }; static enum DATA_REQUEST_ID { REQUEST_1, }; void CALLBACK MyDispatchProcRD(SIMCONNECT_RECV* pData, DWORD cbData, void *pContext) { HRESULT hr; switch(pData->dwID) { case SIMCONNECT_RECV_ID_EVENT: { SIMCONNECT_RECV_EVENT *evt = (SIMCONNECT_RECV_EVENT*)pData; switch(evt->uEventID) { case EVENT_SIM_START: // Now the sim is running, request information on the user aircraft hr = SimConnect_RequestDataOnSimObjectType(hSimConnect, REQUEST_1, DEFINITION_1, 0, SIMCONNECT_SIMOBJECT_TYPE_USER); break; default: break; } break; } case SIMCONNECT_RECV_ID_SIMOBJECT_DATA_BYTYPE: { SIMCONNECT_RECV_SIMOBJECT_DATA_BYTYPE *pObjData = (SIMCONNECT_RECV_SIMOBJECT_DATA_BYTYPE*)pData; switch(pObjData->dwRequestID) { case REQUEST_1: { DWORD ObjectID = pObjData->dwObjectID; Struct1 *pS = (Struct1*)&pObjData->dwData; if (SUCCEEDED(StringCbLengthA(&pS->title[0], sizeof(pS->title), NULL))) // security check { printf("\nObjectID=%d Title=\"%s\"\nLat=%f Lon=%f Alt=%f Kohlsman=%.2f", ObjectID, pS->title, pS->latitude, pS->longitude, pS->altitude, pS->kohlsmann ); } break; } default: break; } break; } case SIMCONNECT_RECV_ID_QUIT: { quit = 1; break; } default: printf("\nReceived:%d",pData->dwID); break; } } void testDataRequest() { HRESULT hr; if (SUCCEEDED(SimConnect_Open(&hSimConnect, "Request Data", NULL, 0, 0, 0))) { printf("\nConnected to Flight Simulator!"); // Set up the data definition, but do not yet do anything with it hr = SimConnect_AddToDataDefinition(hSimConnect, DEFINITION_1, "Title", NULL, SIMCONNECT_DATATYPE_STRING256); hr = SimConnect_AddToDataDefinition(hSimConnect, DEFINITION_1, "Kohlsman setting hg", "inHg"); hr = SimConnect_AddToDataDefinition(hSimConnect, DEFINITION_1, "Plane Altitude", "feet"); hr = SimConnect_AddToDataDefinition(hSimConnect, DEFINITION_1, "Plane Latitude", "degrees"); hr = SimConnect_AddToDataDefinition(hSimConnect, DEFINITION_1, "Plane Longitude", "degrees"); // Request an event when the simulation starts hr = SimConnect_SubscribeToSystemEvent(hSimConnect, EVENT_SIM_START, "SimStart"); while( 0 == quit ) { SimConnect_CallDispatch(hSimConnect, MyDispatchProcRD, NULL); Sleep(1); } hr = SimConnect_Close(hSimConnect); } } int __cdecl _tmain(int argc, _TCHAR* argv[]) { testDataRequest(); return 0; }
Vielleicht könnt Ihr Euch das ja mal anschauen.?
So wisst Ihr wenigstens was ich machen will und könt vielleicht besser helfen.Danke
Matthias
-
Zu 1
Was soll mit der Textbox sein ?Zu 2
Schau Dir String::Format an
-
Hallo,
also die Frage war wie das dann mit einer TextBox gehen soll?
Ich finde das ein bischen umständlich.
Nehmen wir an ich habe auf der Form 10 TextBoxen für die verschiedenen Werte zu liegen. Soll ich dann für jede dieser TextBoxen eine Property machen ?
Das kann doch nicht sein oder wie soll das dann gehen ?Weißt Du was ich meine ?
String::Format ?
Was meinst Du denn damit ? Wozu soll ich das verwenden, in welchem Zusammenhang jetzt ?Matthias
-
Dem Property ist es egal ob Du dort eine Textbox hast oder ein Label oder ein sonst was. Den genau das soll das Property kapseln. Natürlich kannst Du auch weiterhin einfach Public einsetzen und beim tauschen eines Elementes den Quellcode durchsuchen etc....
String::Format noch nicht angeschaut oder die eigene Frage vergessen ?
-
Hallo,
also mit String::Format kann ich gar nichts anfangen. Hab die Beiträger gerade nochmal durchgeschaut und ehrlich gesagt nicht gefunden wo ich danach gefragt habe .::: hmmm
Ok, zu der Property:
Müsste ich dann also zu jedem Label und TextBox ein Property erstellen nur um da nen Wert zu ändern ?
Soll das wirklich soooo umständlich sein ?Ich kenn das noch von Delphi, da konnte mann in eriner Procedure die nicht in der Classe der Form enthalten war auf die elemente der Form mit Form1.lblToChange.Text zugreifen. Geht das denn in VC++ nicht auch irgendwie so einfach wie in Delphi ?
Matthias
-
Also String::Format ist genau das passende Gegenstück zu printf - ich weiß also nicht wo jetzt Deine Verwunderung herkommt.
Für den Fall das Du es in der Hilfe nicht findest und Googel Dir keine Ergebnisse liefert:
http://msdn2.microsoft.com/de-de/library/fht0f5be.aspx
ja es geht, aber es ist keine gute Art zu Programmieren und liefert einige Probleme. Zumal ist C++ keine Sprache der bequemlichkeit. Der Zugriff über Property war eine Empfehlung mit Auflistung der Vorteile. Was Du am Ende machst ist Dir überlassen.
-
STF-DIR schrieb:
Hallo,
also die Frage war wie das dann mit einer TextBox gehen soll?
Ich finde das ein bischen umständlich.
Nehmen wir an ich habe auf der Form 10 TextBoxen für die verschiedenen Werte zu liegen. Soll ich dann für jede dieser TextBoxen eine Property machen ?
Das kann doch nicht sein oder wie soll das dann gehen ?
MatthiasDu siehst das von der falschen Seite.
Grundsätzlich sollten in einem ojektorientierten Ansatz - egal in welcher Sprache - wegen der Datenkapselung Attribute niemals etwas anderes sein als privat. Selbst protected ist streng genommen schon grenzwertig.Das heißt, bei einem sauberen Ansatz müsstest du für jede der Textboxen sowieso eine getWert und setWert-Methode schreiben.
Und mit dieser Vorstellung im Hinterkopf sind die Eigenschaften doch geradezu ein Segen
Nid.
-
Hallo,
dank Euch allen !
Ich werd es "richtig" machen und das ganze über eine Property und eine Set und Get methode machen.
Danke nochmal !!
Matthias