1
0

loginPopup.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733
  1. #include "./loginPopup.h"
  2. #include "../api.h"
  3. #include "../../nu/Vectors.h"
  4. #include "./loginNotifier.h"
  5. #include "./common.h"
  6. typedef Vector<HWND> WindowList;
  7. typedef struct __THREADPOPUPDATA
  8. {
  9. HHOOK hHook;
  10. WindowList windowList;
  11. } THREADPOPUPDATA;
  12. static size_t threadStorage = TLS_OUT_OF_INDEXES;
  13. typedef struct __LOGINPOPUPCREATEPARAM
  14. {
  15. LoginPopup::Creator fnCreator;
  16. LPARAM lParam;
  17. } LOGINPOPUPCREATEPARAM;
  18. #define IDC_NOTIFIER 10001
  19. //#define COLOR_TITLE COLOR_3DLIGHT
  20. //#define COLOR_TITLETEXT COLOR_WINDOWTEXT
  21. #define COLOR_CLIENT COLOR_3DFACE
  22. #define COLOR_CLIENTTEXT COLOR_WINDOWTEXT
  23. LoginPopup::LoginPopup(HWND hwnd, UINT popupType, LPCWSTR pszTitle)
  24. : alertType(-1), alertMessage(NULL)
  25. {
  26. buttonHeight = buttonSpace = 0;
  27. this->hwnd = hwnd;
  28. if (NULL != pszTitle)
  29. SetTitle(popupType, pszTitle);
  30. }
  31. LoginPopup::~LoginPopup()
  32. {
  33. RegisterPopup(hwnd, FALSE);
  34. if (FALSE == IS_INTRESOURCE(alertMessage))
  35. LoginBox_FreeString(alertMessage);
  36. }
  37. HWND LoginPopup::CreatePopup(LPCWSTR pszTemplate, HWND hParent, LPARAM param, Creator fnCreator)
  38. {
  39. if (NULL == hParent || NULL == pszTemplate || NULL == fnCreator)
  40. return NULL;
  41. LOGINPOPUPCREATEPARAM createParam;
  42. createParam.fnCreator = fnCreator;
  43. createParam.lParam = param;
  44. return WASABI_API_CREATEDIALOGPARAMW((INT)(INT_PTR)pszTemplate, hParent, LoginPopup_DialogProc, (LPARAM)&createParam);
  45. }
  46. BOOL LoginPopup::RegisterPopup(HWND hwnd, BOOL fRegister)
  47. {
  48. if (NULL == hwnd || GetWindowThreadProcessId(hwnd, NULL) != GetCurrentThreadId())
  49. return FALSE;
  50. THREADPOPUPDATA *data = NULL;
  51. if (TLS_OUT_OF_INDEXES == threadStorage)
  52. {
  53. if (NULL == WASABI_API_APP)
  54. return FALSE;
  55. threadStorage = WASABI_API_APP->AllocateThreadStorage();
  56. if (TLS_OUT_OF_INDEXES == threadStorage)
  57. return FALSE;
  58. }
  59. else
  60. {
  61. data = (THREADPOPUPDATA*)WASABI_API_APP->GetThreadStorage(threadStorage);
  62. }
  63. if (NULL == data)
  64. {
  65. data = new THREADPOPUPDATA();
  66. if (NULL == data) return FALSE;
  67. data->hHook = SetWindowsHookEx(WH_MSGFILTER, LoginPopup_MessageFilter, NULL, GetCurrentThreadId());
  68. if (NULL == data->hHook)
  69. {
  70. delete data;
  71. return FALSE;
  72. }
  73. WASABI_API_APP->SetThreadStorage(threadStorage, data);
  74. }
  75. size_t index = data->windowList.size();
  76. while(index--)
  77. {
  78. if (hwnd == data->windowList[index])
  79. {
  80. if (FALSE == fRegister)
  81. {
  82. data->windowList.eraseAt(index);
  83. if (0 == data->windowList.size())
  84. {
  85. if (NULL != data->hHook)
  86. UnhookWindowsHookEx(data->hHook);
  87. WASABI_API_APP->SetThreadStorage(threadStorage, NULL);
  88. delete data;
  89. }
  90. }
  91. return TRUE;
  92. }
  93. }
  94. if (FALSE != fRegister)
  95. {
  96. data->windowList.push_back(hwnd);
  97. return TRUE;
  98. }
  99. return FALSE;
  100. }
  101. BOOL LoginPopup::EnumeratePopups(HWND hHost, Enumerator callback, LPARAM param)
  102. {
  103. if (NULL == callback ||
  104. NULL == hHost || GetWindowThreadProcessId(hHost, NULL) != GetCurrentThreadId())
  105. return FALSE;
  106. THREADPOPUPDATA *data = (TLS_OUT_OF_INDEXES != threadStorage && NULL != WASABI_API_APP) ?
  107. (THREADPOPUPDATA *)WASABI_API_APP->GetThreadStorage(threadStorage) : NULL;
  108. if (NULL == data)
  109. return FALSE;
  110. size_t index = data->windowList.size();
  111. while(index--)
  112. {
  113. HWND hPopup = data->windowList[index];
  114. if (IsChild(hHost, hPopup) && FALSE == callback(hPopup, param))
  115. return FALSE;
  116. }
  117. return TRUE;
  118. }
  119. BOOL LoginPopup::AnyPopup(HWND hHost)
  120. {
  121. if (NULL == hHost || GetWindowThreadProcessId(hHost, NULL) != GetCurrentThreadId())
  122. return FALSE;
  123. THREADPOPUPDATA *data = (TLS_OUT_OF_INDEXES != threadStorage && NULL != WASABI_API_APP) ?
  124. (THREADPOPUPDATA *)WASABI_API_APP->GetThreadStorage(threadStorage) : NULL;
  125. if (NULL == data)
  126. return FALSE;
  127. size_t index = data->windowList.size();
  128. while(index--)
  129. {
  130. if (IsChild(hHost, data->windowList[index]))
  131. return TRUE;
  132. }
  133. return FALSE;
  134. }
  135. void LoginPopup::UpdateLayout(BOOL fRedraw)
  136. {
  137. RECT rect;
  138. GetClientRect(hwnd, &rect);
  139. HWND hNotifier;
  140. hNotifier = GetDlgItem(hwnd, IDC_NOTIFIER);
  141. if (NULL != hNotifier)
  142. {
  143. INT height = LoginNotifier_GetIdealHeight(hNotifier);
  144. SetWindowPos(hNotifier, NULL, rect.left, rect.top, rect.right - rect.left, height,
  145. SWP_NOACTIVATE | SWP_NOZORDER);
  146. }
  147. }
  148. void LoginPopup::Paint(HDC hdc, const RECT *prcPaint, BOOL fErase)
  149. {
  150. if (FALSE != fErase)
  151. {
  152. RECT clientRect;
  153. GetClientRect(hwnd, &clientRect);
  154. COLORREF rgbOrig, rgbPart;
  155. rgbOrig = GetBkColor(hdc);
  156. if (buttonHeight > 0)
  157. {
  158. RECT buttonRect;
  159. SetRect(&buttonRect,
  160. clientRect.left, clientRect.bottom - (2* clientMargins.bottom + buttonHeight),
  161. clientRect.right, clientRect.bottom);
  162. clientRect.bottom = buttonRect.top;
  163. buttonRect.top++;
  164. rgbPart = GetSysColor(COLOR_3DFACE);
  165. SetBkColor(hdc, rgbPart);
  166. ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &buttonRect, NULL, 0, NULL);
  167. buttonRect.bottom = buttonRect.top;
  168. buttonRect.top--;
  169. rgbPart = GetSysColor(COLOR_3DLIGHT);
  170. SetBkColor(hdc, rgbPart);
  171. ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &buttonRect, NULL, 0, NULL);
  172. }
  173. rgbPart = GetSysColor(COLOR_CLIENT);
  174. SetBkColor(hdc, rgbPart);
  175. ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &clientRect, NULL, 0, NULL);
  176. SetBkColor(hdc, rgbOrig);
  177. }
  178. }
  179. void LoginPopup::EndDialog(INT_PTR code)
  180. {
  181. DestroyWindow(hwnd);
  182. }
  183. void LoginPopup::UpdateMargins()
  184. {
  185. SetRect(&clientMargins, 8, 6, 8, 6);
  186. MapDialogRect(hwnd, &clientMargins);
  187. SetRect(&infoMargins, 6, 8, 6, 8);
  188. MapDialogRect(hwnd, &infoMargins);
  189. RECT rect;
  190. SetRect(&rect, 4, 15, 0, 0);
  191. MapDialogRect(hwnd, &rect);
  192. buttonHeight = rect.top;
  193. buttonSpace = rect.left;
  194. }
  195. void LoginPopup::SetTitle(UINT type, LPCWSTR title)
  196. {
  197. popupType = type;
  198. if (NULL == title || FALSE == IS_INTRESOURCE(title))
  199. SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)title);
  200. else
  201. {
  202. WCHAR szBuffer[256] = {0};
  203. WASABI_API_LNGSTRINGW_BUF((INT)(INT_PTR)title, szBuffer, ARRAYSIZE(szBuffer));
  204. SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)szBuffer);
  205. }
  206. }
  207. void LoginPopup::UpdateTitle(BOOL playBeep)
  208. {
  209. HWND hNotifier;
  210. hNotifier = GetDlgItem(hwnd, IDC_NOTIFIER);
  211. if (NULL == hNotifier) return;
  212. WCHAR szBuffer[512] = {0};
  213. LPCWSTR text;
  214. UINT type;
  215. if (-1 != alertType && NULL != alertMessage)
  216. {
  217. type = alertType;
  218. text = (IS_INTRESOURCE(alertMessage)) ?
  219. WASABI_API_LNGSTRINGW_BUF((INT)(INT_PTR)alertMessage, szBuffer, ARRAYSIZE(szBuffer)) :
  220. alertMessage;
  221. }
  222. else
  223. {
  224. type = popupType;
  225. SendMessage(hwnd, WM_GETTEXT, (WPARAM)ARRAYSIZE(szBuffer), (LPARAM)szBuffer);
  226. text = szBuffer;
  227. }
  228. LoginNotifier_Notify(hNotifier, type, text);
  229. UINT windowStyle = GetWindowStyle(hNotifier);
  230. if (0 == (WS_VISIBLE & windowStyle))
  231. {
  232. ShowWindow(hNotifier, SW_SHOWNA);
  233. }
  234. if (FALSE != playBeep)
  235. LoginNotifier_PlayBeep(hNotifier);
  236. }
  237. void LoginPopup::SetAlert(UINT type, LPCWSTR message)
  238. {
  239. alertType = type;
  240. if (FALSE == IS_INTRESOURCE(alertMessage))
  241. LoginBox_FreeString(alertMessage);
  242. if (NULL == message)
  243. {
  244. alertMessage = NULL;
  245. return;
  246. }
  247. if (IS_INTRESOURCE(message))
  248. alertMessage = (LPWSTR)message;
  249. else
  250. alertMessage = LoginBox_CopyString(message);
  251. }
  252. void LoginPopup::RemoveAlert()
  253. {
  254. SetAlert(-1, NULL);
  255. }
  256. LRESULT LoginPopup::SendNotification(UINT code, NMHDR *pnmh)
  257. {
  258. if (NULL == pnmh) return 0L;
  259. HWND hParent = GetAncestor(hwnd, GA_PARENT);
  260. if(NULL == hParent) return 0L;
  261. pnmh->code = code;
  262. pnmh->hwndFrom = hwnd;
  263. pnmh->idFrom = (UINT_PTR)GetWindowLongPtr(hwnd, GWLP_ID);
  264. return SendMessage(hParent, WM_NOTIFY, (WPARAM)pnmh->idFrom, (LPARAM)pnmh);
  265. }
  266. BOOL LoginPopup::GetInfoRect(RECT *rect)
  267. {
  268. if (NULL == rect)
  269. return FALSE;
  270. LONG notifierHeight = 0;
  271. HWND hNotifier = GetDlgItem(hwnd, IDC_NOTIFIER);
  272. if (NULL != hNotifier && 0 != (WS_VISIBLE & GetWindowStyle(hNotifier)) &&
  273. FALSE != GetWindowRect(hNotifier, rect))
  274. {
  275. notifierHeight = rect->bottom - rect->top;
  276. if (notifierHeight < 0) notifierHeight = 0;
  277. }
  278. if (FALSE == GetClientRect(hwnd, rect))
  279. return FALSE;
  280. rect->left += (clientMargins.left + infoMargins.left);
  281. rect->right -= (clientMargins.right + infoMargins.right);
  282. if (0 != notifierHeight)
  283. rect->top += (notifierHeight + infoMargins.top);
  284. else
  285. rect->top += (clientMargins.top + infoMargins.top);
  286. if (buttonHeight > 0)
  287. rect->bottom -= (2 * clientMargins.bottom + buttonHeight + infoMargins.bottom);
  288. else
  289. rect->bottom -= (clientMargins.bottom + infoMargins.bottom);
  290. if (rect->right < rect->left) rect->right = rect->left;
  291. if (rect->bottom < rect->top) rect->bottom = rect->top;
  292. return TRUE;
  293. }
  294. BOOL LoginPopup::CalculateWindowRect(LONG infoWidth, LONG infoHeight, const INT *buttonList, UINT buttonCount, BOOL includeTitle, RECT *rect)
  295. {
  296. if (NULL == rect)
  297. return FALSE;
  298. if (infoWidth < 110) infoWidth = 110;
  299. if (infoHeight < 32) infoHeight = 32;
  300. LONG minWidth = 0;
  301. LONG notifierHeight = 0;
  302. HWND hNotifier = GetDlgItem(hwnd, IDC_NOTIFIER);
  303. if (NULL != hNotifier && 0 != (WS_VISIBLE & GetWindowStyle(hNotifier)) &&
  304. FALSE != GetWindowRect(hNotifier, rect))
  305. {
  306. notifierHeight = rect->bottom - rect->top;
  307. if (notifierHeight < 0) notifierHeight = 0;
  308. if (FALSE != includeTitle)
  309. {
  310. SIZE size;
  311. if (FALSE != LoginNotifier_GetIdealSize(hNotifier, &size))
  312. minWidth = size.cx + clientMargins.right;
  313. }
  314. }
  315. if (NULL != buttonList && buttonCount > 0 &&
  316. ((HDWP)TRUE) == LayoutButtons(NULL, buttonList, buttonCount, FALSE, rect))
  317. {
  318. LONG buttonWidth = (rect->right - rect->left) + clientMargins.left + clientMargins.right;
  319. if (buttonWidth > minWidth)
  320. minWidth = buttonWidth;
  321. }
  322. rect->left = 0;
  323. rect->top = 0;
  324. rect->right = rect->left + infoWidth;
  325. rect->bottom = rect->top + infoHeight;
  326. rect->right += (clientMargins.left + infoMargins.left + clientMargins.right + infoMargins.right);
  327. if ((rect->right - rect->left) < minWidth)
  328. rect->right = rect->left + minWidth;
  329. rect->bottom += (0 != notifierHeight) ?
  330. (notifierHeight + infoMargins.top) : (clientMargins.top + infoMargins.top);
  331. rect->bottom += (buttonHeight > 0) ?
  332. (2 * clientMargins.bottom + buttonHeight + infoMargins.bottom) : (clientMargins.bottom + infoMargins.bottom);
  333. return TRUE;
  334. }
  335. HDWP LoginPopup::LayoutButtons(HDWP hdwp, const INT *buttonList, UINT buttonCount, BOOL redraw, RECT *rectOut)
  336. {
  337. RECT rect;
  338. GetClientRect(hwnd, &rect);
  339. rect.left += clientMargins.left;
  340. rect.top += clientMargins.top;
  341. rect.right -= clientMargins.right;
  342. rect.bottom -= clientMargins.bottom;
  343. return LoginBox_LayoutButtonBar(hdwp, hwnd, buttonList, buttonCount, &rect,
  344. buttonHeight, buttonSpace, redraw, rectOut);
  345. }
  346. BOOL LoginPopup::GetTextSize(HWND hText, LONG width, SIZE *size)
  347. {
  348. if (NULL == hText) return FALSE;
  349. WCHAR szBuffer[4096] = {0};
  350. INT cchLen = (INT)SendMessage(hText, WM_GETTEXT, ARRAYSIZE(szBuffer), (LPARAM)szBuffer);
  351. if (0 == cchLen)
  352. {
  353. size->cx = 0;
  354. size->cy = 0;
  355. return TRUE;
  356. }
  357. HDC hdc = GetDCEx(hText, NULL, DCX_CACHE | DCX_WINDOW | DCX_NORESETATTRS);
  358. if (NULL == hdc)
  359. return FALSE;
  360. HFONT font = (HFONT)SendMessage(hText, WM_GETFONT, 0, 0L);
  361. HFONT fontOrig = (HFONT)SelectObject(hdc, font);
  362. BOOL resultOk;
  363. RECT rect;
  364. SetRect(&rect, 0, 0, width, 0);
  365. resultOk = DrawText(hdc, szBuffer, cchLen, &rect,
  366. DT_CALCRECT | DT_EXTERNALLEADING | DT_LEFT | DT_NOPREFIX | DT_WORDBREAK);
  367. if(FALSE != resultOk)
  368. {
  369. size->cx = (rect.right - rect.left);
  370. size->cy = (rect.bottom - rect.top);
  371. }
  372. SelectObject(hdc, fontOrig);
  373. ReleaseDC(hText, hdc);
  374. return resultOk;
  375. }
  376. BOOL LoginPopup::OnInitDialog(HWND hFocus, LPARAM param)
  377. {
  378. RegisterPopup(hwnd, TRUE);
  379. RECT rect;
  380. if (FALSE == GetWindowRect(hwnd, &rect))
  381. SetRectEmpty(&rect);
  382. idealSize.cx = rect.right - rect.left;
  383. idealSize.cy = rect.bottom - rect.top;
  384. HWND hNotifier = LoginNotifier_CreateWindow(0, WS_CHILD | WS_CLIPSIBLINGS, 0, 0, 0, 0, hwnd, IDC_NOTIFIER);
  385. if (NULL != hNotifier)
  386. {
  387. HFONT hFont = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0L);
  388. if (NULL != hFont)
  389. SendMessage(hNotifier, WM_SETFONT, (WPARAM)hFont, 0L);
  390. #ifdef COLOR_TITLE
  391. LoginNotifier_SetBkColor(hNotifier, GetSysColor(COLOR_TITLE));
  392. #endif //COLOR_TITLE
  393. #ifdef COLOR_TITLETEXT
  394. LoginNotifier_SetTextColor(hNotifier, GetSysColor(COLOR_TITLETEXT));
  395. #endif //COLOR_TITLETEXT
  396. UpdateTitle(FALSE);
  397. }
  398. UpdateMargins();
  399. UpdateLayout(FALSE);
  400. PostMessage(hwnd, WM_CHANGEUISTATE, MAKEWPARAM(UIS_INITIALIZE, UISF_HIDEACCEL | UISF_HIDEFOCUS), 0L);
  401. return FALSE;
  402. }
  403. void LoginPopup::OnDestroy()
  404. {
  405. }
  406. void LoginPopup::OnWindowPosChanged(const WINDOWPOS *pwp)
  407. {
  408. if (SWP_NOSIZE != ((SWP_NOSIZE | SWP_FRAMECHANGED) & pwp->flags))
  409. UpdateLayout(0 == (SWP_NOREDRAW & pwp->flags));
  410. }
  411. void LoginPopup::OnCommand(UINT commandId, UINT eventType, HWND hControl)
  412. {
  413. switch(commandId)
  414. {
  415. case IDOK:
  416. case IDCANCEL:
  417. EndDialog(commandId);
  418. break;
  419. }
  420. }
  421. LRESULT LoginPopup::OnNotify(UINT controlId, const NMHDR *pnmh)
  422. {
  423. return FALSE;
  424. }
  425. void LoginPopup::OnPaint()
  426. {
  427. PAINTSTRUCT ps;
  428. if (BeginPaint(hwnd, &ps))
  429. {
  430. if (ps.rcPaint.left != ps.rcPaint.right)
  431. Paint(ps.hdc, &ps.rcPaint, ps.fErase);
  432. EndPaint(hwnd, &ps);
  433. }
  434. }
  435. void LoginPopup::OnPrintClient(HDC hdc, UINT options)
  436. {
  437. if (0 != (PRF_CLIENT & options))
  438. {
  439. RECT clientRect;
  440. if (GetClientRect(hwnd, &clientRect))
  441. Paint(hdc, &clientRect, TRUE);
  442. }
  443. }
  444. HBRUSH LoginPopup::OnGetStaticColor(HDC hdc, HWND hControl)
  445. {
  446. HBRUSH hb = (HBRUSH)GetSysColorBrush(COLOR_CLIENT);
  447. SetTextColor(hdc, GetSysColor(COLOR_CLIENTTEXT));
  448. SetBkColor(hdc, GetSysColor(COLOR_CLIENT));
  449. return hb;
  450. }
  451. void LoginPopup::OnSetFont(HFONT font, BOOL redraw)
  452. {
  453. DefDlgProc(hwnd, WM_SETFONT, (WPARAM)font, MAKELPARAM(redraw, 0));
  454. UpdateMargins();
  455. }
  456. void LoginPopup::OnParentNotify(UINT eventId, UINT wParam, LPARAM lParam)
  457. {
  458. }
  459. BOOL LoginPopup::OnUpdateWindowPos(const RECT* clientRect, RECT *rectOut)
  460. {
  461. if (NULL == clientRect || NULL == rectOut)
  462. return FALSE;
  463. LONG width = idealSize.cx;
  464. LONG height = idealSize.cy;
  465. rectOut->left = clientRect->left + ((clientRect->right - clientRect->left) - width)/2;
  466. rectOut->top = clientRect->top+ ((clientRect->bottom - clientRect->top) - height)/2;
  467. rectOut->right = rectOut->left + width;
  468. rectOut->bottom = rectOut->top + height;
  469. return TRUE;
  470. }
  471. void LoginPopup::OnPlayBeep()
  472. {
  473. LoginBox_MessageBeep(MB_ICONASTERISK);
  474. }
  475. INT_PTR LoginPopup::DialogProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
  476. {
  477. switch (uMsg)
  478. {
  479. case WM_INITDIALOG: return OnInitDialog((HWND)wParam, lParam);
  480. case WM_DESTROY: OnDestroy(); return TRUE;
  481. case WM_NOTIFY: MSGRESULT(hwnd, OnNotify((INT)wParam, (NMHDR*)lParam));
  482. case WM_COMMAND: OnCommand(LOWORD(wParam), HIWORD(wParam), (HWND)lParam); return TRUE;
  483. case WM_WINDOWPOSCHANGED: OnWindowPosChanged((WINDOWPOS*)lParam); return TRUE;
  484. case WM_SIZE: return TRUE;
  485. case WM_SETFONT: OnSetFont((HFONT)wParam, (BOOL)LOWORD(lParam)); return TRUE;
  486. case WM_ERASEBKGND: MSGRESULT(hwnd, 0);
  487. case WM_PAINT: OnPaint(); return TRUE;
  488. case WM_PRINTCLIENT: OnPrintClient((HDC)wParam, (UINT)lParam); return TRUE;
  489. case WM_CTLCOLORSTATIC: return (INT_PTR)OnGetStaticColor((HDC)wParam, (HWND)lParam);
  490. case WM_PARENTNOTIFY: OnParentNotify(LOWORD(wParam), HIWORD(wParam), lParam); return TRUE;
  491. case NLPOPUP_UPDATEWNDPOS: MSGRESULT(hwnd, OnUpdateWindowPos((const RECT*)wParam, (RECT*)lParam));
  492. case NLPOPUP_PLAYBEEP: OnPlayBeep(); return TRUE;
  493. }
  494. return FALSE;
  495. }
  496. static INT_PTR CALLBACK LoginPopup_DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  497. {
  498. static ATOM LOGINPOPUP_PROP = 0;
  499. LoginPopup *popup = (LoginPopup*)GetProp(hwnd, MAKEINTATOM(LOGINPOPUP_PROP));
  500. if (NULL == popup)
  501. {
  502. switch(uMsg)
  503. {
  504. case WM_INITDIALOG:
  505. if (0 == LOGINPOPUP_PROP)
  506. {
  507. LOGINPOPUP_PROP = GlobalAddAtomW(L"NullsoftLoginPopupProp");
  508. if (0 == LOGINPOPUP_PROP)
  509. return 0;
  510. }
  511. if (NULL != lParam)
  512. {
  513. LOGINPOPUPCREATEPARAM *create = (LOGINPOPUPCREATEPARAM*)lParam;
  514. lParam = create->lParam;
  515. if (SUCCEEDED(create->fnCreator(hwnd, lParam, &popup)))
  516. {
  517. if (FALSE == SetProp(hwnd, MAKEINTATOM(LOGINPOPUP_PROP), (HANDLE)popup))
  518. {
  519. delete(popup);
  520. popup = NULL;
  521. }
  522. }
  523. }
  524. if (NULL != popup)
  525. return popup->DialogProc(uMsg, wParam, lParam);
  526. break;
  527. }
  528. return 0;
  529. }
  530. INT_PTR result = popup->DialogProc(uMsg, wParam, lParam);
  531. if (WM_NCDESTROY == uMsg)
  532. {
  533. RemoveProp(hwnd, MAKEINTATOM(LOGINPOPUP_PROP));
  534. delete(popup);
  535. }
  536. return result;
  537. }
  538. static LRESULT CALLBACK LoginPopup_MessageFilter(INT code, WPARAM wParam, LPARAM lParam)
  539. {
  540. THREADPOPUPDATA *data = (NULL != WASABI_API_APP && TLS_OUT_OF_INDEXES != threadStorage) ?
  541. (THREADPOPUPDATA*)WASABI_API_APP->GetThreadStorage(threadStorage) : NULL;
  542. if (NULL == data)
  543. return 0;
  544. if (code >= 0)
  545. {
  546. MSG *pMsg = (MSG*)lParam;
  547. if (pMsg->message >= WM_KEYFIRST && pMsg->message <= WM_KEYLAST)
  548. {
  549. if (L'C' == pMsg->wParam && 0 == (0x40000000 & pMsg->lParam) &&
  550. 0 != (0x8000 & GetAsyncKeyState(VK_MENU)))
  551. {
  552. pMsg->wParam = VK_ESCAPE;
  553. }
  554. if ((VK_ESCAPE == pMsg->wParam || VK_RETURN == pMsg->wParam) &&
  555. 0 == (0x40000000 & pMsg->lParam))
  556. {
  557. size_t index = data->windowList.size();
  558. while(index--)
  559. {
  560. HWND hPopup = data->windowList[index];
  561. if (IsChild(hPopup, pMsg->hwnd))
  562. {
  563. INT commandId;
  564. switch(pMsg->wParam)
  565. {
  566. case VK_ESCAPE:
  567. commandId = IDCANCEL;
  568. break;
  569. case VK_RETURN:
  570. if (0 != (DLGC_BUTTON & SendMessage(pMsg->hwnd, WM_GETDLGCODE, 0, 0L)) &&
  571. IsWindowVisible(pMsg->hwnd) && IsWindowEnabled(pMsg->hwnd))
  572. {
  573. commandId = (INT)(INT_PTR)GetWindowLongPtr(pMsg->hwnd, GWLP_ID);
  574. }
  575. else
  576. {
  577. commandId = (INT)(INT_PTR)SendMessage(hPopup, DM_GETDEFID, 0, 0L);
  578. if (DC_HASDEFID != HIWORD(commandId))
  579. commandId = IDOK;
  580. }
  581. break;
  582. }
  583. SendMessage(hPopup, WM_COMMAND, MAKEWPARAM(commandId, 0), (LPARAM)pMsg->hwnd);
  584. return 1;
  585. }
  586. }
  587. }
  588. // add mnemonic support here (http://msdn.microsoft.com/en-us/library/ms644995%28VS.85%29.aspx)
  589. //HWND hPopup;
  590. //size_t index = data->windowList.size();
  591. //while(index--)
  592. //{
  593. // hPopup = data->windowList[index];
  594. // if (pMsg->hwnd == hPopup || IsChild(hPopup, pMsg->hwnd))
  595. // {
  596. //
  597. // }
  598. //}
  599. }
  600. }
  601. return CallNextHookEx(data->hHook, code, wParam, lParam);
  602. }