bitmap



  • sorry für diese noob frage, aber ich hab bei google gesucht,
    die suchfunktion benutzt und hab einfach kein tut oder ein code
    gefunden aus dem ich wirklich erschleißen konnte wie man ein bitmap
    darstellt...

    OS: WinXP

    Danke für alle antworten

    MFG NULL



  • In der WinAPI-FAQ gibts "Bitmap speichern" falls du das meinst...



  • nein, einfach nur ein bitmap aus recource oder von nem file laden
    und in nem fenster darsellen, draufmalen, ...



  • LoadBitmap, CreateCompatibleDC -> SelectObject -> BitBlt



  • Danke für die antwort, aber kann mir jemand sagen was ich falsch gemacht habe? :

    #include <windows.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    
    HINSTANCE hInst;
    
    int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                        PSTR szCmdLine, int iCmdShow)
    {
        HWND     hWnd;
        MSG      msg;
        WNDCLASS wc;
    
        const char szAppName[] = "bitmapT";
    
        wc.style          = CS_HREDRAW | CS_VREDRAW;
        wc.lpfnWndProc    = WndProc;
        wc.cbClsExtra     = 0;
        wc.cbWndExtra     = 0;
        wc.hInstance      = hInstance;
        wc.hIcon          = LoadIcon(NULL, IDI_APPLICATION);
        wc.hCursor        = LoadCursor(NULL, IDC_ARROW);
        wc.hbrBackground  = (HBRUSH)GetStockObject(WHITE_BRUSH);
        wc.lpszMenuName   = NULL;
        wc.lpszClassName  = szAppName;
    
        RegisterClass(&wc);
    
        hWnd = CreateWindow( szAppName,
                             "bitmapT",
                             WS_OVERLAPPEDWINDOW,
                             CW_USEDEFAULT,
                             CW_USEDEFAULT,
                             CW_USEDEFAULT,
                             CW_USEDEFAULT,
                             NULL,
                             NULL,
                             hInstance,
                             NULL );
    
        ShowWindow(hWnd, iCmdShow);
        UpdateWindow(hWnd);
    
    	hInst = hInstance;
    
        while(GetMessage(&msg, NULL, 0, 0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    
        return msg.wParam;
    }
    
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	HBITMAP hBmp;
    	HDC memdc = GetDC(hWnd);
    	HDC dc = CreateCompatibleDC(memdc);
    
        switch(message)
        {
        case WM_CREATE:
            {
    			hBmp = LoadBitmap(hInst, "..\\test.bmp");
    			SelectObject(dc, hBmp);
    
                return 0;
            }
    
    	case WM_PAINT:
    		{
    			BitBlt(dc, 0, 0, 0, 0, memdc, 0, 0, SRCCOPY);
    
    			return 0;
    		}
    
    	case WM_CLOSE:
    		{
    			PostQuitMessage(0);
    
    			return 0;
    		}
    
        case WM_DESTROY:
            {
                PostQuitMessage(0);
                return 0;
            }
        }
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    


  • die DC's musst du direkt bei Paint ermitteln, um einen aktuellen zu erhalten, und dann nicht mit GetDC, sondern zwingend mit BeginPaint.

    edit: und hBmp muss static sein.



  • NULL schrieb:

    Danke für die antwort, aber kann mir jemand sagen was ich falsch gemacht habe? :

    findest nicht das dieses keine ausreichende fehlerbeschreibung ist?

    ohne micht weiter damit beschäftigt zu haben würde ich darauf tippen denn
    deine var weden zerstört wenn du den scope verlässt
    [code]
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    static HBITMAP hBmp;
    static HDC memdc = GetDC(hWnd);
    static HDC dc = CreateCompatibleDC(memdc);
    // ..
    [code]

    aufräumen nicht vergessen

    [edit]
    😡 zu langsam



  • sorry, die parameter 7 und 8 von BitBlt sind natürlich gefüllt (mit 32),
    was aber auch nicht zur lösung geführt hat...



  • Der DC, den du erzeugst, wird bei jedem Aufruf der WndProc neu erzeugt und damit die Bitmap in einen hinein selektiert (dieser geht verloren) und dann bei einem neuen Durchlauf der Inhalt eines neuen ("leeren") DC in den Zeichen-DC geblittet.

    Ich versuche mal zu korrigieren:

    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        HBITMAP hBmp;
        static HDC DC = GetDC(hWnd);
        static HDC MemDC = CreateCompatibleDC(DC);
    
        switch(message)
        {
        case WM_CREATE:
            {
                hBmp = LoadBitmap(hInst, "..\\test.bmp");
                SelectObject(MemDC, hBmp);
    
                return 0;
            }
    
        case WM_PAINT:
            {
                BitBlt(DC, 0, 0, 0, 0, MemDC, 0, 0, SRCCOPY);
    
                return 0;
            }
    
        case WM_CLOSE:
            {
                PostQuitMessage(0);
    
                return 0;
            }
    
        case WM_DESTROY:
            {
                PostQuitMessage(0);
                return 0;
            }
        }
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    

    Ohne Garantie 🙂

    Gruss,
    DeSoVoDaMu



  • dreifach hält besser 😃 😉



  • Hab ich mir auch gedacht^^
    Aber nebenbei: die Bmp muss nicht zwingend static sein oder? Und es wuerde reichen, wenn man sie nur in dem WM_CREATE Zweig erzeugt afaik. Nur als "Verbesserungsvorschlag" 🙂



  • das geht doch gar nicht, oder? ich hätts so gemacht:

    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 
    { 
        static HBITMAP hBmp; 
        HDC DC;
        HDC MemDC;
        PAINTSTRUCT ps;
    
        switch(message) 
        { 
        case WM_CREATE: 
            { 
                hBmp = LoadBitmap(hInst, "..\\test.bmp"); 
    
                return 0; 
            } 
    
        case WM_PAINT: 
            { 
                DC = BeginPaint(hWnd, &ps);
                MemDC = CreateCompatibleDC(DC);
                SelectObject(MemDC, hBmp); 
                BitBlt(DC, 0, 0, 0, 0, MemDC, 0, 0, SRCCOPY); 
    
                EndPaint(hWnd, &ps);
    
                return 0; 
            } 
    
        case WM_CLOSE: 
            { 
                PostQuitMessage(0); 
    
                return 0; 
            } 
    
        case WM_DESTROY: 
            { 
                PostQuitMessage(0); 
                return 0; 
            } 
        } 
        return DefWindowProc(hWnd, message, wParam, lParam); 
    }
    


  • Also irgendwie funktionierts trozdem nicht...
    scheint zwar alles richtig zu sein, aber er zeigt einfach kein bild an.

    mal abgesehen von den parametern 4 und 5 bei bitblt die verändert werden mussten 😉



  • (regestrierter NULL 😉 )

    Eben hab ich gemerkt das LoadBitmap bei mir NULL zurück gibt,
    es funktioniert jedoch weder wenn ich den genauen pfad angebe, noch mit ..\,
    noch wenn ich die exe in die directory vom bitmap kopiere und .\\ oder einfach nur
    den namen vom bitmap als parameter angebe...

    irgendwelche ideen?

    EDIT:

    Jetzt hab ich mal GetLastError mit eigebaut und bekomme errorcode 1814
    (The specified resource name cannot be found in the image file.)

    obwohl der direckte Pfad angegeben ist... 😕





  • soweit ich weiß nicht nur, oder?

    "The MAKEINTRESOURCE macro can be used to create this value."

    EDIT:

    Habs mit resource versucht und des geht auch net... immernoch der selbe errorcode



  • -[NULL]- schrieb:

    Habs mit resource versucht und des geht auch net... immernoch der selbe errorcode

    Wie sieht denn jetzt dein LoadBitmap bzw. LoadImage-Aufruf aus und ist im ersten Fall hInst auch ein gültiges Instanz-Handle?



  • LoadBitmap() funktioniert nur mit Resourcen. Auch der Satz mit MAKEINTRESOURCE bezieht sich auf Bitmaps in Resourcen...

    Mit LoadImage() sieht es so aus:

    HBITMAP bmp;
    bmp=(HBITMAP)LoadImage(NULL,"c:\\blupp.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
    


  • Ha, thx... mit LoadImage funktionierts jetzt endlich...

    hier nochmal der ganze quellcode... :

    #include <windows.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    
    HINSTANCE hInst;
    
    int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                        PSTR szCmdLine, int iCmdShow)
    {
        HWND     hWnd;
        MSG      msg;
        WNDCLASS wc;
    
        const char szAppName[] = "bitmapT";
    
        wc.style          = CS_HREDRAW | CS_VREDRAW;
        wc.lpfnWndProc    = WndProc;
        wc.cbClsExtra     = 0;
        wc.cbWndExtra     = 0;
        wc.hInstance      = hInstance;
        wc.hIcon          = LoadIcon(NULL, IDI_APPLICATION);
        wc.hCursor        = LoadCursor(NULL, IDC_ARROW);
        wc.hbrBackground  = (HBRUSH)GetStockObject(WHITE_BRUSH);
        wc.lpszMenuName   = NULL;
        wc.lpszClassName  = szAppName;
    
        RegisterClass(&wc);
    
        hWnd = CreateWindow( szAppName,
                             "bitmapT",
                             WS_OVERLAPPEDWINDOW,
                             CW_USEDEFAULT,
                             CW_USEDEFAULT,
                             CW_USEDEFAULT,
                             CW_USEDEFAULT,
                             NULL,
                             NULL,
                             hInstance,
                             NULL );
    
        ShowWindow(hWnd, iCmdShow);
        UpdateWindow(hWnd);
    
    	hInst = hInstance;
    
        while(GetMessage(&msg, NULL, 0, 0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    
        return msg.wParam;
    }
    
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        static HBITMAP hBmp;
        HDC DC;
        HDC MemDC;
        PAINTSTRUCT ps;
    
        switch(message)
        {
        case WM_CREATE:
            {
                hBmp = (HBITMAP) LoadImage(hInst, "D:\\Programme\\Microsoft Visual Studio\\MyProjects\\bitmapT\\test.bmp", IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
    
                return 0;
            }
    
        case WM_PAINT:
            {
                DC = BeginPaint(hWnd, &ps);
                MemDC = CreateCompatibleDC(DC);
                SelectObject(MemDC, hBmp);
                BitBlt(DC, 0, 0, 32, 37, MemDC, 0, 0, SRCCOPY);
    
                EndPaint(hWnd, &ps);
    
                return 0;
            }
    
        case WM_CLOSE:
            {
                PostQuitMessage(0);
    
                return 0;
            }
    
        case WM_DESTROY:
            {
                PostQuitMessage(0);
                return 0;
            }
        }
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    


  • ehem... trotzdem merke ich gerade das das Bitmap sofort verschwindet
    wenn ich das fenster mal minimiere oder maximiere...
    obwohl BitBlt doch in WM_PAINT steht...

    😕


Anmelden zum Antworten