loginPage.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624
  1. #define OEMRESOURCE
  2. #include "./loginPage.h"
  3. #include "./loginData.h"
  4. #include "./loginBox.h"
  5. #include "./loginProvider.h"
  6. #include "./loginGui.h"
  7. #include "./common.h"
  8. #include "../api.h"
  9. #include "../../nu/windowsTheme.h"
  10. #include <vssym32.h>
  11. #include <vsstyle.h>
  12. #include <windows.h>
  13. #define IDC_TITLE 9999
  14. #define IDC_HELPLINK 9998
  15. typedef struct __LOGINPAGECREATEPARAM
  16. {
  17. LOGINPAGECREATOR fnCreator;
  18. LPARAM lParam;
  19. HWND hLoginbox;
  20. } LOGINPAGECREATEPARAM;
  21. LoginPage::LoginPage(HWND hwnd, HWND hLoginbox)
  22. {
  23. this->hwnd = hwnd;
  24. this->hLoginbox = hLoginbox;
  25. }
  26. LoginPage::~LoginPage()
  27. {
  28. }
  29. HWND LoginPage::CreatePage(HWND hLoginbox, LPCWSTR pszTemplate, HWND hParent, LPARAM param, LOGINPAGECREATOR fnCreator)
  30. {
  31. if (NULL == hLoginbox || NULL == hParent)
  32. return NULL;
  33. if (NULL == pszTemplate || NULL == fnCreator)
  34. return NULL;
  35. LOGINPAGECREATEPARAM createParam;
  36. createParam.fnCreator = fnCreator;
  37. createParam.lParam = param;
  38. createParam.hLoginbox = hLoginbox;
  39. return WASABI_API_CREATEDIALOGPARAMW((INT)(INT_PTR)pszTemplate, hParent, LoginPage_DialogProc, (LPARAM)&createParam);
  40. }
  41. void LoginPage::UpdateColors()
  42. {
  43. rgbTitle = RGB(0, 51, 153);
  44. rgbSecondaryText = GetSysColor(COLOR_WINDOWTEXT);
  45. rgbText = GetSysColor(COLOR_WINDOWTEXT);
  46. rgbBack = GetSysColor(COLOR_WINDOW);
  47. hbrBack = GetSysColorBrush(COLOR_WINDOW);
  48. if (SUCCEEDED(UxTheme_LoadLibrary()) && FALSE != UxIsAppThemed())
  49. {
  50. UXTHEME hTheme = UxOpenThemeData(hwnd, L"TEXTSTYLE");
  51. if (NULL != hTheme)
  52. {
  53. UxGetThemeColor(hTheme, TEXT_MAININSTRUCTION, 0, TMT_TEXTCOLOR, &rgbTitle);
  54. UxGetThemeColor(hTheme, TEXT_BODYTEXT, 0, TMT_TEXTCOLOR, &rgbText);
  55. UxGetThemeColor(hTheme, TEXT_SECONDARYTEXT, 0, TMT_TEXTCOLOR, &rgbSecondaryText);
  56. UxCloseThemeData(hTheme);
  57. }
  58. }
  59. }
  60. void LoginPage::UpdateMargins()
  61. {
  62. SetRect(&margins, 14, 7, 7, 7);
  63. MapDialogRect(hwnd, &margins);
  64. RECT controlRect;
  65. HWND hControl = GetDlgItem(hwnd, IDC_HELPLINK);
  66. if (NULL != hControl && GetWindowRect(hControl, &controlRect))
  67. {
  68. INT t = (controlRect.right - controlRect.left) + 1;
  69. if (margins.right < t) margins.right = t;
  70. t = (controlRect.bottom - controlRect.top) + 1;
  71. if (margins.top < t) margins.top = t;
  72. }
  73. }
  74. static HBITMAP LoginPage_GetHelpBitmap(HWND hwnd, HBRUSH hbrBack, INT *pWidth, INT *pHeight)
  75. {
  76. LoginGuiObject *loginGui;
  77. if (FAILED(LoginGuiObject::QueryInstance(&loginGui)))
  78. return NULL;
  79. RECT rectSrc;
  80. HBITMAP hbmpSrc = loginGui->GetIcon(LoginGuiObject::iconQuestion, &rectSrc);
  81. HBITMAP hbmpDst = NULL;
  82. if (NULL != hbmpSrc)
  83. {
  84. HDC hdc = GetDCEx(hwnd, NULL, DCX_CACHE | DCX_NORESETATTRS);
  85. if( NULL != hdc)
  86. {
  87. HDC hdcDst = CreateCompatibleDC(hdc);
  88. HDC hdcSrc = CreateCompatibleDC(hdc);
  89. if (NULL != hdcDst && NULL != hdcSrc)
  90. {
  91. INT imageWidth = rectSrc.right - rectSrc.left;
  92. INT imageHeight = rectSrc.bottom - rectSrc.top;
  93. BITMAPINFOHEADER header;
  94. ZeroMemory(&header, sizeof(BITMAPINFOHEADER));
  95. header.biSize = sizeof(BITMAPINFOHEADER);
  96. header.biCompression = BI_RGB;
  97. header.biBitCount = 24;
  98. header.biPlanes = 1;
  99. header.biWidth = imageWidth;
  100. header.biHeight = -imageHeight;
  101. void *pixelData;
  102. hbmpDst = CreateDIBSection(hdc, (LPBITMAPINFO)&header, DIB_RGB_COLORS, (void**)&pixelData, NULL, 0);
  103. if (NULL != hbmpDst)
  104. {
  105. HBITMAP hbmpDstOrig = (HBITMAP)SelectObject(hdcDst, hbmpDst);
  106. HBITMAP hbmpSrcOrig = (HBITMAP)SelectObject(hdcSrc, hbmpSrc);
  107. RECT fillRect;
  108. SetRect(&fillRect, 0, 0, imageWidth, imageHeight);
  109. FillRect(hdcDst, &fillRect, hbrBack);
  110. BLENDFUNCTION bf;
  111. bf.BlendOp = AC_SRC_OVER;
  112. bf.BlendFlags = 0;
  113. bf.SourceConstantAlpha = 255;
  114. bf.AlphaFormat = AC_SRC_ALPHA;
  115. GdiAlphaBlend(hdcDst, 0, 0, imageWidth, imageHeight,
  116. hdcSrc, rectSrc.left, rectSrc.top, imageWidth, imageHeight, bf);
  117. SelectObject(hdcDst, hbmpDstOrig);
  118. SelectObject(hdcSrc, hbmpSrcOrig);
  119. if (NULL != pWidth) *pWidth = imageWidth;
  120. if (NULL != pHeight) *pHeight = imageHeight;
  121. }
  122. }
  123. if (NULL != hdcDst) DeleteDC(hdcDst);
  124. if (NULL != hdcSrc) DeleteDC(hdcSrc);
  125. ReleaseDC(hwnd, hdc);
  126. }
  127. }
  128. loginGui->Release();
  129. return hbmpDst;
  130. }
  131. void LoginPage::UpdateLayout(BOOL fRedraw)
  132. {
  133. RECT clientRect;
  134. GetClientRect(hwnd, &clientRect);
  135. UINT flags = SWP_NOACTIVATE | SWP_NOZORDER;
  136. if (FALSE == fRedraw) flags |= SWP_NOREDRAW;
  137. const INT szControls[] = { IDC_HELPLINK, IDC_TITLE};
  138. HDWP hdwp = BeginDeferWindowPos(ARRAYSIZE(szControls));
  139. RECT rect;
  140. INT cx, cy, x, y;
  141. for (INT i = 0; i < ARRAYSIZE(szControls); i++)
  142. {
  143. HWND hControl = GetDlgItem(hwnd, szControls[i]);
  144. if (NULL == hControl || FALSE == GetWindowRect(hControl, &rect)) continue;
  145. MapWindowPoints(HWND_DESKTOP, hwnd, (POINT*)&rect, 2);
  146. x = rect.left;
  147. y = rect.top;
  148. cx = rect.right - rect.left;
  149. cy = rect.bottom - rect.top;
  150. switch(szControls[i])
  151. {
  152. case IDC_HELPLINK:
  153. x = clientRect.right - cx - 1;
  154. if (x < clientRect.left + 1) x = clientRect.left + 1;
  155. y = clientRect.top + 1;
  156. break;
  157. case IDC_TITLE:
  158. x = clientRect.left + margins.left;
  159. y = clientRect.top + margins.top;
  160. cx = clientRect.right - margins.right - x;
  161. cy = 0;
  162. LoginBox_GetWindowTextSize(hControl, cx, &cx, &cy);
  163. if ((cx + x) > (clientRect.right - margins.right))
  164. cx = clientRect.right - margins.right - x;
  165. if ((cy + y) > (clientRect.bottom - margins.bottom))
  166. cy = clientRect.bottom - margins.bottom - y;
  167. break;
  168. }
  169. hdwp = DeferWindowPos(hdwp, hControl, NULL, x, y, cx, cy, flags);
  170. if (NULL == hdwp) break;
  171. }
  172. if (NULL != hdwp)
  173. EndDeferWindowPos(hdwp);
  174. }
  175. BOOL LoginPage::GetPageRect(RECT *prc)
  176. {
  177. if (NULL == prc || FALSE == GetClientRect(hwnd, prc))
  178. return FALSE;
  179. prc->left += margins.left;
  180. prc->top += margins.top;
  181. prc->right -= margins.right;
  182. prc->bottom -= margins.bottom;
  183. HWND hTitle = GetDlgItem(hwnd, IDC_TITLE);
  184. if (NULL != hTitle)
  185. {
  186. UINT titleStyle = GetWindowStyle(hTitle);
  187. if (0 != (WS_VISIBLE & titleStyle))
  188. {
  189. RECT titleRect;
  190. if (FALSE != GetWindowRect(hTitle, &titleRect))
  191. {
  192. MapWindowPoints(HWND_DESKTOP, hwnd, (POINT*)&titleRect, 2);
  193. titleRect.bottom += GetTitleSpacing();
  194. if (titleRect.bottom > prc->top)
  195. {
  196. prc->top = titleRect.bottom;
  197. if (prc->top > prc->bottom)
  198. prc->top = prc->bottom;
  199. }
  200. }
  201. }
  202. }
  203. return TRUE;
  204. }
  205. INT LoginPage::GetTitleSpacing()
  206. {
  207. HWND hTitle = GetDlgItem(hwnd, IDC_TITLE);
  208. if (NULL == hTitle) return 0;
  209. HFONT fontTitle = (HFONT)SendMessage(hTitle, WM_GETFONT, 0, 0L);
  210. HDC hdc = GetDCEx(hTitle, NULL, DCX_CACHE | DCX_NORESETATTRS);
  211. if (NULL == hdc) return 0;
  212. HFONT fontOrig = (HFONT)SelectObject(hdc, fontTitle);
  213. TEXTMETRIC tm;
  214. if (FALSE == GetTextMetrics(hdc, &tm))
  215. tm.tmHeight = 0;
  216. SelectObject(hdc, fontOrig);
  217. ReleaseDC(hTitle, hdc);
  218. return tm.tmHeight;
  219. }
  220. BOOL LoginPage::IsHelpAvailable()
  221. {
  222. LoginProvider *provider;
  223. if (NULL == hLoginbox ||
  224. FALSE == LoginBox_GetActiveProvider(hLoginbox, &provider) ||
  225. NULL == provider)
  226. {
  227. return FALSE;
  228. }
  229. WCHAR szBuffer[8192] = {0};
  230. HRESULT hr = provider->GetHelpLink(szBuffer, ARRAYSIZE(szBuffer));
  231. provider->Release();
  232. if (FAILED(hr) || L'\0' == szBuffer[0])
  233. return FALSE;
  234. return TRUE;
  235. }
  236. BOOL LoginPage::ShowHelp()
  237. {
  238. LoginProvider *provider;
  239. if (NULL == hLoginbox ||
  240. FALSE == LoginBox_GetActiveProvider(hLoginbox, &provider) ||
  241. NULL == provider)
  242. {
  243. return FALSE;
  244. }
  245. WCHAR szBuffer[8192] = {0};
  246. HRESULT hr = provider->GetHelpLink(szBuffer, ARRAYSIZE(szBuffer));
  247. provider->Release();
  248. if (FAILED(hr) || L'\0' == szBuffer[0])
  249. return FALSE;
  250. return LoginBox_OpenUrl(hwnd, szBuffer, TRUE);
  251. }
  252. BOOL LoginPage::SetLabelText(INT controlId, LPCWSTR pszText)
  253. {
  254. HWND hLabel = GetDlgItem(hwnd, controlId);
  255. if (NULL == hLabel) return FALSE;
  256. LPWSTR pszTemp = NULL;
  257. if (NULL != pszText && L'\0' != *pszText)
  258. {
  259. INT cchLabel = lstrlenW(pszText);
  260. if (cchLabel > 0 && L':' != pszText[cchLabel-1])
  261. {
  262. pszTemp = LoginBox_MallocString(cchLabel + 2);
  263. if (NULL != pszTemp)
  264. {
  265. CopyMemory(pszTemp, pszText, sizeof(WCHAR) * cchLabel);
  266. pszTemp[cchLabel] = L':';
  267. pszTemp[cchLabel + 1] = L'\0';
  268. pszText = pszTemp;
  269. }
  270. }
  271. }
  272. BOOL result = SetWindowText(hLabel, pszText);
  273. if (NULL != pszTemp)
  274. LoginBox_FreeString(pszTemp);
  275. return result;
  276. }
  277. BOOL LoginPage::OnInitDialog(HWND hFocus, LPARAM param)
  278. {
  279. HWND hControl = CreateWindowEx(WS_EX_NOPARENTNOTIFY, L"Static", NULL,
  280. WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
  281. 0, 0, 100, 24, hwnd, (HMENU)IDC_TITLE, NULL, 0L);
  282. if (NULL != hControl)
  283. {
  284. HFONT fontTitle = NULL;
  285. LoginGuiObject *loginGui;
  286. if (SUCCEEDED(LoginGuiObject::QueryInstance(&loginGui)))
  287. {
  288. fontTitle = loginGui->GetTitleFont();
  289. loginGui->Release();
  290. }
  291. if (NULL == fontTitle)
  292. fontTitle = (HFONT)SNDMSG(hwnd, WM_GETFONT, 0, 0L);
  293. if (NULL != fontTitle)
  294. SNDMSG(hControl, WM_SETFONT, (WPARAM)fontTitle, 0L);
  295. }
  296. INT imageWidth, imageHeight;
  297. HBITMAP bitmapHelp = LoginPage_GetHelpBitmap(hwnd, hbrBack, &imageWidth, &imageHeight);
  298. if (NULL != bitmapHelp)
  299. {
  300. UINT controlStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS |
  301. SS_BITMAP | SS_NOTIFY;
  302. if (FALSE != IsHelpAvailable())
  303. controlStyle |= WS_VISIBLE;
  304. hControl = CreateWindowEx(WS_EX_NOPARENTNOTIFY, L"Static", NULL, controlStyle,
  305. 0, 0, 0, 0, hwnd, (HMENU)IDC_HELPLINK, NULL, 0L);
  306. HBITMAP bitmapSelected = NULL;
  307. if (NULL != hControl)
  308. {
  309. bitmapSelected = (HBITMAP)SNDMSG(hControl, STM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)bitmapHelp);
  310. if (NULL != bitmapSelected)
  311. DeleteObject(bitmapSelected);
  312. bitmapSelected = (HBITMAP)SNDMSG(hControl, STM_GETIMAGE, (WPARAM)IMAGE_BITMAP, 0L);
  313. }
  314. if (bitmapSelected != bitmapHelp)
  315. DeleteObject(bitmapHelp);
  316. }
  317. UpdateMargins();
  318. UpdateColors();
  319. UpdateLayout(FALSE);
  320. PostMessage(hwnd, WM_CHANGEUISTATE, MAKEWPARAM(UIS_INITIALIZE, UISF_HIDEACCEL | UISF_HIDEFOCUS), 0L);
  321. return FALSE;
  322. }
  323. void LoginPage::OnDestroy()
  324. {
  325. HWND hControl = GetDlgItem(hwnd, IDC_HELPLINK);
  326. if (NULL != hControl)
  327. {
  328. HBITMAP bitmapSelected = (HBITMAP)SNDMSG(hControl, STM_SETIMAGE, (WPARAM)IMAGE_BITMAP, 0L);
  329. if (NULL != bitmapSelected)
  330. DeleteObject(bitmapSelected);
  331. }
  332. }
  333. void LoginPage::OnWindowPosChanged(const WINDOWPOS *pwp)
  334. {
  335. if (SWP_NOSIZE != ((SWP_NOSIZE | SWP_FRAMECHANGED) & pwp->flags))
  336. UpdateLayout(0 == (SWP_NOREDRAW & pwp->flags));
  337. }
  338. void LoginPage::OnCommand(UINT commandId, UINT eventType, HWND hControl)
  339. {
  340. switch(commandId)
  341. {
  342. case IDC_HELPLINK:
  343. switch(eventType)
  344. {
  345. case STN_CLICKED:
  346. ShowHelp();
  347. break;
  348. }
  349. break;
  350. }
  351. }
  352. BOOL LoginPage::OnNotify(UINT controlId, const NMHDR *pnmh)
  353. {
  354. return FALSE;
  355. }
  356. BOOL LoginPage::OnGetLoginData(LoginData **ppLoginData)
  357. {
  358. if (FAILED(LoginData::CreateInstance(NULL, hwnd, hLoginbox, ppLoginData)))
  359. return FALSE;
  360. return TRUE;
  361. }
  362. void LoginPage::OnUpdateStateChange(BOOL updateActive)
  363. {
  364. }
  365. BOOL LoginPage::OnSetUsername(LPCWSTR pszUsername)
  366. {
  367. return FALSE;
  368. }
  369. BOOL LoginPage::OnSetPassword(LPCWSTR pszPassword)
  370. {
  371. return FALSE;
  372. }
  373. HWND LoginPage::OnGetFirstItem()
  374. {
  375. return NULL;
  376. }
  377. BOOL LoginPage::OnSetTitle(LPCWSTR pszTitle)
  378. {
  379. HWND hControl = GetDlgItem(hwnd, IDC_TITLE);
  380. if (NULL == hControl) return FALSE;
  381. BOOL result = (BOOL)SNDMSG(hControl, WM_SETTEXT, 0, (LPARAM)pszTitle);
  382. if (FALSE != result)
  383. UpdateLayout(TRUE);
  384. return result;
  385. }
  386. HBRUSH LoginPage::OnGetStaticColor(HDC hdc, HWND hControl)
  387. {
  388. INT controlId = (INT)GetWindowLongPtr(hControl, GWLP_ID);
  389. switch(controlId)
  390. {
  391. case IDC_TITLE:
  392. SetTextColor(hdc, rgbTitle);
  393. break;
  394. default:
  395. SetTextColor(hdc, rgbText);
  396. break;
  397. }
  398. SetBkColor(hdc, rgbBack);
  399. return hbrBack;
  400. }
  401. HBRUSH LoginPage::OnGetDialogColor(HDC hdc, HWND hControl)
  402. {
  403. SetTextColor(hdc, rgbText);
  404. SetBkColor(hdc, rgbBack);
  405. return hbrBack;
  406. }
  407. BOOL LoginPage::OnSetCursor(HWND hTarget, INT hitCode, INT uMsg)
  408. {
  409. HWND hControl = GetDlgItem(hwnd, IDC_HELPLINK);
  410. if (hControl == hTarget && NULL != hControl)
  411. {
  412. UINT controlStyle = GetWindowStyle(hControl);
  413. if (WS_VISIBLE == ((WS_VISIBLE | WS_DISABLED) & controlStyle))
  414. {
  415. HCURSOR hCursor = LoadCursor(NULL, IDC_HAND);
  416. if (NULL != hCursor)
  417. {
  418. SetCursor(hCursor);
  419. return TRUE;
  420. }
  421. }
  422. }
  423. return FALSE;
  424. }
  425. BOOL LoginPage::OnHelp(HELPINFO *phi)
  426. {
  427. return ShowHelp();
  428. }
  429. void LoginPage::OnThemeChanged()
  430. {
  431. UpdateColors();
  432. }
  433. void LoginPage::OnSysColorChanged()
  434. {
  435. UpdateColors();
  436. }
  437. INT_PTR LoginPage::DialogProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
  438. {
  439. switch (uMsg)
  440. {
  441. case WM_INITDIALOG: return OnInitDialog((HWND)wParam, lParam);
  442. case WM_DESTROY: OnDestroy(); return TRUE;
  443. case WM_NOTIFY: MSGRESULT(hwnd, OnNotify((INT)wParam, (NMHDR*)lParam));
  444. case WM_COMMAND: OnCommand(LOWORD(wParam), HIWORD(wParam), (HWND)lParam); return TRUE;
  445. case WM_WINDOWPOSCHANGED: OnWindowPosChanged((WINDOWPOS*)lParam); return TRUE;
  446. case WM_SIZE: return TRUE;
  447. case WM_CTLCOLORSTATIC: return (INT_PTR)OnGetStaticColor((HDC)wParam, (HWND)lParam);
  448. case WM_CTLCOLORDLG: return (INT_PTR)OnGetDialogColor((HDC)wParam, (HWND)lParam);
  449. case WM_SETCURSOR:
  450. if (FALSE != OnSetCursor((HWND)wParam, LOWORD(lParam), HIWORD(lParam)))
  451. MSGRESULT(hwnd, TRUE);
  452. break;
  453. case WM_HELP:
  454. if (FALSE != OnHelp((HELPINFO*)lParam))
  455. MSGRESULT(hwnd, TRUE);
  456. break;
  457. case WM_THEMECHANGED: OnThemeChanged(); return TRUE;
  458. case WM_SYSCOLORCHANGE: OnSysColorChanged(); return TRUE;
  459. case NLPM_GETLOGINDATA: MSGRESULT(hwnd, OnGetLoginData((LoginData**)lParam));
  460. case NLPM_UPDATESTATECHANGE: OnUpdateStateChange((BOOL)lParam); return TRUE;
  461. case NLPM_SETUSERNAME: MSGRESULT(hwnd, OnSetUsername((LPCWSTR)lParam));
  462. case NLPM_SETPASSWORD: MSGRESULT(hwnd, OnSetPassword((LPCWSTR)lParam));
  463. case NLPM_GETFIRSTITEM: MSGRESULT(hwnd, OnGetFirstItem());
  464. case NLPM_SETTITLE: MSGRESULT(hwnd, OnSetTitle((LPCWSTR)lParam));
  465. }
  466. return FALSE;
  467. }
  468. static INT_PTR CALLBACK LoginPage_DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  469. {
  470. static ATOM LOGINPAGE_PROP = 0;
  471. LoginPage *page = (LoginPage*)GetProp(hwnd, MAKEINTATOM(LOGINPAGE_PROP));
  472. if (NULL == page)
  473. {
  474. switch(uMsg)
  475. {
  476. case WM_INITDIALOG:
  477. if (0 == LOGINPAGE_PROP)
  478. {
  479. LOGINPAGE_PROP = GlobalAddAtomW(L"NullsoftLoginPageProp");
  480. if (0 == LOGINPAGE_PROP)
  481. return 0;
  482. }
  483. if (NULL != lParam)
  484. {
  485. LOGINPAGECREATEPARAM *create = (LOGINPAGECREATEPARAM*)lParam;
  486. lParam = create->lParam;
  487. if (SUCCEEDED(create->fnCreator(hwnd, create->hLoginbox, &page)))
  488. {
  489. if (FALSE == SetProp(hwnd, MAKEINTATOM(LOGINPAGE_PROP), (HANDLE)page))
  490. {
  491. delete(page);
  492. page = NULL;
  493. }
  494. }
  495. }
  496. if (NULL != page)
  497. return page->DialogProc(uMsg, wParam, lParam);
  498. break;
  499. }
  500. return 0;
  501. }
  502. INT_PTR result = page->DialogProc(uMsg, wParam, lParam);
  503. if (WM_DESTROY == uMsg)
  504. {
  505. RemoveProp(hwnd, MAKEINTATOM(LOGINPAGE_PROP));
  506. delete(page);
  507. }
  508. return result;
  509. }