733 lines
18 KiB
C++
733 lines
18 KiB
C++
#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);
|
|
} |