Grafik mit GDI+



  • Hallo,

    bei meinem Versuch, ein erstes GDI+-Programm zu schreiben erscheinen
    beim Kompileren Fehlermeldungen ohne rote Markierungen im C++-Eclipse-Editor.

    #include <windows.h>
    #include <gdiplus.h>
    using namespace Gdiplus;
    
    void paint(HDC hdc) {
       Graphics graphics(hdc);    // 04
       Pen      pen(Color(255, 0, 0, 255));   // 05
       graphics.DrawLine(&pen, 0, 0, 200, 100);   // 06
    }
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    
    INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR, INT iCmdShow) {
    
        HWND hWnd;
        MSG msg;
        WNDCLASS wndClass;
    
        GdiplusStartupInput gdiplusStartupInput;
        ULONG_PTR gdiplusToken;
    
        GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); // 02
    
        wndClass.style = CS_HREDRAW | CS_VREDRAW;
        wndClass.lpfnWndProc = WndProc;
        wndClass.cbClsExtra = 0;
        wndClass.cbWndExtra = 0;
        wndClass.hInstance = hInstance;
        wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
        wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
        wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
        wndClass.lpszMenuName = NULL;
        wndClass.lpszClassName = TEXT("GettingStarted");
        RegisterClass(&wndClass);
    
        hWnd = CreateWindow(
                TEXT("GettingStarted"), // window class name
                TEXT("Getting Started"), // window caption
                WS_OVERLAPPEDWINDOW, // window style
                CW_USEDEFAULT, // initial x position
                CW_USEDEFAULT, // initial y position
                CW_USEDEFAULT, // initial x size
                CW_USEDEFAULT, // initial y size
                NULL, // parent window handle
                NULL, // window menu handle
                hInstance, // program instance handle
                NULL); // creation parameters
    
        ShowWindow(hWnd, iCmdShow);
        UpdateWindow(hWnd);
        while(GetMessage(&msg, NULL, 0, 0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    
        GdiplusShutdown(gdiplusToken);  // 03
        return msg.wParam;
    }
    
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message,
    WPARAM wParam, LPARAM lParam)
    {
        HDC hdc;
        PAINTSTRUCT ps;
    
        switch(message)
        {
        case WM_PAINT:
            hdc = BeginPaint(hWnd, &ps);
            paint(hdc);
            EndPaint(hWnd, &ps);
            return 0;
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
    } // WndProc
    


  • Verrätst du uns auch die Fehlermeldungen?



  • Hab noch die Zeile (nach der 3.Zeile) hinzugefügt:

    #pragma comment( lib, "GdiPlus.lib" ) 
    

    Folgende Einstellung geändert:
    In Eclispe ->Projekt->Properties->C/C++-Build->Gross G++ Linker
    ->Libraries und die Datei GdiPlus.lib hinzugefügt.

    Fehlermeldung:
    "cannot find -lC:...\GdiPlus.lib".

    Ohne diese Einstellung in Eclipse kommen einige Fehlermeldung, beginnend mit
    "datei.cpp:22: undefined reference to GdiplusStartup'" , "datei.cpp:22:(.text+0x133): relocation truncated to fit: R_X86_64_PC32 against undefined symbolGdiplusStartup'" und "datei.cpp:31: undefined reference to `__imp_GetStockObject'".



  • Das sind auch Linkerfehler, daher sind auch keine Fehler im Code zu sehen.

    Es reicht aber eine der beiden Einstellungen vorzunehmen (also entweder im Code oder per Settings).
    Schau mal in den konkreten Pfad, der bei

    "cannot find -lC:...\GdiPlus.lib"

    angegeben ist, ob dort wirklich diese Lib nicht existiert (bzw. ob das überhaupt ein Ordner für ".libs"-Dateien ist - evtl. mußt du sonst noch den passenden Pfad in den Linker-Einstellungen hinzufügen [durchsuche dazu am besten dein C++ Installationsverzeichnis nach "GdiPlus.lib"]).

    Edit: Verwendest du MinGW (bzw. GNU C++)? Dann benötigst du wohl libgdiplus.a (Unix/Linux-konforme statische Library-Datei) oder libgdiplus.so (Unix/Linux-konforme Shared-Object-Datei, d.h benötigt dann noch die "GdiPlus.dll" zur Laufzeit).

    PS: Außer für kleine Programme bzw. zum Erlernen sollte man nicht mehr direkt die WinAPI benutzen, sondern passende Grafik- (bzw. Multimedia-) Libraries, wie SFML oder SDL[2] (oder komplette GUI-Frameworks wie Qt, wxWidgets, ImGui, etc.).



  • Das Linker-Problem konnte gelöst werden ("gdiplus" statt "gdiplus.lib" in Eclipse).

    Aufgrund der GetStockObject-Fehlermeldung wurde die Zeile

    wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    

    geändert in

    wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    

    Was hat es mit der GetStockObject-Fehlermeldung auf sich?



  • Das ist eine GDI, keine GDI+ Funktion. Da musst noch gegen die gdi32.lib oder so linken.


Log in to reply