pageAddress.cpp 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. #include "./pageAddress.h"
  2. #include "./dataAddress.h"
  3. #include "./common.h"
  4. #include "./addressEncoder.h"
  5. #include "./addressEditbox.h"
  6. #include "./loginGui.h"
  7. #include "../resource.h"
  8. #include <shlwapi.h>
  9. #include <wininet.h>
  10. static HRESULT CALLBACK LoginPageAddress_CreateInstance(HWND hwnd, HWND hLoginbox, LoginPage **instance)
  11. {
  12. if (NULL == instance) return E_POINTER;
  13. if (NULL == hwnd || NULL == hLoginbox) return E_INVALIDARG;
  14. *instance = new LoginPageAddress(hwnd, hLoginbox);
  15. if (NULL == instance) return E_OUTOFMEMORY;
  16. return S_OK;
  17. }
  18. LoginPageAddress::LoginPageAddress(HWND hwnd, HWND hLoginbox)
  19. : LoginPage(hwnd, hLoginbox)
  20. {
  21. HWND hEdit = GetDlgItem(hwnd, IDC_ADDRESS_EDIT);
  22. if (NULL != hEdit)
  23. AddressEditbox_AttachWindow(hEdit);
  24. }
  25. LoginPageAddress::~LoginPageAddress()
  26. {
  27. }
  28. HWND LoginPageAddress::CreatePage(HWND hLoginbox, HWND hParent)
  29. {
  30. return LoginPage::CreatePage(hLoginbox, MAKEINTRESOURCE(IDD_PAGE_ADDRESS),
  31. hParent, NULL, LoginPageAddress_CreateInstance);
  32. }
  33. BOOL LoginPageAddress::OnInitDialog(HWND hFocus, LPARAM param)
  34. {
  35. HFONT fontEdit = NULL, fontLabel = NULL;
  36. LoginGuiObject *loginGui;
  37. if (SUCCEEDED(LoginGuiObject::QueryInstance(&loginGui)))
  38. {
  39. fontLabel = loginGui->GetTextFont();
  40. fontEdit = loginGui->GetEditorFont();
  41. loginGui->Release();
  42. }
  43. if (NULL != fontLabel)
  44. {
  45. HWND hLabel = GetDlgItem(hwnd, IDC_ADDRESS_LABEL);
  46. if (NULL != hLabel)
  47. SendMessage(hLabel, WM_SETFONT, (WPARAM)fontLabel, 0L);
  48. hLabel = GetDlgItem(hwnd, IDC_MESSAGE);
  49. if (NULL != hLabel)
  50. SendMessage(hLabel, WM_SETFONT, (WPARAM)fontLabel, 0L);
  51. }
  52. if (NULL != fontEdit)
  53. {
  54. HWND hEdit = GetDlgItem(hwnd, IDC_ADDRESS_EDIT);
  55. if (NULL != hEdit)
  56. SendMessage(hEdit, WM_SETFONT, (WPARAM)fontEdit, 0L);
  57. }
  58. LoginPage::OnInitDialog(hFocus, param);
  59. return FALSE;
  60. }
  61. void LoginPageAddress::OnDestroy()
  62. {
  63. LoginPage::OnDestroy();
  64. }
  65. void LoginPageAddress::UpdateLayout(BOOL fRedraw)
  66. {
  67. LoginPage::UpdateLayout(fRedraw);
  68. RECT pageRect;
  69. GetPageRect(&pageRect);
  70. UINT flags = SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOREDRAW;
  71. const INT szControls[] = { IDC_ADDRESS_LABEL, IDC_ADDRESS_EDIT, IDC_MESSAGE, };
  72. HDWP hdwp = BeginDeferWindowPos(ARRAYSIZE(szControls));
  73. INT baseunitX, baseunitY;
  74. if (FALSE == LoginBox_GetWindowBaseUnits(hwnd, &baseunitX, &baseunitY))
  75. {
  76. baseunitY = 13;
  77. }
  78. HRGN invalidRegion = CreateRectRgn(0, 0, 0, 0);
  79. HRGN tempRegion = CreateRectRgn(0, 0, 0, 0);
  80. HWND hControl;
  81. INT nextTop = pageRect.top;
  82. INT x, y, cx, cy;
  83. RECT rect;
  84. INT maxWidth = pageRect.right - pageRect.left;
  85. hControl = GetDlgItem(hwnd, IDC_ADDRESS_EDIT);
  86. if (NULL != hControl)
  87. {
  88. HDC hdc = GetDCEx(hControl, NULL, DCX_CACHE | DCX_NORESETATTRS);
  89. if (NULL != hdc)
  90. {
  91. HFONT fontControl = (HFONT)SendMessage(hControl, WM_GETFONT, 0, 0L);
  92. HFONT fontOrig = (HFONT)SelectObject(hdc, fontControl);
  93. maxWidth = LoginBox_GetAveStrWidth(hdc, 80);
  94. if(maxWidth > (pageRect.right - pageRect.left))
  95. maxWidth = pageRect.right - pageRect.left;
  96. SelectObject(hdc, fontOrig);
  97. ReleaseDC(hControl, hdc);
  98. }
  99. }
  100. for (INT i = 0; i < ARRAYSIZE(szControls); i++)
  101. {
  102. hControl = GetDlgItem(hwnd, szControls[i]);
  103. if (NULL == hControl || FALSE == GetWindowRect(hControl, &rect)) continue;
  104. MapWindowPoints(HWND_DESKTOP, hwnd, (POINT*)&rect, 2);
  105. x = rect.left;
  106. y = rect.top;
  107. cx = rect.right - rect.left;
  108. cy = rect.bottom - rect.top;
  109. switch(szControls[i])
  110. {
  111. case IDC_ADDRESS_LABEL:
  112. case IDC_MESSAGE:
  113. x = pageRect.left;
  114. y = nextTop;
  115. LoginBox_GetWindowTextSize(hControl, maxWidth, &cx, &cy);
  116. nextTop += (cy + MulDiv(2, baseunitY, 8));
  117. break;
  118. case IDC_ADDRESS_EDIT:
  119. x = pageRect.left;
  120. y = nextTop;
  121. cy = LoginBox_GetWindowTextHeight(hControl, 0);
  122. {
  123. RECT r1, r2;
  124. GetWindowRect(hControl, &r1);
  125. SendMessage(hControl, EM_GETRECT, 0, (LPARAM)&r2);
  126. INT t = (r1.bottom - r1.top) - (r2.bottom - r2.top);
  127. cy += t;
  128. }
  129. cx = maxWidth;
  130. nextTop += (cy + MulDiv(7, baseunitY, 8));
  131. break;
  132. }
  133. if (rect.left != x || rect.top != y ||
  134. (rect.right - rect.left) != cx || (rect.bottom - rect.top) != cy)
  135. {
  136. hdwp = DeferWindowPos(hdwp, hControl, NULL, x, y, cx, cy, flags);
  137. if (NULL == hdwp) break;
  138. if (FALSE != fRedraw)
  139. {
  140. SetRectRgn(tempRegion, rect.left, rect.top, rect.right, rect.bottom);
  141. CombineRgn(invalidRegion, invalidRegion, tempRegion, RGN_OR);
  142. SetRectRgn(tempRegion, x, y , x + cx, y + cy);
  143. CombineRgn(invalidRegion, invalidRegion, tempRegion, RGN_OR);
  144. }
  145. }
  146. }
  147. if (NULL != hdwp)
  148. EndDeferWindowPos(hdwp);
  149. if (FALSE != fRedraw)
  150. {
  151. RedrawWindow(hwnd, NULL, invalidRegion,
  152. RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE | RDW_ERASENOW | RDW_ALLCHILDREN | RDW_VALIDATE);
  153. }
  154. if (NULL != invalidRegion)
  155. DeleteObject(invalidRegion);
  156. if (NULL != tempRegion)
  157. DeleteObject(tempRegion);
  158. }
  159. BOOL LoginPageAddress::OnGetLoginData(LoginData **ppLoginData)
  160. {
  161. if (NULL == ppLoginData)
  162. return FALSE;
  163. HWND hEdit;
  164. LPWSTR address;
  165. hEdit = GetDlgItem(hwnd, IDC_ADDRESS_EDIT);
  166. if (NULL == hEdit || FAILED(LoginBox_GetWindowText(hEdit, &address, NULL)))
  167. address = NULL;
  168. else
  169. {
  170. size_t encodedMax = lstrlen(address)*2;
  171. LPWSTR addressEncoded = LoginBox_MallocString(encodedMax);
  172. for(;;)
  173. {
  174. if (FALSE == InternetCanonicalizeUrl(address, addressEncoded, (DWORD*)&encodedMax, ICU_ENCODE_PERCENT | ICU_NO_META))
  175. {
  176. if (ERROR_INSUFFICIENT_BUFFER == GetLastError())
  177. {
  178. LoginBox_FreeString(addressEncoded);
  179. addressEncoded = LoginBox_MallocString(encodedMax);
  180. if (NULL != addressEncoded)
  181. continue;
  182. }
  183. }
  184. else
  185. {
  186. LoginBox_FreeString(address);
  187. address = LoginBox_CopyString(addressEncoded);
  188. }
  189. break;
  190. }
  191. HRESULT hr;
  192. for(;;)
  193. {
  194. hr = AddressEncoder_EncodeString(address, addressEncoded, &encodedMax, ICU_BROWSER_MODE);
  195. if (ENC_E_INSUFFICIENT_BUFFER == hr)
  196. {
  197. LoginBox_FreeString(addressEncoded);
  198. addressEncoded = LoginBox_MallocString(encodedMax);
  199. if (NULL == addressEncoded)
  200. hr = E_OUTOFMEMORY;
  201. else
  202. continue;
  203. }
  204. break;
  205. }
  206. if (SUCCEEDED(hr))
  207. {
  208. LoginBox_FreeString(address);
  209. address = addressEncoded;
  210. addressEncoded = NULL;
  211. }
  212. else
  213. LoginBox_FreeString(addressEncoded);
  214. }
  215. HRESULT hr = LoginDataAddress::CreateInstance(NULL, hwnd, hLoginbox,
  216. address, (LoginDataAddress**)ppLoginData);
  217. LoginBox_FreeString(address);
  218. return SUCCEEDED(hr);
  219. }
  220. BOOL LoginPageAddress::OnSetUsername(LPCWSTR pszUsername)
  221. {
  222. HWND hEdit = GetDlgItem(hwnd, IDC_ADDRESS_EDIT);
  223. if (NULL == hEdit) return FALSE;
  224. if (NULL == pszUsername || L'\0' == *pszUsername)
  225. return FALSE;
  226. INT cchLen = lstrlen(pszUsername);
  227. INT f, l;
  228. SNDMSG(hEdit, EM_GETSEL, (WPARAM)&f, (LPARAM)&l);
  229. if (f == l) return FALSE;
  230. SNDMSG(hEdit, EM_REPLACESEL, FALSE, (LPARAM)pszUsername);
  231. SNDMSG(hEdit, EM_SETSEL, (WPARAM)f, (LPARAM)f + cchLen);
  232. return TRUE;
  233. }
  234. HBRUSH LoginPageAddress::OnGetStaticColor(HDC hdc, HWND hControl)
  235. {
  236. INT_PTR controlId = (INT_PTR)GetWindowLongPtr(hControl, GWLP_ID);
  237. switch(controlId)
  238. {
  239. case IDC_MESSAGE:
  240. SetTextColor(hdc, rgbSecondaryText);
  241. SetBkColor(hdc, rgbBack);
  242. return hbrBack;
  243. }
  244. return LoginPage::OnGetStaticColor(hdc, hControl);
  245. }
  246. BOOL LoginPageAddress::OnSetAddress(LPCWSTR pszAddress, BOOL replaceUsername)
  247. {
  248. HWND hEdit = GetDlgItem(hwnd, IDC_ADDRESS_EDIT);
  249. if (NULL == hEdit) return FALSE;
  250. BOOL succeeded;
  251. LPWSTR addressDecoded;
  252. if (SUCCEEDED(AddressEncoder_DecodeString(pszAddress, &addressDecoded)))
  253. {
  254. succeeded = (BOOL)SNDMSG(hEdit, WM_SETTEXT, 0, (LPARAM)addressDecoded);
  255. LoginBox_FreeString(addressDecoded);
  256. }
  257. else
  258. succeeded = (BOOL)SNDMSG(hEdit, WM_SETTEXT, 0, (LPARAM)pszAddress);
  259. return succeeded;
  260. }
  261. BOOL LoginPageAddress::OnSetAddressTitle(LPCWSTR pszTitle)
  262. {
  263. return SetLabelText(IDC_ADDRESS_LABEL, pszTitle);
  264. }
  265. BOOL LoginPageAddress::OnSetMessage(LPCWSTR pszMessage)
  266. {
  267. HWND hLabel = GetDlgItem(hwnd, IDC_MESSAGE);
  268. if (NULL == hLabel) return FALSE;
  269. return SetWindowText(hLabel, pszMessage);
  270. }
  271. INT_PTR LoginPageAddress::DialogProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
  272. {
  273. switch(uMsg)
  274. {
  275. case NLPAM_SETADDRESS: MSGRESULT(hwnd, OnSetAddress((LPCWSTR)lParam, (BOOL)wParam));
  276. case NLPAM_SETADDRESSTITLE: MSGRESULT(hwnd, OnSetAddressTitle((LPCWSTR)lParam));
  277. case NLPAM_SETMESSAGE: MSGRESULT(hwnd, OnSetMessage((LPCWSTR)lParam));
  278. }
  279. return __super::DialogProc(uMsg, wParam, lParam);
  280. }