eingebettete Ressourcen Problem - Release Modus



  • Moin ...

    Wenn ich versuche meine Anwendung im Release Modus zu kompilieren - gibt es keine Schwierigkeiten dabei. Starte ich nun aber die Anwendung - gibt es welche, und zwar bei denen, denen ich eingebettete Ressourcen hinzugefügt habe. Hierbei handelt es sich meistens um Bitmaps. Hinzugefügt habe ich sie ganz normal über "Vorhandenes Element hinzufügen" im Projekt. Eingetragen unter Linker - Eingabe sind sie auch.

    Abgerufen wird die ganze Sache z.B. so:

    pictureBox2->BackgroundImage = gcnew Bitmap (a->GetManifestResourceStream ("wolkig.png"));
    

    Wie gesagt klappt das im DEBUG Modus einwandfrei. Nun kommt es gelegentlich zu folgender Fehlermeldung:

    ...Auf das verworfene Objekt kann nicht zugegriffen werden. Objektname: "PictureBox".

    Da ich davon überzeugt bin, dass es Fehler bei den Ressourcen gibt, habe ich folgendes Versucht:

    System::IO::Stream^ info = a->GetManifestResourceStream ("wolkig.png");
    		if (info == nullptr) MessageBox::Show ("Wetterpanel","Fehler");
    

    Und wie erwartet wird die MessageBox auch prompt angezeigt. Beim kompilieren erhalte ich lediglich folgenden Warnungen:

    1>LINK : warning LNK4247: Der Einstiegspunkt ""int __clrcall main(cli::array<class System::String ^ >^)" (?main@@$$HYMHP01AP01APAAVString@System@@@Z)" hat bereits ein Threadattribut; "/CLRTHREADATTRIBUTE:MTA" wird ignoriert.
    1>LINK : warning LNK4199: /DELAYLOAD:OleAcc.dll wird ignoriert; keine Importe von OleAcc.dll gefunden.

    Erscheint mir im Moment jedoch nicht relevant, aber lasse mich gerne eines besseren belehren.

    Nun ja, meine Frage ist nun klar. Mache ich einen grundlegenden Fehler bei der Arbeit mit den Ressourcen - oder habe ich einfach etwas übersehen? Vielleich kennst sich einer von euch damit aus .. und hilft mir auf die Sprünge.



  • Das sieht aber eher so aus, also ob die "pictureBox2" schon zerstört wurde... hat also nix mit den Ressourcen zu tun...



  • Bist du dir da sicher, und vor allem - wenn ja, warum ist das so?



  • Hab mal noch nen bisschen gegoogelt. Bin ich beim Stichwort "Instanzzähler" richtig? Muss ich mich darum selber kümmern oder wird das intern geregelt?



  • Ich bin mir sicher, weil die Fehlermeldung ja wohl lautet:

    Auf das verworfene Objekt kann nicht zugegriffen werden. Objektname: "PictureBox".

    Und mit Instanzzähler hat das nix zu tun... dies gibt es in .NET nicht...

    Aber irgendjemand hat von der "PictureBox" das "Dispose" aufgerufen...
    Weis doch einfach mal ein Leeres-Image zu, dann siehst Du es gleich ob es geht oder nicht...



  • Habe ich bereits gemacht. Du hattest recht. Dann stellt sich mir die Frage, wer ruft die PictureBox Dispose auf ? Und gleich bei sämmtlichen UserControls ?

    Habe das ganze mal in einen try catch block gefasst und erhalte folgende ArgumentException:

    pictureBox2->BackgroundImage = gcnew Bitmap (a->GetManifestResourceStream ("bedeckt.png"));
    
    Der Wert Null für Stream ist ungültig
    

    Setze ich vor den try catch Block bspw. die Hintergrundfarbe der PictureBox neu und beende die Funktion wird kein Fehler ausgegeben. Also geht es nun doch um die Ressourcen - da die PictureBox noch aktiv ist? Irgendwie irreführend die Fehlermeldung.



  • Vermutlich Du selber, wenn Du den Dialog schliesst...
    Setzt doch mal ein Breakpoint auf die "Dispose" Methode des übergeordneten Forms/Controls.



  • Jochen Kalmbach schrieb:

    Vermutlich Du selber, wenn Du den Dialog schliesst...
    Setzt doch mal ein Breakpoint auf die "Dispose" Methode des übergeordneten Forms/Controls.

    Wird erst aufgerufen wenn ich die Hauptform schließe. ( Die Hauptform ist die Sidebar - in welcher die UserControls liegen)



  • Und wo ist die "pictureBox2" drin?



  • Jochen Kalmbach schrieb:

    Und wo ist die "pictureBox2" drin?

    Im UserControl "WetterPanel", welches wiederum via

    (SidebarForm)this->Controls->Add (uc);
    

    zu den Sidebar Controls hinzugefügt wurde.



  • Das ganze sieht in etwa so aus:

    Form1.h (Sidebar)

    #pragma once
    #include "PlugManager.h"
    
    using namespace System;
    using namespace System::ComponentModel;
    using namespace System::Collections;
    using namespace System::Windows::Forms;
    using namespace System::Data;
    using namespace System::Drawing;
    
    namespace Sidebar {		
    
    	public ref class Form1 : public System::Windows::Forms::Form
    	{	
    	protected:	static System::Collections::Generic::List<UserControl^>^ plugins = gcnew System::Collections::Generic::List<UserControl^>();
    

    Form1.cpp

    using namespace System::Reflection;	
    	System::Reflection::Assembly ^exAss;	
    
    	//Hier PlugIns in Liste laden
    	for each(String^ fileName in System::IO::Directory::GetFiles (arbeitsordnerholen () + "\\","*.dll"))
    		{
    		if (fileName->Contains ("DLLpanelklasse") || fileName->Contains ("Interface")) continue;
    		// hier eine Fehlerbehebung für Fehler von LoadFrom
    		try{
    			exAss  = ::Reflection::Assembly::LoadFrom (fileName);		
    			}
    ...
    ...
    for each (SidebarInterface::Interface^ plug in result)
    		{		
    		//SidebarInstanz im PlugIn speichern
    		plug->setSidebarForm (this);
    		plug->setConnectionState (connected);
    
    		//UserControl holen und in Liste speichern		
    		UserControl^ uc = plug->getUserControl ();
    ...
    ...
    this->Controls->Add (uc);
    ...
    ...
    

    DLLBasisKlasse

    namespace DLLpanelklasse {
    
    	public ref class BASISpanel : public System::Windows::Forms::UserControl
    	{	
    	public:
    		BASISpanel(void)
    		{
    			InitializeComponent();			
    		}				
    
    	protected:
    
    		~BASISpanel()
    		{
    			if (components)
    			{
    				delete components;
    			}
    		}
    ...
    

    Interface

    // Interface.h
    
    #pragma once
    
    using namespace System;
    using namespace System::Windows::Forms;
    
    namespace SidebarInterface {
    
    	public interface class Interface
    		{
    			//von Sidebar zu PlugIn
    		public: UserControl ^getUserControl();
    		public: String ^getAuthor();		
    		public: String ^getPlugTitle ();
    		public: void setSidebarForm (Form^);
    		public: void callSpeichern ();
    		public: void callBeenden ();
    		public: void überschriftausblenden ();
    		public: void überschrifteinblenden ();
    		public: void drawborder (UserControl^);
    		public: void setConnectionState (int);
    		public: bool NeedConnection ();
    		};
    

    WetterPanel

    namespace Sidebar {
    
    	public ref class WetterPanel : public DLLpanelklasse::BASISpanel
    	{
    ...
    ...
    public:
    		WetterPanel(void)
    		{
    			InitializeComponent();
    			InitializePanel ();
    		}
    ...
    ...
    


  • Sorry, ich kann da nicht erkennen, wo die PictureBox1 sein soll....
    Irgendjemand ruft auf jeden Fall den Destruktor (IDispose) auf...



  • So ... nun kann ich beruhigt ins neue Jahr starten. Es lag nun doch an den Ressourcen. Ich hatte diese nur in der DEBUG Konfiguration eingetragen, nicht aber in der RELEASE. Ein simpler aber folgenschwerer Fehler.

    Aber die Fehlermeldung war da auch etwas verwirrend. Trotzdem danke Jochen 🙂


Anmelden zum Antworten