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
11extern HINSTANCE g_hInstance;
12#ifndef _UNICODE
13extern bool g_IsNT;
14#endif
15
16namespace NWindows {
17namespace NControl {
18
19static 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
33bool 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
57bool CDialog::OnCommand(WPARAM wParam, LPARAM lParam)
58{
59  return OnCommand(HIWORD(wParam), LOWORD(wParam), lParam);
60}
61
62bool 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
69bool CDialog::OnButtonClicked(int buttonID, HWND /* buttonHWND */)
70{
71  switch (buttonID)
72  {
73    case IDOK: OnOK(); break;
74    case IDCANCEL: OnCancel(); break;
75    case IDHELP: OnHelp(); break;
76    default: return false;
77  }
78  return true;
79}
80
81static bool GetWorkAreaRect(RECT *rect)
82{
83  // use another function for multi-monitor.
84  return BOOLToBool(::SystemParametersInfo(SPI_GETWORKAREA, 0, rect, 0));
85}
86
87bool IsDialogSizeOK(int xSize, int ySize)
88{
89  // it returns for system font. Real font uses another values
90  LONG v = GetDialogBaseUnits();
91  int x = LOWORD(v);
92  int y = HIWORD(v);
93
94  RECT rect;
95  GetWorkAreaRect(&rect);
96  int wx = RECT_SIZE_X(rect);
97  int wy = RECT_SIZE_Y(rect);
98  return
99    xSize / 4 * x <= wx &&
100    ySize / 8 * y <= wy;
101}
102
103bool CDialog::GetMargins(int margin, int &x, int &y)
104{
105  x = margin;
106  y = margin;
107  RECT rect;
108  rect.left = 0;
109  rect.top = 0;
110  rect.right = margin;
111  rect.bottom = margin;
112  if (!MapRect(&rect))
113    return false;
114  x = rect.right - rect.left;
115  y = rect.bottom - rect.top;
116  return true;
117}
118
119int CDialog::Units_To_Pixels_X(int units)
120{
121  RECT rect;
122  rect.left = 0;
123  rect.top = 0;
124  rect.right = units;
125  rect.bottom = units;
126  if (!MapRect(&rect))
127    return units * 3 / 2;
128  return rect.right - rect.left;
129}
130
131bool CDialog::GetItemSizes(int id, int &x, int &y)
132{
133  RECT rect;
134  if (!::GetWindowRect(GetItem(id), &rect))
135    return false;
136  x = RECT_SIZE_X(rect);
137  y = RECT_SIZE_Y(rect);
138  return true;
139}
140
141void CDialog::GetClientRectOfItem(int id, RECT &rect)
142{
143  ::GetWindowRect(GetItem(id), &rect);
144  ScreenToClient(&rect);
145}
146
147bool CDialog::MoveItem(int id, int x, int y, int width, int height, bool repaint)
148{
149  return BOOLToBool(::MoveWindow(GetItem(id), x, y, width, height, BoolToBOOL(repaint)));
150}
151
152void CDialog::NormalizeSize(bool fullNormalize)
153{
154  RECT workRect;
155  GetWorkAreaRect(&workRect);
156  int xSize = RECT_SIZE_X(workRect);
157  int ySize = RECT_SIZE_Y(workRect);
158  RECT rect;
159  GetWindowRect(&rect);
160  int xSize2 = RECT_SIZE_X(rect);
161  int ySize2 = RECT_SIZE_Y(rect);
162  bool needMove = (xSize2 > xSize || ySize2 > ySize);
163  if (xSize2 > xSize || (needMove && fullNormalize))
164  {
165    rect.left = workRect.left;
166    rect.right = workRect.right;
167    xSize2 = xSize;
168  }
169  if (ySize2 > ySize || (needMove && fullNormalize))
170  {
171    rect.top = workRect.top;
172    rect.bottom = workRect.bottom;
173    ySize2 = ySize;
174  }
175  if (needMove)
176  {
177    if (fullNormalize)
178      Show(SW_SHOWMAXIMIZED);
179    else
180      Move(rect.left, rect.top, xSize2, ySize2, true);
181  }
182}
183
184void CDialog::NormalizePosition()
185{
186  RECT workRect, rect;
187  GetWorkAreaRect(&workRect);
188  GetWindowRect(&rect);
189  if (rect.bottom > workRect.bottom && rect.top > workRect.top)
190    Move(rect.left, workRect.top, RECT_SIZE_X(rect), RECT_SIZE_Y(rect), true);
191}
192
193bool CModelessDialog::Create(LPCTSTR templateName, HWND parentWindow)
194{
195  HWND aHWND = CreateDialogParam(g_hInstance, templateName, parentWindow, DialogProcedure, (LPARAM)this);
196  if (aHWND == 0)
197    return false;
198  Attach(aHWND);
199  return true;
200}
201
202INT_PTR CModalDialog::Create(LPCTSTR templateName, HWND parentWindow)
203{
204  return DialogBoxParam(g_hInstance, templateName, parentWindow, DialogProcedure, (LPARAM)this);
205}
206
207#ifndef _UNICODE
208
209bool CModelessDialog::Create(LPCWSTR templateName, HWND parentWindow)
210{
211  HWND aHWND;
212  if (g_IsNT)
213    aHWND = CreateDialogParamW(g_hInstance, templateName, parentWindow, DialogProcedure, (LPARAM)this);
214  else
215  {
216    AString name;
217    LPCSTR templateNameA;
218    if (IS_INTRESOURCE(templateName))
219      templateNameA = (LPCSTR)templateName;
220    else
221    {
222      name = GetSystemString(templateName);
223      templateNameA = name;
224    }
225    aHWND = CreateDialogParamA(g_hInstance, templateNameA, parentWindow, DialogProcedure, (LPARAM)this);
226  }
227  if (aHWND == 0)
228    return false;
229  Attach(aHWND);
230  return true;
231}
232
233INT_PTR CModalDialog::Create(LPCWSTR templateName, HWND parentWindow)
234{
235  if (g_IsNT)
236    return DialogBoxParamW(g_hInstance, templateName, parentWindow, DialogProcedure, (LPARAM)this);
237  AString name;
238  LPCSTR templateNameA;
239  if (IS_INTRESOURCE(templateName))
240    templateNameA = (LPCSTR)templateName;
241  else
242  {
243    name = GetSystemString(templateName);
244    templateNameA = name;
245  }
246  return DialogBoxParamA(g_hInstance, templateNameA, parentWindow, DialogProcedure, (LPARAM)this);
247}
248#endif
249
250}}
251