1
0

popupMessage.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. #include "./popupMessage.h"
  2. #include "./loginNotifier.h"
  3. #include "./common.h"
  4. #include "../resource.h"
  5. #include "../api.h"
  6. #include <windows.h>
  7. #include <strsafe.h>
  8. typedef struct __MESSAGECREATEPARAM
  9. {
  10. UINT type;
  11. LPCWSTR title;
  12. LPCWSTR message;
  13. LoginPopupMessage::ResultCallback callback;
  14. LPARAM param;
  15. } MESSAGECREATEPARAM;
  16. typedef struct __MESSAGEBUTTON
  17. {
  18. INT id;
  19. LPCWSTR pTitle;
  20. BOOL fGroup;
  21. BOOL fDisabled;
  22. BOOL fDefault;
  23. } MESSAGEBUTTON;
  24. const static MESSAGEBUTTON szTypeContinue[] =
  25. {
  26. { IDOK, MAKEINTRESOURCE(IDS_BUTTON_CONTINUE), TRUE, FALSE, TRUE, },
  27. };
  28. const static MESSAGEBUTTON szTypeYesNo[] =
  29. {
  30. { IDYES, MAKEINTRESOURCE(IDS_BUTTON_YES), TRUE, FALSE, TRUE, },
  31. { IDNO, MAKEINTRESOURCE(IDS_BUTTON_NO), FALSE, FALSE, FALSE, },
  32. };
  33. static HRESULT CALLBACK LoginPopupMessage_CreateInstance(HWND hwnd, LPARAM param, LoginPopup **instance)
  34. {
  35. if (NULL == instance) return E_POINTER;
  36. if (NULL == hwnd) return E_INVALIDARG;
  37. *instance = new LoginPopupMessage(hwnd);
  38. if (NULL == instance) return E_OUTOFMEMORY;
  39. return S_OK;
  40. }
  41. LoginPopupMessage::LoginPopupMessage(HWND hwnd)
  42. : LoginPopup(hwnd, NLNTYPE_INFORMATION, NULL), callback(NULL), param(0L),
  43. buttonsCount(0)
  44. {
  45. memset(szButtons, 0, sizeof(szButtons));
  46. }
  47. LoginPopupMessage::~LoginPopupMessage()
  48. {
  49. }
  50. HWND LoginPopupMessage::CreatePopup(HWND hParent, LPCWSTR pszTitle, LPCWSTR pszMessage, UINT uType, ResultCallback callback, LPARAM param)
  51. {
  52. switch(typeMask & uType)
  53. {
  54. case typeContinue:
  55. case typeYesNo:
  56. break;
  57. default:
  58. return NULL;
  59. }
  60. MESSAGECREATEPARAM createParam;
  61. createParam.type = uType;
  62. createParam.title = pszTitle;
  63. createParam.message = pszMessage;
  64. createParam.callback = callback;
  65. createParam.param = param;
  66. return LoginPopup::CreatePopup(MAKEINTRESOURCE(IDD_POPUP_MESSAGE), hParent,
  67. (LPARAM)&createParam, LoginPopupMessage_CreateInstance);
  68. }
  69. void LoginPopupMessage::UpdateLayout(BOOL fRedraw)
  70. {
  71. LoginPopup::UpdateLayout(fRedraw);
  72. RECT rect;
  73. if (FALSE == GetInfoRect(&rect)) return;
  74. HDWP hdwp = BeginDeferWindowPos(1 + buttonsCount);
  75. if (NULL == hdwp) return;
  76. UINT flags = SWP_NOZORDER | SWP_NOACTIVATE;
  77. if (FALSE == fRedraw) flags |= SWP_NOREDRAW;
  78. HWND hMessage = GetDlgItem(hwnd, IDC_MESSAGE);
  79. if (NULL != hMessage)
  80. {
  81. hdwp = DeferWindowPos(hdwp, hMessage, NULL,
  82. rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, flags);
  83. if (NULL == hdwp) return;
  84. }
  85. if (NULL != buttonsCount)
  86. hdwp = LayoutButtons(hdwp, szButtons, buttonsCount, fRedraw, NULL);
  87. EndDeferWindowPos(hdwp);
  88. }
  89. void LoginPopupMessage::EndDialog(INT_PTR code)
  90. {
  91. ResultCallback callbackCopy = callback;
  92. LPARAM paramCopy = param;
  93. NLPNRESULT result;
  94. result.exitCode = code;
  95. SendNotification(NLPN_RESULT, (NMHDR*)&result);
  96. if (NULL != callbackCopy)
  97. callbackCopy(hwnd, code, paramCopy);
  98. LoginPopup::EndDialog(code);
  99. }
  100. static BOOL LoginPopupMessage_CreateButtons(HWND hwnd, const MESSAGEBUTTON *buttonList, UINT *buttonsCount, INT *buttonIdList)
  101. {
  102. if (NULL == hwnd || NULL == buttonList || NULL == buttonsCount || 0 == *buttonsCount)
  103. return FALSE;
  104. UINT count = *buttonsCount;
  105. *buttonsCount = 0;
  106. WCHAR szBuffer[256] = {0};
  107. RECT rect;
  108. SetRect(&rect, 50, 15, 0, 0);
  109. MapDialogRect(hwnd, &rect);
  110. LONG width = rect.left;
  111. LONG height = rect.top;
  112. HFONT font = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0L);
  113. for (UINT i = 0; i < count; i++)
  114. {
  115. LPCWSTR title = buttonList[i].pTitle;
  116. if (NULL != title && FALSE != IS_INTRESOURCE(title))
  117. {
  118. WASABI_API_LNGSTRINGW_BUF((INT)(INT_PTR)title, szBuffer, ARRAYSIZE(szBuffer));
  119. title = szBuffer;
  120. }
  121. UINT style = BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP;
  122. if (FALSE != buttonList[i].fGroup) style |= WS_GROUP;
  123. if (FALSE != buttonList[i].fDisabled) style |= WS_DISABLED;
  124. if (FALSE != buttonList[i].fDefault) style |= BS_DEFPUSHBUTTON;
  125. HWND hButton = CreateWindowEx(WS_EX_NOPARENTNOTIFY, L"Button", title, style,
  126. 0, 0, width, height, hwnd, (HMENU)(INT_PTR)buttonList[i].id, NULL, 0L);
  127. if (NULL != hButton)
  128. {
  129. if (NULL != font)
  130. SendMessage(hButton, WM_SETFONT, (WPARAM)font, 0L);
  131. if (NULL != buttonIdList)
  132. buttonIdList[*buttonsCount] = buttonList[i].id;
  133. (*buttonsCount)++;
  134. }
  135. }
  136. return TRUE;
  137. }
  138. BOOL LoginPopupMessage::OnInitDialog(HWND hFocus, LPARAM param)
  139. {
  140. MESSAGECREATEPARAM *createParam = (MESSAGECREATEPARAM*)param;
  141. if (NULL != createParam)
  142. {
  143. callback = createParam->callback;
  144. param = createParam->param;
  145. switch(iconMask & createParam->type)
  146. {
  147. case iconInfo: popupType = NLNTYPE_INFORMATION; break;
  148. case iconWarning: popupType = NLNTYPE_WARNING; break;
  149. case iconError: popupType = NLNTYPE_ERROR; break;
  150. }
  151. SetTitle(popupType, createParam->title);
  152. switch(typeMask & createParam->type)
  153. {
  154. case typeContinue:
  155. buttonsCount = ARRAYSIZE(szTypeContinue);
  156. LoginPopupMessage_CreateButtons(hwnd, szTypeContinue, &buttonsCount, szButtons);
  157. break;
  158. case typeYesNo:
  159. buttonsCount = ARRAYSIZE(szTypeYesNo);
  160. LoginPopupMessage_CreateButtons(hwnd, szTypeYesNo, &buttonsCount, szButtons);
  161. break;
  162. }
  163. HWND hMessage = GetDlgItem(hwnd, IDC_MESSAGE);
  164. if (NULL != hMessage)
  165. {
  166. if (NULL != createParam->message && FALSE != IS_INTRESOURCE(createParam->message))
  167. {
  168. WCHAR szBuffer[4096] = {0};
  169. WASABI_API_LNGSTRINGW_BUF((INT)(INT_PTR)createParam->message, szBuffer, ARRAYSIZE(szBuffer));
  170. SendMessage(hMessage, WM_SETTEXT, 0, (LPARAM)szBuffer);
  171. }
  172. else
  173. SendMessage(hMessage, WM_SETTEXT, 0, (LPARAM)createParam->message);
  174. }
  175. }
  176. return LoginPopup::OnInitDialog(hFocus, param);
  177. }
  178. BOOL LoginPopupMessage::OnUpdateWindowPos(const RECT* clientRect, RECT *rectOut)
  179. {
  180. if (NULL == clientRect || NULL == rectOut)
  181. return FALSE;
  182. SIZE size;
  183. LONG maxWidth = clientRect->right - clientRect->left -
  184. (clientMargins.right + clientMargins.left) -
  185. (infoMargins.right + infoMargins.left);
  186. if (FALSE == GetTextSize(GetDlgItem(hwnd, IDC_MESSAGE), maxWidth, &size))
  187. {
  188. size.cx = 0;
  189. size.cy = 0;
  190. }
  191. if (FALSE == CalculateWindowRect(size.cx, size.cy, szButtons, buttonsCount, TRUE, rectOut))
  192. return FALSE;
  193. LONG ox = clientRect->left + ((clientRect->right - clientRect->left) - (rectOut->right - rectOut->left))/2;
  194. LONG oy = clientRect->top + ((clientRect->bottom - clientRect->top) - (rectOut->bottom - rectOut->top))/2;
  195. if (ox < clientRect->left) ox = clientRect->left;
  196. if (oy < clientRect->top) oy = clientRect->top;
  197. OffsetRect(rectOut, ox, oy);
  198. return TRUE;
  199. }