BOOL Calculate(int cx, int cy, RECT& rect)
{
HDC hDC = ::GetDC(NULL);
const int w = GetDeviceCaps(hDC, HORZRES);
const int h = GetDeviceCaps(hDC, VERTRES);
::ReleaseDC(NULL, hDC);
rect.left = (w >> 1) - (cx >> 1);
rect.top = (h >> 1) - (cy >> 1);
rect.right = rect.left + cx;
rect.bottom = rect.top + cy;
return TRUE;
}
Note: the full source code demonstrating the solution is in the Appendix.
BOOL Calculate(HWND hWnd, int cx, int cy, RECT& rect)
{
if (hWnd == NULL)
return FALSE;
HDC hDC = ::GetDC(NULL);
const int w = GetDeviceCaps(hDC, HORZRES);
const int h = GetDeviceCaps(hDC, VERTRES);
::ReleaseDC(NULL, hDC);
RECT rcWindow;
GetWindowRect(hWnd, &rcWindow);
RECT rcClient;
GetClientRect(hWnd, &rcClient);
cx += (rcWindow.right - rcWindow.left) - rcClient.right;
cy += (rcWindow.bottom - rcWindow.top) - rcClient.bottom;
rect.left = (w >> 1) - (cx >> 1);
rect.top = (h >> 1) - (cy >> 1);
rect.right = rect.left + cx;
rect.bottom = rect.top + cy;
return TRUE;
}
BOOL Calculate(HWND hWnd,
DWORD nWndStyle, DWORD nWndStyleEx,
int cx, int cy, RECT& rect)
{
if (hWnd == NULL)
return FALSE;
HDC hDC = ::GetDC(NULL);
const int w = GetDeviceCaps(hDC, HORZRES);
const int h = GetDeviceCaps(hDC, VERTRES);
::ReleaseDC(NULL, hDC);
rect.left = (w >> 1) - (cx >> 1);
rect.top = (h >> 1) - (cy >> 1);
rect.right = rect.left + cx;
rect.bottom = rect.top + cy;
AdjustWindowRectEx(&rect,
nWndStyle, FALSE, nWndStyleEx);
return TRUE;
}
case WM_GETMINMAXINFO:
{
LPMINMAXINFO pInfo = (LPMINMAXINFO)lParam;
if (pInfo != NULL)
{
BITMAP bitmap;
GetObject(s_hBitmap, sizeof(BITMAP), &bitmap);
pInfo->ptMinTrackSize.x = bitmap.bmWidth;
pInfo->ptMinTrackSize.y = bitmap.bmHeight;
}
}
break;
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
LPCWSTR s_szWndName = L"Adjust Window Rectangle";
LPCWSTR s_szFileName = L"image.bmp";
HBITMAP s_hBitmap = NULL;
ATOM RegisterWndClass(HINSTANCE, LPCWSTR);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
BOOL Calculate(int, int, RECT&);
int WINAPI wWinMain(HINSTANCE hInstance,
HINSTANCE, LPWSTR, int nShowCmd)
{
s_hBitmap = (HBITMAP)LoadImage(NULL, s_szFileName,
IMAGE_BITMAP, 0, 0,
LR_CREATEDIBSECTION | LR_DEFAULTSIZE |
LR_LOADFROMFILE);
if (s_hBitmap == NULL)
return 0;
RegisterWndClass(hInstance, s_szWndName);
BITMAP bitmap = { 0 };
GetObject(s_hBitmap, sizeof(BITMAP), &bitmap);
HWND hWnd = CreateWindow(s_szWndName, s_szWndName,
WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
NULL, NULL, hInstance, NULL);
if (hWnd != NULL)
{
RECT rect = { 0 };
Calculate(bitmap.bmWidth, bitmap.bmHeight, rect);
MoveWindow(hWnd,
rect.left, rect.top,
rect.right - rect.left,
rect.bottom - rect.top,
FALSE);
ShowWindow(hWnd, nShowCmd);
UpdateWindow(hWnd);
MSG msg = { 0 };
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
if (s_hBitmap != NULL)
DeleteObject(s_hBitmap);
return 0;
}
ATOM RegisterWndClass(HINSTANCE hInstance,
LPCWSTR lpszWndClassName)
{
WNDCLASSEX wcex = { 0 };
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.hInstance = hInstance;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = lpszWndClassName;
return RegisterClassEx(&wcex);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_ERASEBKGND:
if (s_hBitmap != NULL)
{
RECT rect = { 0 };
GetClientRect(hWnd, &rect);
HDC hDC = (HDC)wParam;
HDC hMemDC = CreateCompatibleDC(hDC);
HGDIOBJ hOld = SelectObject(hMemDC,
s_hBitmap);
BitBlt(hDC,
0, 0, rect.right, rect.bottom,
hMemDC, 0, 0,
SRCCOPY);
SelectObject(hMemDC, hOld);
DeleteDC(hMemDC);
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
}
break;
case WM_LBUTTONDOWN:
PostMessage(hWnd, WM_CLOSE, 0, 0);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
BOOL Calculate(int cx, int cy, RECT& rect)
{
HDC hDC = ::GetDC(NULL);
const int w = GetDeviceCaps(hDC, HORZRES);
const int h = GetDeviceCaps(hDC, VERTRES);
::ReleaseDC(NULL, hDC);
rect.left = (w >> 1) - (cx >> 1);
rect.top = (h >> 1) - (cy >> 1);
rect.right = rect.left + cx;
rect.bottom = rect.top + cy;
return TRUE;
}
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
LPCWSTR s_szWndName = L"Adjust Window Rectangle";
LPCWSTR s_szFileName = L"image.bmp";
HBITMAP s_hBitmap = NULL;
ATOM RegisterWndClass(HINSTANCE, LPCWSTR);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
BOOL Calculate(HWND, int, int, RECT&);
int WINAPI wWinMain(HINSTANCE hInstance,
HINSTANCE, LPWSTR, int nShowCmd)
{
s_hBitmap = (HBITMAP)LoadImage(NULL, s_szFileName,
IMAGE_BITMAP, 0, 0,
LR_CREATEDIBSECTION | LR_DEFAULTSIZE |
LR_LOADFROMFILE);
if (s_hBitmap == NULL)
return 0;
RegisterWndClass(hInstance, s_szWndName);
BITMAP bitmap = { 0 };
GetObject(s_hBitmap, sizeof(BITMAP), &bitmap);
HWND hWnd = CreateWindowEx(
WS_EX_APPWINDOW | WS_EX_WINDOWEDGE,
s_szWndName, s_szWndName,
WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS |
WS_CLIPCHILDREN,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
NULL, NULL, hInstance, NULL);
if (hWnd != NULL)
{
RECT rect = { 0 };
Calculate(hWnd, bitmap.bmWidth, bitmap.bmHeight, rect);
MoveWindow(hWnd,
rect.left, rect.top,
rect.right - rect.left,
rect.bottom - rect.top,
FALSE);
ShowWindow(hWnd, nShowCmd);
UpdateWindow(hWnd);
MSG msg = { 0 };
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
if (s_hBitmap != NULL)
DeleteObject(s_hBitmap);
return 0;
}
ATOM RegisterWndClass(HINSTANCE hInstance,
LPCWSTR lpszWndClassName)
{
WNDCLASSEX wcex = { 0 };
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.hInstance = hInstance;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = lpszWndClassName;
return RegisterClassEx(&wcex);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_ERASEBKGND:
if (s_hBitmap != NULL)
{
BITMAP bitmap;
GetObject(s_hBitmap, sizeof(BITMAP), &bitmap);
RECT rect = { 0 };
GetClientRect(hWnd, &rect);
HDC hDC = (HDC)wParam;
HDC hMemDC = CreateCompatibleDC(hDC);
HGDIOBJ hOld = SelectObject(hMemDC,
s_hBitmap);
StretchBlt(hDC,
0, 0, rect.right, rect.bottom,
hMemDC,
0, 0, bitmap.bmWidth, bitmap.bmHeight,
SRCCOPY);
SelectObject(hMemDC, hOld);
DeleteDC(hMemDC);
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
BOOL Calculate(HWND hWnd, int cx, int cy, RECT& rect)
{
if (hWnd == NULL)
return FALSE;
HDC hDC = ::GetDC(NULL);
const int w = GetDeviceCaps(hDC, HORZRES);
const int h = GetDeviceCaps(hDC, VERTRES);
::ReleaseDC(NULL, hDC);
RECT rcWindow;
GetWindowRect(hWnd, &rcWindow);
RECT rcClient;
GetClientRect(hWnd, &rcClient);
cx += (rcWindow.right - rcWindow.left) - rcClient.right;
cy += (rcWindow.bottom - rcWindow.top) - rcClient.bottom;
rect.left = (w >> 1) - (cx >> 1);
rect.top = (h >> 1) - (cy >> 1);
rect.right = rect.left + cx;
rect.bottom = rect.top + cy;
return TRUE;
}
BOOL Calculate(HWND hWnd,
DWORD nWndStyle, DWORD nWndStyleEx,
int cx, int cy, RECT& rect)
{
if (hWnd == NULL)
return FALSE;
HDC hDC = ::GetDC(NULL);
const int w = GetDeviceCaps(hDC, HORZRES);
const int h = GetDeviceCaps(hDC, VERTRES);
::ReleaseDC(NULL, hDC);
rect.left = (w >> 1) - (cx >> 1);
rect.top = (h >> 1) - (cy >> 1);
rect.right = rect.left + cx;
rect.bottom = rect.top + cy;
AdjustWindowRectEx(&rect, nWndStyle, FALSE, nWndStyleEx);
return TRUE;
}
#define STRICT
#define WIN32_LEAN_AND_MEAN
#include <atlbase.h>
#include <atlwin.h>
#include <atlimage.h>
static const LPCWSTR s_szFileName = L"image.jpg";
static const DWORD s_nWndStyle = WS_OVERLAPPEDWINDOW |
WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
static const DWORD s_nWndStyleEx = WS_EX_APPWINDOW |
WS_EX_WINDOWEDGE;
typedef CWinTraits<s_nWndStyle, s_nWndStyleEx> CMyWindowTraits;
class CMyWindow : public CWindowImpl<CMyWindow, CWindow, CMyWindowTraits>
{
CImage m_Bk;
RECT m_rcMin;
public:
DECLARE_WND_CLASS(L"My Window")
BEGIN_MSG_MAP(CMyWindow)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
MESSAGE_HANDLER(WM_GETMINMAXINFO, OnGetMinMaxInfo)
MESSAGE_HANDLER(WM_CLOSE, OnClose)
MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
END_MSG_MAP()
LRESULT OnCreate(UINT nMsg, WPARAM wParam,
LPARAM lParam, BOOL& bHandled)
{
HRESULT hr = m_Bk.Load(s_szFileName);
if (SUCCEEDED(hr))
{
int cx = m_Bk.GetWidth();
int cy = m_Bk.GetHeight();
if (cx > 0 && cy > 0)
{
Center(cx, cy, m_rcMin);
MoveWindow(&m_rcMin);
}
}
return 0;
}
LRESULT OnClose(UINT nMsg, WPARAM wParam,
LPARAM lParam, BOOL& bHandled)
{
DestroyWindow();
return 0;
}
LRESULT OnDestroy(UINT nMsg, WPARAM wParam,
LPARAM lParam, BOOL& bHandled)
{
PostQuitMessage(0);
return 0;
}
LRESULT OnEraseBkgnd(UINT nMsg, WPARAM wParam,
LPARAM lParam, BOOL& bHandled)
{
if (m_Bk.IsNull())
{
bHandled = FALSE;
return 1;
}
RECT rect = { 0 };
GetClientRect(&rect);
RECT image = { 0, 0, m_Bk.GetWidth(), m_Bk.GetHeight() };
HDC hDC = (HDC)wParam;
m_Bk.AlphaBlend(hDC, rect, image);
return 1;
}
LRESULT OnGetMinMaxInfo(UINT nMsg, WPARAM wParam,
LPARAM lParam, BOOL& bHandled)
{
if (m_Bk.IsNull())
{
bHandled = FALSE;
return 1;
}
LPMINMAXINFO pInfo = (LPMINMAXINFO)lParam;
if (pInfo != NULL)
{
pInfo->ptMinTrackSize.x =
m_rcMin.right - m_rcMin.left;
pInfo->ptMinTrackSize.y =
m_rcMin.bottom - m_rcMin.top;
}
return 0;
}
BOOL Center(int cx, int cy, RECT& rect)
{
HDC hDC = ::GetDC(NULL);
const int w = GetDeviceCaps(hDC, HORZRES);
const int h = GetDeviceCaps(hDC, VERTRES);
::ReleaseDC(NULL, hDC);
rect.left = (w >> 1) - (cx >> 1);
rect.top = (h >> 1) - (cy >> 1);
rect.right = rect.left + cx;
rect.bottom = rect.top + cy;
AdjustWindowRectEx(&rect, s_nWndStyle, FALSE,
s_nWndStyleEx);
return TRUE;
}
int Run()
{
HWND hWnd = Create(NULL, CWindow::rcDefault,
L"Adjust Window Rectangle");
if (hWnd == NULL)
return 0;
ShowWindow(SW_SHOWNORMAL);
UpdateWindow();
MSG msg;
while (GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
};
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nShowCmd)
{
CMyWindow wnd;
int nRun = wnd.Run();
return nRun;
}
Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.
Comments (0)