Reine resource dll
-
@std
es handelt sich nicht nur um BMP sondern auch um Deteien die nicht in einem Verzeichnis liegen dürfen. Mit dem BMP sollte nur ein Beispiel sein.@Redhead
dein Prinzip habe ich verstanden, und entspricht dem was ich möchte. Nur geht es nicht vielleicht ein bischen genauer?Was muss ich wo includen, wir genau funktioniert das "benutzedefinierten Erstellen", hast du vielleicht nen Link zum Beispiel, oder einer genaueren Erklärung?
Vielen Dank euch allen schon mal.
asmodia
-
Link hab ich keinen. Vielleicht helfen dir paar Einstellungen weiter.
Also wo unter Projekteintsleungen findest du den Tab "Benutzerdefiniertes Erstellen".
Dort gibst unter Befehle in etwa folgende Zeilen ein.set RCNAME=myApplicationRC set RCPATH=.\%RCNAME%.rc set RESPATH=$(IntDir)\%RCNAME%.res set RCDLL=$(OutDir)\%RCNAME%.dll rc.exe /l 0x407 /d "_DEBUG" /d "_AFXDLL" /fo %RESPATH% %RCPATH% link.exe /nologo /subsystem:windows /dll /machine:I386 /out:"%RCDLL%" /NOENTRY %RESPATH%
Unter Ausgabe steht dann das Ergebnis.
$(OutDir)\myApplicationRC.dll
Nicht vergessen diese Einträge für alle Projekttypen zu machen.
-
Danke, ich werde es gleich mal versuchen.
asmodia
-
Noch eins, wenn ich dich jetzt richtig verstanden habe, werden dann alle Resouren in eine DLL gepackt? ich habe probleme das zweite RC File anzulegen und zu verwenden.
Ich weis das ist ein bischen frech von mir zu fragen, aber kannst du mir nicht ein leerer Dialog Besipiel Projekt per Email schicken?? das sind für dich doch bestimmt nur 3 Minuten und du würdest mich sehr glücklich machen.
Asmodia
-
ich hoffe ich habe dich nicht verärgert. Ich habe es jetzt soweit hinbekommen das die dll erstellt wird. Aber das Icon daraus wird mir noch nicht angezeigt.
Ich werde es weiter probieren, bin aber für jeden weiteren Tipp sehr dankbar.
cu
asmodia
-
Wann und wo wird DAS Icon nicht angezeigt ? Im Explorer oder beim Zugriff auf die
Resource ?
Kuck nach der Erstellung einfach mal mit nem Resource-Editor in deine DLL und
wenn alles drin ist dann ist doch ok. Beim Zugriff musst du dann natürlich diese
DLL laden und verwenden statt deiner Applikation oder auch parrallel beide.
-
Ein einfacher Weg, eine Ressourcen-DLL zu machen, ist ein leeres DLL-Projekt anzulegen (so dass zumindest DllMain() existiert), und dafuer zu sorgen, dass die Resourcen an die DLL angehaengt werden (so wie man's beim EXE macht). Die DLL laedt man spaeter mit LoadLibrary() ein, und nimmt das Library-Handle fuer Aufrufe wie LoadIcon() usw. -- beim Applikations-Icon, das z.B. im Windows Explorer angezeigt wird, musst Du eine Ausnahme machen und es in der EXE belassen.
-
aha, ich habe das laden der DLL vergessen
Wie muss das denn genau aussehen?
Da ich aber in meinem Programm ca 300 Icons und 150 BMP habe, möchte ich nicht vor jedem Icon die DLL laden. Kann ich das auch irgendwie in der Main Klasse machen??
Ich habe schon ein bischen mit dlls gearbeitet und mit dem
__declspec(dllexport)
aber wie schon geschrieben will ich nicht für jede Ressource den Code ändern müssen.
Ich hoffe ihr habt mich jetzt verstanden.
cu
asmodia
-
LoadLibrary(), wenn das funktioniert hat kannst du über den Instance-Handle
LoadIcon() und andere Funktionen aufrufen um die Resourcen zu Laden.
Zum Schluss FreeLibrary() nicht vergessen.
-
puhha, ich glaub ich bin kurz vor der Erleuchtung.
die eine oder andere Frage habe ich gleich noch. Geht jetzt bitte nicht wegasmodia
-
Hier ist mein Code in der OnInt meiner DialogTestExe
HINSTANCE hResDLL = LoadLibrary(_T("mydll_gfx.dll")); HBITMAP hBitmap = LoadBitmap(hResDLL, MAKEINTRESOURCE(IDB_BITMAP1)); FreeLibrary(hResDLL); // Der Rahmen im Dialog in dem das Bitmap der dll angezeigt werden soll.. m_cPic.SetBitmap(hBitmap);
Ich bekomme immer den Fehler
error C2065: 'IDB_BITMAP1': nichtdeklarierter Bezeichner
Meine DLL ist eine MFC Standard (Statische) dll die sich im Release Verzeichnis von meiner Anwendung befindet.
Muss ich noch irgendwas includen, oder wieso wird IDB_BITMAP1 nicht gefunden, was sich sehr wohl in der DLL befindet...??
DANKE
asmodia
-
IDB_BITMAP1 ist nichts anderes als eine Nummer. Unter dieser Nummer ist die
Resource abgelegt. Im Anwendungsprogramm muss diese Nummer natürlich bekannt sein.
Da du die Nummer deiner Bitmap natürlich in der deiner Resource-DLL nachkucken
kannst sollte das für dich kein Problem sein..
-
in der Resource.h der DLL hat IDB_BITMAP1 die ID 3001!?!
Deshalb habe ich in der Resource.h meiner Anwendung
diese Zeile eingefügt.#define IDB_BITMAP2 3001
Die Fehlermeldung ist weg, aber das Bitmap wird nicht angezeigt... ich bin sooo kurz davor, das spüre ich
Was ist jedoch jetzt noch falsch??!?!?
asmodia
-
LoadBitmap()
If the function succeeds, the return value is the handle to the specified bitmap.
If the function fails, the return value is NULL.Windows NT: To get extended error information, callGetLastError.
-
Ja danke, aber das hilft mir jetzt nicht wirklich.
Ich gehe schlafen, vielen Dank euch nocheinmal.
Morgen starte ich den nächsten Versuch ..
asmodia
-
Jaaaa Hurra!!!! es klappt.
hier für alle Verwirrten (wie mich) die Lösung:
Beim Erstellen der DLL unbedingt einen MFC Erweiterungs DLL erstellen.(hatte vorher eine Statisch Verknüpfte)
Dann in der APP Main (.exe) die resource.h der DLL includieren.Und dann um z.B ein Bitmap aus der DLL in der Anwendung anzuzeigen einfach folgenden Code in die Int packen
HINSTANCE hResDLL = LoadLibrary(_T("testDLL.dll")); HBITMAP hBitmap = LoadBitmap(hResDLL, MAKEINTRESOURCE(IDB_BITMAP1)); // Btmap Rahmen m_cPic.SetBitmap(hBitmap); FreeLibrary(hResDLL);
Ich weis Redhead, du hast die Lösung die ganze Zeit gewusst, aber jetzt weis ich sie auch, und bin Mega Happy.
Danke dir nochmal für deine geduld
Ich habe ja auch gerade mal 16 h für die Lösung gebraucht..
Bin wieder pennen
asmodia
-
Folgende Fehlermeldung habe ich noch nach dem Einbau in meine MDI Anwendung
MainFrm.cpp(616) : error C2664: 'CMdiClient::SetBitmap': Konvertierung des Parameters 1 von 'HBITMAP' in 'UINT' nicht möglich Diese Konvertierung erfordert einen reinterpret_cast-Operator oder eine Typumwandlung im C- oder Funktionsformat
Hier ist mein Code
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) { if (CMDIFrameWnd::OnCreateClient(lpcs, pContext)) { m_wndMdiClient.SubclassWindow(m_hWndMDIClient); HINSTANCE hResDLL = LoadLibrary(_T("my_bitmap.dll")); HBITMAP BACKROUNDBMP = LoadBitmap(hResDLL, MAKEINTRESOURCE(IDB_BACKROUND)); FreeLibrary(hResDLL); m_wndMdiClient.SetBitmap(BACKROUNDBMP); // Hintergrundbild MDI Child // alt m_wndMdiClient.SetBitmap(IDB_BACKROUND); // Hintergrundbild MDI Child return TRUE; } else return FALSE; }
An dieser Stelle setzte ich das Hintergrund Bild in meiner MDI Anwendung.
Mit dem alten Code
m_wndMdiClient.SetBitmap(IDB_BACKROUND); //
klappte es wunderbar als das Bitmap noch eine Resource der Anwendung und nicht der DLL war, nur jetzt wo ich das Bitmap aus der DLL Laden will kommt es zu dieser Fehlermledung. Wo ist das Problem, was muss ich tun??
DANKE
asmodia
-
Sach mal, so wie ich deinen Code gerade sehr lädst und schließt du ständig diese eine arme DLL. Warum denn nicht nur einmal laden?
HINSTANCE Klasse::getDll() { static HINSTANCE DLL; if(!DLL) DLL = LoadLibrary(T_("testDLL.dll")); return DLL; } Klasse::~Klasse() { HINSTANCE DLL = getDll(); if(DLL) FreeLibrary(DLL); }
-
Ja, hast schon recht. Aber in dieser Klasse lade ich nur ein Bitmap aus der DLL und öffne Sie also nur einmal. Später wenn ich in einer Klasse mehr Bitmaps aus der DLL benötige, mach ich das anders. Nur wie wandel ich jetzt das HBITMAP in ein UINT um? Denn ein UNIT wird von der Funktion SetBitmap erwartet. Hier ist der Code der Funktion SetBitmap für meinen MDI Client Bereich
//MdiClient.h BOOL SetBitmap(UINT nID);
//MdiClient.cpp BOOL CMdiClient::SetBitmap(UINT nID) { BOOL bResult = true; LockWindowUpdate(); if (m_pBmp) { m_pBmp->DeleteObject(); delete m_pBmp; m_pBmp = NULL; } m_pBmp = new CBitmap(); bResult = m_pBmp->LoadBitmap(nID); UnlockWindowUpdate(); return bResult; }
Ich weis das ich es ändern muss, das kein UNIT erwartet wird. Aber wie mach ich das? oder kann man auch vorher ein HBITMAP in ein UNIT umwandeln??
asmodia
-
Wenn ich jetzt das BMP aus der DLL beim Start der Anwendung Temporär auslagern würde, und es dann m_wndMdiClient.SetBitmap(">>hier<<"); wieder laden würde, müsst das doch funktionieren?!?! aber das wäre nicht soo schön, oder??
asmodia