aboutsummaryrefslogtreecommitdiff
path: root/Src/auth/Loginbox/loginPopup.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Src/auth/Loginbox/loginPopup.cpp')
-rw-r--r--Src/auth/Loginbox/loginPopup.cpp733
1 files changed, 733 insertions, 0 deletions
diff --git a/Src/auth/Loginbox/loginPopup.cpp b/Src/auth/Loginbox/loginPopup.cpp
new file mode 100644
index 00000000..e0fc6494
--- /dev/null
+++ b/Src/auth/Loginbox/loginPopup.cpp
@@ -0,0 +1,733 @@
+#include "./loginPopup.h"
+#include "../api.h"
+#include "../../nu/Vectors.h"
+#include "./loginNotifier.h"
+#include "./common.h"
+
+typedef Vector<HWND> WindowList;
+
+typedef struct __THREADPOPUPDATA
+{
+ HHOOK hHook;
+ WindowList windowList;
+} THREADPOPUPDATA;
+
+static size_t threadStorage = TLS_OUT_OF_INDEXES;
+
+typedef struct __LOGINPOPUPCREATEPARAM
+{
+ LoginPopup::Creator fnCreator;
+ LPARAM lParam;
+} LOGINPOPUPCREATEPARAM;
+
+#define IDC_NOTIFIER 10001
+
+//#define COLOR_TITLE COLOR_3DLIGHT
+//#define COLOR_TITLETEXT COLOR_WINDOWTEXT
+#define COLOR_CLIENT COLOR_3DFACE
+#define COLOR_CLIENTTEXT COLOR_WINDOWTEXT
+
+LoginPopup::LoginPopup(HWND hwnd, UINT popupType, LPCWSTR pszTitle)
+ : alertType(-1), alertMessage(NULL)
+{
+ buttonHeight = buttonSpace = 0;
+ this->hwnd = hwnd;
+
+ if (NULL != pszTitle)
+ SetTitle(popupType, pszTitle);
+}
+
+LoginPopup::~LoginPopup()
+{
+ RegisterPopup(hwnd, FALSE);
+
+ if (FALSE == IS_INTRESOURCE(alertMessage))
+ LoginBox_FreeString(alertMessage);
+}
+
+HWND LoginPopup::CreatePopup(LPCWSTR pszTemplate, HWND hParent, LPARAM param, Creator fnCreator)
+{
+ if (NULL == hParent || NULL == pszTemplate || NULL == fnCreator)
+ return NULL;
+
+ LOGINPOPUPCREATEPARAM createParam;
+ createParam.fnCreator = fnCreator;
+ createParam.lParam = param;
+
+ return WASABI_API_CREATEDIALOGPARAMW((INT)(INT_PTR)pszTemplate, hParent, LoginPopup_DialogProc, (LPARAM)&createParam);
+}
+
+BOOL LoginPopup::RegisterPopup(HWND hwnd, BOOL fRegister)
+{
+ if (NULL == hwnd || GetWindowThreadProcessId(hwnd, NULL) != GetCurrentThreadId())
+ return FALSE;
+
+ THREADPOPUPDATA *data = NULL;
+ if (TLS_OUT_OF_INDEXES == threadStorage)
+ {
+ if (NULL == WASABI_API_APP)
+ return FALSE;
+
+ threadStorage = WASABI_API_APP->AllocateThreadStorage();
+ if (TLS_OUT_OF_INDEXES == threadStorage)
+ return FALSE;
+ }
+ else
+ {
+ data = (THREADPOPUPDATA*)WASABI_API_APP->GetThreadStorage(threadStorage);
+ }
+
+ if (NULL == data)
+ {
+ data = new THREADPOPUPDATA();
+ if (NULL == data) return FALSE;
+ data->hHook = SetWindowsHookEx(WH_MSGFILTER, LoginPopup_MessageFilter, NULL, GetCurrentThreadId());
+ if (NULL == data->hHook)
+ {
+ delete data;
+ return FALSE;
+ }
+ WASABI_API_APP->SetThreadStorage(threadStorage, data);
+ }
+
+ size_t index = data->windowList.size();
+ while(index--)
+ {
+ if (hwnd == data->windowList[index])
+ {
+ if (FALSE == fRegister)
+ {
+ data->windowList.eraseAt(index);
+ if (0 == data->windowList.size())
+ {
+ if (NULL != data->hHook)
+ UnhookWindowsHookEx(data->hHook);
+ WASABI_API_APP->SetThreadStorage(threadStorage, NULL);
+ delete data;
+ }
+ }
+ return TRUE;
+ }
+ }
+
+ if (FALSE != fRegister)
+ {
+ data->windowList.push_back(hwnd);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+BOOL LoginPopup::EnumeratePopups(HWND hHost, Enumerator callback, LPARAM param)
+{
+ if (NULL == callback ||
+ NULL == hHost || GetWindowThreadProcessId(hHost, NULL) != GetCurrentThreadId())
+ return FALSE;
+
+ THREADPOPUPDATA *data = (TLS_OUT_OF_INDEXES != threadStorage && NULL != WASABI_API_APP) ?
+ (THREADPOPUPDATA *)WASABI_API_APP->GetThreadStorage(threadStorage) : NULL;
+ if (NULL == data)
+ return FALSE;
+
+ size_t index = data->windowList.size();
+ while(index--)
+ {
+ HWND hPopup = data->windowList[index];
+ if (IsChild(hHost, hPopup) && FALSE == callback(hPopup, param))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+BOOL LoginPopup::AnyPopup(HWND hHost)
+{
+ if (NULL == hHost || GetWindowThreadProcessId(hHost, NULL) != GetCurrentThreadId())
+ return FALSE;
+
+ THREADPOPUPDATA *data = (TLS_OUT_OF_INDEXES != threadStorage && NULL != WASABI_API_APP) ?
+ (THREADPOPUPDATA *)WASABI_API_APP->GetThreadStorage(threadStorage) : NULL;
+ if (NULL == data)
+ return FALSE;
+
+ size_t index = data->windowList.size();
+ while(index--)
+ {
+ if (IsChild(hHost, data->windowList[index]))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void LoginPopup::UpdateLayout(BOOL fRedraw)
+{
+ RECT rect;
+ GetClientRect(hwnd, &rect);
+
+ HWND hNotifier;
+ hNotifier = GetDlgItem(hwnd, IDC_NOTIFIER);
+ if (NULL != hNotifier)
+ {
+ INT height = LoginNotifier_GetIdealHeight(hNotifier);
+ SetWindowPos(hNotifier, NULL, rect.left, rect.top, rect.right - rect.left, height,
+ SWP_NOACTIVATE | SWP_NOZORDER);
+ }
+}
+
+void LoginPopup::Paint(HDC hdc, const RECT *prcPaint, BOOL fErase)
+{
+ if (FALSE != fErase)
+ {
+ RECT clientRect;
+ GetClientRect(hwnd, &clientRect);
+
+ COLORREF rgbOrig, rgbPart;
+ rgbOrig = GetBkColor(hdc);
+
+ if (buttonHeight > 0)
+ {
+ RECT buttonRect;
+ SetRect(&buttonRect,
+ clientRect.left, clientRect.bottom - (2* clientMargins.bottom + buttonHeight),
+ clientRect.right, clientRect.bottom);
+
+ clientRect.bottom = buttonRect.top;
+
+ buttonRect.top++;
+ rgbPart = GetSysColor(COLOR_3DFACE);
+ SetBkColor(hdc, rgbPart);
+ ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &buttonRect, NULL, 0, NULL);
+
+ buttonRect.bottom = buttonRect.top;
+ buttonRect.top--;
+
+ rgbPart = GetSysColor(COLOR_3DLIGHT);
+ SetBkColor(hdc, rgbPart);
+ ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &buttonRect, NULL, 0, NULL);
+ }
+
+ rgbPart = GetSysColor(COLOR_CLIENT);
+ SetBkColor(hdc, rgbPart);
+ ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &clientRect, NULL, 0, NULL);
+
+ SetBkColor(hdc, rgbOrig);
+ }
+}
+
+void LoginPopup::EndDialog(INT_PTR code)
+{
+ DestroyWindow(hwnd);
+}
+
+void LoginPopup::UpdateMargins()
+{
+ SetRect(&clientMargins, 8, 6, 8, 6);
+ MapDialogRect(hwnd, &clientMargins);
+
+ SetRect(&infoMargins, 6, 8, 6, 8);
+ MapDialogRect(hwnd, &infoMargins);
+
+ RECT rect;
+ SetRect(&rect, 4, 15, 0, 0);
+ MapDialogRect(hwnd, &rect);
+ buttonHeight = rect.top;
+ buttonSpace = rect.left;
+}
+
+void LoginPopup::SetTitle(UINT type, LPCWSTR title)
+{
+ popupType = type;
+
+
+ if (NULL == title || FALSE == IS_INTRESOURCE(title))
+ SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)title);
+ else
+ {
+ WCHAR szBuffer[256] = {0};
+ WASABI_API_LNGSTRINGW_BUF((INT)(INT_PTR)title, szBuffer, ARRAYSIZE(szBuffer));
+ SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)szBuffer);
+ }
+}
+
+void LoginPopup::UpdateTitle(BOOL playBeep)
+{
+ HWND hNotifier;
+ hNotifier = GetDlgItem(hwnd, IDC_NOTIFIER);
+ if (NULL == hNotifier) return;
+
+ WCHAR szBuffer[512] = {0};
+ LPCWSTR text;
+ UINT type;
+
+ if (-1 != alertType && NULL != alertMessage)
+ {
+ type = alertType;
+ text = (IS_INTRESOURCE(alertMessage)) ?
+ WASABI_API_LNGSTRINGW_BUF((INT)(INT_PTR)alertMessage, szBuffer, ARRAYSIZE(szBuffer)) :
+ alertMessage;
+ }
+ else
+ {
+ type = popupType;
+ SendMessage(hwnd, WM_GETTEXT, (WPARAM)ARRAYSIZE(szBuffer), (LPARAM)szBuffer);
+ text = szBuffer;
+ }
+
+ LoginNotifier_Notify(hNotifier, type, text);
+
+ UINT windowStyle = GetWindowStyle(hNotifier);
+ if (0 == (WS_VISIBLE & windowStyle))
+ {
+ ShowWindow(hNotifier, SW_SHOWNA);
+ }
+
+ if (FALSE != playBeep)
+ LoginNotifier_PlayBeep(hNotifier);
+}
+
+void LoginPopup::SetAlert(UINT type, LPCWSTR message)
+{
+ alertType = type;
+
+ if (FALSE == IS_INTRESOURCE(alertMessage))
+ LoginBox_FreeString(alertMessage);
+
+ if (NULL == message)
+ {
+ alertMessage = NULL;
+ return;
+ }
+
+ if (IS_INTRESOURCE(message))
+ alertMessage = (LPWSTR)message;
+ else
+ alertMessage = LoginBox_CopyString(message);
+}
+
+void LoginPopup::RemoveAlert()
+{
+ SetAlert(-1, NULL);
+}
+
+LRESULT LoginPopup::SendNotification(UINT code, NMHDR *pnmh)
+{
+ if (NULL == pnmh) return 0L;
+
+ HWND hParent = GetAncestor(hwnd, GA_PARENT);
+ if(NULL == hParent) return 0L;
+
+ pnmh->code = code;
+ pnmh->hwndFrom = hwnd;
+ pnmh->idFrom = (UINT_PTR)GetWindowLongPtr(hwnd, GWLP_ID);
+
+ return SendMessage(hParent, WM_NOTIFY, (WPARAM)pnmh->idFrom, (LPARAM)pnmh);
+}
+
+
+BOOL LoginPopup::GetInfoRect(RECT *rect)
+{
+ if (NULL == rect)
+ return FALSE;
+
+ LONG notifierHeight = 0;
+ HWND hNotifier = GetDlgItem(hwnd, IDC_NOTIFIER);
+ if (NULL != hNotifier && 0 != (WS_VISIBLE & GetWindowStyle(hNotifier)) &&
+ FALSE != GetWindowRect(hNotifier, rect))
+ {
+ notifierHeight = rect->bottom - rect->top;
+ if (notifierHeight < 0) notifierHeight = 0;
+ }
+
+ if (FALSE == GetClientRect(hwnd, rect))
+ return FALSE;
+
+ rect->left += (clientMargins.left + infoMargins.left);
+ rect->right -= (clientMargins.right + infoMargins.right);
+
+
+ if (0 != notifierHeight)
+ rect->top += (notifierHeight + infoMargins.top);
+ else
+ rect->top += (clientMargins.top + infoMargins.top);
+
+ if (buttonHeight > 0)
+ rect->bottom -= (2 * clientMargins.bottom + buttonHeight + infoMargins.bottom);
+ else
+ rect->bottom -= (clientMargins.bottom + infoMargins.bottom);
+
+ if (rect->right < rect->left) rect->right = rect->left;
+ if (rect->bottom < rect->top) rect->bottom = rect->top;
+
+ return TRUE;
+}
+
+BOOL LoginPopup::CalculateWindowRect(LONG infoWidth, LONG infoHeight, const INT *buttonList, UINT buttonCount, BOOL includeTitle, RECT *rect)
+{
+ if (NULL == rect)
+ return FALSE;
+
+ if (infoWidth < 110) infoWidth = 110;
+ if (infoHeight < 32) infoHeight = 32;
+
+ LONG minWidth = 0;
+
+ LONG notifierHeight = 0;
+
+ HWND hNotifier = GetDlgItem(hwnd, IDC_NOTIFIER);
+ if (NULL != hNotifier && 0 != (WS_VISIBLE & GetWindowStyle(hNotifier)) &&
+ FALSE != GetWindowRect(hNotifier, rect))
+ {
+ notifierHeight = rect->bottom - rect->top;
+ if (notifierHeight < 0) notifierHeight = 0;
+
+ if (FALSE != includeTitle)
+ {
+ SIZE size;
+ if (FALSE != LoginNotifier_GetIdealSize(hNotifier, &size))
+ minWidth = size.cx + clientMargins.right;
+ }
+ }
+
+ if (NULL != buttonList && buttonCount > 0 &&
+ ((HDWP)TRUE) == LayoutButtons(NULL, buttonList, buttonCount, FALSE, rect))
+ {
+ LONG buttonWidth = (rect->right - rect->left) + clientMargins.left + clientMargins.right;
+ if (buttonWidth > minWidth)
+ minWidth = buttonWidth;
+ }
+
+ rect->left = 0;
+ rect->top = 0;
+ rect->right = rect->left + infoWidth;
+ rect->bottom = rect->top + infoHeight;
+
+ rect->right += (clientMargins.left + infoMargins.left + clientMargins.right + infoMargins.right);
+ if ((rect->right - rect->left) < minWidth)
+ rect->right = rect->left + minWidth;
+
+ rect->bottom += (0 != notifierHeight) ?
+ (notifierHeight + infoMargins.top) : (clientMargins.top + infoMargins.top);
+
+ rect->bottom += (buttonHeight > 0) ?
+ (2 * clientMargins.bottom + buttonHeight + infoMargins.bottom) : (clientMargins.bottom + infoMargins.bottom);
+
+ return TRUE;
+
+}
+
+HDWP LoginPopup::LayoutButtons(HDWP hdwp, const INT *buttonList, UINT buttonCount, BOOL redraw, RECT *rectOut)
+{
+ RECT rect;
+ GetClientRect(hwnd, &rect);
+ rect.left += clientMargins.left;
+ rect.top += clientMargins.top;
+ rect.right -= clientMargins.right;
+ rect.bottom -= clientMargins.bottom;
+
+ return LoginBox_LayoutButtonBar(hdwp, hwnd, buttonList, buttonCount, &rect,
+ buttonHeight, buttonSpace, redraw, rectOut);
+}
+
+BOOL LoginPopup::GetTextSize(HWND hText, LONG width, SIZE *size)
+{
+ if (NULL == hText) return FALSE;
+
+ WCHAR szBuffer[4096] = {0};
+ INT cchLen = (INT)SendMessage(hText, WM_GETTEXT, ARRAYSIZE(szBuffer), (LPARAM)szBuffer);
+ if (0 == cchLen)
+ {
+ size->cx = 0;
+ size->cy = 0;
+ return TRUE;
+ }
+
+ HDC hdc = GetDCEx(hText, NULL, DCX_CACHE | DCX_WINDOW | DCX_NORESETATTRS);
+ if (NULL == hdc)
+ return FALSE;
+
+ HFONT font = (HFONT)SendMessage(hText, WM_GETFONT, 0, 0L);
+ HFONT fontOrig = (HFONT)SelectObject(hdc, font);
+
+ BOOL resultOk;
+ RECT rect;
+ SetRect(&rect, 0, 0, width, 0);
+ resultOk = DrawText(hdc, szBuffer, cchLen, &rect,
+ DT_CALCRECT | DT_EXTERNALLEADING | DT_LEFT | DT_NOPREFIX | DT_WORDBREAK);
+
+ if(FALSE != resultOk)
+ {
+ size->cx = (rect.right - rect.left);
+ size->cy = (rect.bottom - rect.top);
+ }
+
+ SelectObject(hdc, fontOrig);
+ ReleaseDC(hText, hdc);
+
+ return resultOk;
+}
+
+BOOL LoginPopup::OnInitDialog(HWND hFocus, LPARAM param)
+{
+ RegisterPopup(hwnd, TRUE);
+
+ RECT rect;
+ if (FALSE == GetWindowRect(hwnd, &rect))
+ SetRectEmpty(&rect);
+
+ idealSize.cx = rect.right - rect.left;
+ idealSize.cy = rect.bottom - rect.top;
+
+
+ HWND hNotifier = LoginNotifier_CreateWindow(0, WS_CHILD | WS_CLIPSIBLINGS, 0, 0, 0, 0, hwnd, IDC_NOTIFIER);
+ if (NULL != hNotifier)
+ {
+ HFONT hFont = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0L);
+ if (NULL != hFont)
+ SendMessage(hNotifier, WM_SETFONT, (WPARAM)hFont, 0L);
+
+#ifdef COLOR_TITLE
+ LoginNotifier_SetBkColor(hNotifier, GetSysColor(COLOR_TITLE));
+#endif //COLOR_TITLE
+
+#ifdef COLOR_TITLETEXT
+ LoginNotifier_SetTextColor(hNotifier, GetSysColor(COLOR_TITLETEXT));
+#endif //COLOR_TITLETEXT
+
+ UpdateTitle(FALSE);
+ }
+
+ UpdateMargins();
+ UpdateLayout(FALSE);
+
+ PostMessage(hwnd, WM_CHANGEUISTATE, MAKEWPARAM(UIS_INITIALIZE, UISF_HIDEACCEL | UISF_HIDEFOCUS), 0L);
+ return FALSE;
+}
+
+void LoginPopup::OnDestroy()
+{
+}
+
+void LoginPopup::OnWindowPosChanged(const WINDOWPOS *pwp)
+{
+ if (SWP_NOSIZE != ((SWP_NOSIZE | SWP_FRAMECHANGED) & pwp->flags))
+ UpdateLayout(0 == (SWP_NOREDRAW & pwp->flags));
+}
+
+void LoginPopup::OnCommand(UINT commandId, UINT eventType, HWND hControl)
+{
+ switch(commandId)
+ {
+ case IDOK:
+ case IDCANCEL:
+ EndDialog(commandId);
+ break;
+ }
+}
+
+LRESULT LoginPopup::OnNotify(UINT controlId, const NMHDR *pnmh)
+{
+ return FALSE;
+}
+
+void LoginPopup::OnPaint()
+{
+ PAINTSTRUCT ps;
+ if (BeginPaint(hwnd, &ps))
+ {
+ if (ps.rcPaint.left != ps.rcPaint.right)
+ Paint(ps.hdc, &ps.rcPaint, ps.fErase);
+ EndPaint(hwnd, &ps);
+ }
+}
+
+void LoginPopup::OnPrintClient(HDC hdc, UINT options)
+{
+ if (0 != (PRF_CLIENT & options))
+ {
+ RECT clientRect;
+ if (GetClientRect(hwnd, &clientRect))
+ Paint(hdc, &clientRect, TRUE);
+ }
+}
+
+HBRUSH LoginPopup::OnGetStaticColor(HDC hdc, HWND hControl)
+{
+ HBRUSH hb = (HBRUSH)GetSysColorBrush(COLOR_CLIENT);
+ SetTextColor(hdc, GetSysColor(COLOR_CLIENTTEXT));
+ SetBkColor(hdc, GetSysColor(COLOR_CLIENT));
+ return hb;
+}
+
+void LoginPopup::OnSetFont(HFONT font, BOOL redraw)
+{
+ DefDlgProc(hwnd, WM_SETFONT, (WPARAM)font, MAKELPARAM(redraw, 0));
+ UpdateMargins();
+}
+
+void LoginPopup::OnParentNotify(UINT eventId, UINT wParam, LPARAM lParam)
+{
+}
+
+BOOL LoginPopup::OnUpdateWindowPos(const RECT* clientRect, RECT *rectOut)
+{
+ if (NULL == clientRect || NULL == rectOut)
+ return FALSE;
+
+ LONG width = idealSize.cx;
+ LONG height = idealSize.cy;
+ rectOut->left = clientRect->left + ((clientRect->right - clientRect->left) - width)/2;
+ rectOut->top = clientRect->top+ ((clientRect->bottom - clientRect->top) - height)/2;
+ rectOut->right = rectOut->left + width;
+ rectOut->bottom = rectOut->top + height;
+
+ return TRUE;
+}
+
+void LoginPopup::OnPlayBeep()
+{
+ LoginBox_MessageBeep(MB_ICONASTERISK);
+}
+
+INT_PTR LoginPopup::DialogProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_INITDIALOG: return OnInitDialog((HWND)wParam, lParam);
+ case WM_DESTROY: OnDestroy(); return TRUE;
+ case WM_NOTIFY: MSGRESULT(hwnd, OnNotify((INT)wParam, (NMHDR*)lParam));
+ case WM_COMMAND: OnCommand(LOWORD(wParam), HIWORD(wParam), (HWND)lParam); return TRUE;
+ case WM_WINDOWPOSCHANGED: OnWindowPosChanged((WINDOWPOS*)lParam); return TRUE;
+ case WM_SIZE: return TRUE;
+ case WM_SETFONT: OnSetFont((HFONT)wParam, (BOOL)LOWORD(lParam)); return TRUE;
+ case WM_ERASEBKGND: MSGRESULT(hwnd, 0);
+ case WM_PAINT: OnPaint(); return TRUE;
+ case WM_PRINTCLIENT: OnPrintClient((HDC)wParam, (UINT)lParam); return TRUE;
+ case WM_CTLCOLORSTATIC: return (INT_PTR)OnGetStaticColor((HDC)wParam, (HWND)lParam);
+ case WM_PARENTNOTIFY: OnParentNotify(LOWORD(wParam), HIWORD(wParam), lParam); return TRUE;
+
+ case NLPOPUP_UPDATEWNDPOS: MSGRESULT(hwnd, OnUpdateWindowPos((const RECT*)wParam, (RECT*)lParam));
+ case NLPOPUP_PLAYBEEP: OnPlayBeep(); return TRUE;
+ }
+ return FALSE;
+}
+
+static INT_PTR CALLBACK LoginPopup_DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ static ATOM LOGINPOPUP_PROP = 0;
+ LoginPopup *popup = (LoginPopup*)GetProp(hwnd, MAKEINTATOM(LOGINPOPUP_PROP));
+
+ if (NULL == popup)
+ {
+ switch(uMsg)
+ {
+ case WM_INITDIALOG:
+ if (0 == LOGINPOPUP_PROP)
+ {
+ LOGINPOPUP_PROP = GlobalAddAtomW(L"NullsoftLoginPopupProp");
+ if (0 == LOGINPOPUP_PROP)
+ return 0;
+ }
+
+ if (NULL != lParam)
+ {
+ LOGINPOPUPCREATEPARAM *create = (LOGINPOPUPCREATEPARAM*)lParam;
+ lParam = create->lParam;
+ if (SUCCEEDED(create->fnCreator(hwnd, lParam, &popup)))
+ {
+ if (FALSE == SetProp(hwnd, MAKEINTATOM(LOGINPOPUP_PROP), (HANDLE)popup))
+ {
+ delete(popup);
+ popup = NULL;
+ }
+ }
+ }
+
+ if (NULL != popup)
+ return popup->DialogProc(uMsg, wParam, lParam);
+
+ break;
+ }
+ return 0;
+ }
+
+ INT_PTR result = popup->DialogProc(uMsg, wParam, lParam);
+
+ if (WM_NCDESTROY == uMsg)
+ {
+ RemoveProp(hwnd, MAKEINTATOM(LOGINPOPUP_PROP));
+ delete(popup);
+ }
+
+ return result;
+}
+
+static LRESULT CALLBACK LoginPopup_MessageFilter(INT code, WPARAM wParam, LPARAM lParam)
+{
+ THREADPOPUPDATA *data = (NULL != WASABI_API_APP && TLS_OUT_OF_INDEXES != threadStorage) ?
+ (THREADPOPUPDATA*)WASABI_API_APP->GetThreadStorage(threadStorage) : NULL;
+ if (NULL == data)
+ return 0;
+
+ if (code >= 0)
+ {
+ MSG *pMsg = (MSG*)lParam;
+ if (pMsg->message >= WM_KEYFIRST && pMsg->message <= WM_KEYLAST)
+ {
+ if (L'C' == pMsg->wParam && 0 == (0x40000000 & pMsg->lParam) &&
+ 0 != (0x8000 & GetAsyncKeyState(VK_MENU)))
+ {
+ pMsg->wParam = VK_ESCAPE;
+ }
+
+ if ((VK_ESCAPE == pMsg->wParam || VK_RETURN == pMsg->wParam) &&
+ 0 == (0x40000000 & pMsg->lParam))
+ {
+ size_t index = data->windowList.size();
+ while(index--)
+ {
+ HWND hPopup = data->windowList[index];
+ if (IsChild(hPopup, pMsg->hwnd))
+ {
+ INT commandId;
+ switch(pMsg->wParam)
+ {
+ case VK_ESCAPE:
+ commandId = IDCANCEL;
+ break;
+ case VK_RETURN:
+ if (0 != (DLGC_BUTTON & SendMessage(pMsg->hwnd, WM_GETDLGCODE, 0, 0L)) &&
+ IsWindowVisible(pMsg->hwnd) && IsWindowEnabled(pMsg->hwnd))
+ {
+ commandId = (INT)(INT_PTR)GetWindowLongPtr(pMsg->hwnd, GWLP_ID);
+ }
+ else
+ {
+ commandId = (INT)(INT_PTR)SendMessage(hPopup, DM_GETDEFID, 0, 0L);
+ if (DC_HASDEFID != HIWORD(commandId))
+ commandId = IDOK;
+ }
+ break;
+ }
+ SendMessage(hPopup, WM_COMMAND, MAKEWPARAM(commandId, 0), (LPARAM)pMsg->hwnd);
+ return 1;
+ }
+ }
+ }
+
+ // add mnemonic support here (http://msdn.microsoft.com/en-us/library/ms644995%28VS.85%29.aspx)
+ //HWND hPopup;
+ //size_t index = data->windowList.size();
+ //while(index--)
+ //{
+ // hPopup = data->windowList[index];
+ // if (pMsg->hwnd == hPopup || IsChild(hPopup, pMsg->hwnd))
+ // {
+ //
+ // }
+ //}
+ }
+ }
+ return CallNextHookEx(data->hHook, code, wParam, lParam);
+} \ No newline at end of file