Toon posts:

[C++/win32] Bitmap in een Dialog

Pagina: 1
Acties:
  • 247 views sinds 30-01-2008
  • Reageer

Verwijderd

Topicstarter
Mijn vraag is simpel:

Kan ik een bitmap in een dialog zetten?
Ja toch? Maar hoe?

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
                                                BITMAP bm;
            PAINTSTRUCT ps;

            HDC hdc = BeginPaint(hwnd, &ps);

            HDC hdcMem = CreateCompatibleDC(hdc);
            HBITMAP hbmOld = SelectObject(hdcMem, g_hbmBall);

            GetObject(g_hbmBall, sizeof(bm), &bm);

            BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);

            SelectObject(hdcMem, hbmOld);
            DeleteDC(hdcMem);

            EndPaint(hwnd, &ps);


Dit staat in me WM_PAINT case.
De LoadBitmap functie werkt, maar hij geeft een error op regel 54 en daar staat dit:

code:
1
HBITMAP hbmOld = SelectObject(hdcMem, g_hbmBall);


De error is: Cannot convert void * to HBITMAP__ *

Hoe los ik dat op?

  • Freak_NL
  • Registratie: Juli 2000
  • Laatst online: 20-07 09:47
SelectObject geeft void * terug, niet HBITMAP__ *? Ik ben niet zo'n C++ held, maar dat lijkt me waar de compiler over valt.. Drie regels lager gebruik je SelectObject wel als functie die niets retourneerd.

Verwijderd

Topicstarter
Ik heb al geprobeert om alleen SelectObject te gebruiken, zonder dat hij iets returned. Alleen dan verschijnt het plaatje niet op me Dialog.

Verwijderd

Ehhh, kan je dat ding niet gewoon casten??

(Als je trouwens MFC gebruikt kan je ook gewoon een CStatic control in je dialog gooien waarin je vervolgens een bitmap weergeeft dmv CStatic::SetBitmap(...) )

[ Voor 66% gewijzigd door Verwijderd op 10-01-2003 19:59 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 16:13

.oisyn

Moderator Devschuur®

Demotivational Speaker

SelectObject returnt een HGDIOBJ, waar alle gdi objecten zoals de bitmap een soort van subclass van zijn. Je zult expliciet moeten casten naar HBITMAP

[ Voor 46% gewijzigd door .oisyn op 10-01-2003 20:07 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

Topicstarter
Ik begrijp niet helemaal wat je bedoelt, want als ik ze omdraai dan herkent hij HbmOld niet.
En die heb ik wel nodig toch? Of niet?

En wat is expliciet casten? :P

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 16:13

.oisyn

Moderator Devschuur®

Demotivational Speaker

hmm, je hebt het vast over het stuk wat ik weggeedit heb... dat was een foutje, niet goed gelezen :)

casten doe je zo: HBITMAP hbmOld = (HBITMAP) SelectObject(hdcMem, g_hbmBall);

maar dat zal je probleem niet oplossen

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

Topicstarter
Nee dat doet het idd niet, jammer. Ik werk liever nog niet met MFC (ben best een noob, zoals je waarschijnlijk al door had ;)) maar als het niet anders kan???

Iemand anders nog andere suggesties?
Of anders meer info over dat Cstatic control?

alsjeblieft? :)

Verwijderd

.oisyn schreef op 10 januari 2003 @ 20:18:
maar dat zal je probleem niet oplossen
Wat is dan nu het probleem? Met die cast compileert het hier prima!

Verwijderd

Topicstarter
Nou, hij compileert wel, maar dat doet ie ook als je bovenaan \* zet ;).
Het probleem is dan, net als nu, dat ie dan nix doet.

De bitmap komt niet op me beeldscherm.


Ik weet trouwens niet of dit ook belangrijk is: :S

code:
1
2
3
    case WM_CREATE:
    g_hbmBall = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_BALL));
                break;


ghbm_Ball is een global HBITMAP

[ Voor 42% gewijzigd door Verwijderd op 10-01-2003 20:41 . Reden: anders extra post moeten doen ]


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Erm ik zag geen fouten in je code, dus heb ik even voor de zekerheid Petzold erbij opengetrokken en idd je code klopt perfect. Er moet dus iets anders foutgaan.... Post je hele programma eens zodat ik kan uitproberen? Als het 50+ regels is mail maar.

Je hoeft trouwens alleen niet de 'oldbmp' terug te selecten in je memDC voor deletion, als je een DC wegflikkert releast ie automatisch alle selected GDI objects.

Professionele website nodig?


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Verwijderd schreef op 10 januari 2003 @ 18:45:
code:
1
2
                                                BITMAP bm;
            PAINTSTRUCT ps;

Dit staat in me WM_PAINT case.
Dat staat er niet, want in C++ mag je binnen een case geen lokale variabelen definieren :Y)

Professionele website nodig?


Verwijderd

Verwijderd schreef op 10 januari 2003 @ 20:34:
Nou, hij compileert wel, maar dat doet ie ook als je bovenaan \* zet ;).
Het probleem is dan, net als nu, dat ie dan nix doet.

De bitmap komt niet op me beeldscherm.
Zet effe een breakpoint in je WM_PAINT handler en controlleer of alle handles wel normale waarden hebben (!=NULL) en of de height+width van je bitmap kloppen (>0)

  • Korben
  • Registratie: Januari 2001
  • Laatst online: 14-11-2025

Korben

() => {};

curry684 schreef op 10 January 2003 @ 23:15:
[...]

Dat staat er niet, want in C++ mag je binnen een case geen lokale variabelen definieren :Y)
Wel als je de case omsluit met accolades:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
switch (blaat)
{
    case 1:
        int a;
        // dit mag idd niet

        break;

    case 2:
    {
        int b;
        // maar dit wel
    }
}

.oisyn: Échte programmeurs haten PHP met een passie. Ben jij soms geen echte programmeur?


Verwijderd

Topicstarter
Op verzoek van curry684:

code:
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
#include <windows.h>
#include "resource.h"

BOOL check = TRUE;
HBITMAP g_hbmBall = NULL;



BOOL CALLBACK DlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
        case WM_CREATE:
            g_hbmBall = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_BALL));
            if(g_hbmBall == NULL)
                MessageBox(hwnd, "Nope IDB_BALL is niet geladen!", "Error", MB_OK | MB_ICONEXCLAMATION);
        break;
        case WM_CLOSE:
            EndDialog(hwnd, 0);
        break;
        case WM_PAINT:  
        {

            BITMAP bm;
            PAINTSTRUCT ps;

            HDC hdc = BeginPaint(hwnd, &ps);

            HDC hdcMem = CreateCompatibleDC(hdc);
            HBITMAP hbmOld = (HBITMAP) SelectObject(hdcMem, g_hbmBall);

            GetObject(g_hbmBall, sizeof(bm), &bm);

            SelectObject(hdcMem, hbmOld);
            BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);

            DeleteDC(hdcMem);

            EndPaint(hwnd, &ps);

            }
        break;
        
        default:
        return FALSE;
    }
    return TRUE;
}


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow)
{
return DialogBox(hInstance, MAKEINTRESOURCE(IDD_MAIN), NULL, DlgProc);
}


Moet ik de .h en de .rc files ook nog posten?

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Verwijderd schreef op 11 January 2003 @ 12:19:
Moet ik de .h en de .rc files ook nog posten?
Tziet er perfect uit dus mail het hele project maar ff door, kan ik 'm meteen in de compiler gooien.

Professionele website nodig?


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Korben schreef op 11 januari 2003 @ 11:26:
Wel als je de case omsluit met accolades:
Dan staat het technisch gezien niet meer in de case maar in een lokale scope :)

Mooier is, gezien het feit dat deze code C is en geen C++, om de lokale variabelen static te maken bovenin de DlgProc.

Professionele website nodig?


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Sja aan de hand van je mailtje had ik alle fouten binnen 5 minuten gevonden, dus het lijkt me sterk dat je uberhaupt hebt geprobeerd te debuggen: dan was je er namelijk achter gekomen dat je resource nooit wordt geladen (!!!!!) en dat de HBITMAP naar de Ball dus altijd op NULL blijft staan en GetObject dus failt en poep produceert in de Bitmap structuur. De fout is heel simpel overigens en ik had er zonder debugger ook overheen gekeken:
C++:
1
2
3
4
5
case WM_CREATE:
  g_hbmBall = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_BALL));
  if(g_hbmBall == NULL)
    MessageBox(hwnd, "Nope IDB_BALL is niet geladen!", "Error", MB_OK | MB_ICONEXCLAMATION);
  break;

Een DlgProc krijgt nooit een WM_CREATE want die geldt enkel voor afzonderlijke WndProcs. Hier moet je WM_INITDIALOG voor afvangen.

En foutje 2 verscheen pas in je laatste versie (stond in openingspost wel goed):
C++:
1
2
            SelectObject(hdcMem, hbmOld);
            BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);

Op zich is het zoals ik al zei overbodig om de bitmap er weer uit te selecteren voordat je de memDC wegkiepert, maar als je het al zonodig netjes wil doen, doe het dan wel in de correcte volgorde en dus andersom :P Dit schiet niet echt op, lege bitmap terugselecten en dan gaan blitten...

Volgende keer aub even de debugger gebruiken dan had je dit een stuk sneller duidelijker geweest.

Professionele website nodig?


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 16:13

.oisyn

Moderator Devschuur®

Demotivational Speaker

curry684 schreef op 12 januari 2003 @ 22:40:
En foutje 2 verscheen pas in je laatste versie (stond in openingspost wel goed):
C++:
1
2
            SelectObject(hdcMem, hbmOld);
            BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);


dat is waarschijnlijk mijn schuld :P
In mijn eerste post in deze thread had ik namelijk gezegd dat ie de blit en de select om moest draaien, omdat je natuurlijk wel moet selecteren voordat je de blit uitvoert. Echter had ik de code niet goed gelezen, want wat ie juist selecteerde was de oude bitmap, de bitmap die geblit moest worden had ie daarvoor al geselecteerd. Dus ik had het weer weggeedit, maar dat was nadat de topicstarter het al gelezen had, dus hij had het al geprobeerd. En waarschijnlijk is dat probeersel ook de versie die jij ontvangen hebt :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

Topicstarter
Ja hij doet het!

bedankt voor je hulp curry684 en .oisyn!
Pagina: 1