1 // Windows/Control/Dialog.cpp
2 
3 #include "StdAfx.h"
4 
5 #ifndef _UNICODE
6 #include "../../Common/StringConvert.h"
7 #endif
8 
9 #include "Dialog.h"
10 
11 extern HINSTANCE g_hInstance;
12 #ifndef _UNICODE
13 extern bool g_IsNT;
14 #endif
15 
16 namespace NWindows {
17 namespace NControl {
18 
DialogProcedure(HWND dialogHWND,UINT message,WPARAM wParam,LPARAM lParam)19 static INT_PTR APIENTRY DialogProcedure(HWND dialogHWND, UINT message, WPARAM wParam, LPARAM lParam)
20 {
21   CWindow tempDialog(dialogHWND);
22   if (message == WM_INITDIALOG)
23     tempDialog.SetUserDataLongPtr(lParam);
24   CDialog *dialog = (CDialog *)(tempDialog.GetUserDataLongPtr());
25   if (dialog == NULL)
26     return FALSE;
27   if (message == WM_INITDIALOG)
28     dialog->Attach(dialogHWND);
29   try { return BoolToBOOL(dialog->OnMessage(message, wParam, lParam)); }
30   catch(...) { return TRUE; }
31 }
32 
OnMessage(UINT message,WPARAM wParam,LPARAM lParam)33 bool CDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
34 {
35   switch (message)
36   {
37     case WM_INITDIALOG: return OnInit();
38     case WM_COMMAND: return OnCommand(wParam, lParam);
39     case WM_NOTIFY: return OnNotify((UINT)wParam, (LPNMHDR) lParam);
40     case WM_TIMER: return OnTimer(wParam, lParam);
41     case WM_SIZE: return OnSize(wParam, LOWORD(lParam), HIWORD(lParam));
42     case WM_HELP: OnHelp(); return true;
43     /*
44         OnHelp(
45           #ifdef UNDER_CE
46           (void *)
47           #else
48           (LPHELPINFO)
49           #endif
50           lParam);
51         return true;
52     */
53     default: return false;
54   }
55 }
56 
OnCommand(WPARAM wParam,LPARAM lParam)57 bool CDialog::OnCommand(WPARAM wParam, LPARAM lParam)
58 {
59   return OnCommand(HIWORD(wParam), LOWORD(wParam), lParam);
60 }
61 
OnCommand(int code,int itemID,LPARAM lParam)62 bool CDialog::OnCommand(int code, int itemID, LPARAM lParam)
63 {
64   if (code == BN_CLICKED)
65     return OnButtonClicked(itemID, (HWND)lParam);
66   return false;
67 }
68 
OnButtonClicked(int buttonID,HWND)69 bool CDialog::OnButtonClicked(int buttonID, HWND /* buttonHWND */)
70 {
71   switch (buttonID)
72   {
73     case IDOK: OnOK(); break;
74     case IDCANCEL: OnCancel(); break;
75     case IDCLOSE: OnClose(); break;
76     case IDHELP: OnHelp(); break;
77     default: return false;
78   }
79   return true;
80 }
81 
GetWorkAreaRect(RECT * rect)82 static bool GetWorkAreaRect(RECT *rect)
83 {
84   // use another function for multi-monitor.
85   return BOOLToBool(::SystemParametersInfo(SPI_GETWORKAREA, 0, rect, 0));
86 }
87 
IsDialogSizeOK(int xSize,int ySize)88 bool IsDialogSizeOK(int xSize, int ySize)
89 {
90   // it returns for system font. Real font uses another values
91   LONG v = GetDialogBaseUnits();
92   int x = LOWORD(v);
93   int y = HIWORD(v);
94 
95   RECT rect;
96   GetWorkAreaRect(&rect);
97   int wx = RECT_SIZE_X(rect);
98   int wy = RECT_SIZE_Y(rect);
99   return
100     xSize / 4 * x <= wx &&
101     ySize / 8 * y <= wy;
102 }
103 
GetMargins(int margin,int & x,int & y)104 bool CDialog::GetMargins(int margin, int &x, int &y)
105 {
106   x = margin;
107   y = margin;
108   RECT rect;
109   rect.left = 0;
110   rect.top = 0;
111   rect.right = margin;
112   rect.bottom = margin;
113   if (!MapRect(&rect))
114     return false;
115   x = rect.right - rect.left;
116   y = rect.bottom - rect.top;
117   return true;
118 }
119 
Units_To_Pixels_X(int units)120 int CDialog::Units_To_Pixels_X(int units)
121 {
122   RECT rect;
123   rect.left = 0;
124   rect.top = 0;
125   rect.right = units;
126   rect.bottom = units;
127   if (!MapRect(&rect))
128     return units * 3 / 2;
129   return rect.right - rect.left;
130 }
131 
GetItemSizes(int id,int & x,int & y)132 bool CDialog::GetItemSizes(int id, int &x, int &y)
133 {
134   RECT rect;
135   if (!::GetWindowRect(GetItem(id), &rect))
136     return false;
137   x = RECT_SIZE_X(rect);
138   y = RECT_SIZE_Y(rect);
139   return true;
140 }
141 
GetClientRectOfItem(int id,RECT & rect)142 void CDialog::GetClientRectOfItem(int id, RECT &rect)
143 {
144   ::GetWindowRect(GetItem(id), &rect);
145   ScreenToClient(&rect);
146 }
147 
MoveItem(int id,int x,int y,int width,int height,bool repaint)148 bool CDialog::MoveItem(int id, int x, int y, int width, int height, bool repaint)
149 {
150   return BOOLToBool(::MoveWindow(GetItem(id), x, y, width, height, BoolToBOOL(repaint)));
151 }
152 
NormalizeSize(bool fullNormalize)153 void CDialog::NormalizeSize(bool fullNormalize)
154 {
155   RECT workRect;
156   GetWorkAreaRect(&workRect);
157   int xSize = RECT_SIZE_X(workRect);
158   int ySize = RECT_SIZE_Y(workRect);
159   RECT rect;
160   GetWindowRect(&rect);
161   int xSize2 = RECT_SIZE_X(rect);
162   int ySize2 = RECT_SIZE_Y(rect);
163   bool needMove = (xSize2 > xSize || ySize2 > ySize);
164   if (xSize2 > xSize || (needMove && fullNormalize))
165   {
166     rect.left = workRect.left;
167     rect.right = workRect.right;
168     xSize2 = xSize;
169   }
170   if (ySize2 > ySize || (needMove && fullNormalize))
171   {
172     rect.top = workRect.top;
173     rect.bottom = workRect.bottom;
174     ySize2 = ySize;
175   }
176   if (needMove)
177   {
178     if (fullNormalize)
179       Show(SW_SHOWMAXIMIZED);
180     else
181       Move(rect.left, rect.top, xSize2, ySize2, true);
182   }
183 }
184 
NormalizePosition()185 void CDialog::NormalizePosition()
186 {
187   RECT workRect, rect;
188   GetWorkAreaRect(&workRect);
189   GetWindowRect(&rect);
190   if (rect.bottom > workRect.bottom && rect.top > workRect.top)
191     Move(rect.left, workRect.top, RECT_SIZE_X(rect), RECT_SIZE_Y(rect), true);
192 }
193 
Create(LPCTSTR templateName,HWND parentWindow)194 bool CModelessDialog::Create(LPCTSTR templateName, HWND parentWindow)
195 {
196   HWND aHWND = CreateDialogParam(g_hInstance, templateName, parentWindow, DialogProcedure, (LPARAM)this);
197   if (aHWND == 0)
198     return false;
199   Attach(aHWND);
200   return true;
201 }
202 
Create(LPCTSTR templateName,HWND parentWindow)203 INT_PTR CModalDialog::Create(LPCTSTR templateName, HWND parentWindow)
204 {
205   return DialogBoxParam(g_hInstance, templateName, parentWindow, DialogProcedure, (LPARAM)this);
206 }
207 
208 #ifndef _UNICODE
209 
Create(LPCWSTR templateName,HWND parentWindow)210 bool CModelessDialog::Create(LPCWSTR templateName, HWND parentWindow)
211 {
212   HWND aHWND;
213   if (g_IsNT)
214     aHWND = CreateDialogParamW(g_hInstance, templateName, parentWindow, DialogProcedure, (LPARAM)this);
215   else
216   {
217     AString name;
218     LPCSTR templateNameA;
219     if (IS_INTRESOURCE(templateName))
220       templateNameA = (LPCSTR)templateName;
221     else
222     {
223       name = GetSystemString(templateName);
224       templateNameA = name;
225     }
226     aHWND = CreateDialogParamA(g_hInstance, templateNameA, parentWindow, DialogProcedure, (LPARAM)this);
227   }
228   if (aHWND == 0)
229     return false;
230   Attach(aHWND);
231   return true;
232 }
233 
Create(LPCWSTR templateName,HWND parentWindow)234 INT_PTR CModalDialog::Create(LPCWSTR templateName, HWND parentWindow)
235 {
236   if (g_IsNT)
237     return DialogBoxParamW(g_hInstance, templateName, parentWindow, DialogProcedure, (LPARAM)this);
238   AString name;
239   LPCSTR templateNameA;
240   if (IS_INTRESOURCE(templateName))
241     templateNameA = (LPCSTR)templateName;
242   else
243   {
244     name = GetSystemString(templateName);
245     templateNameA = name;
246   }
247   return DialogBoxParamA(g_hInstance, templateNameA, parentWindow, DialogProcedure, (LPARAM)this);
248 }
249 #endif
250 
251 }}
252