| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544 |
- #include "./loginCurtain.h"
- #include "./loginPopup.h"
- #include "./common.h"
- #include "./graphics.h"
- #include "./imageLoader.h"
- #include "../resource.h"
- #include "../api.h"
- #define NWC_LOGINCURTAIN L"NullsoftLoginCurtain"
- typedef struct __LOGINCURTAINCREATEPARAM
- {
- HWND owner;
- } LOGINCURTAINCREATEPARAM;
- #define NLPF_IMAGEINVALID 0x00000001
- typedef struct __LOGINCURTAIN
- {
- HWND owner;
- HBITMAP bkImage;
- UINT flags;
- UINT childCount;
- } LOGINCURTAIN;
- typedef struct __DRAWBORDERPARAM
- {
- HWND hParent;
- RECT rect;
- HDC hdc;
- HDC hdcSrc;
- HBITMAP bitmapFrame;
- HBITMAP bitmapOrig;
- BLENDFUNCTION blendFunc;
- } DRAWBORDERPARAM;
- typedef struct __UPDATEPOSPARAM
- {
- HWND hParent;
- RECT clientRect;
- RECT childRect;
- HDWP hdwp;
- UINT childCount;
- } UPDATEPOSPARAM;
- typedef struct __EXCLUDERGNPARAM
- {
- HWND hParent;
- HRGN exclude;
- HRGN tmp;
- RECT rect;
- } EXCLUDERGNPARAM;
- #define BACKGROUND_ALPHA 200
- #define GetCurtain(__hwnd) ((LOGINCURTAIN*)(LONG_PTR)(LONGX86)GetWindowLongPtr((__hwnd), 0))
- static LRESULT WINAPI LoginCurtain_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
- static BOOL LoginCurtain_RegisterClass(HINSTANCE hInstance)
- {
- WNDCLASSW wc;
- if (FALSE != GetClassInfo(hInstance, NWC_LOGINCURTAIN, &wc))
- return TRUE;
-
- ZeroMemory(&wc, sizeof(wc));
- wc.lpszClassName = NWC_LOGINCURTAIN;
- wc.lpfnWndProc = LoginCurtain_WindowProc;
- wc.style = CS_PARENTDC;
- wc.cbWndExtra = sizeof(LOGINCURTAIN*);
- wc.hInstance = hInstance;
- wc.hCursor = LoadCursor(NULL, IDC_ARROW);
-
- return ( 0 != RegisterClassW(&wc));
- }
- HWND LoginCurtain_CreateWindow(HWND hParent, HWND hOwner)
- {
- if (FALSE == LoginCurtain_RegisterClass(WASABI_API_ORIG_HINST))
- return NULL;
- RECT rect;
- if (FALSE == GetClientRect(hOwner, &rect))
- SetRectEmpty(&rect);
- else
- MapWindowPoints(hOwner, hParent, (POINT*)&rect, 2);
- LOGINCURTAINCREATEPARAM createParam;
- createParam.owner = hOwner;
-
- return CreateWindowEx(WS_EX_CONTROLPARENT, NWC_LOGINCURTAIN, NULL,
- WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | DS_CONTROL,
- rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
- hParent, NULL, WASABI_API_ORIG_HINST, &createParam);
-
- }
- static BOOL CALLBACK LoginCurtain_ExcludeChildRgnCallback(HWND hwnd, LPARAM lParam)
- {
- EXCLUDERGNPARAM *param = (EXCLUDERGNPARAM*)lParam;
- if (NULL == param) return FALSE;
- RECT *r = ¶m->rect;
- if (0 == (WS_VISIBLE & GetWindowStyle(hwnd)) ||
- param->hParent != (HWND)(LONG_PTR)GetWindowLongPtr(hwnd, GWLP_HWNDPARENT) ||
- FALSE == GetWindowRect(hwnd, r))
- return TRUE;
- MapWindowPoints(HWND_DESKTOP, param->hParent, (POINT*)r, 2);
- if (NULL == param->tmp)
- {
- param->tmp = CreateRectRgn(0, 0, 0, 0);
- if (NULL == param->tmp) return FALSE;
- }
- if (NULL == param->exclude)
- {
- param->exclude = CreateRectRgn(0, 0, 0, 0);
- if (NULL == param->exclude) return FALSE;
- }
- INT regionType = GetWindowRgn(hwnd, param->tmp);
- switch(regionType)
- {
- case NULLREGION:
- SetRectRgn(param->tmp, r->left, r->top, r->right, r->bottom);
- CombineRgn(param->exclude, param->exclude, param->tmp, RGN_OR);
- break;
- case SIMPLEREGION:
- case COMPLEXREGION:
- OffsetRgn(param->tmp, r->left, r->top);
- CombineRgn(param->exclude, param->exclude, param->tmp, RGN_OR);
- break;
- }
- return TRUE;
- }
- static void LoginCurtain_ExcludeChildren(HWND hwnd, HDC hdc)
- {
- EXCLUDERGNPARAM param;
- param.hParent = hwnd;
- param.exclude = NULL;
- param.tmp = NULL;
- EnumChildWindows(hwnd, LoginCurtain_ExcludeChildRgnCallback, (LPARAM)¶m);
- if (NULL != param.exclude)
- {
- ExtSelectClipRgn(hdc, param.exclude, RGN_DIFF);
- DeleteObject(param.exclude);
- }
- if (NULL != param.tmp)
- DeleteObject(param.tmp);
- }
- static BOOL CALLBACK LoginCurtain_DrawWindowBorderCallback(HWND hwnd, LPARAM lParam)
- {
- DRAWBORDERPARAM *param = (DRAWBORDERPARAM*)lParam;
- if (NULL == param) return FALSE;
- RECT *r = ¶m->rect;
- if (0 == (WS_VISIBLE & GetWindowStyle(hwnd)) ||
- param->hParent != (HWND)(LONG_PTR)GetWindowLongPtr(hwnd, GWLP_HWNDPARENT) ||
- FALSE == GetWindowRect(hwnd, r))
- return TRUE;
- MapWindowPoints(HWND_DESKTOP, param->hParent, (POINT*)r, 2);
- if (NULL == param->bitmapFrame)
- {
- INT frameHeight, frameWidth;
- param->bitmapFrame = ImageLoader_LoadBitmap(WASABI_API_ORIG_HINST, MAKEINTRESOURCE(IDR_POPUPBORDER_IMAGE),
- TRUE, &frameWidth, &frameHeight);
- if (NULL == param->bitmapFrame)
- return FALSE;
- param->hdcSrc = CreateCompatibleDC(param->hdc);
- if (NULL == param->hdcSrc) return FALSE;
- param->bitmapOrig = (HBITMAP)SelectObject(param->hdcSrc, param->bitmapFrame);
- param->blendFunc.AlphaFormat = AC_SRC_ALPHA;
- param->blendFunc.BlendFlags = 0;
- param->blendFunc.BlendOp = AC_SRC_OVER;
- param->blendFunc.SourceConstantAlpha = 255;
- }
-
- r->left -= 14;
- r->top -= 13;
- r->right += 17;
- r->bottom += 19;
- GdiAlphaBlend(param->hdc, r->left, r->top, 26, 26, param->hdcSrc, 0, 0, 26, 26, param->blendFunc);
- GdiAlphaBlend(param->hdc, r->right - 28, r->top, 28, 26, param->hdcSrc, 27, 0, 28, 26, param->blendFunc);
- GdiAlphaBlend(param->hdc, r->left, r->bottom - 31, 26, 31, param->hdcSrc, 0, 27, 26, 31, param->blendFunc);
- GdiAlphaBlend(param->hdc, r->right - 28, r->bottom - 31, 28, 31, param->hdcSrc, 27, 27, 28, 31, param->blendFunc);
- LONG l = (r->right - r->left - (26 + 28));
- GdiAlphaBlend(param->hdc, r->left + 26, r->top, l, 26, param->hdcSrc, 25, 0, 1, 26, param->blendFunc);
- GdiAlphaBlend(param->hdc, r->left + 26, r->bottom - 31, l, 31, param->hdcSrc, 25, 27, 1, 31, param->blendFunc);
- l = (r->bottom - r->top - (26 + 31));
- GdiAlphaBlend(param->hdc, r->left, r->top + 26, 26, l, param->hdcSrc, 0, 28, 26, 1, param->blendFunc);
- GdiAlphaBlend(param->hdc, r->right - 28, r->top + 26, 28, l, param->hdcSrc, 27, 28, 28, 1, param->blendFunc);
- return TRUE;
- }
- static void LoginCurtain_DrawChildBorders(HWND hwnd, HDC hdc)
- {
- DRAWBORDERPARAM param;
- ZeroMemory(¶m, sizeof(param));
- param.hdc = hdc;
- param.hParent = hwnd;
- EnumChildWindows(hwnd, LoginCurtain_DrawWindowBorderCallback, (LPARAM)¶m);
- if (NULL != param.hdcSrc)
- {
- SelectObject(param.hdcSrc, param.bitmapOrig);
- DeleteDC(param.hdcSrc);
- }
- if (NULL != param.bitmapFrame)
- DeleteObject(param.bitmapFrame);
- }
- static HBITMAP LoginCurtain_CreateBkImage(HWND hwnd, HDC hdc, HBITMAP hBitmap, HWND hOwner)
- {
- RECT rect;
- if (FALSE == GetClientRect(hwnd, &rect))
- return NULL;
- LONG width = rect.right - rect.left;
- LONG height = rect.bottom - rect.top;
- BITMAP bi;
-
- if (NULL == hBitmap ||
- sizeof(BITMAP) != GetObject(hBitmap, sizeof(BITMAP), &bi) ||
- bi.bmWidth < width || bi.bmHeight < height)
- {
- if (NULL != hBitmap)
- DeleteObject(hBitmap);
- BITMAPINFOHEADER header;
- ZeroMemory(&header, sizeof(BITMAPINFOHEADER));
- header.biSize = sizeof(BITMAPINFOHEADER);
- header.biCompression = BI_RGB;
- header.biBitCount = 32;
- header.biPlanes = 1;
- header.biWidth = (width + 32);
- header.biHeight = -(height + 32);
-
- bi.bmBitsPixel = header.biBitCount;
- bi.bmWidth = header.biWidth;
- bi.bmHeight = header.biHeight;
- bi.bmPlanes = header.biPlanes;
- hBitmap = CreateDIBSection(NULL, (LPBITMAPINFO)&header, DIB_RGB_COLORS, (void**)&bi.bmBits, NULL, 0);
- if (NULL == hBitmap) return NULL;
- }
- else
- {
- bi.bmHeight = -bi.bmHeight;
- }
- HBRUSH bkBrush = (HBRUSH)SendMessage(hOwner, WM_CTLCOLORDLG, (WPARAM)hdc, (LPARAM)hwnd);
-
- HBITMAP hbo = (HBITMAP)SelectObject(hdc, hBitmap);
- if (NULL == hOwner)
- {
- if (NULL != bkBrush)
- FillRect(hdc, &rect, bkBrush);
- else
- ExtTextOut(hdc, 0, 0, OPAQUE, &rect, NULL, 0, NULL);
- }
- else
- {
- if (FALSE == LoginBox_PrintWindow(hOwner, hdc, 0))
- SendMessage(hOwner, WM_PRINT, (WPARAM)hdc, (LPARAM) (PRF_NONCLIENT | PRF_CLIENT | PRF_CHILDREN | PRF_ERASEBKGND));
- COLORREF rgbBlend = GetDCBrushColor(hdc);
- if (CLR_INVALID == rgbBlend)
- rgbBlend = GetBkColor(hdc);
- rgbBlend |= (BACKGROUND_ALPHA << 24);
- Image_ColorOverEx((BYTE*)bi.bmBits, bi.bmWidth, bi.bmHeight, 0, 0, width, height, bi.bmBitsPixel, FALSE, rgbBlend);
- }
- LoginCurtain_DrawChildBorders(hwnd, hdc);
-
- SelectObject(hdc, hbo);
- return hBitmap;
- }
- static void LoginCurtain_EraseBkGround(HWND hwnd, HDC hdc, const RECT *prcPaint)
- {
- LOGINCURTAIN *curtain = GetCurtain(hwnd);
- if (NULL == curtain) return;
-
- HDC hdcSrc = CreateCompatibleDC(hdc);
- if (NULL == hdcSrc) return;
-
- if (NULL == curtain->bkImage || 0 != (NLPF_IMAGEINVALID & curtain->flags))
- {
- HRGN clipRegion = CreateRectRgn(0,0,0,0);
- if (NULL != clipRegion)
- {
- INT regionType = GetClipRgn(hdc, clipRegion);
- if (1 == regionType)
- SelectClipRgn(hdcSrc, clipRegion);
- DeleteObject(clipRegion);
- }
- curtain->bkImage = LoginCurtain_CreateBkImage(hwnd, hdcSrc, curtain->bkImage, curtain->owner);
- curtain->flags &= ~NLPF_IMAGEINVALID;
- }
- if (NULL != curtain->bkImage)
- {
- HBITMAP hbmpOld = (HBITMAP)SelectObject(hdcSrc, curtain->bkImage);
- BitBlt(hdc, prcPaint->left, prcPaint->top,
- prcPaint->right - prcPaint->left, prcPaint->bottom - prcPaint->top,
- hdcSrc, prcPaint->left, prcPaint->top, SRCCOPY);
- SelectObject(hdcSrc, hbmpOld);
- }
- DeleteDC(hdcSrc);
- }
- static void LoginCurtain_Paint(HWND hwnd, HDC hdc, const RECT *prcPaint, BOOL fErase)
- {
- if (FALSE != fErase)
- {
- LoginCurtain_ExcludeChildren(hwnd, hdc);
- LoginCurtain_EraseBkGround(hwnd, hdc, prcPaint);
- }
- }
- static BOOL CALLBACK LoginCurtain_UpdateChildPosCallback(HWND hwnd, LPARAM lParam)
- {
- UPDATEPOSPARAM *param = (UPDATEPOSPARAM*)lParam;
- if (NULL == param) return FALSE;
- if (param->hParent != (HWND)(LONG_PTR)GetWindowLongPtr(hwnd, GWLP_HWNDPARENT))
- return TRUE;
- if (NULL == param->hdwp)
- {
- param->hdwp = BeginDeferWindowPos(param->childCount);
- param->childCount = 0;
-
- if (NULL == param->hdwp) return FALSE;
- }
- LONG prevWidth(0), prevHeight(0);
- if (FALSE != GetWindowRect(hwnd, ¶m->childRect))
- {
- prevWidth = param->childRect.right - param->childRect.left;
- prevHeight = param->childRect.bottom - param->childRect.top;
- }
-
- if (FALSE != LoginPopup_UpdateWindowPos(hwnd, ¶m->clientRect, ¶m->childRect))
- {
- param->hdwp = DeferWindowPos(param->hdwp, hwnd, NULL, param->childRect.left, param->childRect.top,
- param->childRect.right - param->childRect.left, param->childRect.bottom - param->childRect.top,
- SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW);
- if (NULL == param->hdwp) return FALSE;
-
- LONG width = param->childRect.right - param->childRect.left;
- LONG height = param->childRect.bottom - param->childRect.top;
- if (width != prevWidth || height != prevHeight)
- {
- HRGN clipRgn = CreateRoundRectRgn(0, 0, width, height, 9, 9);
- SetWindowRgn(hwnd, clipRgn, FALSE);
- }
- }
- param->childCount++;
- return TRUE;
- }
- static void LoginCurtain_UpdateLayout(HWND hwnd, BOOL fRedraw)
- {
- LOGINCURTAIN *curtain = GetCurtain(hwnd);
- if (NULL == curtain) return;
- curtain->flags |= NLPF_IMAGEINVALID;
- RECT clientRect;
- GetClientRect(hwnd, &clientRect);
- UPDATEPOSPARAM param;
- param.hParent = hwnd;
- param.hdwp = 0;
- param.childCount = curtain->childCount;
- CopyRect(¶m.clientRect, &clientRect);
- param.clientRect.left += 15;
- param.clientRect.top += 14;
- param.clientRect.right -= 18;
- param.clientRect.bottom -= 20;
- EnumChildWindows(hwnd, LoginCurtain_UpdateChildPosCallback, (LPARAM)¶m);
- curtain->childCount = param.childCount;
- if (NULL != param.hdwp)
- EndDeferWindowPos(param.hdwp);
- if (FALSE != fRedraw)
- {
- RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_ERASENOW | RDW_ALLCHILDREN);
- }
- }
- static LRESULT LoginCurtain_OnCreate(HWND hwnd, CREATESTRUCT* pcs)
- {
- LOGINCURTAIN *curtain = (LOGINCURTAIN*)calloc(1, sizeof(LOGINCURTAIN));
- if (NULL != curtain)
- {
- SetLastError(ERROR_SUCCESS);
- if (!SetWindowLongPtr(hwnd, 0, (LONGX86)(LONG_PTR)curtain) && ERROR_SUCCESS != GetLastError())
- {
- free(curtain);
- curtain = NULL;
- }
- }
- if (NULL == curtain)
- return -1;
- LOGINCURTAINCREATEPARAM *createParam = (LOGINCURTAINCREATEPARAM*)pcs->lpCreateParams;
- if (NULL != createParam)
- {
- curtain->owner = createParam->owner;
- }
- SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED | SWP_NOREDRAW);
- return 0;
- }
- static void LoginCurtain_OnDestroy(HWND hwnd)
- {
- LOGINCURTAIN *curtain = GetCurtain(hwnd);
- SetWindowLongPtr(hwnd, 0, 0L);
- if (NULL == curtain) return;
- if (NULL != curtain->bkImage)
- DeleteObject(curtain->bkImage);
- free(curtain);
- }
- static void LoginCurtain_OnWindowPosChanged(HWND hwnd, WINDOWPOS *pwp)
- {
- if (SWP_NOSIZE == ((SWP_NOSIZE | SWP_FRAMECHANGED) & pwp->flags))
- return;
- LoginCurtain_UpdateLayout(hwnd, 0 == (SWP_NOREDRAW & pwp->flags));
- }
- static void LoginCurtain_OnPaint(HWND hwnd)
- {
- PAINTSTRUCT ps;
- if (BeginPaint(hwnd, &ps))
- {
- if (ps.rcPaint.left != ps.rcPaint.right)
- LoginCurtain_Paint(hwnd, ps.hdc, &ps.rcPaint, ps.fErase);
- EndPaint(hwnd, &ps);
- }
- }
- static void LoginCurtain_OnPrintClient(HWND hwnd, HDC hdc, UINT options)
- {
- RECT clientRect;
- if (GetClientRect(hwnd, &clientRect))
- LoginCurtain_Paint(hwnd, hdc, &clientRect, 0 != (PRF_ERASEBKGND & options));
- }
- static void LoginCurtain_OnParentNotify(HWND hwnd, INT eventId, INT childId, LPARAM eventParam)
- {
- switch(eventId)
- {
- case WM_CREATE:
- {
- HWND hChild = (HWND)eventParam;
- RECT rect;
- GetWindowRect(hChild, &rect);
- HRGN clipRgn = CreateRoundRectRgn(0, 0, rect.right - rect.left, rect.bottom - rect.top, 9, 9);
- SetWindowRgn(hChild, clipRgn, FALSE);
- }
- SetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED );
- break;
- case WM_DESTROY:
- {
- HWND hChild = (HWND)eventParam;
- SetWindowLongPtr(hChild, GWLP_ID, 0);
- }
- SetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED);
- break;
- }
- }
- static LRESULT LoginCurtain_OnNotify(HWND hwnd, INT controlId, NMHDR *pnmh)
- {
- HWND hAncestor = GetAncestor(hwnd, GA_PARENT);
- if (NULL != hAncestor)
- return SendMessage(hAncestor, WM_NOTIFY, (WPARAM)controlId, (LPARAM)pnmh);
- return 0;
- }
- static LRESULT WINAPI LoginCurtain_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- switch(uMsg)
- {
- case WM_CREATE: return LoginCurtain_OnCreate(hwnd, (CREATESTRUCT*)lParam);
- case WM_DESTROY: LoginCurtain_OnDestroy(hwnd); return 0;
- case WM_ERASEBKGND: return 0;
- case WM_PAINT: LoginCurtain_OnPaint(hwnd); return 0;
- case WM_PRINTCLIENT: LoginCurtain_OnPrintClient(hwnd, (HDC)wParam, (UINT)lParam); return 0;
- case WM_WINDOWPOSCHANGED: LoginCurtain_OnWindowPosChanged(hwnd, (WINDOWPOS*)lParam); return 0;
- case WM_SIZE: return 0;
- case WM_PARENTNOTIFY: LoginCurtain_OnParentNotify(hwnd, LOWORD(wParam), HIWORD(wParam), lParam); return 0;
- case WM_NOTIFY: return LoginCurtain_OnNotify(hwnd, (INT)wParam, (NMHDR*)lParam);
- }
- return DefWindowProc(hwnd, uMsg, wParam, lParam);
- }
|