#include "./creddlg.h" #include typedef struct _DLGTEMPLATEEX { WORD dlgVer; WORD signature; DWORD helpID; DWORD exStyle; DWORD style; WORD cDlgItems; short x; short y; short cx; short cy; WORD menu; WORD windowClass; WCHAR title; WORD pointsize; WORD weight; BYTE italic; BYTE charset; WCHAR typeface; } DLGTEMPLATEEX; #include static const DLGTEMPLATEEX dlg_template = {1, 0xFFFF, 0, WS_EX_DLGMODALFRAME | WS_EX_CONTROLPARENT | WS_EX_NOPARENTNOTIFY, WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_CAPTION | WS_SYSMENU, 0, 0, 0, 0, 0, 0, 0, 0, }; typedef struct _CREDDATA { LPWSTR szUser; INT cchUser; LPWSTR szPassword; INT cchPassword; DWORD flags; HBITMAP hbmp; LPCWSTR greating; INT retcode; } CREDDATA, *PCREDDATA; typedef struct _WNDLIST { HWND hwndModal; HWND *list; INT count; INT allocated; } WNDLIST; #define CREDCTRL L"CREDCTRL" #define BITMAP_HEIGHT 64 #define DIALOG_HEIGHT 236 #define DIALOG_WIDTH 316 static LRESULT WINAPI WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); static HWND CreateCredCtrl(const PCREDDATA pcd, INT x, INT y, INT cx, INT cy, HWND hwndParent, HINSTANCE hInstance, INT ctrlID); static void BlokedWndLst_Initialize(WNDLIST *plist, HWND hwndModal); static void BlokedWndLst_Add(WNDLIST *plist, HWND hwnd); static void BlokedWndLst_RemoveAll(WNDLIST *plist); static BOOL CALLBACK BlockedWndLst_EnumThread(HWND hwnd, LPARAM param); static HWND GetRoot(HWND hwnd ) { HWND hwndParent; while ((WS_CHILD & GetWindowLongPtr(hwnd, GWL_STYLE)) && (hwndParent = GetParent(hwnd))) hwnd = hwndParent; return hwnd; } static BOOL CALLBACK BlockedWndLst_EnumThread(HWND hwnd, LPARAM param) { BlokedWndLst_Add((WNDLIST*)param, hwnd); return TRUE; } static void BlokedWndLst_Initialize(WNDLIST *plist, HWND hwndModal) { plist->hwndModal = GetRoot(hwndModal); plist->count = 0; plist->allocated = 0; plist->list = NULL; EnumThreadWindows(GetCurrentThreadId(), BlockedWndLst_EnumThread, (LPARAM)plist); } static void BlokedWndLst_Add(WNDLIST *plist, HWND hwnd) { int i; if (!hwnd || hwnd == plist->hwndModal || !IsWindowVisible(hwnd) || !IsWindowEnabled(hwnd)) return; hwnd = GetRoot(hwnd); if (!hwnd || hwnd == plist->hwndModal || !IsWindowVisible(hwnd) || !IsWindowEnabled(hwnd)) return; for (i = 0; i < plist->count; i++) if (hwnd == plist->list[i]) return; if (plist->count == plist->allocated) { plist->allocated += 8; plist->list = realloc(plist->list, plist->allocated*sizeof(HWND)); } if (!plist->list) return; plist->list[plist->count] = hwnd; plist->count++; EnableWindow(hwnd, FALSE); } static void BlokedWndLst_RemoveAll(WNDLIST *plist) { int i; for ( i = 0; i < plist->count; i++) EnableWindow(plist->list[i], TRUE); if (plist->list) free(plist->list); } static HWND CreateCredCtrl(const PCREDDATA pcd, INT x, INT y, INT cx, INT cy, HWND hwndParent, HINSTANCE hInstance, INT ctrlID) { WNDCLASSW wndclass; if (!GetClassInfoW(hInstance, CREDCTRL, &wndclass)) { wndclass.lpszClassName = CREDCTRL; wndclass.lpfnWndProc = WndProc; wndclass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); wndclass.hCursor = NULL; wndclass.hIcon = NULL; wndclass.hInstance = hInstance; wndclass.lpszMenuName = NULL; wndclass.style = 0x0; wndclass.cbClsExtra = 0x0; wndclass.cbWndExtra = sizeof(CREDDATA*); if (!RegisterClassW(&wndclass)) return NULL; } return CreateWindowExW(WS_EX_CONTROLPARENT | WS_EX_NOPARENTNOTIFY, CREDCTRL, pcd->greating, WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_CHILD, x, y, cx, cy, hwndParent, (HMENU)(INT_PTR)ctrlID, hInstance, (LPVOID)pcd); } typedef struct _CONTROLS { INT id; LPCWSTR pClass; DWORD style; DWORD exStyle; LPCWSTR pTitle; }CONTROLS; #define IDC_CREDCTRL 1101 #define IDC_BMP_LOGO 1001 #define IDC_LBL_GREATING 1002 #define IDC_LBL_USERNAME 1003 #define IDC_LBL_PASSWORD 1004 #define IDC_EDT_USERNAME 1005 #define IDC_EDT_PASSWORD 1006 #define BASE_WND_STYLE WS_CHILD | WS_VISIBLE static CONTROLS controls[] = { {IDC_BMP_LOGO, L"STATIC", BASE_WND_STYLE | SS_BITMAP | SS_REALSIZEIMAGE, WS_EX_NOPARENTNOTIFY, NULL }, {IDC_LBL_GREATING, L"STATIC", BASE_WND_STYLE, WS_EX_NOPARENTNOTIFY, NULL }, {IDC_LBL_USERNAME, L"STATIC", BASE_WND_STYLE, WS_EX_NOPARENTNOTIFY, L"User name:" }, {IDC_EDT_USERNAME, L"EDIT", BASE_WND_STYLE | WS_TABSTOP, WS_EX_NOPARENTNOTIFY | WS_EX_CLIENTEDGE, NULL }, {IDC_LBL_PASSWORD, L"STATIC", BASE_WND_STYLE, WS_EX_NOPARENTNOTIFY, L"Password:" }, {IDC_EDT_PASSWORD, L"EDIT", BASE_WND_STYLE | WS_TABSTOP | ES_PASSWORD, WS_EX_NOPARENTNOTIFY | WS_EX_CLIENTEDGE, NULL }, {IDOK, L"BUTTON", BASE_WND_STYLE | BS_DEFPUSHBUTTON | WS_TABSTOP, WS_EX_NOPARENTNOTIFY, L"Ok" }, {IDCANCEL, L"BUTTON", BASE_WND_STYLE | WS_TABSTOP, WS_EX_NOPARENTNOTIFY, L"Cancel" }, }; //// skinning #include "../winamp/wa_ipc.h" #include "../winamp/wa_dlg.h" typedef HRESULT (__stdcall *UX_SETWINDOWTHEME)(HWND, LPCWSTR, LPCWSTR); static LRESULT OnCreate(HWND hwnd, LPCREATESTRUCTW pcs) { int i; HFONT hf; CREDDATA *pcd; HMODULE uxdll; UX_SETWINDOWTHEME uxSetWindowTheme = NULL; pcd = (CREDDATA*)pcs->lpCreateParams; SetLastError(0); if (!SetWindowLongPtr(hwnd, GWL_USERDATA, (LONG)(LONG_PTR)pcd) && GetLastError()) return -1; hf = GetStockObject(DEFAULT_GUI_FONT); if (CDS_SKINDIALOG & pcd->flags) { uxdll = LoadLibrary("uxtheme.dll"); uxSetWindowTheme = (uxdll) ? (UX_SETWINDOWTHEME)GetProcAddress(uxdll, "SetWindowTheme") : NULL; if (uxSetWindowTheme) uxSetWindowTheme(hwnd, L" ", L" "); }else uxdll = NULL; for (i = 0; i < sizeof(controls)/sizeof(controls[0]); i++) { switch(controls[i].id) { case IDC_BMP_LOGO: controls[i].style &= ~WS_VISIBLE; if (pcd->hbmp) controls[i].style |= WS_VISIBLE; break; case IDC_LBL_GREATING: controls[i].pTitle = pcs->lpszName; break; case IDC_EDT_USERNAME: controls[i].exStyle &= ~WS_EX_CLIENTEDGE; if (0 == (CDS_SKINDIALOG & pcd->flags)) controls[i].exStyle |= WS_EX_CLIENTEDGE; controls[i].pTitle = (CDS_USEUSERNAME & pcd->flags) ? pcd->szUser : NULL; break; case IDC_EDT_PASSWORD: controls[i].exStyle &= ~WS_EX_CLIENTEDGE; if (0 == (CDS_SKINDIALOG & pcd->flags)) controls[i].exStyle |= WS_EX_CLIENTEDGE; controls[i].pTitle = (CDS_USEPASSWORD & pcd->flags) ? pcd->szPassword : NULL; break; case IDOK: case IDCANCEL: controls[i].style &= ~BS_OWNERDRAW; if (CDS_SKINDIALOG & pcd->flags) controls[i].style |= BS_OWNERDRAW; break; } HWND hwndCtrl = CreateWindowExW(controls[i].exStyle, controls[i].pClass, controls[i].pTitle, controls[i].style, 0, 0, 0, 0, hwnd, (HMENU)(INT_PTR)controls[i].id, NULL, NULL); if (IsWindow(hwndCtrl)) { SendMessageW(hwndCtrl, WM_SETFONT, (WPARAM)hf, FALSE); if ((CDS_SKINDIALOG & pcd->flags) && uxSetWindowTheme) uxSetWindowTheme(hwndCtrl, L" ", L" "); } } if (pcd->hbmp) SendDlgItemMessage(hwnd, IDC_BMP_LOGO, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)pcd->hbmp); if (uxdll) FreeLibrary(uxdll); pcd->retcode = -4; //- we are running return 0; } static void LayoutWindows(HWND hwnd) { int i; RECT rc, ri; GetClientRect(hwnd, &rc); for (i = 0; i < sizeof(controls)/sizeof(controls[0]); i++) { HWND hwndCtrl = GetDlgItem(hwnd, controls[i].id); switch(controls[i].id) { case IDC_BMP_LOGO: SetRect(&ri, rc.left, rc.top, rc.right, rc.top + BITMAP_HEIGHT); if (WS_VISIBLE & GetWindowLongPtr(hwndCtrl, GWL_STYLE)) rc.top = ri.bottom + 2; InflateRect(&rc, -8, -8); break; case IDC_LBL_GREATING: SetRect(&ri, rc.left, rc.top, rc.right, rc.top + 36); rc.top = ri.bottom + 12; break; case IDC_LBL_USERNAME: case IDC_LBL_PASSWORD: SetRect(&ri, rc.left, rc.top, rc.left + 84, rc.top + 20); break; case IDC_EDT_USERNAME: case IDC_EDT_PASSWORD: ri.left = rc.left + 92; SetRect(&ri, ri.left, rc.top, rc.right, rc.top + 20); rc.top = ri.bottom + 8; break; case IDOK: SetRect(&ri, rc.right - 150, rc.bottom - 22, rc.right - 78, rc.bottom); break; case IDCANCEL: SetRect(&ri, rc.right - 72, rc.bottom - 22, rc.right, rc.bottom); break; } SetWindowPos(hwndCtrl, NULL, ri.left, ri.top, ri.right - ri.left, ri.bottom - ri.top, SWP_NOACTIVATE | SWP_NOZORDER); } } static LRESULT WINAPI WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { PCREDDATA pcd; pcd = (PCREDDATA)(LONG_PTR)GetWindowLongPtr(hwnd, GWLP_USERDATA); if(pcd && (CDS_SKINDIALOG & pcd->flags)) { INT_PTR a; a = WADlg_handleDialogMsgs(hwnd, uMsg, wParam, lParam); if (a) return a; } switch(uMsg) { case WM_CREATE: return OnCreate(hwnd, (LPCREATESTRUCTW) lParam); case WM_DESTROY: PostQuitMessage(0); return 0; case WM_COMMAND: switch(LOWORD(wParam)) { case IDOK: if (pcd) { pcd->retcode = 1; SetLastError(0); GetWindowTextW(GetDlgItem(hwnd, IDC_EDT_USERNAME), pcd->szUser, pcd->cchUser); if (GetLastError()) pcd->retcode = -1; GetWindowTextW(GetDlgItem(hwnd, IDC_EDT_PASSWORD), pcd->szPassword, pcd->cchPassword); if (GetLastError()) pcd->retcode = -1; } case IDCANCEL: if (pcd && IDCANCEL == LOWORD(wParam)) pcd->retcode = 0; DestroyWindow(GetParent(hwnd)); return 0; } break; case WM_CLOSE: if (pcd) pcd->retcode = 0; DestroyWindow(GetParent(hwnd)); break; case WM_WINDOWPOSCHANGED: LayoutWindows(hwnd); return 0; case WM_PAINT: if(pcd && (CDS_SKINDIALOG & pcd->flags)) { int tab[] = { IDC_EDT_USERNAME | DCW_SUNKENBORDER , IDC_EDT_PASSWORD | DCW_SUNKENBORDER}; WADlg_DrawChildWindowBorders(hwnd, tab, 2); } break; case WM_ERASEBKGND: if(pcd && (CDS_SKINDIALOG & pcd->flags)) { RECT rc; GetClientRect(hwnd, &rc); FillRect((HDC)wParam, &rc, (HBRUSH) SendMessage(hwnd, WM_CTLCOLORDLG, wParam, (LPARAM)hwnd)); return 1; } break; } return DefWindowProcW(hwnd, uMsg, wParam, lParam); } static INT_PTR WINAPI DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg) { case WM_WINDOWPOSCHANGED: { RECT rc; HWND hwndChild; hwndChild = FindWindowExW(hwnd, NULL, CREDCTRL, NULL); if (hwndChild) { GetClientRect(hwnd, &rc); SetWindowPos(hwndChild, NULL, 0,0, rc.right, rc.bottom, SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER); } } break; return TRUE; case WM_COMMAND: switch(LOWORD(wParam)) { case IDCANCEL: case IDOK: { HWND hwndChild; hwndChild = FindWindowExW(hwnd, NULL, CREDCTRL, NULL); if (hwndChild) SendMessage(hwndChild, WM_CLOSE, 0, 0L); } return TRUE; } break; } return 0; } INT ShowCredentialDialog(const WACREDDLG *pcd) { HWND hwnd; MSG msg; WNDLIST list; CREDDATA cd; embedWindowState embedWnd = {0}; if (!pcd || pcd->size != sizeof(WACREDDLG) || !pcd->szUser || !pcd->cchUser || !pcd->szPassword || !pcd->cchPassword) return -1; ZeroMemory(&cd, sizeof(CREDDATA)); cd.szUser = pcd->szUser; cd.szPassword = pcd->szPassword; cd.cchUser = pcd->cchUser; cd.cchPassword = pcd->cchPassword; cd.flags = pcd->flags; cd.greating = pcd->greating; cd.hbmp = pcd->hbmp; cd.retcode = -1; if ((CDS_SKINDIALOG & pcd->flags) && pcd->hwndWA) { ZeroMemory(&embedWnd, sizeof(embedWindowState)); SetRect(&embedWnd.r, 0, 0, 1, 1); embedWnd.flags = EMBED_FLAGS_NORESIZE | EMBED_FLAGS_NOTRANSPARENCY | EMBED_FLAGS_NOWINDOWMENU; hwnd = (HWND)SendMessage(pcd->hwndWA, WM_WA_IPC, (LPARAM)&embedWnd, IPC_GET_EMBEDIF); } else hwnd = NULL; if(!IsWindow(hwnd)) hwnd = CreateDialogIndirect(GetModuleHandleW(NULL), (LPCDLGTEMPLATEW)&dlg_template, pcd->hwndParent, DialogProc); if (IsWindow(hwnd)) { RECT rw; INT fx, fy; HWND hwndActive = GetActiveWindow(); SetWindowTextW(hwnd, pcd->title); GetClientRect(hwnd, &rw); HWND hwndCtrl = CreateCredCtrl(&cd, 0, 0, rw.right, rw.bottom, hwnd, GetModuleHandleW(NULL), IDC_CREDCTRL); if ((CDS_SKINDIALOG & pcd->flags)) { SetWindowPos(hwnd, NULL, 0, 0, 100, 100, SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOREDRAW); GetWindowRect(hwnd, &rw); fx = rw.right - rw.left; fy = rw.bottom - rw.top; GetWindowRect(hwndCtrl, &rw); fx -= (rw.right - rw.left); fy -= (rw.bottom - rw.top); } else { GetWindowRect(hwnd, &rw); fx = rw.right - rw.left; fy = rw.bottom - rw.top; GetClientRect(hwnd, &rw); fx -= (rw.right - rw.left); fy -= (rw.bottom - rw.top); } if (pcd->hwndParent) GetWindowRect(pcd->hwndParent, &rw); else GetWindowRect(GetDesktopWindow(), &rw); SetWindowPos(hwnd, HWND_TOP, rw.left + (rw.right - rw.left - (DIALOG_WIDTH + fx)) / 2, rw.top + (rw.bottom - rw.top - (DIALOG_HEIGHT + fy - ((pcd->hbmp) ? 0 : BITMAP_HEIGHT))) / 2, DIALOG_WIDTH + fx, (DIALOG_HEIGHT + fy - ((pcd->hbmp) ? 0 : BITMAP_HEIGHT)), 0); ShowWindow(hwnd, SW_SHOW); if (CDS_APPMODAL & pcd->flags) BlokedWndLst_Initialize(&list, hwnd); else if (pcd->hwndParent) EnableWindow(GetRoot(pcd->hwndParent), FALSE); BOOL result; while(0 != (result = GetMessage(&msg, NULL, 0, 0)) && -1 != result) { if (!IsDialogMessage(hwnd, &msg)) { if ((CDS_APPMODAL & pcd->flags) && WM_TIMER != msg.message) BlokedWndLst_Add(&list, msg.hwnd); TranslateMessage(&msg); DispatchMessage(&msg); } } if (CDS_APPMODAL & pcd->flags) BlokedWndLst_RemoveAll(&list); else if (pcd->hwndParent) EnableWindow(GetRoot(pcd->hwndParent), TRUE); if (hwndActive) SetActiveWindow(hwndActive); if (!result) { if (-4 == cd.retcode) { PostQuitMessage((INT)msg.wParam); } } } if (-4 == cd.retcode) cd.retcode = 0; return cd.retcode; }