Home | History | Annotate | Download | only in Control
      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 
     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 
     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 
     57 bool CDialog::OnCommand(WPARAM wParam, LPARAM lParam)
     58 {
     59   return OnCommand(HIWORD(wParam), LOWORD(wParam), lParam);
     60 }
     61 
     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 
     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 IDHELP: OnHelp(); break;
     76     default: return false;
     77   }
     78   return true;
     79 }
     80 
     81 static bool GetWorkAreaRect(RECT *rect)
     82 {
     83   // use another function for multi-monitor.
     84   return BOOLToBool(::SystemParametersInfo(SPI_GETWORKAREA, 0, rect, 0));
     85 }
     86 
     87 bool 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 
    103 bool 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 
    119 int 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 
    131 bool 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 
    141 void CDialog::GetClientRectOfItem(int id, RECT &rect)
    142 {
    143   ::GetWindowRect(GetItem(id), &rect);
    144   ScreenToClient(&rect);
    145 }
    146 
    147 bool 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 
    152 void 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 
    184 void 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 
    193 bool 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 
    202 INT_PTR CModalDialog::Create(LPCTSTR templateName, HWND parentWindow)
    203 {
    204   return DialogBoxParam(g_hInstance, templateName, parentWindow, DialogProcedure, (LPARAM)this);
    205 }
    206 
    207 #ifndef _UNICODE
    208 
    209 bool 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 
    233 INT_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