xref: /aosp_15_r20/external/lzma/CPP/Windows/Control/Dialog.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // Windows/Control/Dialog.cpp
2*f6dc9357SAndroid Build Coastguard Worker 
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker 
5*f6dc9357SAndroid Build Coastguard Worker // #include "../../Windows/DLL.h"
6*f6dc9357SAndroid Build Coastguard Worker 
7*f6dc9357SAndroid Build Coastguard Worker #ifndef _UNICODE
8*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/StringConvert.h"
9*f6dc9357SAndroid Build Coastguard Worker #endif
10*f6dc9357SAndroid Build Coastguard Worker 
11*f6dc9357SAndroid Build Coastguard Worker #include "Dialog.h"
12*f6dc9357SAndroid Build Coastguard Worker 
13*f6dc9357SAndroid Build Coastguard Worker extern HINSTANCE g_hInstance;
14*f6dc9357SAndroid Build Coastguard Worker #ifndef _UNICODE
15*f6dc9357SAndroid Build Coastguard Worker extern bool g_IsNT;
16*f6dc9357SAndroid Build Coastguard Worker #endif
17*f6dc9357SAndroid Build Coastguard Worker 
18*f6dc9357SAndroid Build Coastguard Worker namespace NWindows {
19*f6dc9357SAndroid Build Coastguard Worker namespace NControl {
20*f6dc9357SAndroid Build Coastguard Worker 
21*f6dc9357SAndroid Build Coastguard Worker static
22*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_OLD_WIN_SDK
23*f6dc9357SAndroid Build Coastguard Worker   BOOL
24*f6dc9357SAndroid Build Coastguard Worker #else
25*f6dc9357SAndroid Build Coastguard Worker   INT_PTR
26*f6dc9357SAndroid Build Coastguard Worker #endif
27*f6dc9357SAndroid Build Coastguard Worker APIENTRY
DialogProcedure(HWND dialogHWND,UINT message,WPARAM wParam,LPARAM lParam)28*f6dc9357SAndroid Build Coastguard Worker DialogProcedure(HWND dialogHWND, UINT message, WPARAM wParam, LPARAM lParam)
29*f6dc9357SAndroid Build Coastguard Worker {
30*f6dc9357SAndroid Build Coastguard Worker   CWindow tempDialog(dialogHWND);
31*f6dc9357SAndroid Build Coastguard Worker   if (message == WM_INITDIALOG)
32*f6dc9357SAndroid Build Coastguard Worker     tempDialog.SetUserDataLongPtr(lParam);
33*f6dc9357SAndroid Build Coastguard Worker   CDialog *dialog = (CDialog *)(tempDialog.GetUserDataLongPtr());
34*f6dc9357SAndroid Build Coastguard Worker   if (dialog == NULL)
35*f6dc9357SAndroid Build Coastguard Worker     return FALSE;
36*f6dc9357SAndroid Build Coastguard Worker   if (message == WM_INITDIALOG)
37*f6dc9357SAndroid Build Coastguard Worker     dialog->Attach(dialogHWND);
38*f6dc9357SAndroid Build Coastguard Worker 
39*f6dc9357SAndroid Build Coastguard Worker   /* MSDN: The dialog box procedure should return
40*f6dc9357SAndroid Build Coastguard Worker        TRUE  - if it processed the message
41*f6dc9357SAndroid Build Coastguard Worker        FALSE - if it did not process the message
42*f6dc9357SAndroid Build Coastguard Worker      If the dialog box procedure returns FALSE,
43*f6dc9357SAndroid Build Coastguard Worker      the dialog manager performs the default dialog operation in response to the message.
44*f6dc9357SAndroid Build Coastguard Worker   */
45*f6dc9357SAndroid Build Coastguard Worker 
46*f6dc9357SAndroid Build Coastguard Worker   try { return BoolToBOOL(dialog->OnMessage(message, wParam, lParam)); }
47*f6dc9357SAndroid Build Coastguard Worker   catch(...) { return TRUE; }
48*f6dc9357SAndroid Build Coastguard Worker }
49*f6dc9357SAndroid Build Coastguard Worker 
OnMessage(UINT message,WPARAM wParam,LPARAM lParam)50*f6dc9357SAndroid Build Coastguard Worker bool CDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
51*f6dc9357SAndroid Build Coastguard Worker {
52*f6dc9357SAndroid Build Coastguard Worker   switch (message)
53*f6dc9357SAndroid Build Coastguard Worker   {
54*f6dc9357SAndroid Build Coastguard Worker     case WM_INITDIALOG: return OnInit();
55*f6dc9357SAndroid Build Coastguard Worker     case WM_COMMAND: return OnCommand(HIWORD(wParam), LOWORD(wParam), lParam);
56*f6dc9357SAndroid Build Coastguard Worker     case WM_NOTIFY: return OnNotify((UINT)wParam, (LPNMHDR) lParam);
57*f6dc9357SAndroid Build Coastguard Worker     case WM_TIMER: return OnTimer(wParam, lParam);
58*f6dc9357SAndroid Build Coastguard Worker     case WM_SIZE: return OnSize(wParam, LOWORD(lParam), HIWORD(lParam));
59*f6dc9357SAndroid Build Coastguard Worker     case WM_DESTROY: return OnDestroy();
60*f6dc9357SAndroid Build Coastguard Worker     case WM_HELP: OnHelp(); return true;
61*f6dc9357SAndroid Build Coastguard Worker     /*
62*f6dc9357SAndroid Build Coastguard Worker         OnHelp(
63*f6dc9357SAndroid Build Coastguard Worker           #ifdef UNDER_CE
64*f6dc9357SAndroid Build Coastguard Worker           (void *)
65*f6dc9357SAndroid Build Coastguard Worker           #else
66*f6dc9357SAndroid Build Coastguard Worker           (LPHELPINFO)
67*f6dc9357SAndroid Build Coastguard Worker           #endif
68*f6dc9357SAndroid Build Coastguard Worker           lParam);
69*f6dc9357SAndroid Build Coastguard Worker         return true;
70*f6dc9357SAndroid Build Coastguard Worker     */
71*f6dc9357SAndroid Build Coastguard Worker     default: return false;
72*f6dc9357SAndroid Build Coastguard Worker   }
73*f6dc9357SAndroid Build Coastguard Worker }
74*f6dc9357SAndroid Build Coastguard Worker 
75*f6dc9357SAndroid Build Coastguard Worker /*
76*f6dc9357SAndroid Build Coastguard Worker bool CDialog::OnCommand2(WPARAM wParam, LPARAM lParam)
77*f6dc9357SAndroid Build Coastguard Worker {
78*f6dc9357SAndroid Build Coastguard Worker   return OnCommand(HIWORD(wParam), LOWORD(wParam), lParam);
79*f6dc9357SAndroid Build Coastguard Worker }
80*f6dc9357SAndroid Build Coastguard Worker */
81*f6dc9357SAndroid Build Coastguard Worker 
OnCommand(unsigned code,unsigned itemID,LPARAM lParam)82*f6dc9357SAndroid Build Coastguard Worker bool CDialog::OnCommand(unsigned code, unsigned itemID, LPARAM lParam)
83*f6dc9357SAndroid Build Coastguard Worker {
84*f6dc9357SAndroid Build Coastguard Worker   if (code == BN_CLICKED)
85*f6dc9357SAndroid Build Coastguard Worker     return OnButtonClicked(itemID, (HWND)lParam);
86*f6dc9357SAndroid Build Coastguard Worker   return false;
87*f6dc9357SAndroid Build Coastguard Worker }
88*f6dc9357SAndroid Build Coastguard Worker 
OnButtonClicked(unsigned buttonID,HWND)89*f6dc9357SAndroid Build Coastguard Worker bool CDialog::OnButtonClicked(unsigned buttonID, HWND /* buttonHWND */)
90*f6dc9357SAndroid Build Coastguard Worker {
91*f6dc9357SAndroid Build Coastguard Worker   switch (buttonID)
92*f6dc9357SAndroid Build Coastguard Worker   {
93*f6dc9357SAndroid Build Coastguard Worker     case IDOK: OnOK(); break;
94*f6dc9357SAndroid Build Coastguard Worker     case IDCANCEL: OnCancel(); break;
95*f6dc9357SAndroid Build Coastguard Worker     case IDCLOSE: OnClose(); break;
96*f6dc9357SAndroid Build Coastguard Worker     case IDCONTINUE: OnContinue(); break;
97*f6dc9357SAndroid Build Coastguard Worker     case IDHELP: OnHelp(); break;
98*f6dc9357SAndroid Build Coastguard Worker     default: return false;
99*f6dc9357SAndroid Build Coastguard Worker   }
100*f6dc9357SAndroid Build Coastguard Worker   return true;
101*f6dc9357SAndroid Build Coastguard Worker }
102*f6dc9357SAndroid Build Coastguard Worker 
103*f6dc9357SAndroid Build Coastguard Worker #ifndef UNDER_CE
104*f6dc9357SAndroid Build Coastguard Worker /* in win2000/win98 : monitor functions are supported.
105*f6dc9357SAndroid Build Coastguard Worker    We need dynamic linking, if we want nt4/win95 support in program.
106*f6dc9357SAndroid Build Coastguard Worker    Even if we compile the code with low (WINVER) value, we still
107*f6dc9357SAndroid Build Coastguard Worker    want to use monitor functions. So we declare missing functions here */
108*f6dc9357SAndroid Build Coastguard Worker // #if (WINVER < 0x0500)
109*f6dc9357SAndroid Build Coastguard Worker #ifndef MONITOR_DEFAULTTOPRIMARY
110*f6dc9357SAndroid Build Coastguard Worker extern "C" {
111*f6dc9357SAndroid Build Coastguard Worker DECLARE_HANDLE(HMONITOR);
112*f6dc9357SAndroid Build Coastguard Worker #define MONITOR_DEFAULTTOPRIMARY    0x00000001
113*f6dc9357SAndroid Build Coastguard Worker typedef struct tagMONITORINFO
114*f6dc9357SAndroid Build Coastguard Worker {
115*f6dc9357SAndroid Build Coastguard Worker     DWORD   cbSize;
116*f6dc9357SAndroid Build Coastguard Worker     RECT    rcMonitor;
117*f6dc9357SAndroid Build Coastguard Worker     RECT    rcWork;
118*f6dc9357SAndroid Build Coastguard Worker     DWORD   dwFlags;
119*f6dc9357SAndroid Build Coastguard Worker } MONITORINFO, *LPMONITORINFO;
120*f6dc9357SAndroid Build Coastguard Worker WINUSERAPI HMONITOR WINAPI MonitorFromWindow(HWND hwnd, DWORD dwFlags);
121*f6dc9357SAndroid Build Coastguard Worker WINUSERAPI BOOL WINAPI GetMonitorInfoA(HMONITOR hMonitor, LPMONITORINFO lpmi);
122*f6dc9357SAndroid Build Coastguard Worker }
123*f6dc9357SAndroid Build Coastguard Worker #endif
124*f6dc9357SAndroid Build Coastguard Worker #endif
125*f6dc9357SAndroid Build Coastguard Worker 
GetWorkAreaRect(RECT * rect,HWND hwnd)126*f6dc9357SAndroid Build Coastguard Worker static bool GetWorkAreaRect(RECT *rect, HWND hwnd)
127*f6dc9357SAndroid Build Coastguard Worker {
128*f6dc9357SAndroid Build Coastguard Worker   if (hwnd)
129*f6dc9357SAndroid Build Coastguard Worker   {
130*f6dc9357SAndroid Build Coastguard Worker     #ifndef UNDER_CE
131*f6dc9357SAndroid Build Coastguard Worker     /* MonitorFromWindow() is supported in Win2000+
132*f6dc9357SAndroid Build Coastguard Worker        MonitorFromWindow() : retrieves a handle to the display monitor that has the
133*f6dc9357SAndroid Build Coastguard Worker          largest area of intersection with the bounding rectangle of a specified window.
134*f6dc9357SAndroid Build Coastguard Worker        dwFlags: Determines the function's return value if the window does not intersect any display monitor.
135*f6dc9357SAndroid Build Coastguard Worker          MONITOR_DEFAULTTONEAREST : Returns display that is nearest to the window.
136*f6dc9357SAndroid Build Coastguard Worker          MONITOR_DEFAULTTONULL    : Returns NULL.
137*f6dc9357SAndroid Build Coastguard Worker          MONITOR_DEFAULTTOPRIMARY : Returns the primary display monitor.
138*f6dc9357SAndroid Build Coastguard Worker     */
139*f6dc9357SAndroid Build Coastguard Worker     const HMONITOR hmon = MonitorFromWindow(hwnd, MONITOR_DEFAULTTOPRIMARY);
140*f6dc9357SAndroid Build Coastguard Worker     if (hmon)
141*f6dc9357SAndroid Build Coastguard Worker     {
142*f6dc9357SAndroid Build Coastguard Worker       MONITORINFO mi;
143*f6dc9357SAndroid Build Coastguard Worker       memset(&mi, 0, sizeof(mi));
144*f6dc9357SAndroid Build Coastguard Worker       mi.cbSize = sizeof(mi);
145*f6dc9357SAndroid Build Coastguard Worker       if (GetMonitorInfoA(hmon, &mi))
146*f6dc9357SAndroid Build Coastguard Worker       {
147*f6dc9357SAndroid Build Coastguard Worker         *rect = mi.rcWork;
148*f6dc9357SAndroid Build Coastguard Worker         return true;
149*f6dc9357SAndroid Build Coastguard Worker       }
150*f6dc9357SAndroid Build Coastguard Worker     }
151*f6dc9357SAndroid Build Coastguard Worker     #endif
152*f6dc9357SAndroid Build Coastguard Worker   }
153*f6dc9357SAndroid Build Coastguard Worker 
154*f6dc9357SAndroid Build Coastguard Worker   /* Retrieves the size of the work area on the primary display monitor.
155*f6dc9357SAndroid Build Coastguard Worker      The work area is the portion of the screen not obscured
156*f6dc9357SAndroid Build Coastguard Worker      by the system taskbar or by application desktop toolbars.
157*f6dc9357SAndroid Build Coastguard Worker      Any DPI virtualization mode of the caller has no effect on this output. */
158*f6dc9357SAndroid Build Coastguard Worker 
159*f6dc9357SAndroid Build Coastguard Worker   return BOOLToBool(::SystemParametersInfo(SPI_GETWORKAREA, 0, rect, 0));
160*f6dc9357SAndroid Build Coastguard Worker }
161*f6dc9357SAndroid Build Coastguard Worker 
162*f6dc9357SAndroid Build Coastguard Worker 
IsDialogSizeOK(int xSize,int ySize,HWND hwnd)163*f6dc9357SAndroid Build Coastguard Worker bool IsDialogSizeOK(int xSize, int ySize, HWND hwnd)
164*f6dc9357SAndroid Build Coastguard Worker {
165*f6dc9357SAndroid Build Coastguard Worker   // it returns for system font. Real font uses another values
166*f6dc9357SAndroid Build Coastguard Worker   const LONG v = GetDialogBaseUnits();
167*f6dc9357SAndroid Build Coastguard Worker   const int x = LOWORD(v);
168*f6dc9357SAndroid Build Coastguard Worker   const int y = HIWORD(v);
169*f6dc9357SAndroid Build Coastguard Worker 
170*f6dc9357SAndroid Build Coastguard Worker   RECT rect;
171*f6dc9357SAndroid Build Coastguard Worker   GetWorkAreaRect(&rect, hwnd);
172*f6dc9357SAndroid Build Coastguard Worker   const int wx = RECT_SIZE_X(rect);
173*f6dc9357SAndroid Build Coastguard Worker   const int wy = RECT_SIZE_Y(rect);
174*f6dc9357SAndroid Build Coastguard Worker   return
175*f6dc9357SAndroid Build Coastguard Worker     xSize / 4 * x <= wx &&
176*f6dc9357SAndroid Build Coastguard Worker     ySize / 8 * y <= wy;
177*f6dc9357SAndroid Build Coastguard Worker }
178*f6dc9357SAndroid Build Coastguard Worker 
GetMargins(int margin,int & x,int & y)179*f6dc9357SAndroid Build Coastguard Worker bool CDialog::GetMargins(int margin, int &x, int &y)
180*f6dc9357SAndroid Build Coastguard Worker {
181*f6dc9357SAndroid Build Coastguard Worker   x = margin;
182*f6dc9357SAndroid Build Coastguard Worker   y = margin;
183*f6dc9357SAndroid Build Coastguard Worker   RECT rect;
184*f6dc9357SAndroid Build Coastguard Worker   rect.left = 0;
185*f6dc9357SAndroid Build Coastguard Worker   rect.top = 0;
186*f6dc9357SAndroid Build Coastguard Worker   rect.right = margin;
187*f6dc9357SAndroid Build Coastguard Worker   rect.bottom = margin;
188*f6dc9357SAndroid Build Coastguard Worker   if (!MapRect(&rect))
189*f6dc9357SAndroid Build Coastguard Worker     return false;
190*f6dc9357SAndroid Build Coastguard Worker   x = rect.right - rect.left;
191*f6dc9357SAndroid Build Coastguard Worker   y = rect.bottom - rect.top;
192*f6dc9357SAndroid Build Coastguard Worker   return true;
193*f6dc9357SAndroid Build Coastguard Worker }
194*f6dc9357SAndroid Build Coastguard Worker 
Units_To_Pixels_X(int units)195*f6dc9357SAndroid Build Coastguard Worker int CDialog::Units_To_Pixels_X(int units)
196*f6dc9357SAndroid Build Coastguard Worker {
197*f6dc9357SAndroid Build Coastguard Worker   RECT rect;
198*f6dc9357SAndroid Build Coastguard Worker   rect.left = 0;
199*f6dc9357SAndroid Build Coastguard Worker   rect.top = 0;
200*f6dc9357SAndroid Build Coastguard Worker   rect.right = units;
201*f6dc9357SAndroid Build Coastguard Worker   rect.bottom = units;
202*f6dc9357SAndroid Build Coastguard Worker   if (!MapRect(&rect))
203*f6dc9357SAndroid Build Coastguard Worker     return units * 3 / 2;
204*f6dc9357SAndroid Build Coastguard Worker   return rect.right - rect.left;
205*f6dc9357SAndroid Build Coastguard Worker }
206*f6dc9357SAndroid Build Coastguard Worker 
GetItemSizes(unsigned id,int & x,int & y)207*f6dc9357SAndroid Build Coastguard Worker bool CDialog::GetItemSizes(unsigned id, int &x, int &y)
208*f6dc9357SAndroid Build Coastguard Worker {
209*f6dc9357SAndroid Build Coastguard Worker   RECT rect;
210*f6dc9357SAndroid Build Coastguard Worker   if (!::GetWindowRect(GetItem(id), &rect))
211*f6dc9357SAndroid Build Coastguard Worker     return false;
212*f6dc9357SAndroid Build Coastguard Worker   x = RECT_SIZE_X(rect);
213*f6dc9357SAndroid Build Coastguard Worker   y = RECT_SIZE_Y(rect);
214*f6dc9357SAndroid Build Coastguard Worker   return true;
215*f6dc9357SAndroid Build Coastguard Worker }
216*f6dc9357SAndroid Build Coastguard Worker 
GetClientRectOfItem(unsigned id,RECT & rect)217*f6dc9357SAndroid Build Coastguard Worker void CDialog::GetClientRectOfItem(unsigned id, RECT &rect)
218*f6dc9357SAndroid Build Coastguard Worker {
219*f6dc9357SAndroid Build Coastguard Worker   ::GetWindowRect(GetItem(id), &rect);
220*f6dc9357SAndroid Build Coastguard Worker   ScreenToClient(&rect);
221*f6dc9357SAndroid Build Coastguard Worker }
222*f6dc9357SAndroid Build Coastguard Worker 
MoveItem(unsigned id,int x,int y,int width,int height,bool repaint)223*f6dc9357SAndroid Build Coastguard Worker bool CDialog::MoveItem(unsigned id, int x, int y, int width, int height, bool repaint)
224*f6dc9357SAndroid Build Coastguard Worker {
225*f6dc9357SAndroid Build Coastguard Worker   return BOOLToBool(::MoveWindow(GetItem(id), x, y, width, height, BoolToBOOL(repaint)));
226*f6dc9357SAndroid Build Coastguard Worker }
227*f6dc9357SAndroid Build Coastguard Worker 
228*f6dc9357SAndroid Build Coastguard Worker 
229*f6dc9357SAndroid Build Coastguard Worker /*
230*f6dc9357SAndroid Build Coastguard Worker typedef BOOL (WINAPI * Func_DwmGetWindowAttribute)(
231*f6dc9357SAndroid Build Coastguard Worker     HWND hwnd, DWORD dwAttribute, PVOID pvAttribute, DWORD cbAttribute);
232*f6dc9357SAndroid Build Coastguard Worker 
233*f6dc9357SAndroid Build Coastguard Worker static bool GetWindowsRect_DWM(HWND hwnd, RECT *rect)
234*f6dc9357SAndroid Build Coastguard Worker {
235*f6dc9357SAndroid Build Coastguard Worker   // dll load and free is too slow : 300 calls in second.
236*f6dc9357SAndroid Build Coastguard Worker   NDLL::CLibrary dll;
237*f6dc9357SAndroid Build Coastguard Worker   if (!dll.Load(FTEXT("dwmapi.dll")))
238*f6dc9357SAndroid Build Coastguard Worker     return false;
239*f6dc9357SAndroid Build Coastguard Worker   Func_DwmGetWindowAttribute f = (Func_DwmGetWindowAttribute)dll.GetProc("DwmGetWindowAttribute" );
240*f6dc9357SAndroid Build Coastguard Worker   if (f)
241*f6dc9357SAndroid Build Coastguard Worker   {
242*f6dc9357SAndroid Build Coastguard Worker     #define MY__DWMWA_EXTENDED_FRAME_BOUNDS 9
243*f6dc9357SAndroid Build Coastguard Worker     // 30000 per second
244*f6dc9357SAndroid Build Coastguard Worker     RECT r;
245*f6dc9357SAndroid Build Coastguard Worker     if (f(hwnd, MY__DWMWA_EXTENDED_FRAME_BOUNDS, &r, sizeof(RECT)) == S_OK)
246*f6dc9357SAndroid Build Coastguard Worker     {
247*f6dc9357SAndroid Build Coastguard Worker       *rect = r;
248*f6dc9357SAndroid Build Coastguard Worker       return true;
249*f6dc9357SAndroid Build Coastguard Worker     }
250*f6dc9357SAndroid Build Coastguard Worker   }
251*f6dc9357SAndroid Build Coastguard Worker   return false;
252*f6dc9357SAndroid Build Coastguard Worker }
253*f6dc9357SAndroid Build Coastguard Worker */
254*f6dc9357SAndroid Build Coastguard Worker 
255*f6dc9357SAndroid Build Coastguard Worker 
IsRect_Small_Inside_Big(const RECT & sm,const RECT & big)256*f6dc9357SAndroid Build Coastguard Worker static bool IsRect_Small_Inside_Big(const RECT &sm, const RECT &big)
257*f6dc9357SAndroid Build Coastguard Worker {
258*f6dc9357SAndroid Build Coastguard Worker   return sm.left   >= big.left
259*f6dc9357SAndroid Build Coastguard Worker       && sm.right  <= big.right
260*f6dc9357SAndroid Build Coastguard Worker       && sm.top    >= big.top
261*f6dc9357SAndroid Build Coastguard Worker       && sm.bottom <= big.bottom;
262*f6dc9357SAndroid Build Coastguard Worker }
263*f6dc9357SAndroid Build Coastguard Worker 
264*f6dc9357SAndroid Build Coastguard Worker 
AreRectsOverlapped(const RECT & r1,const RECT & r2)265*f6dc9357SAndroid Build Coastguard Worker static bool AreRectsOverlapped(const RECT &r1, const RECT &r2)
266*f6dc9357SAndroid Build Coastguard Worker {
267*f6dc9357SAndroid Build Coastguard Worker   return r1.left   < r2.right
268*f6dc9357SAndroid Build Coastguard Worker       && r1.right  > r2.left
269*f6dc9357SAndroid Build Coastguard Worker       && r1.top    < r2.bottom
270*f6dc9357SAndroid Build Coastguard Worker       && r1.bottom > r2.top;
271*f6dc9357SAndroid Build Coastguard Worker }
272*f6dc9357SAndroid Build Coastguard Worker 
273*f6dc9357SAndroid Build Coastguard Worker 
AreRectsEqual(const RECT & r1,const RECT & r2)274*f6dc9357SAndroid Build Coastguard Worker static bool AreRectsEqual(const RECT &r1, const RECT &r2)
275*f6dc9357SAndroid Build Coastguard Worker {
276*f6dc9357SAndroid Build Coastguard Worker   return r1.left   == r2.left
277*f6dc9357SAndroid Build Coastguard Worker       && r1.right  == r2.right
278*f6dc9357SAndroid Build Coastguard Worker       && r1.top    == r2.top
279*f6dc9357SAndroid Build Coastguard Worker       && r1.bottom == r2.bottom;
280*f6dc9357SAndroid Build Coastguard Worker }
281*f6dc9357SAndroid Build Coastguard Worker 
282*f6dc9357SAndroid Build Coastguard Worker 
NormalizeSize(bool fullNormalize)283*f6dc9357SAndroid Build Coastguard Worker void CDialog::NormalizeSize(bool fullNormalize)
284*f6dc9357SAndroid Build Coastguard Worker {
285*f6dc9357SAndroid Build Coastguard Worker   RECT workRect;
286*f6dc9357SAndroid Build Coastguard Worker   if (!GetWorkAreaRect(&workRect, *this))
287*f6dc9357SAndroid Build Coastguard Worker     return;
288*f6dc9357SAndroid Build Coastguard Worker   RECT rect;
289*f6dc9357SAndroid Build Coastguard Worker   if (!GetWindowRect(&rect))
290*f6dc9357SAndroid Build Coastguard Worker     return;
291*f6dc9357SAndroid Build Coastguard Worker   int xs = RECT_SIZE_X(rect);
292*f6dc9357SAndroid Build Coastguard Worker   int ys = RECT_SIZE_Y(rect);
293*f6dc9357SAndroid Build Coastguard Worker 
294*f6dc9357SAndroid Build Coastguard Worker   // we don't want to change size using workRect, if window is outside of WorkArea
295*f6dc9357SAndroid Build Coastguard Worker   if (!AreRectsOverlapped(rect, workRect))
296*f6dc9357SAndroid Build Coastguard Worker     return;
297*f6dc9357SAndroid Build Coastguard Worker 
298*f6dc9357SAndroid Build Coastguard Worker   /* here rect and workRect are overlapped, but it can be false
299*f6dc9357SAndroid Build Coastguard Worker      overlapping of small shadow when window in another display. */
300*f6dc9357SAndroid Build Coastguard Worker 
301*f6dc9357SAndroid Build Coastguard Worker   const int xsW = RECT_SIZE_X(workRect);
302*f6dc9357SAndroid Build Coastguard Worker   const int ysW = RECT_SIZE_Y(workRect);
303*f6dc9357SAndroid Build Coastguard Worker   if (xs <= xsW && ys <= ysW)
304*f6dc9357SAndroid Build Coastguard Worker     return; // size of window is OK
305*f6dc9357SAndroid Build Coastguard Worker   if (fullNormalize)
306*f6dc9357SAndroid Build Coastguard Worker   {
307*f6dc9357SAndroid Build Coastguard Worker     Show(SW_SHOWMAXIMIZED);
308*f6dc9357SAndroid Build Coastguard Worker     return;
309*f6dc9357SAndroid Build Coastguard Worker   }
310*f6dc9357SAndroid Build Coastguard Worker   int x = workRect.left;
311*f6dc9357SAndroid Build Coastguard Worker   int y = workRect.top;
312*f6dc9357SAndroid Build Coastguard Worker   if (xs < xsW)  x += (xsW - xs) / 2;  else xs = xsW;
313*f6dc9357SAndroid Build Coastguard Worker   if (ys < ysW)  y += (ysW - ys) / 2;  else ys = ysW;
314*f6dc9357SAndroid Build Coastguard Worker   Move(x, y, xs, ys, true);
315*f6dc9357SAndroid Build Coastguard Worker }
316*f6dc9357SAndroid Build Coastguard Worker 
317*f6dc9357SAndroid Build Coastguard Worker 
NormalizePosition()318*f6dc9357SAndroid Build Coastguard Worker void CDialog::NormalizePosition()
319*f6dc9357SAndroid Build Coastguard Worker {
320*f6dc9357SAndroid Build Coastguard Worker   RECT workRect;
321*f6dc9357SAndroid Build Coastguard Worker   if (!GetWorkAreaRect(&workRect, *this))
322*f6dc9357SAndroid Build Coastguard Worker     return;
323*f6dc9357SAndroid Build Coastguard Worker 
324*f6dc9357SAndroid Build Coastguard Worker   RECT rect2 = workRect;
325*f6dc9357SAndroid Build Coastguard Worker   bool useWorkArea = true;
326*f6dc9357SAndroid Build Coastguard Worker   const HWND parentHWND = GetParent();
327*f6dc9357SAndroid Build Coastguard Worker 
328*f6dc9357SAndroid Build Coastguard Worker   if (parentHWND)
329*f6dc9357SAndroid Build Coastguard Worker   {
330*f6dc9357SAndroid Build Coastguard Worker     RECT workRectParent;
331*f6dc9357SAndroid Build Coastguard Worker     if (!GetWorkAreaRect(&workRectParent, parentHWND))
332*f6dc9357SAndroid Build Coastguard Worker       return;
333*f6dc9357SAndroid Build Coastguard Worker 
334*f6dc9357SAndroid Build Coastguard Worker     // if windows are in different monitors, we use only workArea of current window
335*f6dc9357SAndroid Build Coastguard Worker 
336*f6dc9357SAndroid Build Coastguard Worker     if (AreRectsEqual(workRectParent, workRect))
337*f6dc9357SAndroid Build Coastguard Worker     {
338*f6dc9357SAndroid Build Coastguard Worker       // RECT rect3; if (GetWindowsRect_DWM(parentHWND, &rect3)) {}
339*f6dc9357SAndroid Build Coastguard Worker       CWindow wnd(parentHWND);
340*f6dc9357SAndroid Build Coastguard Worker       if (wnd.GetWindowRect(&rect2))
341*f6dc9357SAndroid Build Coastguard Worker       {
342*f6dc9357SAndroid Build Coastguard Worker         // it's same monitor. So we try to use parentHWND rect.
343*f6dc9357SAndroid Build Coastguard Worker         /* we don't want to change position, if parent window is not inside work area.
344*f6dc9357SAndroid Build Coastguard Worker            In Win10 : parent window rect is 8 pixels larger for each corner than window size for shadow.
345*f6dc9357SAndroid Build Coastguard Worker            In maximize mode : window is outside of workRect.
346*f6dc9357SAndroid Build Coastguard Worker            if parent window is inside workRect, we will use parent window instead of workRect */
347*f6dc9357SAndroid Build Coastguard Worker         if (IsRect_Small_Inside_Big(rect2, workRect))
348*f6dc9357SAndroid Build Coastguard Worker           useWorkArea = false;
349*f6dc9357SAndroid Build Coastguard Worker       }
350*f6dc9357SAndroid Build Coastguard Worker     }
351*f6dc9357SAndroid Build Coastguard Worker   }
352*f6dc9357SAndroid Build Coastguard Worker 
353*f6dc9357SAndroid Build Coastguard Worker   RECT rect;
354*f6dc9357SAndroid Build Coastguard Worker   if (!GetWindowRect(&rect))
355*f6dc9357SAndroid Build Coastguard Worker     return;
356*f6dc9357SAndroid Build Coastguard Worker 
357*f6dc9357SAndroid Build Coastguard Worker   if (useWorkArea)
358*f6dc9357SAndroid Build Coastguard Worker   {
359*f6dc9357SAndroid Build Coastguard Worker     // we don't want to move window, if it's already inside.
360*f6dc9357SAndroid Build Coastguard Worker     if (IsRect_Small_Inside_Big(rect, workRect))
361*f6dc9357SAndroid Build Coastguard Worker       return;
362*f6dc9357SAndroid Build Coastguard Worker     // we don't want to move window, if it's outside of workArea
363*f6dc9357SAndroid Build Coastguard Worker     if (!AreRectsOverlapped(rect, workRect))
364*f6dc9357SAndroid Build Coastguard Worker       return;
365*f6dc9357SAndroid Build Coastguard Worker     rect2 = workRect;
366*f6dc9357SAndroid Build Coastguard Worker   }
367*f6dc9357SAndroid Build Coastguard Worker 
368*f6dc9357SAndroid Build Coastguard Worker   {
369*f6dc9357SAndroid Build Coastguard Worker     const int xs = RECT_SIZE_X(rect);
370*f6dc9357SAndroid Build Coastguard Worker     const int ys = RECT_SIZE_Y(rect);
371*f6dc9357SAndroid Build Coastguard Worker     const int xs2 = RECT_SIZE_X(rect2);
372*f6dc9357SAndroid Build Coastguard Worker     const int ys2 = RECT_SIZE_Y(rect2);
373*f6dc9357SAndroid Build Coastguard Worker     // we don't want to change position if parent is smaller.
374*f6dc9357SAndroid Build Coastguard Worker     if (xs <= xs2 && ys <= ys2)
375*f6dc9357SAndroid Build Coastguard Worker     {
376*f6dc9357SAndroid Build Coastguard Worker       const int x = rect2.left + (xs2 - xs) / 2;
377*f6dc9357SAndroid Build Coastguard Worker       const int y = rect2.top  + (ys2 - ys) / 2;
378*f6dc9357SAndroid Build Coastguard Worker 
379*f6dc9357SAndroid Build Coastguard Worker       if (x != rect.left || y != rect.top)
380*f6dc9357SAndroid Build Coastguard Worker         Move(x, y, xs, ys, true);
381*f6dc9357SAndroid Build Coastguard Worker       // SetWindowPos(*this, HWND_TOP, x, y, 0, 0, SWP_NOSIZE);
382*f6dc9357SAndroid Build Coastguard Worker       return;
383*f6dc9357SAndroid Build Coastguard Worker     }
384*f6dc9357SAndroid Build Coastguard Worker   }
385*f6dc9357SAndroid Build Coastguard Worker }
386*f6dc9357SAndroid Build Coastguard Worker 
387*f6dc9357SAndroid Build Coastguard Worker 
388*f6dc9357SAndroid Build Coastguard Worker 
Create(LPCTSTR templateName,HWND parentWindow)389*f6dc9357SAndroid Build Coastguard Worker bool CModelessDialog::Create(LPCTSTR templateName, HWND parentWindow)
390*f6dc9357SAndroid Build Coastguard Worker {
391*f6dc9357SAndroid Build Coastguard Worker   const HWND aHWND = CreateDialogParam(g_hInstance, templateName, parentWindow, DialogProcedure, (LPARAM)this);
392*f6dc9357SAndroid Build Coastguard Worker   if (!aHWND)
393*f6dc9357SAndroid Build Coastguard Worker     return false;
394*f6dc9357SAndroid Build Coastguard Worker   Attach(aHWND);
395*f6dc9357SAndroid Build Coastguard Worker   return true;
396*f6dc9357SAndroid Build Coastguard Worker }
397*f6dc9357SAndroid Build Coastguard Worker 
Create(LPCTSTR templateName,HWND parentWindow)398*f6dc9357SAndroid Build Coastguard Worker INT_PTR CModalDialog::Create(LPCTSTR templateName, HWND parentWindow)
399*f6dc9357SAndroid Build Coastguard Worker {
400*f6dc9357SAndroid Build Coastguard Worker   return DialogBoxParam(g_hInstance, templateName, parentWindow, DialogProcedure, (LPARAM)this);
401*f6dc9357SAndroid Build Coastguard Worker }
402*f6dc9357SAndroid Build Coastguard Worker 
403*f6dc9357SAndroid Build Coastguard Worker #ifndef _UNICODE
404*f6dc9357SAndroid Build Coastguard Worker 
Create(LPCWSTR templateName,HWND parentWindow)405*f6dc9357SAndroid Build Coastguard Worker bool CModelessDialog::Create(LPCWSTR templateName, HWND parentWindow)
406*f6dc9357SAndroid Build Coastguard Worker {
407*f6dc9357SAndroid Build Coastguard Worker   HWND aHWND;
408*f6dc9357SAndroid Build Coastguard Worker   if (g_IsNT)
409*f6dc9357SAndroid Build Coastguard Worker     aHWND = CreateDialogParamW(g_hInstance, templateName, parentWindow, DialogProcedure, (LPARAM)this);
410*f6dc9357SAndroid Build Coastguard Worker   else
411*f6dc9357SAndroid Build Coastguard Worker   {
412*f6dc9357SAndroid Build Coastguard Worker     AString name;
413*f6dc9357SAndroid Build Coastguard Worker     LPCSTR templateNameA;
414*f6dc9357SAndroid Build Coastguard Worker     if (IS_INTRESOURCE(templateName))
415*f6dc9357SAndroid Build Coastguard Worker       templateNameA = (LPCSTR)templateName;
416*f6dc9357SAndroid Build Coastguard Worker     else
417*f6dc9357SAndroid Build Coastguard Worker     {
418*f6dc9357SAndroid Build Coastguard Worker       name = GetSystemString(templateName);
419*f6dc9357SAndroid Build Coastguard Worker       templateNameA = name;
420*f6dc9357SAndroid Build Coastguard Worker     }
421*f6dc9357SAndroid Build Coastguard Worker     aHWND = CreateDialogParamA(g_hInstance, templateNameA, parentWindow, DialogProcedure, (LPARAM)this);
422*f6dc9357SAndroid Build Coastguard Worker   }
423*f6dc9357SAndroid Build Coastguard Worker   if (aHWND == 0)
424*f6dc9357SAndroid Build Coastguard Worker     return false;
425*f6dc9357SAndroid Build Coastguard Worker   Attach(aHWND);
426*f6dc9357SAndroid Build Coastguard Worker   return true;
427*f6dc9357SAndroid Build Coastguard Worker }
428*f6dc9357SAndroid Build Coastguard Worker 
Create(LPCWSTR templateName,HWND parentWindow)429*f6dc9357SAndroid Build Coastguard Worker INT_PTR CModalDialog::Create(LPCWSTR templateName, HWND parentWindow)
430*f6dc9357SAndroid Build Coastguard Worker {
431*f6dc9357SAndroid Build Coastguard Worker   if (g_IsNT)
432*f6dc9357SAndroid Build Coastguard Worker     return DialogBoxParamW(g_hInstance, templateName, parentWindow, DialogProcedure, (LPARAM)this);
433*f6dc9357SAndroid Build Coastguard Worker   AString name;
434*f6dc9357SAndroid Build Coastguard Worker   LPCSTR templateNameA;
435*f6dc9357SAndroid Build Coastguard Worker   if (IS_INTRESOURCE(templateName))
436*f6dc9357SAndroid Build Coastguard Worker     templateNameA = (LPCSTR)templateName;
437*f6dc9357SAndroid Build Coastguard Worker   else
438*f6dc9357SAndroid Build Coastguard Worker   {
439*f6dc9357SAndroid Build Coastguard Worker     name = GetSystemString(templateName);
440*f6dc9357SAndroid Build Coastguard Worker     templateNameA = name;
441*f6dc9357SAndroid Build Coastguard Worker   }
442*f6dc9357SAndroid Build Coastguard Worker   return DialogBoxParamA(g_hInstance, templateNameA, parentWindow, DialogProcedure, (LPARAM)this);
443*f6dc9357SAndroid Build Coastguard Worker }
444*f6dc9357SAndroid Build Coastguard Worker #endif
445*f6dc9357SAndroid Build Coastguard Worker 
446*f6dc9357SAndroid Build Coastguard Worker }}
447