From 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d Mon Sep 17 00:00:00 2001 From: Jef Date: Tue, 24 Sep 2024 14:54:57 +0200 Subject: Initial community commit --- Src/auth/Loginbox/popupAgreement.cpp | 567 +++++++++++++++++++++++++++++++++++ 1 file changed, 567 insertions(+) create mode 100644 Src/auth/Loginbox/popupAgreement.cpp (limited to 'Src/auth/Loginbox/popupAgreement.cpp') diff --git a/Src/auth/Loginbox/popupAgreement.cpp b/Src/auth/Loginbox/popupAgreement.cpp new file mode 100644 index 00000000..08682f9b --- /dev/null +++ b/Src/auth/Loginbox/popupAgreement.cpp @@ -0,0 +1,567 @@ +#include "./popupAgreement.h" +#include "./loginNotifier.h" +#include "./loginProvider.h" + +#include "./common.h" +#include "../resource.h" +#include "../api.h" + +#include "../../winamp/commandLink.h" + +#include +#include +#include + +#define LINK_TOS 0 +#define STATIC_AND 1 +#define LINK_PRIVACY 2 + +#define IDC_AOL 11000 +#define IDC_AOL_TOS (IDC_AOL + LINK_TOS) +#define IDC_AOL_AND (IDC_AOL + STATIC_AND) +#define IDC_AOL_PRIVACY (IDC_AOL + LINK_PRIVACY) + +#define IDC_3DPARTY 11010 +#define IDC_3DPARTY_TOS (IDC_3DPARTY + LINK_TOS) +#define IDC_3DPARTY_AND (IDC_3DPARTY + STATIC_AND) +#define IDC_3DPARTY_PRIVACY (IDC_3DPARTY + LINK_PRIVACY) + + +#define LINK_TARGET L"LinkTargetProp" + +typedef struct __PARTSIZE +{ + HWND hwnd; + LONG cx; + LONG cy; +} PARTSIZE; + +typedef struct __LINKSIZEINFO +{ + PARTSIZE tos; + PARTSIZE and; + PARTSIZE privacy; + LONG spaceWidth; + RECT linkMargins; +} LINKSIZEINFO; + +static HRESULT CALLBACK LoginPopupAgreement_CreateInstance(HWND hwnd, LPARAM param, LoginPopup **instance) +{ + if (NULL == instance) return E_POINTER; + if (NULL == hwnd) return E_INVALIDARG; + + *instance = new LoginPopupAgreement(hwnd); + if (NULL == instance) return E_OUTOFMEMORY; + + return S_OK; +} + +LoginPopupAgreement::LoginPopupAgreement(HWND hwnd) + : LoginPopup(hwnd, -1, MAKEINTRESOURCE(IDS_POPUP_AGREEMENT_TITLE)) +{ +} + +LoginPopupAgreement::~LoginPopupAgreement() +{ + +} + +HWND LoginPopupAgreement::CreatePopup(HWND hParent, LoginProvider *provider) +{ + if (NULL == provider) + return NULL; + + return LoginPopup::CreatePopup(MAKEINTRESOURCE(IDD_POPUP_AGREEMENT), hParent, (LPARAM)provider, LoginPopupAgreement_CreateInstance); +} + +void LoginPopupAgreement::UpdateLayout(BOOL fRedraw) +{ + LoginPopup::UpdateLayout(fRedraw); + + RECT rect; + if (FALSE == GetInfoRect(&rect)) return; + + const INT szButtons[] = { IDOK, IDCANCEL, }; + + + UINT flags = SWP_NOZORDER | SWP_NOACTIVATE; + if (FALSE == fRedraw) flags |= SWP_NOREDRAW; + + HDWP hdwp = BeginDeferWindowPos(ARRAYSIZE(szButtons) + 1 + 2*3); + if (NULL == hdwp) return; + + hdwp = LayoutButtons(hdwp, szButtons, ARRAYSIZE(szButtons), fRedraw, NULL); + + LONG top = rect.top; + SIZE partSize; + HWND hText = GetDlgItem(hwnd, IDC_TEXT); + if (NULL != hText && FALSE != GetTextSize(hText, rect.right - rect.left, &partSize)) + { + hdwp = DeferWindowPos(hdwp, hText, NULL, rect.left, top, partSize.cx, partSize.cy, flags); + if (NULL == hdwp) return; + top += partSize.cy; + } + + top += marginLinkFirst; + hdwp = LayoutProviderLinks(hdwp, IDC_AOL, NULL, rect.left + marginLinkLeft, top, flags, &partSize); + if (NULL == hdwp) return; + + if (0 != partSize.cy) + top += partSize.cy + marginLinkNext; + hdwp = LayoutProviderLinks(hdwp, IDC_3DPARTY, NULL, rect.left + marginLinkLeft, top, flags, &partSize); + if (NULL == hdwp) return; + + EndDeferWindowPos(hdwp); + + if (FALSE != fRedraw) + { + HWND hControl = GetDlgItem(hwnd, IDC_TEXT); + if (NULL != hControl) InvalidateRect(hControl, NULL, FALSE); + } +} + +void LoginPopupAgreement::EndDialog(INT_PTR code) +{ + NLPNRESULT result; + result.exitCode = code; + SendNotification(NLPN_RESULT, (NMHDR*)&result); + + LoginPopup::EndDialog(code); +} + +void LoginPopupAgreement::UpdateMargins() +{ + RECT rect; + SetRect(&rect, 8, 8, 0, 2); + MapDialogRect(hwnd, &rect); + + marginLinkLeft = rect.left; + marginLinkFirst = rect.top; + marginLinkNext = rect.bottom; + + LoginPopup::UpdateMargins(); +} + +static BOOL ProviderLinks_GetSizeInfo(HWND hwnd, INT groupId, LINKSIZEINFO *sizeInfo) +{ + if(NULL == sizeInfo) + return FALSE; + + HWND hControl; + SIZE partSize; + + SetRectEmpty(&sizeInfo->linkMargins); + + hControl = GetDlgItem(hwnd, groupId + LINK_TOS); + if (NULL == hControl || + 0 == (WS_VISIBLE & GetWindowStyle(hControl)) || + FALSE == CommandLink_GetIdealSize(hControl, &partSize)) + { + ZeroMemory(&sizeInfo->tos, sizeof(PARTSIZE)); + } + else + { + sizeInfo->tos.hwnd = hControl; + sizeInfo->tos.cx = partSize.cx; + sizeInfo->tos.cy = partSize.cy; + + CommandLink_GetMargins(hControl, &sizeInfo->linkMargins); + } + + hControl = GetDlgItem(hwnd, groupId + LINK_PRIVACY); + if (NULL == hControl || + 0 == (WS_VISIBLE & GetWindowStyle(hControl)) || + FALSE == CommandLink_GetIdealSize(hControl, &partSize)) + { + ZeroMemory(&sizeInfo->privacy, sizeof(PARTSIZE)); + } + else + { + sizeInfo->privacy.hwnd = hControl; + sizeInfo->privacy.cx = partSize.cx; + sizeInfo->privacy.cy = partSize.cy; + + if (IsRectEmpty(&sizeInfo->linkMargins)) + CommandLink_GetMargins(hControl, &sizeInfo->linkMargins); + } + + if (NULL == sizeInfo->tos.hwnd && NULL == sizeInfo->privacy.hwnd) + return FALSE; + + ZeroMemory(&sizeInfo->and, sizeof(PARTSIZE)); + sizeInfo->spaceWidth = 0; + + if (NULL != sizeInfo->tos.hwnd && NULL != sizeInfo->privacy.hwnd) + { + hControl = GetDlgItem(hwnd, groupId + STATIC_AND); + if (NULL != hControl) + { + WCHAR szBuffer[64] = {0}; + INT cchLen = (INT)SendMessage(hControl, WM_GETTEXT, ARRAYSIZE(szBuffer), (LPARAM)szBuffer); + if (cchLen > 0) + { + HDC hdc = GetDCEx(hControl, NULL, DCX_CACHE | DCX_WINDOW | DCX_NORESETATTRS); + if (NULL != hdc) + { + HFONT font = (HFONT)SendMessage(hControl, WM_GETFONT, 0, 0L); + HFONT fontOrig = (HFONT)SelectObject(hdc, font); + + if (FALSE != GetTextExtentPoint32W(hdc, szBuffer, cchLen, &partSize)) + { + sizeInfo->and.hwnd = hControl; + sizeInfo->and.cx = partSize.cx; + sizeInfo->and.cy = partSize.cy; + } + + if (FALSE != GetTextExtentPoint32W(hdc, L" ", 1, &partSize)) + { + sizeInfo->spaceWidth = partSize.cx; + } + + SelectObject(hdc, fontOrig); + ReleaseDC(hControl, hdc); + } + } + } + } + return TRUE; +} + +HDWP LoginPopupAgreement::LayoutProviderLinks(HDWP hdwp, INT groupId, HWND hwndInsertAfter, INT x, INT y, UINT flags, SIZE *size) +{ + if (NULL == hdwp) + { + if (NULL == size) + return NULL; + x = 0; + y = 0; + } + + LONG ox = x, cy = 0; + + LINKSIZEINFO sizeInfo; + if (FALSE == ProviderLinks_GetSizeInfo(hwnd, groupId, &sizeInfo)) + return hdwp; + + if (NULL != sizeInfo.tos.hwnd) + { + if (NULL != hdwp) + { + hdwp = DeferWindowPos(hdwp, sizeInfo.tos.hwnd, hwndInsertAfter, x, y, sizeInfo.tos.cx, sizeInfo.tos.cy, flags); + if (NULL == hdwp) return NULL; + } + + x += sizeInfo.tos.cx; + if (cy < sizeInfo.tos.cy) cy = sizeInfo.tos.cy; + } + + if (NULL != sizeInfo.and.hwnd) + { + LONG top = y + ((sizeInfo.tos.cy - (sizeInfo.linkMargins.bottom + sizeInfo.linkMargins.top)) - sizeInfo.and.cy)/2; + LONG space = (sizeInfo.spaceWidth - sizeInfo.linkMargins.right); + if (space < 1) space = 1; + x += space; + if (NULL != hdwp) + { + hdwp = DeferWindowPos(hdwp, sizeInfo.and.hwnd, hwndInsertAfter, x, top, sizeInfo.and.cx, sizeInfo.and.cy, flags); + if (NULL == hdwp) return NULL; + } + + x += sizeInfo.and.cx; + if (cy < sizeInfo.and.cy) cy = sizeInfo.and.cy; + } + + if (NULL != sizeInfo.privacy.hwnd) + { + if (NULL != sizeInfo.and.hwnd) + { + LONG space = (sizeInfo.spaceWidth - sizeInfo.linkMargins.left); + if (space < 1) space = 1; + x += space; + } + + if (NULL != hdwp) + { + hdwp = DeferWindowPos(hdwp, sizeInfo.privacy.hwnd, hwndInsertAfter, x, y, sizeInfo.privacy.cx, sizeInfo.privacy.cy, flags); + if (NULL == hdwp) return NULL; + } + + x += sizeInfo.privacy.cx; + if (cy < sizeInfo.privacy.cy) cy = sizeInfo.privacy.cy; + + } + + if (NULL != size) + { + size->cx = (x - ox); + size->cy = cy; + } + + return (NULL == hdwp) ? (HDWP)(TRUE) : hdwp; +} + +BOOL LoginPopupAgreement::CreateProviderLinks(LPCWSTR pszProvider, LPCWSTR pszTos, LPCWSTR pszPrivacy, INT groupId, HWND hwndInsertAfter) +{ + WCHAR szTemplate[256] = {0}, szBuffer[256] = {0}; + UINT linkStyle = WS_CHILD | WS_TABSTOP | WS_GROUP | WS_VISIBLE | + CLS_DEFAULTCOLORS | CLS_HOTTRACK /*| CLS_ALWAYSUNDERLINE*/; + + HFONT font = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0L); + + LPWSTR pszUrl; + HWND hControl; + INT createdCount = 0; + INT failedCount = 0; + if (NULL != pszTos && L'\0' != *pszTos) + { + WASABI_API_LNGSTRINGW_BUF(IDS_TOSLINK_TEMPLATE, szTemplate, ARRAYSIZE(szTemplate)); + StringCchPrintf(szBuffer, ARRAYSIZE(szBuffer), szTemplate, pszProvider); + hControl = CommandLink_CreateWindow(0, szBuffer, linkStyle, 0, 0, 0, 0, hwnd, groupId + LINK_TOS); + if (NULL != hControl) + { + pszUrl = LoginBox_CopyString(pszTos); + if (NULL == pszUrl || FALSE == SetProp(hControl, LINK_TARGET, pszUrl)) + { + LoginBox_FreeString(pszUrl); + DestroyWindow(hControl); + hControl = NULL; + } + } + + if (NULL != hControl) + { + SendMessage(hControl, WM_SETFONT, (WPARAM)font, 0L); + SetWindowPos(hControl, hwndInsertAfter, 0, 0,0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW); + hwndInsertAfter = hControl; + createdCount++; + } + else failedCount++; + } + + if (0 == failedCount && NULL != pszPrivacy && L'\0' != *pszPrivacy) + { + WASABI_API_LNGSTRINGW_BUF(IDS_PRIVACYLINK_TEMPLATE, szTemplate, ARRAYSIZE(szTemplate)); + StringCchPrintf(szBuffer, ARRAYSIZE(szBuffer), szTemplate, pszProvider); + hControl = CommandLink_CreateWindow(0, szBuffer, linkStyle, 0, 0, 0, 0, hwnd, groupId + LINK_PRIVACY); + if (NULL != hControl) + { + pszUrl = LoginBox_CopyString(pszPrivacy); + if (NULL == pszUrl || FALSE == SetProp(hControl, LINK_TARGET, pszUrl)) + { + LoginBox_FreeString(pszUrl); + DestroyWindow(hControl); + hControl = NULL; + } + } + if (NULL != hControl) + { + SendMessage(hControl, WM_SETFONT, (WPARAM)font, 0L); + SetWindowPos(hControl, hwndInsertAfter, 0, 0,0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW); + hwndInsertAfter = hControl; + createdCount++; + } + else failedCount++; + } + + if (0 == failedCount && createdCount > 1) + { + WASABI_API_LNGSTRINGW_BUF(IDS_AND, szBuffer, ARRAYSIZE(szBuffer)); + hControl = CreateWindowEx(WS_EX_NOPARENTNOTIFY, L"Static", szBuffer, WS_CHILD | WS_VISIBLE | SS_LEFT, + 0, 0, 0, 0, hwnd, (HMENU)(INT_PTR)(groupId + STATIC_AND), NULL, 0L); + if (NULL != hControl) + { + SendMessage(hControl, WM_SETFONT, (WPARAM)font, 0L); + SetWindowPos(hControl, hwndInsertAfter, 0, 0,0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW); + hwndInsertAfter = hControl; + createdCount++; + } + else + failedCount++; + } + + if (0 != failedCount) + { + hControl = GetDlgItem(hwnd, (groupId + LINK_TOS)); + if (NULL != hControl) DestroyWindow(hControl); + hControl = GetDlgItem(hwnd, (groupId + LINK_PRIVACY)); + if (NULL != hControl) DestroyWindow(hControl); + hControl = GetDlgItem(hwnd, (groupId + STATIC_AND)); + if (NULL != hControl) DestroyWindow(hControl); + } + + return (0 == failedCount); +} + +BOOL LoginPopupAgreement::OnInitDialog(HWND hFocus, LPARAM param) +{ + LoginProvider *provider = (LoginProvider*)param; + if (NULL != provider) + { + WCHAR szName[128] = {0}, szTos[4096] = {0}, szPrivacy[4096] = {0}; + if (FAILED(provider->GetTosLink(szTos, ARRAYSIZE(szTos)))) + szTos[0] = L'\0'; + if (FAILED(provider->GetPrivacyLink(szPrivacy, ARRAYSIZE(szPrivacy)))) + szPrivacy[0] = L'\0'; + + if((L'\0' != szTos[0] || L'\0' != szPrivacy[0]) && + SUCCEEDED(provider->GetName(szName, ARRAYSIZE(szName)))) + { + CreateProviderLinks(szName, szTos, szPrivacy, IDC_3DPARTY, NULL); + } + } + + CreateProviderLinks(L"AOL", L"https://new.aol.com/freeaolweb/resources/jsp/mem_tos.jsp", + L"http://about.aol.com/aolnetwork/mem_policy", IDC_AOL, NULL); + + LoginPopup::OnInitDialog(hFocus, param); + + HWND hAgree = GetDlgItem(hwnd, IDOK); + if (NULL != hAgree && (WS_VISIBLE == ((WS_VISIBLE | WS_DISABLED) & GetWindowStyle(hAgree)))) + { + PostMessage(hwnd, WM_NEXTDLGCTL, (WPARAM)hAgree, TRUE); + return TRUE; + } + + return FALSE; +} +void LoginPopupAgreement::OnDestroy() +{ + INT szLinks[] = {IDC_AOL_TOS, IDC_AOL_PRIVACY, IDC_3DPARTY_TOS, IDC_3DPARTY_PRIVACY, }; + for (INT i = 0; i < ARRAYSIZE(szLinks); i++) + { + HWND hLink = GetDlgItem(hwnd, szLinks[i]); + if (NULL != hLink) DestroyWindow(hLink); + } +} + +BOOL LoginPopupAgreement::OnUpdateWindowPos(const RECT* clientRect, RECT *rectOut) +{ + if (NULL == clientRect || NULL == rectOut) + return FALSE; + + SIZE maxSize; + SIZE partSize; + + maxSize.cx = 0; + maxSize.cy = 0; + + if (((HDWP)TRUE) == LayoutProviderLinks(NULL, IDC_AOL, NULL, 0, 0, 0, &partSize)) + { + if (maxSize.cx < partSize.cx) maxSize.cx = partSize.cx; + maxSize.cy += (partSize.cy + marginLinkFirst); + } + + if (((HDWP)TRUE) == LayoutProviderLinks(NULL, IDC_3DPARTY, NULL, 0, 0, 0, &partSize)) + { + if (maxSize.cx < partSize.cx) maxSize.cx = partSize.cx; + maxSize.cy += (partSize.cy + ((0 == maxSize.cy) ? marginLinkFirst : marginLinkNext)); + } + + if (0 != maxSize.cx) + maxSize.cx += marginLinkLeft; + + if (0 != maxSize.cy) + maxSize.cy += marginLinkFirst; + + LONG maxWidth = clientRect->right - clientRect->left - + (clientMargins.right + clientMargins.left) - + (infoMargins.right + infoMargins.left); + + if (maxSize.cx > maxWidth) + maxSize.cx = maxWidth; + + if (FALSE != GetTextSize(GetDlgItem(hwnd, IDC_TEXT), maxWidth, &partSize)) + { + if (maxSize.cx < partSize.cx) maxSize.cx = partSize.cx; + maxSize.cy += partSize.cy; + } + + if (FALSE == CalculateWindowRect(maxSize.cx, maxSize.cy, NULL, 0, TRUE, rectOut)) + return FALSE; + + + LONG ox = clientRect->left + ((clientRect->right - clientRect->left) - (rectOut->right - rectOut->left))/2; + LONG oy = clientRect->top + ((clientRect->bottom - clientRect->top) - (rectOut->bottom - rectOut->top))/2; + + if (ox < clientRect->left) ox = clientRect->left; + if (oy < clientRect->top) oy = clientRect->top; + + OffsetRect(rectOut, ox, oy); + return TRUE; +} +HBRUSH LoginPopupAgreement::OnGetStaticColor(HDC hdc, HWND hControl) +{ + HBRUSH hb = LoginPopup::OnGetStaticColor(hdc, hControl); + INT controlId = (NULL != hControl) ? (INT)GetWindowLongPtr(hControl, GWLP_ID) : 0; + switch(controlId) + { + case IDC_AOL_AND: + case IDC_3DPARTY_AND: + { + HWND hLink = GetDlgItem(hwnd, (controlId - STATIC_AND)); + if (NULL != hLink) + { + // SetTextColor(hdc, CommandLink_GetTextColor(hLink)); + } + } + break; + } + + return hb; +} + +void LoginPopupAgreement::OnParentNotify(UINT eventId, UINT wParam, LPARAM lParam) +{ + switch(eventId) + { + case WM_DESTROY: + switch(wParam) + { + case IDC_AOL_TOS: + case IDC_AOL_PRIVACY: + case IDC_3DPARTY_TOS: + case IDC_3DPARTY_PRIVACY: + { + LPWSTR url = (LPWSTR)GetProp((HWND)lParam, LINK_TARGET); + RemoveProp((HWND)lParam, LINK_TARGET); + LoginBox_FreeString(url); + } + break; + } + break; + + } + LoginPopup::OnParentNotify(eventId, wParam, lParam); +} + + +void LoginPopupAgreement::OnLinkClicked(HWND hLink) +{ + if (NULL == hLink) + return; + + LPCWSTR pszTarget = (LPCWSTR)GetProp(hLink, LINK_TARGET); + if (NULL != pszTarget && L'\0' != *pszTarget) + { + LoginBox_OpenUrl(hwnd, pszTarget, TRUE); + } +} + +LRESULT LoginPopupAgreement::OnNotify(UINT controlId, const NMHDR *pnmh) +{ + switch(controlId) + { + case IDC_AOL_TOS: + case IDC_AOL_PRIVACY: + case IDC_3DPARTY_TOS: + case IDC_3DPARTY_PRIVACY: + switch(pnmh->code) + { + case NM_CLICK: + OnLinkClicked(pnmh->hwndFrom); + return 0; + } + break; + } + return LoginPopup::OnNotify(controlId, pnmh); +} -- cgit