1 /*
2  * PROJECT:    PAINT for ReactOS
3  * LICENSE:    LGPL-2.0-or-later (https://spdx.org/licenses/LGPL-2.0-or-later)
4  * PURPOSE:    Window procedure of the main window and all children apart from
5  *             hPalWin, hToolSettings and hSelection
6  * COPYRIGHT:  Copyright 2015 Benedikt Freisen <b.freisen@gmx.net>
7  *             Copyright 2023 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
8  */
9 
10 #include "precomp.h"
11 
12 CMiniatureWindow miniature;
13 
14 /* FUNCTIONS ********************************************************/
15 
16 CMiniatureWindow::CMiniatureWindow()
17     : m_hbmCached(NULL)
18 {
19 }
20 
21 CMiniatureWindow::~CMiniatureWindow()
22 {
23     if (m_hbmCached)
24         ::DeleteObject(m_hbmCached);
25 }
26 
27 HWND CMiniatureWindow::DoCreate(HWND hwndParent)
28 {
29     if (m_hWnd)
30         return m_hWnd;
31 
32     RECT rc =
33     {
34         (LONG)registrySettings.ThumbXPos, (LONG)registrySettings.ThumbYPos,
35         (LONG)(registrySettings.ThumbXPos + registrySettings.ThumbWidth),
36         (LONG)(registrySettings.ThumbYPos + registrySettings.ThumbHeight)
37     };
38 
39     WCHAR strTitle[100];
40     ::LoadStringW(g_hinstExe, IDS_MINIATURETITLE, strTitle, _countof(strTitle));
41 
42     DWORD style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME;
43     return Create(hwndParent, rc, strTitle, style, WS_EX_PALETTEWINDOW);
44 }
45 
46 LRESULT CMiniatureWindow::OnMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
47 {
48     if (IsWindowVisible() && !IsIconic() && !IsZoomed())
49     {
50         CRect rc;
51         GetWindowRect(&rc);
52         registrySettings.ThumbXPos = rc.left;
53         registrySettings.ThumbYPos = rc.top;
54     }
55     return 0;
56 }
57 
58 LRESULT CMiniatureWindow::OnSize(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
59 {
60     if (IsWindowVisible() && !IsIconic() && !IsZoomed())
61     {
62         CRect rc;
63         GetWindowRect(&rc);
64         registrySettings.ThumbWidth = rc.Width();
65         registrySettings.ThumbHeight = rc.Height();
66     }
67     return 0;
68 }
69 
70 LRESULT CMiniatureWindow::OnClose(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
71 {
72     ShowWindow(SW_HIDE);
73     registrySettings.ShowThumbnail = FALSE;
74     return 0;
75 }
76 
77 LRESULT CMiniatureWindow::OnEraseBkgnd(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
78 {
79     return TRUE; /* Avoid flickering */
80 }
81 
82 LRESULT CMiniatureWindow::OnPaint(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
83 {
84     RECT rc;
85     GetClientRect(&rc);
86 
87     // Start painting
88     PAINTSTRUCT ps;
89     HDC hDC = BeginPaint(&ps);
90     if (!hDC)
91         return 0;
92 
93     // Use a memory bitmap to reduce flickering
94     HDC hdcMem = ::CreateCompatibleDC(hDC);
95     m_hbmCached = CachedBufferDIB(m_hbmCached, rc.right, rc.bottom);
96     HGDIOBJ hbmOld = ::SelectObject(hdcMem, m_hbmCached);
97 
98     // FIXME: Consider aspect ratio
99 
100     // Fill the background
101     ::FillRect(hdcMem, &rc, (HBRUSH)(COLOR_BTNFACE + 1));
102 
103     // Draw the image (hdcMem <-- imageModel)
104     int cxImage = imageModel.GetWidth();
105     int cyImage = imageModel.GetHeight();
106     ::StretchBlt(hdcMem, 0, 0, rc.right, rc.bottom,
107                  imageModel.GetDC(), 0, 0, cxImage, cyImage,
108                  SRCCOPY);
109 
110     // Move the image (hDC <-- hdcMem)
111     ::BitBlt(hDC, 0, 0, rc.right, rc.bottom, hdcMem, 0, 0, SRCCOPY);
112 
113     // Clean up
114     ::SelectObject(hdcMem, hbmOld);
115     ::DeleteDC(hdcMem);
116 
117     EndPaint(&ps);
118     return 0;
119 }
120 
121 LRESULT CMiniatureWindow::OnGetMinMaxInfo(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
122 {
123     // Avoid too small
124     LPMINMAXINFO pInfo = (LPMINMAXINFO)lParam;
125     pInfo->ptMinTrackSize = { 100, 75 };
126     return 0;
127 }
128