win32-使用GDI+缩放图像

滑动鼠标滚轮可以改变图像大小

#include <windows.h>
#include <tchar.h>

#include <Urlmon.h> // URLDownloadToCacheFile
#pragma comment (lib, "Urlmon")
#include <shlwapi.h> // SHCreateStreamOnFile
#pragma comment (lib, "shlwapi")

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

#include <Uxtheme.h> // BeginBufferedPaint
#pragma comment(lib,"Uxtheme")

HINSTANCE hInst;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int nWidth = 800, nHeight = 600;
Bitmap* pBitmap = NULL;
int nBitmapWidth = 0, nBitmapHeight = 0;
float nScale = 1;

int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
{
    GdiplusStartupInput gdiplusStartupInput;
    ULONG_PTR gdiplusToken;
    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

    hInst = hInstance;
    WNDCLASSEX wcex =
    {
        sizeof(WNDCLASSEX), CS_HREDRAW | CS_VREDRAW, WndProc, 0, 0, hInst, LoadIcon(NULL, IDI_APPLICATION),
        LoadCursor(NULL, IDC_ARROW), (HBRUSH)(COLOR_WINDOW + 1), NULL, TEXT("WindowClass"), NULL,
    };
    if (!RegisterClassEx(&wcex))
        return MessageBox(NULL, TEXT("Cannot register class !"), TEXT("Error"), MB_ICONERROR | MB_OK);
    int nX = (GetSystemMetrics(SM_CXSCREEN) - nWidth) / 2, nY = (GetSystemMetrics(SM_CYSCREEN) - nHeight) / 2;
    HWND hWnd = CreateWindowEx(0, wcex.lpszClassName, TEXT("Test"), WS_OVERLAPPEDWINDOW, nX, nY, nWidth, nHeight, NULL, NULL, hInst, NULL);
    if (!hWnd)
        return MessageBox(NULL, TEXT("Cannot create window !"), TEXT("Error"), MB_ICONERROR | MB_OK);
    ShowWindow(hWnd, SW_SHOWNORMAL);
    UpdateWindow(hWnd);
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return (int)msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_CREATE:
    {
        WCHAR wszURL[MAX_PATH] = TEXT("https://image.ibb.co/buLv2e/Little_Girl3.jpg");
        WCHAR wszFilename[MAX_PATH];
        HRESULT hr = URLDownloadToCacheFile(NULL, wszURL, wszFilename, ARRAYSIZE(wszFilename), 0x0, NULL);
        if (SUCCEEDED(hr))
        {
            IStream* pStream = NULL;
            hr = SHCreateStreamOnFile(wszFilename, STGM_READ | STGM_SHARE_DENY_WRITE, &pStream);
            if (SUCCEEDED(hr))
            {
                pBitmap = new Gdiplus::Bitmap(pStream);
                if (pBitmap)
                {
                    nBitmapWidth = (int)pBitmap->GetWidth();
                    nBitmapHeight = (int)pBitmap->GetHeight();
                }
            }
        }
        return 0;
    }
    break;
    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC hDC = BeginPaint(hWnd, &ps);
        RECT rcClient;
        GetClientRect(hWnd, &rcClient);
        if (pBitmap)
        {
            HDC targetDC = hDC;
            HDC bufferedDC = NULL;
            HRESULT hr = S_OK;
            HPAINTBUFFER pb = BeginBufferedPaint(targetDC, &rcClient, BPBF_TOPDOWNDIB, 0, &bufferedDC);
            Graphics* g = new Graphics(bufferedDC);
            if (g && g->GetLastStatus() == Ok)
            {
                g->Clear(Color(255, 255, 255));
                int nX = (rcClient.right - rcClient.left - nBitmapWidth * nScale) / 2;
                int nY = (rcClient.bottom - rcClient.top - nBitmapHeight * nScale) / 2;
                g->DrawImage(pBitmap, nX, nY, (int)(nBitmapWidth * nScale), (int)(nBitmapHeight * nScale));
                delete g;
            }
            hr = EndBufferedPaint(pb, TRUE);
        }
        EndPaint(hWnd, &ps);
    }
    break;
    case WM_MOUSEWHEEL:
    {
        static int nDelta = 0;
        nDelta += GET_WHEEL_DELTA_WPARAM(wParam);
        if (abs(nDelta) >= WHEEL_DELTA)
        {
            if (nDelta > 0)
            {
                nScale *= 1.1f;
            }
            else
            {
                nScale /= 1.1f;
            }
            nDelta = 0;
            InvalidateRect(hWnd, NULL, FALSE);
        }
    }
    break;
    case WM_DESTROY:
    {
        PostQuitMessage(0);
        return 0;
    }
    break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

 

posted @ 2020-06-10 11:01  strive-sun  阅读(718)  评论(0编辑  收藏  举报