creddlg.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503
  1. #include "./creddlg.h"
  2. #include <pshpack2.h>
  3. typedef struct _DLGTEMPLATEEX
  4. {
  5. WORD dlgVer;
  6. WORD signature;
  7. DWORD helpID;
  8. DWORD exStyle;
  9. DWORD style;
  10. WORD cDlgItems;
  11. short x;
  12. short y;
  13. short cx;
  14. short cy;
  15. WORD menu;
  16. WORD windowClass;
  17. WCHAR title;
  18. WORD pointsize;
  19. WORD weight;
  20. BYTE italic;
  21. BYTE charset;
  22. WCHAR typeface;
  23. } DLGTEMPLATEEX;
  24. #include <poppack.h>
  25. static const DLGTEMPLATEEX dlg_template = {1, 0xFFFF, 0,
  26. WS_EX_DLGMODALFRAME | WS_EX_CONTROLPARENT | WS_EX_NOPARENTNOTIFY,
  27. WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_CAPTION | WS_SYSMENU,
  28. 0, 0, 0, 0, 0, 0, 0, 0, };
  29. typedef struct _CREDDATA
  30. {
  31. LPWSTR szUser;
  32. INT cchUser;
  33. LPWSTR szPassword;
  34. INT cchPassword;
  35. DWORD flags;
  36. HBITMAP hbmp;
  37. LPCWSTR greating;
  38. INT retcode;
  39. } CREDDATA, *PCREDDATA;
  40. typedef struct _WNDLIST
  41. {
  42. HWND hwndModal;
  43. HWND *list;
  44. INT count;
  45. INT allocated;
  46. } WNDLIST;
  47. #define CREDCTRL L"CREDCTRL"
  48. #define BITMAP_HEIGHT 64
  49. #define DIALOG_HEIGHT 236
  50. #define DIALOG_WIDTH 316
  51. static LRESULT WINAPI WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  52. static HWND CreateCredCtrl(const PCREDDATA pcd, INT x, INT y, INT cx, INT cy, HWND hwndParent, HINSTANCE hInstance, INT ctrlID);
  53. static void BlokedWndLst_Initialize(WNDLIST *plist, HWND hwndModal);
  54. static void BlokedWndLst_Add(WNDLIST *plist, HWND hwnd);
  55. static void BlokedWndLst_RemoveAll(WNDLIST *plist);
  56. static BOOL CALLBACK BlockedWndLst_EnumThread(HWND hwnd, LPARAM param);
  57. static HWND GetRoot(HWND hwnd )
  58. {
  59. HWND hwndParent;
  60. while ((WS_CHILD & GetWindowLongPtr(hwnd, GWL_STYLE)) && (hwndParent = GetParent(hwnd))) hwnd = hwndParent;
  61. return hwnd;
  62. }
  63. static BOOL CALLBACK BlockedWndLst_EnumThread(HWND hwnd, LPARAM param)
  64. {
  65. BlokedWndLst_Add((WNDLIST*)param, hwnd);
  66. return TRUE;
  67. }
  68. static void BlokedWndLst_Initialize(WNDLIST *plist, HWND hwndModal)
  69. {
  70. plist->hwndModal = GetRoot(hwndModal);
  71. plist->count = 0;
  72. plist->allocated = 0;
  73. plist->list = NULL;
  74. EnumThreadWindows(GetCurrentThreadId(), BlockedWndLst_EnumThread, (LPARAM)plist);
  75. }
  76. static void BlokedWndLst_Add(WNDLIST *plist, HWND hwnd)
  77. {
  78. int i;
  79. if (!hwnd || hwnd == plist->hwndModal || !IsWindowVisible(hwnd) || !IsWindowEnabled(hwnd)) return;
  80. hwnd = GetRoot(hwnd);
  81. if (!hwnd || hwnd == plist->hwndModal || !IsWindowVisible(hwnd) || !IsWindowEnabled(hwnd)) return;
  82. for (i = 0; i < plist->count; i++) if (hwnd == plist->list[i]) return;
  83. if (plist->count == plist->allocated)
  84. {
  85. plist->allocated += 8;
  86. plist->list = realloc(plist->list, plist->allocated*sizeof(HWND));
  87. }
  88. if (!plist->list) return;
  89. plist->list[plist->count] = hwnd;
  90. plist->count++;
  91. EnableWindow(hwnd, FALSE);
  92. }
  93. static void BlokedWndLst_RemoveAll(WNDLIST *plist)
  94. {
  95. int i;
  96. for ( i = 0; i < plist->count; i++) EnableWindow(plist->list[i], TRUE);
  97. if (plist->list) free(plist->list);
  98. }
  99. static HWND CreateCredCtrl(const PCREDDATA pcd, INT x, INT y, INT cx, INT cy, HWND hwndParent, HINSTANCE hInstance, INT ctrlID)
  100. {
  101. WNDCLASSW wndclass;
  102. if (!GetClassInfoW(hInstance, CREDCTRL, &wndclass))
  103. {
  104. wndclass.lpszClassName = CREDCTRL;
  105. wndclass.lpfnWndProc = WndProc;
  106. wndclass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
  107. wndclass.hCursor = NULL;
  108. wndclass.hIcon = NULL;
  109. wndclass.hInstance = hInstance;
  110. wndclass.lpszMenuName = NULL;
  111. wndclass.style = 0x0;
  112. wndclass.cbClsExtra = 0x0;
  113. wndclass.cbWndExtra = sizeof(CREDDATA*);
  114. if (!RegisterClassW(&wndclass)) return NULL;
  115. }
  116. return CreateWindowExW(WS_EX_CONTROLPARENT | WS_EX_NOPARENTNOTIFY, CREDCTRL, pcd->greating,
  117. WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_CHILD,
  118. x, y, cx, cy, hwndParent, (HMENU)(INT_PTR)ctrlID, hInstance, (LPVOID)pcd);
  119. }
  120. typedef struct _CONTROLS
  121. {
  122. INT id;
  123. LPCWSTR pClass;
  124. DWORD style;
  125. DWORD exStyle;
  126. LPCWSTR pTitle;
  127. }CONTROLS;
  128. #define IDC_CREDCTRL 1101
  129. #define IDC_BMP_LOGO 1001
  130. #define IDC_LBL_GREATING 1002
  131. #define IDC_LBL_USERNAME 1003
  132. #define IDC_LBL_PASSWORD 1004
  133. #define IDC_EDT_USERNAME 1005
  134. #define IDC_EDT_PASSWORD 1006
  135. #define BASE_WND_STYLE WS_CHILD | WS_VISIBLE
  136. static CONTROLS controls[] =
  137. {
  138. {IDC_BMP_LOGO, L"STATIC", BASE_WND_STYLE | SS_BITMAP | SS_REALSIZEIMAGE, WS_EX_NOPARENTNOTIFY, NULL },
  139. {IDC_LBL_GREATING, L"STATIC", BASE_WND_STYLE, WS_EX_NOPARENTNOTIFY, NULL },
  140. {IDC_LBL_USERNAME, L"STATIC", BASE_WND_STYLE, WS_EX_NOPARENTNOTIFY, L"User name:" },
  141. {IDC_EDT_USERNAME, L"EDIT", BASE_WND_STYLE | WS_TABSTOP, WS_EX_NOPARENTNOTIFY | WS_EX_CLIENTEDGE, NULL },
  142. {IDC_LBL_PASSWORD, L"STATIC", BASE_WND_STYLE, WS_EX_NOPARENTNOTIFY, L"Password:" },
  143. {IDC_EDT_PASSWORD, L"EDIT", BASE_WND_STYLE | WS_TABSTOP | ES_PASSWORD, WS_EX_NOPARENTNOTIFY | WS_EX_CLIENTEDGE, NULL },
  144. {IDOK, L"BUTTON", BASE_WND_STYLE | BS_DEFPUSHBUTTON | WS_TABSTOP, WS_EX_NOPARENTNOTIFY, L"Ok" },
  145. {IDCANCEL, L"BUTTON", BASE_WND_STYLE | WS_TABSTOP, WS_EX_NOPARENTNOTIFY, L"Cancel" },
  146. };
  147. //// skinning
  148. #include "../winamp/wa_ipc.h"
  149. #include "../winamp/wa_dlg.h"
  150. typedef HRESULT (__stdcall *UX_SETWINDOWTHEME)(HWND, LPCWSTR, LPCWSTR);
  151. static LRESULT OnCreate(HWND hwnd, LPCREATESTRUCTW pcs)
  152. {
  153. int i;
  154. HFONT hf;
  155. CREDDATA *pcd;
  156. HMODULE uxdll;
  157. UX_SETWINDOWTHEME uxSetWindowTheme = NULL;
  158. pcd = (CREDDATA*)pcs->lpCreateParams;
  159. SetLastError(0);
  160. if (!SetWindowLongPtr(hwnd, GWL_USERDATA, (LONG)(LONG_PTR)pcd) && GetLastError()) return -1;
  161. hf = GetStockObject(DEFAULT_GUI_FONT);
  162. if (CDS_SKINDIALOG & pcd->flags)
  163. {
  164. uxdll = LoadLibrary("uxtheme.dll");
  165. uxSetWindowTheme = (uxdll) ? (UX_SETWINDOWTHEME)GetProcAddress(uxdll, "SetWindowTheme") : NULL;
  166. if (uxSetWindowTheme) uxSetWindowTheme(hwnd, L" ", L" ");
  167. }else uxdll = NULL;
  168. for (i = 0; i < sizeof(controls)/sizeof(controls[0]); i++)
  169. {
  170. switch(controls[i].id)
  171. {
  172. case IDC_BMP_LOGO:
  173. controls[i].style &= ~WS_VISIBLE;
  174. if (pcd->hbmp) controls[i].style |= WS_VISIBLE;
  175. break;
  176. case IDC_LBL_GREATING:
  177. controls[i].pTitle = pcs->lpszName;
  178. break;
  179. case IDC_EDT_USERNAME:
  180. controls[i].exStyle &= ~WS_EX_CLIENTEDGE;
  181. if (0 == (CDS_SKINDIALOG & pcd->flags)) controls[i].exStyle |= WS_EX_CLIENTEDGE;
  182. controls[i].pTitle = (CDS_USEUSERNAME & pcd->flags) ? pcd->szUser : NULL;
  183. break;
  184. case IDC_EDT_PASSWORD:
  185. controls[i].exStyle &= ~WS_EX_CLIENTEDGE;
  186. if (0 == (CDS_SKINDIALOG & pcd->flags)) controls[i].exStyle |= WS_EX_CLIENTEDGE;
  187. controls[i].pTitle = (CDS_USEPASSWORD & pcd->flags) ? pcd->szPassword : NULL;
  188. break;
  189. case IDOK:
  190. case IDCANCEL:
  191. controls[i].style &= ~BS_OWNERDRAW;
  192. if (CDS_SKINDIALOG & pcd->flags) controls[i].style |= BS_OWNERDRAW;
  193. break;
  194. }
  195. HWND hwndCtrl = CreateWindowExW(controls[i].exStyle, controls[i].pClass, controls[i].pTitle, controls[i].style,
  196. 0, 0, 0, 0, hwnd, (HMENU)(INT_PTR)controls[i].id, NULL, NULL);
  197. if (IsWindow(hwndCtrl))
  198. {
  199. SendMessageW(hwndCtrl, WM_SETFONT, (WPARAM)hf, FALSE);
  200. if ((CDS_SKINDIALOG & pcd->flags) && uxSetWindowTheme) uxSetWindowTheme(hwndCtrl, L" ", L" ");
  201. }
  202. }
  203. if (pcd->hbmp) SendDlgItemMessage(hwnd, IDC_BMP_LOGO, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)pcd->hbmp);
  204. if (uxdll) FreeLibrary(uxdll);
  205. pcd->retcode = -4; //- we are running
  206. return 0;
  207. }
  208. static void LayoutWindows(HWND hwnd)
  209. {
  210. int i;
  211. RECT rc, ri;
  212. GetClientRect(hwnd, &rc);
  213. for (i = 0; i < sizeof(controls)/sizeof(controls[0]); i++)
  214. {
  215. HWND hwndCtrl = GetDlgItem(hwnd, controls[i].id);
  216. switch(controls[i].id)
  217. {
  218. case IDC_BMP_LOGO:
  219. SetRect(&ri, rc.left, rc.top, rc.right, rc.top + BITMAP_HEIGHT);
  220. if (WS_VISIBLE & GetWindowLongPtr(hwndCtrl, GWL_STYLE)) rc.top = ri.bottom + 2;
  221. InflateRect(&rc, -8, -8);
  222. break;
  223. case IDC_LBL_GREATING:
  224. SetRect(&ri, rc.left, rc.top, rc.right, rc.top + 36);
  225. rc.top = ri.bottom + 12;
  226. break;
  227. case IDC_LBL_USERNAME:
  228. case IDC_LBL_PASSWORD:
  229. SetRect(&ri, rc.left, rc.top, rc.left + 84, rc.top + 20);
  230. break;
  231. case IDC_EDT_USERNAME:
  232. case IDC_EDT_PASSWORD:
  233. ri.left = rc.left + 92;
  234. SetRect(&ri, ri.left, rc.top, rc.right, rc.top + 20);
  235. rc.top = ri.bottom + 8;
  236. break;
  237. case IDOK:
  238. SetRect(&ri, rc.right - 150, rc.bottom - 22, rc.right - 78, rc.bottom);
  239. break;
  240. case IDCANCEL:
  241. SetRect(&ri, rc.right - 72, rc.bottom - 22, rc.right, rc.bottom);
  242. break;
  243. }
  244. SetWindowPos(hwndCtrl, NULL, ri.left, ri.top, ri.right - ri.left, ri.bottom - ri.top, SWP_NOACTIVATE | SWP_NOZORDER);
  245. }
  246. }
  247. static LRESULT WINAPI WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  248. {
  249. PCREDDATA pcd;
  250. pcd = (PCREDDATA)(LONG_PTR)GetWindowLongPtr(hwnd, GWLP_USERDATA);
  251. if(pcd && (CDS_SKINDIALOG & pcd->flags))
  252. {
  253. INT_PTR a;
  254. a = WADlg_handleDialogMsgs(hwnd, uMsg, wParam, lParam);
  255. if (a) return a;
  256. }
  257. switch(uMsg)
  258. {
  259. case WM_CREATE: return OnCreate(hwnd, (LPCREATESTRUCTW) lParam);
  260. case WM_DESTROY:
  261. PostQuitMessage(0);
  262. return 0;
  263. case WM_COMMAND:
  264. switch(LOWORD(wParam))
  265. {
  266. case IDOK:
  267. if (pcd)
  268. {
  269. pcd->retcode = 1;
  270. SetLastError(0);
  271. GetWindowTextW(GetDlgItem(hwnd, IDC_EDT_USERNAME), pcd->szUser, pcd->cchUser);
  272. if (GetLastError()) pcd->retcode = -1;
  273. GetWindowTextW(GetDlgItem(hwnd, IDC_EDT_PASSWORD), pcd->szPassword, pcd->cchPassword);
  274. if (GetLastError()) pcd->retcode = -1;
  275. }
  276. case IDCANCEL:
  277. if (pcd && IDCANCEL == LOWORD(wParam)) pcd->retcode = 0;
  278. DestroyWindow(GetParent(hwnd));
  279. return 0;
  280. }
  281. break;
  282. case WM_CLOSE:
  283. if (pcd) pcd->retcode = 0;
  284. DestroyWindow(GetParent(hwnd));
  285. break;
  286. case WM_WINDOWPOSCHANGED:
  287. LayoutWindows(hwnd);
  288. return 0;
  289. case WM_PAINT:
  290. if(pcd && (CDS_SKINDIALOG & pcd->flags))
  291. {
  292. int tab[] = { IDC_EDT_USERNAME | DCW_SUNKENBORDER , IDC_EDT_PASSWORD | DCW_SUNKENBORDER};
  293. WADlg_DrawChildWindowBorders(hwnd, tab, 2);
  294. }
  295. break;
  296. case WM_ERASEBKGND:
  297. if(pcd && (CDS_SKINDIALOG & pcd->flags))
  298. {
  299. RECT rc;
  300. GetClientRect(hwnd, &rc);
  301. FillRect((HDC)wParam, &rc, (HBRUSH) SendMessage(hwnd, WM_CTLCOLORDLG, wParam, (LPARAM)hwnd));
  302. return 1;
  303. }
  304. break;
  305. }
  306. return DefWindowProcW(hwnd, uMsg, wParam, lParam);
  307. }
  308. static INT_PTR WINAPI DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  309. {
  310. switch(uMsg)
  311. {
  312. case WM_WINDOWPOSCHANGED:
  313. {
  314. RECT rc;
  315. HWND hwndChild;
  316. hwndChild = FindWindowExW(hwnd, NULL, CREDCTRL, NULL);
  317. if (hwndChild)
  318. {
  319. GetClientRect(hwnd, &rc);
  320. SetWindowPos(hwndChild, NULL, 0,0, rc.right, rc.bottom, SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
  321. }
  322. }
  323. break;
  324. return TRUE;
  325. case WM_COMMAND:
  326. switch(LOWORD(wParam))
  327. {
  328. case IDCANCEL:
  329. case IDOK:
  330. {
  331. HWND hwndChild;
  332. hwndChild = FindWindowExW(hwnd, NULL, CREDCTRL, NULL);
  333. if (hwndChild) SendMessage(hwndChild, WM_CLOSE, 0, 0L);
  334. }
  335. return TRUE;
  336. }
  337. break;
  338. }
  339. return 0;
  340. }
  341. INT ShowCredentialDialog(const WACREDDLG *pcd)
  342. {
  343. HWND hwnd;
  344. MSG msg;
  345. WNDLIST list;
  346. CREDDATA cd;
  347. embedWindowState embedWnd = {0};
  348. if (!pcd || pcd->size != sizeof(WACREDDLG) || !pcd->szUser || !pcd->cchUser || !pcd->szPassword || !pcd->cchPassword) return -1;
  349. ZeroMemory(&cd, sizeof(CREDDATA));
  350. cd.szUser = pcd->szUser;
  351. cd.szPassword = pcd->szPassword;
  352. cd.cchUser = pcd->cchUser;
  353. cd.cchPassword = pcd->cchPassword;
  354. cd.flags = pcd->flags;
  355. cd.greating = pcd->greating;
  356. cd.hbmp = pcd->hbmp;
  357. cd.retcode = -1;
  358. if ((CDS_SKINDIALOG & pcd->flags) && pcd->hwndWA)
  359. {
  360. ZeroMemory(&embedWnd, sizeof(embedWindowState));
  361. SetRect(&embedWnd.r, 0, 0, 1, 1);
  362. embedWnd.flags = EMBED_FLAGS_NORESIZE | EMBED_FLAGS_NOTRANSPARENCY | EMBED_FLAGS_NOWINDOWMENU;
  363. hwnd = (HWND)SendMessage(pcd->hwndWA, WM_WA_IPC, (LPARAM)&embedWnd, IPC_GET_EMBEDIF);
  364. }
  365. else hwnd = NULL;
  366. if(!IsWindow(hwnd)) hwnd = CreateDialogIndirect(GetModuleHandleW(NULL), (LPCDLGTEMPLATEW)&dlg_template, pcd->hwndParent, DialogProc);
  367. if (IsWindow(hwnd))
  368. {
  369. RECT rw;
  370. INT fx, fy;
  371. HWND hwndActive = GetActiveWindow();
  372. SetWindowTextW(hwnd, pcd->title);
  373. GetClientRect(hwnd, &rw);
  374. HWND hwndCtrl = CreateCredCtrl(&cd, 0, 0, rw.right, rw.bottom, hwnd, GetModuleHandleW(NULL), IDC_CREDCTRL);
  375. if ((CDS_SKINDIALOG & pcd->flags))
  376. {
  377. SetWindowPos(hwnd, NULL, 0, 0, 100, 100, SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOREDRAW);
  378. GetWindowRect(hwnd, &rw);
  379. fx = rw.right - rw.left;
  380. fy = rw.bottom - rw.top;
  381. GetWindowRect(hwndCtrl, &rw);
  382. fx -= (rw.right - rw.left);
  383. fy -= (rw.bottom - rw.top);
  384. }
  385. else
  386. {
  387. GetWindowRect(hwnd, &rw);
  388. fx = rw.right - rw.left;
  389. fy = rw.bottom - rw.top;
  390. GetClientRect(hwnd, &rw);
  391. fx -= (rw.right - rw.left);
  392. fy -= (rw.bottom - rw.top);
  393. }
  394. if (pcd->hwndParent) GetWindowRect(pcd->hwndParent, &rw);
  395. else GetWindowRect(GetDesktopWindow(), &rw);
  396. SetWindowPos(hwnd, HWND_TOP,
  397. rw.left + (rw.right - rw.left - (DIALOG_WIDTH + fx)) / 2,
  398. rw.top + (rw.bottom - rw.top - (DIALOG_HEIGHT + fy - ((pcd->hbmp) ? 0 : BITMAP_HEIGHT))) / 2,
  399. DIALOG_WIDTH + fx,
  400. (DIALOG_HEIGHT + fy - ((pcd->hbmp) ? 0 : BITMAP_HEIGHT)),
  401. 0);
  402. ShowWindow(hwnd, SW_SHOW);
  403. if (CDS_APPMODAL & pcd->flags) BlokedWndLst_Initialize(&list, hwnd);
  404. else if (pcd->hwndParent) EnableWindow(GetRoot(pcd->hwndParent), FALSE);
  405. BOOL result;
  406. while(0 != (result = GetMessage(&msg, NULL, 0, 0)) && -1 != result)
  407. {
  408. if (!IsDialogMessage(hwnd, &msg))
  409. {
  410. if ((CDS_APPMODAL & pcd->flags) && WM_TIMER != msg.message) BlokedWndLst_Add(&list, msg.hwnd);
  411. TranslateMessage(&msg);
  412. DispatchMessage(&msg);
  413. }
  414. }
  415. if (CDS_APPMODAL & pcd->flags) BlokedWndLst_RemoveAll(&list);
  416. else if (pcd->hwndParent) EnableWindow(GetRoot(pcd->hwndParent), TRUE);
  417. if (hwndActive) SetActiveWindow(hwndActive);
  418. if (!result)
  419. {
  420. if (-4 == cd.retcode)
  421. {
  422. PostQuitMessage((INT)msg.wParam);
  423. }
  424. }
  425. }
  426. if (-4 == cd.retcode) cd.retcode = 0;
  427. return cd.retcode;
  428. }