Как нарисовать изображение на окне?

Я создал окно с api createwindow (), используя VS2005 на C ++ в Windows Vista

Мое требование - нарисовать изображение (любого формата) в этом окне. Я не использую MFC в этом приложении.


person Vinayaka Karjigi    schedule 17.11.2009    source источник


Ответы (3)


не совсем уверен, в чем ваша проблема: нарисуйте растровое изображение в форме, или вы хотите знать, как работать с различными форматами изображений, или и тем, и другим. В любом случае ниже приведен пример того, как вы можете загрузить растровое изображение и нарисовать его в форме:

HBITMAP hBitmap = NULL;

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;

    switch (message)
    {
<...>

    case WM_CREATE:
        hBitmap = (HBITMAP)LoadImage(hInst, L"c:\\test.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
        break;
    case WM_PAINT:
        PAINTSTRUCT     ps;
        HDC             hdc;
        BITMAP          bitmap;
        HDC             hdcMem;
        HGDIOBJ         oldBitmap;

        hdc = BeginPaint(hWnd, &ps);

        hdcMem = CreateCompatibleDC(hdc);
        oldBitmap = SelectObject(hdcMem, hBitmap);

        GetObject(hBitmap, sizeof(bitmap), &bitmap);
        BitBlt(hdc, 0, 0, bitmap.bmWidth, bitmap.bmHeight, hdcMem, 0, 0, SRCCOPY);

        SelectObject(hdcMem, oldBitmap);
        DeleteDC(hdcMem);

        EndPaint(hWnd, &ps);
        break;
    case WM_DESTROY:
        DeleteObject(hBitmap);
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

LoadImage загружает значок, курсор, анимированный курсор или растровое изображение. Подробности здесь

Для работы с различными форматами изображений вы можете использовать компонент Windows Imaging (см. IWICBitmapDecoder) или код отсюда Загрузка изображений JPEG и GIF или сторонних инструментов например FreeImage или LeadTools

надеюсь, что это поможет, с уважением

person serge_gubenko    schedule 19.11.2009
comment
Привет, Серж, это решило мою проблему рисования изображения в окне. Спасибо за помощь. но поскольку для этого нужны только файлы bmp, cur и ico, мне нужно поработать над преобразованием png в bmp, а затем я передам этот bmp этой функции - person Vinayaka Karjigi; 19.11.2009
comment
Может ли кто-нибудь помочь мне поместить изображение PNG в окно без использования MFC - person Vinayaka Karjigi; 23.11.2009
comment
Если я могу сэкономить кому-то несколько минут поисков, я попытался использовать этот ответ, но он не сработал. Через некоторое время я попытался изменить sizeof (bitmap) на sizeof (BITMAP), и код заработал. Я использую Visual Studio 2015 в Windows 10. Вот полная строка: GetObject (hBitmap, sizeof (BITMAP), & bitmap); - person Tristan Dubé; 02.08.2016
comment
Зачем беспокоиться о сохранении старого HBITMAP и повторном вызове SelectObject, если вы удаляете DC сразу после этого? - person flarn2006; 09.10.2020

#include <windows.h>
#include <string.h>

HBITMAP hBitmap, hOldBitmap;
HDC hdc, hdcMem;
BITMAP bm;
HINSTANCE hI;
PAINTSTRUCT ps;
RECT rect;
RECT rc;

LRESULT CALLBACK WindowProcedure(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
    {
    case WM_CREATE:
    hBitmap = (HBITMAP)LoadImage(hI, "1.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
    GetObject(hBitmap, sizeof(BITMAP), &bm);
    hdc = GetDC(hWnd);
    hdcMem = CreateCompatibleDC(hdc);
    hOldBitmap = SelectBitmap(hdcMem, hBitmap);
    ReleaseDC(hWnd, hdc);
    return 0;

    case WM_LBUTTONDOWN:
    //for dragging not only by the title, but also by any part of the window 
    ReleaseCapture();
    SendMessage(hWnd, 0xA1, 2, 0);
    break;
    case WM_PAINT:
    hdc=BeginPaint(hWnd,&ps);
    
    //overlay image with stretching to fit the window 
    GetClientRect(hWnd,&rect);
    SetStretchBltMode(hdc, STRETCH_HALFTONE);
    StretchBlt(hdc,0,0,rect.right,rect.bottom,
    hdcMem,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY);
    
    EndPaint(hWnd,&ps);
    break;      


    case WM_DESTROY:
    PostQuitMessage(0);
      
    DeleteDC(hdcMem);
    DeleteObject(hBitmap);
    DeleteObject(hOldBitmap);
    break;
    }
return DefWindowProc(hWnd, msg, wParam, lParam);
}
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPInst, LPSTR lpCmdLine, int nCmdShow)
{
//copying a pointer to a running application instance (module)
hI=hInstance;

WNDCLASS wc;

wc.style         = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc   = WindowProcedure;
wc.hInstance     = hInstance;
wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) GetStockObject(LTGRAY_BRUSH);
wc.lpszClassName = "test_class";
wc.lpszMenuName  = NULL;
wc.cbClsExtra    = 0;
wc.cbWndExtra    = 0;

RegisterClass(&wc);

HWND hWnd = CreateWindow(wc.lpszClassName, "Image Window", 
//window with title (overlapping window) 
WS_OVERLAPPEDWINDOW,
//window without title
//WS_VISIBLE | WS_POPUP | WS_SYSMENU | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
CW_USEDEFAULT, CW_USEDEFAULT, 500, 500, NULL, NULL, hInstance, NULL);

ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);

MSG msg;
while(GetMessage (&msg, NULL, 0, 0))
    {
    DispatchMessage (&msg);
    TranslateMessage (&msg);
    }
UnregisterClass(wc.lpszClassName, hInstance);
return (int) msg.wParam;
}

введите описание изображения здесь

person Severin Turin    schedule 30.03.2021
comment
широкий путин: P - person MARSHMALLOW; 23.07.2021

person    schedule
comment
И просочившийся HDC, который так и не был выпущен при выходе из функции? Правило 101 Windows GDI: если вы его получили, то отпустите; если вы его создаете, то удалите его. Вы правильно сделали это с помощью кисти (Create / Delete), но не смогли сделать это с вашим клиентским DC (Get / Release). - person WhozCraig; 02.05.2017
comment
Ах, спасибо :) Решил. Просто добавила одну строчку перед закрытием фигурной скобки. ReleaseDC (hWnd, hdc); - person Ahmed Hussein; 02.05.2017
comment
С точки зрения функциональности, как это соотносится с ответом serge_gubenko? - person Stevoisiak; 02.08.2018
comment
Я не знаю, но вижу, что мое решение намного проще, понятнее и понятнее. - person Ahmed Hussein; 19.12.2019