Heike711 Geschrieben 20. Juni 2007 Geschrieben 20. Juni 2007 Hallo, ich schreibe momentan ein Programm bei dem verschieden Elemente visualisiert werden sollen (Linien, Bitmaps, Rechtecke,...), dazu verwende ich Microsoft eMbedded Visual C++. Jetzt habe ich ein Problem. Ich habe in einem Testprogramm ein Bitmap in die Resource geladen und es dann mit der LoadBitmap-Funktion auch darstellen können. Jedoch habe ich jetzt das Problem, dass das Bitmap nicht dargestellt wird. Habe eine Klasse SIControl erstellt, von der die Klassen erben (SILine, SIBitmap,...). Die Linien werden gezeichnet und dargestellt nur eben nicht das Bitmap. :confused: Hier zuerst der Code in dem die Klassen definiert sind: // SIControl.cpp: implementation of the SIControl class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include <windows.h> #include "resource.h" #include <Commctrl.h> #include "SIControl.h" #include "SIBitmap.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// SIControl::SIControl() { } SIControl::~SIControl() { } ////////////////////////////////////////////////////////////////////// // SILine Class ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// SILine::SILine(int p_Xstart, int p_Ystart, int p_Xend, int p_Yend, COLORREF p_penColor, int p_penWidth, int p_penDashed, int p_Dashlen, int p_Dashbreak) { Xstart = p_Xstart; Ystart = p_Ystart; Xend = p_Xend; Yend = p_Yend; penColor = p_penColor; penWidth = p_penWidth; penDashed = p_penDashed ; Dashlen = p_Dashlen; Dashbreak = p_Dashbreak; } SILine::~SILine() { } BOOL SILine::Paint(HDC hdc) { HPEN mypen; if(penDashed == 0){ mypen = CreatePen(PS_SOLID,penWidth,penColor); }else{ mypen = CreatePen(PS_DASH,1,penColor); } SelectObject(hdc,mypen); POINT p[2]; p[0].x=Xstart; p[0].y=Ystart; p[1].x=Xend; p[1].y=Yend; Polyline(hdc,p,2); DeleteObject(mypen); return TRUE; } ////////////////////////////////////////////////////////////////////// // SIBitmap Class ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// SIBitmap::SIBitmap(int p_Adress, int p_Align, int p_Autosize, int p_Stretch, int p_BitmapResourceBit0, int p_BitmapResourceBit1, int p_BitmapFileBit0, int p_BitmapFileBit1, int p_Center, int p_BitNr, int p_BitmapWidth, int p_SubsheetEnable, int p_HelpActivate0, int p_HelpActivate1, int p_HelpKontext0, int p_HelpKontext1, int p_Height, int p_Left, int p_Top, BOOL p_Transparent, int p_Variable) { Adress = p_Adress; Align = p_Align; Autosize = p_Autosize; Stretch = p_Stretch; BitmapResourceBit0 = p_BitmapResourceBit0; BitmapResourceBit1 = p_BitmapResourceBit1; BitmapFileBit0 = p_BitmapFileBit0; BitmapFileBit1 = p_BitmapFileBit1; Center = p_Center; BitNr = p_BitNr; BitmapWidth = p_BitmapWidth; SubsheetEnable = p_SubsheetEnable; HelpActivate0 = p_HelpActivate0; HelpActivate1 = p_HelpActivate1; HelpKontext0 = p_HelpKontext0; HelpKontext1 = p_HelpKontext1; Height = p_Height; Left = p_Left; Top = p_Top; Transparent = p_Transparent; Variable = p_Variable; } SIBitmap::~SIBitmap() { } BOOL SIBitmap::Paint(HDC hdc) { PAINTSTRUCT ps; HINSTANCE g_hInst; HDC memory = CreateCompatibleDC(hdc); HBITMAP bild = LoadBitmap(g_hInst,MAKEINTRESOURCE(IDB_BITMAP1)); SelectObject(memory, bild); BitBlt(ps.hdc, 10,10, 50,50, memory, 0, 0, SRCCOPY); DeleteObject(bild); return TRUE; } Hier ist ein weiterer Codeschnipsel, indem die Funktionen in das Fenster eingefügt werden: LRESULT CALLBACK WndProc (HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; switch (umsg) { // Add cases such as WM_CREATE, WM_COMMAND, WM_PAINT if you don't // want to pass these messages along for default processing. case WM_CLOSE: DestroyWindow (hwnd); return 0; case WM_DESTROY: CommandBar_Destroy(hwndCB); PostQuitMessage (0); return 0; case WM_CREATE: break; case WM_COMMAND: break; case WM_SIZE: // Tell the command bar to resize itself to fill the top of the break; case WM_PAINT: PAINTSTRUCT ps; HDC hdc; COLORREF crTxt, crBk; RECT rcClient; hdc = BeginPaint(hwnd, &ps); GetClientRect(hwnd,&rcClient); SILine* pLine = new SILine(0,130,100,30,RGB(255,0,0),2,false,1,2); pLine->Paint(ps.hdc); delete pLine; pLine = new SILine(10,130,220,130,RGB(255,0,255),20,true,1,2); pLine->Paint(ps.hdc); delete pLine; SIBitmap* pBitmap = new SIBitmap(1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 100, 0, 0, 0, 0, 0, 100, 300, 100, true, 0); pBitmap->Paint(ps.hdc); delete pBitmap; EndPaint(hwnd, &ps); break; } return DefWindowProc (hwnd, umsg, wParam, lParam); } Ich bekomme auch keine Fehlermeldung beim Kompilieren oder Bilden. Hoffe, dass mir jemand helfen kann. Mfg und schon einmal vielen Dank im voraus Heike Zitieren
Klotzkopp Geschrieben 20. Juni 2007 Geschrieben 20. Juni 2007 g_hInst ist nicht initialisiert (und auch keine globale Variable, auch wenn der Präfix das andeutet). Bist du sicher, dass LoadBitmap nicht fehlschlägt?Du darfst keine GDI-Objekte löschen, die noch in einen DC selektiert sind.In SIBitmap::Paint gibst du den memory-DC nicht wieder frei (DeleteDC fehlt).Was gibt BitBlt zurück? Zitieren
Heike711 Geschrieben 20. Juni 2007 Autor Geschrieben 20. Juni 2007 Hallo Klotzkopp, erst einmal Danke für deine schnelle Antwort. Nun zu deinen Gegenfragen: 1.) g_hInst ist in einem anderen Codeteil, den ich nicht aufgeführt habe initialisiert ( HINSTANCE g_hInst = NULL; // Handle to the application instance ) 2.) wo soll ich die GDI-Objekte denn ansonsten löschen? 4.) BitBlt soll einen Wert zurückgeben, ist der Wert 0 dann ist ein Fehler aufgetreten. Hoffe, die Helfen diese Info´s und du kannst mir weiter helfen. MFG Heike Zitieren
Klotzkopp Geschrieben 20. Juni 2007 Geschrieben 20. Juni 2007 1.) g_hInst ist in einem anderen Codeteil, den ich nicht aufgeführt habe initialisiert ( HINSTANCE g_hInst = NULL; // Handle to the application instance )Das mag sein, aber in SIBitmap::Paint legst du zusätzlich eine lokale Variable an, die genauso heißt, und die die globale Variable verdeckt. Und diese lokale Variable ist nicht initialisiert. 2.) wo soll ich die GDI-Objekte denn ansonsten löschen?Üblicherweise selektiert man zuerst das Objekt wieder in den DC, das vorher drin war (Rückgabewert von SelectObject), und löscht dann sein eigenes. 4.) BitBlt soll einen Wert zurückgeben, ist der Wert 0 dann ist ein Fehler aufgetreten.Das ist mir klar . Ich möchte wissen, welchen konkreten Wert der Aufruf in deinem Programm zurückgibt. Du solltest dir ganz allgemein angewöhnen, die Rückgabewerte solcher Funktionen zu prüfen. Momentan machst du überhaupt keine Fehlerbehandlung. Zitieren
Heike711 Geschrieben 20. Juni 2007 Autor Geschrieben 20. Juni 2007 Hallo, ich werde jetzt mal ein wenig probieren, wie ich denke das es gehen könnte. Stehe glaub ich momentan auf dem Schlauch, oder es liegt daran, dass ich erst angefangen habe C++ zu programmieren. Zitieren
Heike711 Geschrieben 27. Juni 2007 Autor Geschrieben 27. Juni 2007 Hi, das Problem hat sich erledigt und war wie vermutet nur ein ganz kleiner, hab ein paar Tage mich um etwas anderes gekümmert und heute drauf geschaut und den Fehler gefunden. Danke trotzdem für die Hilfe. Heike Zitieren
Heike711 Geschrieben 28. Juni 2007 Autor Geschrieben 28. Juni 2007 Hi, wollte euch noch mal eben die Lösung posten, falls jemand den selben Fehler macht und ihn wie ich nicht sehe. Ich hatte wie Klotzkopp es sagte das falsche in die DeleteObject() Funktion eingeben, aber habe nicht sofort gewusst, was ich sonst dahinein tun muss. Jetzt steht bei mir im Code: BOOL SIBitmap::Paint(HDC hdc) { PAINTSTRUCT ps; HINSTANCE g_hInst; HDC memory = CreateCompatibleDC(hdc); HBITMAP bild = LoadBitmap(g_hInst,MAKEINTRESOURCE(IDB_BITMAP1)); SelectObject(memory, bild); BitBlt(ps.hdc, 10,10, 50,50, memory, 0, 0, SRCCOPY); DeleteObject(memory); return TRUE; } und alles funktioniert wunderbar. Danke für deine Hilfe Klotzkopp, auch wenn ich für die Lösung trotzdem etwas gebraucht habe. LG und einen schönen Tag (trotz des schlechten Wetters) Heike Zitieren
Klotzkopp Geschrieben 2. Juli 2007 Geschrieben 2. Juli 2007 und alles funktioniert wunderbar.Das bedeutet leider weder, dass der Code fehlerfrei ist, noch dass der Code gut ist. Du hast immer noch ein GDI-Ressourcenleck in dieser Methode, weil du die geladene Bitmap nicht wieder löschst. Früher oder später wird sich das in Anzeigefehlern bemerkbar machen. Außerdem ist es ziemlich schwachsinnig, für jedes Paint-Ereignis die Bitmap erneut zu laden. Die ändert sich doch während der Lebenszeit eines SIBitmap-Objekts nicht. Also lade sie im Konstruktur, merke dir nur das Handle in einem Member, und gib sie im Destruktur wieder frei. Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.