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; }