2025-11-28 00:35:46 +09:00

248 lines
5.2 KiB
C++

/*++
Copyright (c) Microsoft Corporation. All rights reserved.
--*/
#include "stdafx.h"
#include "resource.h"
#include "BitmapUtil.h"
#include "BitmapWnd.h"
//////////////////////////////////////////////////////////////////////////
//
// CBitmapWnd::CBitmapWnd
//
CBitmapWnd::CBitmapWnd(IStream *pStream) : m_Image(pStream)
{
m_cRef = 0;
}
//////////////////////////////////////////////////////////////////////////
//
// CBitmapWnd::CBitmapWnd
//
CBitmapWnd::CBitmapWnd(PCWSTR pszFileName) : m_Image(pszFileName)
{
m_cRef = 0;
}
//////////////////////////////////////////////////////////////////////////
//
// CBitmapWnd::QueryInterface
//
STDMETHODIMP CBitmapWnd::QueryInterface(REFIID iid, LPVOID *ppvObj)
{
if (ppvObj == NULL)
{
return E_POINTER;
}
if (iid == IID_IUnknown)
{
*ppvObj = (IUnknown *) this;
}
else
{
*ppvObj = NULL;
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
//////////////////////////////////////////////////////////////////////////
//
// CBitmapWnd::AddRef
//
STDMETHODIMP_(ULONG) CBitmapWnd::AddRef()
{
return InterlockedIncrement(&m_cRef);
}
//////////////////////////////////////////////////////////////////////////
//
// CBitmapWnd::Release
//
STDMETHODIMP_(ULONG) CBitmapWnd::Release()
{
LONG cRef = InterlockedDecrement(&m_cRef);
if (cRef == 0)
{
delete this;
}
return cRef;
}
///////////////////////////////////////////////////////////////////////////////
//
// CBitmapWnd::Register
//
ATOM CBitmapWnd::Register()
{
WNDCLASSEX wcex = { 0 };
wcex.cbSize = sizeof(wcex);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WindowProc;
wcex.hInstance = g_hInstance;
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.lpszClassName = _T("BitmapWindow");
return RegisterClassEx(&wcex);
}
//////////////////////////////////////////////////////////////////////////
//
// CBitmapWnd::WindowProc
//
LRESULT
CALLBACK
CBitmapWnd::WindowProc(
HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
switch (uMsg)
{
case WM_CREATE:
{
LPCREATESTRUCT pcs = (LPCREATESTRUCT) lParam;
LPMDICREATESTRUCT pmdics = (LPMDICREATESTRUCT) pcs->lpCreateParams;
CBitmapWnd *that = (CBitmapWnd *) pmdics->lParam;
that->AddRef();
SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR) that);
break;
}
case WM_DESTROY:
{
CBitmapWnd *that = (CBitmapWnd *) GetWindowLongPtr(hWnd, GWLP_USERDATA);
SetWindowLongPtr(hWnd, GWLP_USERDATA, NULL);
that->Release();
break;
}
case WM_PAINT:
{
CBitmapWnd *that = (CBitmapWnd *) GetWindowLongPtr(hWnd, GWLP_USERDATA);
that->OnPaint(hWnd);
break;
}
}
return DefMDIChildProc(
hWnd,
uMsg,
wParam,
lParam
);
}
//////////////////////////////////////////////////////////////////////////
//
// CBitmapWnd::OnPaint
//
LRESULT CBitmapWnd::OnPaint(HWND hWnd)
{
// Get the destination DC
PAINTSTRUCT ps;
HDC hDC = BeginPaint(hWnd, &ps);
if (hDC != NULL)
{
Gdiplus::Graphics graphics(hDC);
// Get the size of the window
RECT r;
GetClientRect(hWnd, &r);
UINT nWindowWidth = r.right;
UINT nWindowHeight = r.bottom;
// Get the size of the image
UINT nBitmapWidth = m_Image.GetWidth();
UINT nBitmapHeight = m_Image.GetHeight();
if (nBitmapWidth != 0 && nBitmapHeight != 0)
{
// Calculate the coordinates and the size of the image
Gdiplus::Rect rDest;
if (nBitmapWidth <= nWindowWidth && nBitmapHeight <= nWindowHeight)
{
// If the image is smaller than the window, center the image
rDest.X = (nWindowWidth - nBitmapWidth) / 2;
rDest.Y = (nWindowHeight - nBitmapHeight) / 2;
rDest.Width = nBitmapWidth;
rDest.Height = nBitmapHeight;
}
else
{
// If the image is larger than the window, resize and center
// the image while keeping the aspect ratio
UINT nStretchedWidth = nWindowWidth;
UINT nStretchedHeight = MulDiv(nBitmapHeight, nWindowWidth, nBitmapWidth);
if (nStretchedHeight > nWindowHeight)
{
nStretchedWidth = MulDiv(nBitmapWidth, nWindowHeight, nBitmapHeight);
nStretchedHeight = nWindowHeight;
}
rDest.X = (nWindowWidth - nStretchedWidth) / 2;
rDest.Y = (nWindowHeight - nStretchedHeight) / 2;
rDest.Width = nStretchedWidth;
rDest.Height = nStretchedHeight;
}
// Paint the image with a white background
graphics.DrawImage(&m_Image, rDest);
graphics.ExcludeClip(rDest);
}
graphics.Clear((DWORD)Gdiplus::Color::White);
EndPaint(hWnd, &ps);
}
return 0;
}