C++ GDI+ ImageLoadFromFile -Function?

  • Hallo liebe Community,
    ich sitz mal wieder vor einem woll zu einfachen Problem, bei dem nicht mal mehr Bloodhound Gang hilft...

    Ich möchte wie in diesem Threadversucht auch in C++ die UpdateLayeredWindow-Function nutzen. Nun weiß ich jeddoch nicht wie ich mit GDI+ ein PNG-Image lade und dieses korrekt übergebe (siehe SourceCode).

    C++ Code

    #pragma comment(lib, "Msimg32.lib")
    #pragma comment(lib, "GDIplus.lib")
    #include <Windows.h>
    #include <gdiplus.h>

    using namespace Gdiplus;


    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);


    static char sClassName[] = "MyClass";
    static HINSTANCE zhInstance = NULL;


    // Main
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    WNDCLASSEX WndClass;
    HWND hWnd;
    MSG Msg;

    zhInstance = hInstance;

    WndClass.cbSize = sizeof(WNDCLASSEX);
    WndClass.style = NULL;
    WndClass.lpfnWndProc = WndProc;
    WndClass.cbClsExtra = 0;
    WndClass.cbWndExtra = 0;
    WndClass.hInstance = zhInstance;
    WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    WndClass.lpszMenuName = NULL;
    WndClass.lpszClassName = sClassName;
    WndClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    RegisterClassEx(&WndClass);


    // Set Size of Image;
    int iWidth = 200;
    int iHeight = 200;


    // Create Window
    hWnd = CreateWindowEx( WS_EX_LAYERED, // Ex-Styles
    sClassName, // Class
    "Faweyr´s Problem", // Title
    WS_OVERLAPPEDWINDOW, // Style
    0, // x-Position
    0, // y-Position
    iWidth, // Width
    iHeight, // Height
    NULL, // Chield
    NULL, // No menu
    zhInstance, // Program Instance handler
    NULL ); // No Window Creation data


    // Show Window
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);


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

    // Start GDI+
    GdiplusStartupInput gdiplusStartupInput;
    ULONG_PTR gdiplusToken;
    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);


    // Image laden
    //?????????????????????????????????????????????
    Image img = ImageLoadFromFile("C:\Button.png"); // wie lade ich verdammt noch mal ein Bild?
    //?????????????????????????????????????????????

    // Make mem DC + mem bitmap
    HDC hdcScreen = GetDC(NULL);
    HDC hDC = CreateCompatibleDC(hdcScreen);
    HBITMAP hBmp = CreateCompatibleBitmap(hdcScreen, iWidth, iHeight);
    HBITMAP hBmpOld = (HBITMAP)SelectObject(hDC, /*??? Bild */ ); // und übergebe es hier korrekt!


    // Call UpdateLayeredWindow
    BLENDFUNCTION blend = {0};
    blend.BlendOp = AC_SRC_OVER;
    blend.SourceConstantAlpha = 255;
    blend.AlphaFormat = AC_SRC_ALPHA;
    POINT ptPos = {0, 0};
    SIZE sizeWnd = {iWidth, iHeight};
    POINT ptSrc = {0, 0};
    UpdateLayeredWindow(hWnd, hdcScreen, &ptPos, &sizeWnd, hDC, &ptSrc, 0, &blend, ULW_ALPHA);
    SelectObject(hDC, hBmpOld);
    //---------------------------------------------------------------------------------------------------------------------


    // Main Loop
    while(GetMessage(&Msg, NULL, 0, 0))
    {
    TranslateMessage(&Msg);
    DispatchMessage(&Msg);
    }

    // Exit/ Ressourcen frei geben!
    DeleteObject(hBmp);
    DeleteDC(hDC);
    ReleaseDC(NULL, hdcScreen);
    GdiplusShutdown(gdiplusToken);

    return Msg.wParam;
    }


    // Callback Function
    LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
    {
    switch(Message)
    {
    case WM_CLOSE:
    DestroyWindow(hwnd);
    break;
    case WM_DESTROY:
    PostQuitMessage(0);
    break;
    default:
    return DefWindowProc(hwnd, Message, wParam, lParam);
    }
    return 0;
    }

    Wäre voll geil wenn mir jemand weiter helfen könnte :thumbup: !

    Source und PNG hängen mit an!

  • Alter, sau geil...dass das soo schnell ging...vielen vielen Dank!
    Kannst du mir vll auch noch sagen wie die Funktion " $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)" in C++ lautet, da ich davon ausgehe das man wie in AutoIt:

    [autoit]

    $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
    $hOld = _WinAPI_SelectObject($hMemDC, $hBitmap)

    [/autoit]

    , das auch in C++ machen muss!
    Grüße Faweyr

  • Hmm, vermutlich solltest du das Bild mit Bitmap::fromFile laden und dann GetHBITMAP oder so darauf aufrufen.

  • Okey....danke euch beiden...
    Wenn jemand ne Idee hätte wie dies in der Praxis aussehen könnte, würde ich mich über ein Code freuen, den ich bin geistig noch nicht soweit mein Vorhaben zu vollenden... :rofl:

  • So, habs geschafft...werd morgen den Code posten...Dank für eure Hilfe... :rock:


    Zu früh gefreut...mit
    HBITMAP hBmp = (HBITMAP)LoadImage(NULL, "Button.bmp", IMAGE_BITMAP, 0,0, LR_LOADFROMFILE);
    funktioniert es, jeddoch´nur bei bmp -Bilder und dann auch mit einem seltsamen Weißstich! ;(

    Hat jemand eine Lösung mit GDI+? Wäre schön!

    Einmal editiert, zuletzt von Faweyr (16. März 2011 um 20:19)

  • Ich hoffe, das noch jemand vorbei schaut der sich in C++ gut auskennt.
    Bin nun so weit, jeddoch komm ich mir schon wie ein ScriptKiddy vor, den ich verstehe nur noch die Hälfte von dem was ich mach!

    Spoiler anzeigen

    Nach dem Start des Programms wird immer der Fehler "// Run-Time Check Failure #3 - The variable 'img' is being used without being initialized." ausgegeben, dachte das mit "Bitmap* img;" die Variable iniziert wurde!
    Help me pls :)

  • Spoiler anzeigen
  • Nun hab ich es endlich geschafft...

    Da ich das ganze für ein großeres Projekt brauche, habe ich noch 2 Graphics erzeugt und nun kann man auf zGraphics zeichnen.

    Spoiler anzeigen


    Wenn jemand öfters auf zGraphic zeichnen, und dies anzeigt...dann rate ich dazu dies in einem Thread zu verstauen...denn sonst werden die Änderungen nicht immer sofort übernommen...(wer ein Beispiel dafür braucht sollte mich anfragen)...
    Grüße Faweyr

  • Mir ist aufgeafallen, dass meines auch funktiooniert hat, danke. Ich habe eine lustige Entdeckung gemacht, mit der man schwarzen Text von anderen Fenstern plötzlich grün sieht, wenn das Fenster dadrüber ist:

    Code
    RECT r={0,0,100,100};
          HBRUSH hBrush = CreateSolidBrush(RGB(0,255,0));
          HRGN bgRgn=CreateRectRgnIndirect(&r);
          FillRgn(cdc, bgRgn, hBrush);


    EDIT:
    Perfekt, jetzt ist meine Aero-UDF auch für C++ bald vielleicht fertig, mal sehen ob ich das mach. GDI+ in Dev-C++ eingebaut und GUIT (GUI-transparent) funktioniert auch wudnerbar: Bild geladen, GUI updaten, fertig)

    2 Mal editiert, zuletzt von TheShadowAE (20. März 2011 um 13:19)

  • Ich möchte ja eine Multitouch-Oberflächhe für Tablets programmieren... Mit der man schneller zum Ziel kommt, zb. Soundregelung, Helligkeitsregelung...und Musikplayer...den die Buttons von Winamp sind nicht für Finger geschaffen....