Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

spacegaier

Alter Hase

  • »spacegaier« ist der Autor dieses Themas

Beiträge: 572

Beruf: Student

  • Private Nachricht senden

1

27.12.2006, 00:50

"Bild konnte nicht geladen werden!"

Hallo zusammen,

ich habe mal wieder ein total blödes Problem:

ich will mit der Winapi ein Bild laden und anzeigen, aber das Laden klappt (wie mir meine Sicherheitsabfrage mitteilt) nicht :( . Ich sehe aber keinen Fehler und die IDE motz auch nicht.

Hier der Code (ich hoffe jemand findet meinen Fehler):

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
HBITMAP         hBitmap;
BITMAP          bitmap ;
HDC             hdc, hdcBmp;

//[---]


case WM_CREATE:
        {
            hBitmap = (HBITMAP)LoadImage(NULL,TEXT("bmp_2.bmp"),IMAGE_BITMAP,0,0,LR_LOADFROMFILE);

            if(hBitmap == NULL) 
            { 
                MessageBoxW(hwnd,TEXT("Bild konnte nicht geladen werden"),TEXT("Error"),0); 
                return -1; 
            }

            hdcBmp = CreateCompatibleDC(hdc);
            SelectObject(hdcBmp, hBitmap);

            return 0;
        }

//[---]


case WM_PAINT:
        {
            hdc = BeginPaint(hwnd, &ps);      

            BitBlt(hdc, x * cxBlock, y * cyBlock, bitmap.bmWidth, bitmap.bmHeight,  
                                    hdcBmp, 0, 0, SRCCOPY) ; 
         
            EndPaint(hwnd, &ps);
            return 0;
        }

        
    case WM_DESTROY:
        {
            DeleteDC (hdcBmp);
            DeleteObject(hBitmap); 
            PostQuitMessage(0);
            return 0;
        }

Fred

Supermoderator

Beiträge: 2 121

Beruf: Softwareentwickler

  • Private Nachricht senden

2

27.12.2006, 01:00

Sicher, dass das Bild fehlerfrei ist?

rklaffehn

Treue Seele

Beiträge: 267

Wohnort: Braunschweig

  • Private Nachricht senden

3

27.12.2006, 11:41

Es gibt ein paar potentielle Probleme hier.

Ohne explizite Pfadangabe sucht die Funktion im aktuellen Verzeichnis. Es könnte also sein, dass das Bild einfach nicht gefunden wird.

GetLastError liefert dir einen Fehlercode, der evtl. eher erklärt, was genau eigentlich fehlgeschlagen ist.

Versuch mal LoadImageW (falls das nicht sowieso als Macro abgebildet ist), dann aber ohne das TEXT Macro, sondern mit L"bmp_2.bmp" als Parameter. Generell gilt: Wenn du eine LalalaW Funktion benutzt, darfst du das TEXT Macro nicht verwenden, sondern musst immer L"aber" schreiben.
God is real... unless declared integer.
http://www.boincstats.com/signature/user_967277_banner.gif

Fred

Supermoderator

Beiträge: 2 121

Beruf: Softwareentwickler

  • Private Nachricht senden

4

27.12.2006, 11:43

Also in meinem Programmverwenete ich auch TEXT() Das funktionierte auch

rklaffehn

Treue Seele

Beiträge: 267

Wohnort: Braunschweig

  • Private Nachricht senden

5

27.12.2006, 11:46

Zitat von »"Fred"«

Also in meinem Programmverwenete ich auch TEXT() Das funktionierte auch


Lies nochmal genau, was ich dazu geschrieben habe... :evil:

Wenn nämlich _UNICODE definiert ist, hast du Glück, und TEXT liefert den richtigen Typ. Sonst klappt das nicht. ABER: Unicode war hier nicht die Frage.
God is real... unless declared integer.
http://www.boincstats.com/signature/user_967277_banner.gif

spacegaier

Alter Hase

  • »spacegaier« ist der Autor dieses Themas

Beiträge: 572

Beruf: Student

  • Private Nachricht senden

6

27.12.2006, 11:50

Eigentlich ja. Ich habe einfach ein Quadrat genommen und es mit einer Farbe gefüllt (in Paint) und als 24-Bit-Bitmap gespeichert.

Heißt deine Nachfrage, dass der Code eingentlich stimmt?

rklaffehn

Treue Seele

Beiträge: 267

Wohnort: Braunschweig

  • Private Nachricht senden

7

27.12.2006, 12:01

Zitat von »"spacegaier"«

Heißt deine Nachfrage, dass der Code eingentlich stimmt?


Naja, wenn deine Sicherheitsabfrage, ob das Bild geladen werden konnte schon anschlägt, braucht man sich den restlichen Code nicht anschauen, weil der sowieso nichts richtig machen kann. Das Zeichnen wird logischerweise fehlschlagen, wenn kein Bild geladen werden konnte.

Aber, jetzt wo du fragst, würde ich sagen, der Rest hat auch noch Fehler, oder dein Code-Schnipsel zeigt nicht alles, was da wirklich steht.

hdcBmp und hBitmap dürfen z.B. keine lokalen Variablen sein, weil die Fensterprozedur mehrfach aufgerufen wird, und sie somit immer ihren Wert "vergessen".

bitmap wird an keiner Stelle initialisiert, aber zum Zeichnen benutzt.

Ein paar Variablen (x, y, cxBlock, ...) sind nichtmal deklariert.
God is real... unless declared integer.
http://www.boincstats.com/signature/user_967277_banner.gif

spacegaier

Alter Hase

  • »spacegaier« ist der Autor dieses Themas

Beiträge: 572

Beruf: Student

  • Private Nachricht senden

8

27.12.2006, 12:17

Also: Der Fehler kommt nicht mehr. Ich habe gerade bemerkt, dass VC++8 das Bild in einem anderen Ordner sucht, als es VC++7 gemacht hat (total blöde find ich) -> jetzt kommt kein Fehler mehr.

Aber die Bilder werden noch nicht gezeichnet. Ich poste jetzt mal die ganze Fensterprozedur und könntest du mir bitte sagen, wo ich dann hdcitmap und Co. definieren soll, wenn nicht in der Fensterprozedur (soll ich es ganz am Anfang nach #inlcude <windows.h> machen?).

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    //Variablen

    //---------

    static BOOL     fState[FIELD_COUNT_X][FIELD_COUNT_Y];
    static int      cxBlock, cyBlock;
    HBITMAP         hBitmap;
    BITMAP          bitmap ;
    HDC             hdc, hdcBmp;
    int             x, y;
    PAINTSTRUCT     ps;
    RECT            rect;
    
    // Nachrichten switchen

    //-------------------

    switch(message)
    {
        // Fenster wird erstellt

        //----------------------

    case WM_CREATE:
        {
            hBitmap = (HBITMAP)LoadImageW(NULL,L"bmp_top.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);

            if(hBitmap == NULL) 
            { 
                MessageBoxW(hwnd,TEXT("Bild konnte nicht geladen werden"),TEXT("Error"),0); 
                return -1; 
            }

            hdcBmp = CreateCompatibleDC(hdc);
            SelectObject(hdcBmp, hBitmap);

            return 0;
        }

        // Fenstergröße wird verändert

        //----------------------------

    case WM_SIZE:
        {   
            cxBlock = LOWORD(lParam) / FIELD_COUNT_X;
            cyBlock = HIWORD(lParam) / FIELD_COUNT_Y;
            return 0;
        }

        // Linke Maustaste gedrückt

        //-------------------------

    case WM_LBUTTONDOWN:
        {
            x = LOWORD(lParam) / cxBlock;
            y = HIWORD(lParam) / cyBlock;

            if(x < FIELD_COUNT_X && y < FIELD_COUNT_Y)
            {
                fState[x][y] ^= 1;

                rect.left   = x * cxBlock;
                rect.top    = y * cyBlock;
                rect.right  = (x + 1) * cxBlock;
                rect.bottom = (y + 1) * cyBlock;

                InvalidateRect(hwnd, &rect, FALSE);
            }
            else
            {
                MessageBeep(0);
            }
            return 0;
        }

        // System oder andere Anwendung will zeichnen

        //-------------------------------------------

    case WM_PAINT:
        {
            hdc = BeginPaint(hwnd, &ps);      

            for(x = 0 ; x < FIELD_COUNT_X ; x++)
            for(y = 0 ; y < FIELD_COUNT_Y ; y++)
            {
                Rectangle(hdc, x * cxBlock, y      * cyBlock,
                         (x + 1) * cxBlock, (y +1) * cyBlock);

                BitBlt(hdc, x * cxBlock, y * cyBlock, bitmap.bmWidth, bitmap.bmHeight,  
                                    hdcBmp, 0, 0, SRCCOPY) ; 

                if(fState[x][y])
                {
                    MoveToEx(hdc, x      * cxBlock, y      * cyBlock, NULL);
                    LineTo  (hdc,(x + 1) * cxBlock,(y + 1) * cyBlock);
                    MoveToEx(hdc, x      * cxBlock,(y + 1) * cyBlock, NULL);
                    LineTo  (hdc,(x + 1) * cxBlock, y      * cyBlock); 
                }
            }
            EndPaint(hwnd, &ps);
            return 0;
        }

        // Anfrage zum Beenden

        //--------------------

    case WM_DESTROY:
        {
            DeleteDC (hdcBmp);
            DeleteObject(hBitmap); 
            PostQuitMessage(0);
            return 0;
        }
    }
    // Den Rest der Standardwindowprozedur überlassen

    //-----------------------------------------------

    return DefWindowProc(hwnd, message, wParam, lParam);
}

rklaffehn

Treue Seele

Beiträge: 267

Wohnort: Braunschweig

  • Private Nachricht senden

9

27.12.2006, 12:37

Also,

hdcBmp und hBitmap müssen, wie z.B. cxBlock ebenfalls static sein, damit sie ihren Wert auch über mehrerer Aufrufe der WndProc hinweg behalten. Damit sind sie dann keine lokalen Variablen mehr, sondern globale, die aber nur in WndProc sichtbar sind.

Gleiches gibt für bitmap, nur dass du hier zusätzlich niemals etwas zuweist. Vermutlich muss man erst aus hBitmap die entsprechenden Informationen abgreifen, aber k.a. ob das stimmt und wie das ggf. geht. Das musst du schon selbst rausfinden. ;) Ausserdem meinst du eigentlich an dieser Stelle vermutlich sowies min (cxBlock, bitmap.bwWidth) etc., weil BitBlt nicht skaliert (sonst eben StrechBlt nehmen)

Was ich eben auch noch sehe: der Parameter hdc in CreateCompatibleDC wird ebenfalls uninitialisiert benutzt, so dass auch dieser Aufruf fehlschlagen dürfte.

Ob das aber alle Probleme sind, kann ich nicht sagen. :p
God is real... unless declared integer.
http://www.boincstats.com/signature/user_967277_banner.gif

Firefly

Alter Hase

Beiträge: 484

Wohnort: Irgendwoundnirgendwo

  • Private Nachricht senden

10

27.12.2006, 12:59

Zitat

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
case WM_CREATE: 
        { 
            hBitmap = (HBITMAP)LoadImageW(NULL,L"bmp_top.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE); 

            if(hBitmap == NULL) 
            { 
                MessageBoxW(hwnd,TEXT("Bild konnte nicht geladen werden"),TEXT("Error"),0); 
                return -1; 
            } 

            hdcBmp = CreateCompatibleDC(hdc); 
            SelectObject(hdcBmp, hBitmap); 

            return 0; 
        }


Verschieb doch mal alle Zeichenfunktionen in WM_PAINT!
Dann müsste es funktionieren!


C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hDC,hDCmem;
hDC=BeginPaint(hWnd,&ps);
//Zeichenfunktionen

hDCmem=CreateCompatibleDC(hDC);
SelectObject(hdcmem,hBitmap);
BitBlt(...);
EndPaint(hWnd,&ps);
return 0;
}


Edit: Wenn du allerdings die Bitmap in WM_CREATE laden willst muss sie static sein!

Werbeanzeige