Announcement

Collapse
No announcement yet.

Bitmap/JPG im Code einbinden

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Bitmap/JPG im Code einbinden

    Hallo Experten,

    ich suche nach einer Möglichkeit Bitmaps oder ähnliche Grafikobjekte direkt zur Kompilationszeit in den Code meiner EXE einzubinden.
    Ich habe jetzt schon einige Zeit gesucht, weiß aber nicht, wie ich es anstellen soll. Ich könnte ja das bmp in einen TBlobStream oder was ähnliches schreiben, aber wie stelle ich es an, dass dieser Stream in meine EXE mit reinkompiliert wird?

    Viele Grüße und Danke im voraus!

    Bodo

  • #2
    Das geht als Resource, die dann durch den Resourcecompiler compiliert wird und zusammen mit den *.obj zu einer EXE gelinkt wird

    So wie das in der DLL beschrieben ist

    http://www.marquardtnet.info/cecke/t...n in einer DLL
    Christian

    Comment


    • #3
      Hallo Christian,

      danke für die schnelle Antwort!

      Comment


      • #4
        Hallo!
        Irgendwie gibts da ein Problem...
        Im Projekt habe ich diverse bmp's und jpg's verwendet.
        Alle Operationen mit den bmp's kalppen auch einwandfrei, aber sobald ich versuche ein JPG in den stream zu laden, bekomme ich eine Exception. Aufruf folgender Zeile:
        Code:
        TResourceStream *rcStream=new TResourceStream((int)hinstDLL,"BACKGRD","RT_RCDATA");
        Resultat: Exception-Klasse: EResNotFound Meldung: 'Ressource 'BACKGRD' wurde nicht gefunden.

        BACKGRD ist aber auf jeden Fall in der *.rc definert, als:
        BACKGRD RCDATA "C:\hierstehtderpfad\Backgrd.jpg"

        Bin mir auch ziemlich sicher, dass Backgrd.jpg in die Ressourcendatei mit rein kompiliert wurde, da die Größe dementsprechend ist.
        Woran kann das also liegen?

        Grüße,

        Bodo

        Comment


        • #5
          Ok, ich habe mich mal Schritt für Schritt voran gehangelt, bin aber leider noch nicht weiter:
          Die Exception wird getriggert, weil in der unit classes TResourceStream.Initialize() von TResourceStream.Create() aufgerufen wird und nicht von TResourceStream.CreateFromID().
          Was auch immer das bedeuten mag...

          Mittlerweiel glaube ich fast, dass meine dll nicht richtig eingebunden ist, denn die Methode Bitmap->LoadFromResourceName() funktioniert auch ohne dass ich die dll dynamisch lade.

          Deshalb hier mal mein Vorgehen:
          Ich habe ein dll-Project erzeugt, hierin befinden sich die dlltest.cpp:
          Code:
          #include <vcl.h>
          #include <windows.h>
          #pragma hdrstop
          int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
          {
          	return 1;
          }
          und die Grafik_src.rc:
          Code:
          BILD1 BITMAP "C:\Dokumente und Einstellungen\bodo\Eigene Dateien\RAD Studio\Projekte\29.bmp"
          BACKGRD  RCDATA "C:\Bild008.jpg"
          Bei Start|Parameter habe ich den Aufruf der exe eines anderen Projekts angegeben.

          Und hier ist der Code, welcher im anderen Projekt ausgeführt wird:
          Code:
          #include <vcl.h>
          #include <jpeg.hpp>
          #pragma hdrstop
          
          #include "Unit2.h"
          //---------------------------------------------------------------------------
          #pragma package(smart_init)
          #pragma resource "*.dfm"
          TForm2 *Form2;
          //---------------------------------------------------------------------------
          __fastcall TForm2::TForm2(TComponent* Owner)
          	: TForm(Owner)
          {
          }
          //---------------------------------------------------------------------------
          void __fastcall TForm2::Button1Click(TObject *Sender)   //Klappt wunderbar!!!
          {
          HINSTANCE hinstDLL=LoadLibrary("dlltest.dll");
          
          Graphics::TBitmap *mybitmap1=new Graphics::TBitmap();
          mybitmap1->LoadFromResourceName((int)hinstDLL,"BILD1");
          TRect pixarea;
          pixarea.top=10;
          pixarea.left=10;
          pixarea.right=100;
          pixarea.Bottom=110;
          
          Canvas->StretchDraw(pixarea,mybitmap1);
          }
          //---------------------------------------------------------------------------
          void __fastcall TForm2::Button2Click(TObject *Sender)
          {
          HINSTANCE hinstDLL=LoadLibrary("dlltest.dll");
          TJPEGImage* NewJpg = new TJPEGImage();            
          TResourceStream *rcStream=new TResourceStream((int)hinstDLL,"BACKGRD","RT_RCDATA");  //EXCEPTION!!!
          NewJpg->LoadFromStream(rcStream);
          TRect pixarea;
          pixarea.top=10;
          pixarea.left=10;
          pixarea.right=100;
          pixarea.Bottom=110;
          
          Canvas->StretchDraw(pixarea,NewJpg);
          		NewJpg->Free();
          }
          Edit: Ach so, wenn ich übrigens ein weiteres Bild mit in die *.rc mit aufnehme, wächst auch die Größe meiner exe um die entsprechende Bytezahl an...
          Zuletzt editiert von bodo2407; 09.11.2009, 16:44. Reason: weitere Bemerkung eingefügt

          Comment


          • #6
            Hallo, ich habe nochmal etwas tiefer gebohrt.
            Aus irgendeinem Grunde werden die Funktionen in der dll nicht gefunden.

            Habe folgende dll (dlltest.cpp) erzeugt:
            Code:
            //---------------------------------------------------------------------------
            
            #include <vcl.h>
            #include <windows.h>
            #include "dlltest.h"
            #pragma hdrstop
            /
            //---------------------------------------------------------------------------
            
            #pragma argsused
            int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
            {
            
            
            	return 1;
            }
            //---------------------------------------------------------------------------
            int _export __stdcall getsum(int a, int b){
            
            return (a+b);
            }
            Hier der Header (dlltest.h):
            Code:
            #ifdef __DLL__
            #	define DLL_TYP __declspec(dllexport)
            #else
            #	define DLL_TYP __declspec(dllimport)
            #endif
            
            int DLL_TYP __stdcall getsum(int,int);
            In einem externen Projekt versuche ich nun folgendes (unit2.cpp):
            Code:
            void __fastcall TForm2::Button3Click(TObject *Sender)
            {
            int i;
            
            HINSTANCE hinstDLL=LoadLibrary("dlltest.dll");
            if(hinstDLL==0)ShowMessage("Satz mit X...");
            int (__stdcall* getsum)(int,int);
            
            getsum=(int(__stdcall*)(int,int))GetProcAddress(hinstDLL,"_getsum");
            //getsum=(int(__stdcall*)(int,int))GetProcAddress(hinstDLL,"getsum$qqsii");  //name aus impdef
            if(getsum==0)ShowMessage("sapperlott!!!");
            i=getsum(50,35);
            Edit1->Text=i;
            }
            "getsum$qqsii" als Namen des Einsprungpunkts (die kommentierte Zeile) habe ich mittels IMPDEF herausgefunden. Ändert leider nix am Resultat: GetProcAddress gibt stets 0 zurück.
            Die dll und die lib wurden erzeugt.

            An was kann das liegen? Die Library wird ohne zu meckern geladen.

            Comment


            • #7
              Originally posted by bodo2407 View Post
              Mittlerweiel glaube ich fast, dass meine dll nicht richtig eingebunden ist, denn die Methode Bitmap->LoadFromResourceName() funktioniert auch ohne dass ich die dll dynamisch lade.
              Du hattest vor die dll zur laufzeit zu laden mit LoadLibrary(). Aber du hast sie bei compilieren und linken schon mit in die exe gebunden.

              Mann kann nämlich eine dll statisch und dynamisch linken. Bij dynamisch linken brachts du zur 'runzeit' LoadLibrary();

              Edit: Ach so, wenn ich übrigens ein weiteres Bild mit in die *.rc mit aufnehme, wächst auch die Größe meiner exe um die entsprechende Bytezahl an...
              Siehst du warum dass so ist? Du hattest vor die bilder in eine dll zu speichern damit deine exe klein bleibt. Jetzt hast die dll mit in den exe gebunden. Zur runzeit brauchst die dll dann nicht mehr.

              Wenn du die dll in die exe last dann macht eine dll kein zweck. Dan kanst die resource besser gleich einbinden.

              Comment


              • #8
                Originally posted by bodo2407 View Post
                int _export __stdcall getsum(int a, int b)
                int getsum(int a, int b)

                int DLL_TYP __stdcall getsum(int,int);
                extern "C" int DLL_TYP getsum(int,int);

                Versuch es mahl anders.

                Comment


                • #9
                  Siehst du warum dass so ist? Du hattest vor die bilder in eine dll zu speichern damit deine exe klein bleibt. Jetzt hast die dll mit in den exe gebunden. Zur runzeit brauchst die dll dann nicht mehr.
                  Mein eigentliches Ziel war, die Bilder in die Exe mit einzubinden, so dass der USer kein umständliches Install, etc. braucht, sondern nur die exe starten muss.
                  Sprich, wenn ich dass mit dem JPEG als Ressource hinbekommen würde, wäre ich schon sehr dankbar.

                  Wenn du die dll in die exe last dann macht eine dll kein zweck. Dan kanst die resource besser gleich einbinden.
                  Da hast du natürlich Recht, allerdings weiß ich nicht, wie es möglich sein soll, JPEGS ohne dll einzubinden, da
                  Code:
                  TResourceStream *rcStream=new TResourceStream((int)hinstDLL,"BACKGRD","RT_RCDATA");
                  ja hinstDLL benötigt. Dumm nur, dass der Aufruf eine Exception auslöst.

                  Mann kann nämlich eine dll statisch und dynamisch linken. Bij dynamisch linken brachts du zur 'runzeit' LoadLibrary();
                  Wie kann ich denn unterscheiden ob explizit oder implizit gelinkt wird?

                  Danke!

                  Comment


                  • #10
                    Zitat:
                    Zitat von bodo2407 Beitrag anzeigen
                    int _export __stdcall getsum(int a, int b)
                    int getsum(int a, int b)

                    Zitat:
                    int DLL_TYP __stdcall getsum(int,int);
                    extern "C" int DLL_TYP getsum(int,int);

                    Versuch es mahl anders.
                    Danke, dass hat geklappt!
                    Warum versteh ich zwar nicht, aber trotzdem schon mal schön

                    Das öffnen der "BACKGRD"-Ressource als Stream klappt leider immer noch nicht....

                    Comment


                    • #11
                      Denke dass du dich es alles zu schwer machst.

                      Wenn du zum beispiel fünf Bilder einbinden wilst nimme dann einfach ein extra TForm auf in dein Programm. Placiere funf TImage componenten darauf und lade ueber den ObjectInspector in den Property Picture in jedes TImage::Picture ein Bild.

                      Fertig.

                      Zur runzeit brauchst nur de TForm da zu sein. Wenn du ein Bild brauchst kopierst er einfach.

                      Du kannst auch dass TImage not Visible auf denn richtigen Plaz plazieren und wenn nötig Visible machen.

                      Comment


                      • #12
                        Placiere funf TImage componenten darauf und lade ueber den ObjectInspector in den Property Picture in jedes TImage::Picture ein Bild.
                        Das würde natürlich gehen. Allerdings hab ich noch ein größeres binärfile mit messdaten, welches ich z.Zt. mit fopen() und Konsorten behandle. Wenn ich das mittels RCDATA in die Ressource eibetten könnte, wäre das natürlich ideal...

                        Comment


                        • #13
                          Also, ich stehe immer noch auf dem Schlauch... vielleicht kann mir ja nochmal jemand helfen?

                          Wenn ich die Ressource direkt in die exe mit rein linken will (nix dynamisches) benötige ich dann überhaupt eine dll?
                          Zumindest funktioniert es für bmp's ohne diese, indem ich einfach NULL für Instance übergebe...
                          Code:
                          NewBmp->LoadFromResourceName(NULL,"BILD1");
                          Aus welchem Grunde funktioniert das nicht für
                          Code:
                          TResourceStream *rcStream=new TResourceStream(NULL,"BACKGRD","RT_RCDATA");
                          Muss ich irgendwo noch die *.res datei includen?
                          Benötige ich noch irgendwelche Linker/Compiler/Ressourcencompiler-Direktiven?

                          Comment


                          • #14
                            Originally posted by bodo2407 View Post
                            Wenn ich die Ressource direkt in die exe mit rein linken will (nix dynamisches) benötige ich dann überhaupt eine dll?
                            Nein.

                            Code:
                            NewBmp->LoadFromResourceName(NULL,"BILD1");
                            TResourceStream *rcStream=new TResourceStream(NULL,"BACKGRD","RT_RCDATA");
                            Weshalb benutzt du zwei verschiedene Functionen?
                            Edit: Ok verstehe schon. De bitmap macht alles selbs. Aber bei die resourcestream musst du wahscheinlich erst eine resource
                            ofnen und ein handle bekommen. Google mahl was...


                            Muss ich irgendwo noch die *.res datei includen?;
                            Wenn der bitmap schon mitkomt kann das nicht das Problem sein.
                            Zuletzt editiert von Hans G; 11.11.2009, 17:03.

                            Comment

                            Working...
                            X