C ++ WinApi Нарисовать изображение .jpg в новом окне?

Я новичок в Windows API. Использование некоторых примеров кода Windows из руководств по Winapi:

Graphics.DrawImage (Image *, const Rect) метод

Я хочу открыть .jpg изображение и нарисовать его в новом окне, которое я создал. Проблема в том, что я не совсем уверен, как использовать метод VOID Example_DrawImage9(HDC hdc) с моим существующим окном. Моим первым побуждением было вызвать его внутри case WM_PAINT в процедуре обратного вызова и использовать hdc оттуда, но изображение не отображается. Как мне узнать правильный hdc для поставки? А где мне вызывать метод?

#include <windows.h>
#include "stdafx.h" 
#include <objidl.h>
#include <gdiplus.h>

using namespace Gdiplus;
#pragma comment (lib,"Gdiplus.lib")

//*************************************************** added for gdiplus
HWND hEdit;

//************************************************how do I use this method   with the window I have created below?
VOID Example_DrawImage9(HDC hdc){
    Graphics graphics(hdc); // Create an Image object.
    Image image(L"C:/Users/Me/Desktop/fuzz.jpg"); // Create a Pen object.
    Pen pen(Color(255, 255, 0, 0), 2); // Draw the original source image.
    graphics.DrawImage(&image, 10, 10); // Create a Rect object that specifies the destination of the image.
    Rect destRect(200, 50, 150, 75); // Draw the rectangle that bounds the image.
    graphics.DrawRectangle(&pen, destRect); // Draw the image.
    graphics.DrawImage(&image, destRect);
}
//*********************************************************************************************



LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)
{
    const wchar_t CLASS_NAME[] = L"Sample Window Class";
    WNDCLASS wc = {}; 
    wc.lpfnWndProc = WindowProc; //attach this callback procedure
    wc.hInstance = hInstance; //handle to application instance
    wc.lpszClassName = CLASS_NAME; 
    RegisterClass(&wc); //register wc
    // Create the window.
    HWND hwnd = CreateWindowEx( 
        0,                              // Optional window styles.
        CLASS_NAME,                     // Window class
        L"Learn to Program Windows",    // Window text
        WS_OVERLAPPEDWINDOW,            // Window style

                                        // Size and position
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,

        NULL,       // Parent window    
        NULL,       // Menu
        hInstance,  // Instance handle
        NULL        // Additional application data
        );

    if (hwnd == NULL){
        return 0;
    }

    ShowWindow(hwnd, nCmdShow);

    MSG msg = {};
    while (GetMessage(&msg, NULL, 0, 0)){
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}
return 0;
}

//callback procedure for this window, takes in all the window details
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
    switch (uMsg){
        case WM_DESTROY: 
            PostQuitMessage(0);
            return 0;

        case WM_PAINT:{
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hwnd, &ps);
            //***************************************************************
            //do we call DrawImage here? what do we need to pass as hdc?
            //Example_DrawImage9(HDC hdc);//?????????????
            //***************************************************************
            FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));
            EndPaint(hwnd, &ps);
        }
        return 0;
    }
    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

person user3545370    schedule 02.03.2016    source источник
comment
Не программируйте инстинктивно. Вместо этого прочтите ресурсы, предлагаемые вам в комментарии на ваш предыдущий вопрос.   -  person IInspectable    schedule 02.03.2016
comment
Я думаю, что Graphics попытается уничтожить HDC, который вы передаете, когда он выйдет за пределы области видимости. А если нет, как вы думаете, что будет в результате, если сразу после этого заполнить прямоугольник?   -  person Mark Ransom    schedule 02.03.2016
comment
@MarkRansom: класс Graphics не уничтожает предоставленный HDC.   -  person Remy Lebeau    schedule 02.03.2016
comment
@RemyLebeau полезно знать, спасибо. Я не нашел указаний в документации.   -  person Mark Ransom    schedule 02.03.2016


Ответы (2)


Ты на правильном пути. Используйте HDC, который предоставляет BeginPaint(). И не забудьте инициализировать GDI + перед его использованием.

#include <windows.h>
#include "stdafx.h" 
#include <objidl.h>
#include <gdiplus.h>

using namespace Gdiplus;
#pragma comment (lib, "Gdiplus.lib")

void Example_DrawImage9(HDC hdc)
{
    Graphics graphics(hdc);
    // Create an Image object.
    Image image(L"C:/Users/Me/Desktop/fuzz.jpg");
    // Create a Pen object.
    Pen pen(Color(255, 255, 0, 0), 2);
    // Draw the original source image.
    graphics.DrawImage(&image, 10, 10);
    // Create a Rect object that specifies the destination of the image.
    Rect destRect(200, 50, 150, 75);
    // Draw the rectangle that bounds the image.
    graphics.DrawRectangle(&pen, destRect);
    // Draw the image.
    graphics.DrawImage(&image, destRect);
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)
{
    ULONG_PTR token;
    GdiplusStartupInput input = {0};
    input.GdiplusVersion = 1;
    GdiplusStartup(&token, &input, NULL);

    const wchar_t CLASS_NAME[] = L"Sample Window Class";
    WNDCLASS wc = {}; 
    wc.lpfnWndProc = &WindowProc; //attach this callback procedure
    wc.hInstance = hInstance; //handle to application instance
    wc.lpszClassName = CLASS_NAME; 
    RegisterClass(&wc); //register wc
    // Create the window.
    HWND hwnd = CreateWindowEx( 
        0,                              // Optional window styles.
        CLASS_NAME,                     // Window class
        L"Learn to Program Windows",    // Window text
        WS_OVERLAPPEDWINDOW,            // Window style

        // Size and position
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,

        NULL,       // Parent window    
        NULL,       // Menu
        hInstance,  // Instance handle
        NULL        // Additional application data
    );

    if (hwnd != NULL)
    {
        ShowWindow(hwnd, nCmdShow);

        MSG msg;
        while (GetMessage(&msg, NULL, 0, 0) > 0)
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    GdiplusShutdown(token);
    return 0;
}

//callback procedure for this window, takes in all the window details
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
        case WM_DESTROY: 
            PostQuitMessage(0);
            return 0;

        case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hwnd, &ps);
            FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));
            Example_DrawImage9(hdc);
            EndPaint(hwnd, &ps);
            return 0;
        }
    }

    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
person Remy Lebeau    schedule 02.03.2016

Вам необходимо инициализировать GDI +, а затем выключить его перед выходом.

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)
{
    Gdiplus::GdiplusStartupInput gdiplusStartupInput;
    ULONG_PTR gdiplusToken;
    Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

    //...

    Gdiplus::GdiplusShutdown(gdiplusToken);

    return 0;
}

graphics.DrawImage(&image, 10, 10); достаточно, чтобы раскрасить изображение. После того, как вы нарисуете изображение, больше ничего не рисуйте поверх него.

Вы можете использовать Example_DrawImage9(hdc) в WM_PAINT. Используйте FillRect перед рисованием изображения.

person Barmak Shemirani    schedule 02.03.2016