Windows Forms und Übergabe Objekte?



  • Hallo, bin neu hier und habe durch die Suchfunktion auf meine Frage keine Antwort gefunden. Ich benutze VC++ mit .NET und hänge seit 2 Tagen bei folgendem Problem:

    Ich habe Form1.cpp (mit Form1.h) und BExcel.cpp (mit BExcel.h). In der Applikation werden (mit Hilfe von Methoden aus BExcel) XLS-Files geladen und die Namen der verschiedenen Worksheets (falls vorhanden) einer Excel-Datei in einer ComboBox aufgelistet. Klappt wunderbar.

    Jetzt sollen nach manueller Auswahl (Mausklick) eines Worksheets die Namen der Spaltennamen des Worksheets in einer Listbox daneben gezeigt werden. Theoretisch kein Problem, jedoch muss ich das erstelle Objekt ("BExcel be;") an die "private: System::Void ComboBoxWorkSheets_SelectedIndexChanged(System::Object * sender, System::EventArgs * e)" in der Datei "Form1.h" übergeben, sonst kennt sie das geladene File (das ja nun an dem Excel Objekt "hängt") nicht und kann die Methode "ListColNames(be);" nicht aufrufen, weil ihr das Objekt nicht zur Verfügung steht.

    Frage: Wie übergebe ich der o.g. Methode das Objekt damit die Methode "ListColNames(be);" damit aufgerufen werden kann, um bei Mausklick auf ein Worksheet die Spaltennamen aufzulisten? Ich habe bisher versucht, ein globales Objekt in Form1.cpp zu definieren aber das funktioniert nicht. Form1.cpp kennt alles von Form1.h aber Form1.h kennt das dort deklarierte BExcel Objekt aus Form1.cpp nicht. 😕

    Minimalbeispiel als Code anbei. Für andere Tipps, was z.B. guten Programmierstil angeht, bin ich immer äusserst dankbar! Vielen Dank schon mal im voraus.

    Form1.h:

    #pragma once
    #include "BExcel.hpp"
    #include <string>
    #include <vcclr.h>
    
    using namespace YExcel;
    
    namespace testwinforms
    {
    	using namespace System;
    	using namespace System::ComponentModel;
    	using namespace System::Collections;
    	using namespace System::Windows::Forms;
    	using namespace System::Data;
    	using namespace System::Drawing;
    	using namespace System::Runtime::InteropServices;
    	using namespace std;
    
    	public __gc class Form1 : public System::Windows::Forms::Form
    	{	
    	public:
    		Form1(void)
    		{
    			InitializeComponent();
    		}
    
    	protected:
    		void Dispose(Boolean disposing)
    		{
    			if (disposing && components)
    			{
    				components->Dispose();
    			}
    			__super::Dispose(disposing);
    		}
    
    	private: System::Windows::Forms::MainMenu *  mainMenu1;
      (...)
    
    	private:
    		System::ComponentModel::Container * components;
    		void InitializeComponent(void)
    		{
    			this->mainMenu1 = new System::Windows::Forms::MainMenu();
    			this->FileMenu = new System::Windows::Forms::MenuItem();
    			(...)
    
    		}	
    
    public: void LoadXLSFile();
    
    private: System::Void FileLoad_Click(System::Object *  sender, System::EventArgs *  e)
    		 {	 					
    				LoadXLSFile();
    		 }
    
    private: void ListWorksheets(BExcel* bexcel);
    
    private: void ListColNames(BExcel* bexcel);
    
    private: System::Void ComboBoxWorkSheets_SelectedIndexChanged(System::Object *  sender, System::EventArgs *  e)
    		 {			
    			 ListColNames(&bexcel); // FÜHRT ZU FEHLER!
    		      // ListColNames(*bexcel); // FÜHRT AUCH ZU FEHLER!
    		 }
    };
    }
    

    Form1.cpp:

    #include "stdafx.h"
    #include "Form1.h"
    #include "stdafx.h" 
    #include "BExcel.hpp"
    #include <windows.h>
    
    using namespace testwinforms;
    using namespace YExcel;
    
    int APIENTRY _tWinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPTSTR    lpCmdLine,
                         int       nCmdShow)
    {
    	System::Threading::Thread::CurrentThread->ApartmentState = System::Threading::ApartmentState::STA;
    	Application::Run(new Form1());
    	return 0;
    }
    
    BExcel bexcel;
    
    void Form1::LoadXLSFile()
    		{
    			        // Sicherheitsabfrage fehlt, ob aktuelles file save oder close oder abort
    			 		System::Windows::Forms::OpenFileDialog* dlg = new OpenFileDialog();
    					dlg->Filter="Excel (*.xls)|*.xls";
    					if(System::Windows::Forms::DialogResult::OK==dlg->ShowDialog()) {
    						String *strPath = dlg->FileName; // Pointer auf Pfad
    						const char* cPath = (char*)(void*)Marshal::StringToHGlobalAnsi(strPath); //String* to char*	
    
    						try{
    							FileCloser();
    							if (bexcel.Load(cPath)) {
    								FileSave->set_Enabled(1);
    								FileSaveAs->set_Enabled(1);
    								FileClose->set_Enabled(1);
    								ComboBoxWorkSheets->set_Enabled(1);
    								labelCurrentFile->Text=String::Concat("Current File: ",cPath);								
                                 	statusBar_FileSucLoaded->Text = "File has been loaded successfully.";
    								statusBar->ShowPanels = true;
    
    							    ListWorksheets(&bexcel); // FUNKTIONIERT
    							}						
    							else {
    							    statusBar->ShowPanels = false;
    							}
    						}
    						catch (exception ex){};				 
    					}
    		}
    
    void Form1::ListColNames(BExcel* bexcel) {...}
    
    void Form1::ListWorksheets(BExcel* bexcel)
    		 {	
    			 int strTotalWorkSheets = bexcel->GetTotalWorkSheets();
    			 if (strTotalWorkSheets==1)
    (...)
    		 }
    


  • Welchen Fehler wirfst es denn ?
    Geht nicht ist keine Fehlerbeschreibung!

    Leg doch BExcel bexcel; als Member der Klasse Form an.



  • der fehler ist:

    Form1.h(354): error C2065: 'bexcel' : undeclared identifier

    ...kannst du mir bitte sagen, wie ich so einen "member" anlege?



  • class Grundlagen
    {
      Irgnedwas yzx; // << Member
    }
    


  • herrje, das hab ich ja eigentlich gemacht, nur die class def. fehlt. danke! werd ich nachher mal probieren, muss jetzt leider los. sonst noch verbesserungsvorschläge?



  • errje, das hab ich ja eigentlich gemacht, nur die class def. fehlt

    😕



  • Ich würde Dir raten eine aktuellere IDE zu benutzen (z.B. VS2008) welche C++/CLI unterstützt.

    Dein Code ist Managed C++, eine nicht mehr supportete Zwischenlösung, die auf dem Weg zu C++/CLI entstanden ist.

    Grüsse Simon



  • Danke für den Hinweis. Läuft der Code dann so wie er ist auch auf VS 2008 oder müsste ich Umstellungen vornehmen? Falls ja, welche wären das, gibt es dazu einen Text/Thread, der die Änderungen beschreibt? 🙂



  • @Knuddlbaer: Sorry, ich brauch noch nen Tipp für den member. Ich erstelle also die class in form1.h, deklariere dann BExcel bexcel; und packe alle Methoden auch in die class, richtig? Was muss ich dann in der form.cpp ändern und wie greife ich dann auf bexcel zu?



  • Scanner schrieb:

    Danke für den Hinweis. Läuft der Code dann so wie er ist auch auf VS 2008 oder müsste ich Umstellungen vornehmen? Falls ja, welche wären das, gibt es dazu einen Text/Thread, der die Änderungen beschreibt? 🙂

    http://msdn.microsoft.com/de-de/library/ms235298(VS.80).aspx

    http://blog.kalmbachnet.de/?postid=71
    http://blog.kalmbachnet.de/?postid=95

    Zu dem Member: Schau bitte in einem C++ Tutorial oder C++ Buch im Bereich Klassen und Objekte nach. Du findest auch ein paar Informationen dazu in der FAQ (http://www.c-plusplus.net/forum/viewforum-var-f-is-59.html)



  • Danke für die Links. Was ein Member ist, scheint mir jetzt klar zu sein und ich habe ihn in Form1.h eingefügt, was 80x die Fehlermeldung "Form1.h(30): error C3633: cannot define 'bexcel' as a member of managed 'testwinforms::Form1'" brachte. Er verweigert also offenbar genau das, was Du mir geraten hast. Liegt das vielleicht an meiner IDE VS2003 und daran, dass ich managed code verwende (was Simon vorher gesagt hat)? Würde das denn mit "modernisiertem Code" in VS2008 nun funktionieren? Bin verwirrt... 😞

    (...)
    	public __gc class Form1 : public System::Windows::Forms::Form
    	{
    		BExcel bexcel;
    
    	public:
    		Form1(void)
    		{
    			InitializeComponent();
    		}
    (...)
    


  • ...kann ich hier noch mit hilfe rechnen oder was muss ich vorher noch handstand machen? Ich glaub mehr als mich einlesen und ein paar stunden probieren kann man nicht oder?


Anmelden zum Antworten