12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538 |
- #include "api__gen_ml.h"
- #include "main.h"
- #include "./skinnedmenuwnd.h"
- #include "./skinnedmenu.h"
- #include "./skinning.h"
- #include "./ml_imagelist.h"
- #include "./colors.h"
- #include "./resource.h"
- #include "../winamp/wa_dlg.h"
- #define MENU_BORDER_WIDTH 3
- static HMLIMGLST hmlilCheck = NULL;
- static INT imageCheckMark = -1;
- static INT imageRadioMark = -1;
- static INT imageExpandArrow = -1;
- // menu hit test codes
- #define MHF_NOWHERE 0xFFFFFFFF
- #define MHF_SCROLLUP 0xFFFFFFFD
- #define MHF_SCROLLDOWN 0xFFFFFFFC
- #define MN_SIZEWINDOW 0x01E2
- #define MN_SELECTITEM 0x01E5 // wParam - item position or MHF_XXX
- #define MN_LBUTTONDOWN 0x01ED // wParam - item position or MHF_XXX
- #define MN_LBUTTONUP 0x01EF // wParam - item position or MHF_XXX
- #define MN_LBUTTONDBLCLK 0x01F1 // ?
- // menu timer id
- #define MTID_OPENSUBMENU 0x0000FFFE
- #define MTID_SCROLLUP 0xFFFFFFFD
- #define MTID_SCROLLDOWN 0xFFFFFFFC
- #define MTID_EX_UNBLOCKDRAW 0x0001980
- extern HMLIMGFLTRMNGR hmlifMngr; // default gen_ml fitler manager
- #define SMIF_BLOCKDRAW 0x00000001
- #define SMIF_REMOVEREFLECTOR 0x00000002
- static HBRUSH SkinnedMenuWnd_GetBackBrush(HMENU hMenu)
- {
- MENUINFO mi = {0};
- mi.cbSize = sizeof(MENUINFO);
- mi.fMask = MIM_BACKGROUND;
- if (NULL == hMenu || !GetMenuInfo(hMenu, &mi))
- mi.hbrBack = NULL;
- return (NULL != mi.hbrBack) ? mi.hbrBack : GetSysColorBrush(COLOR_MENU);
- }
- static INT SkinnedMenuWnd_AddPngResource(HMLIMGLST imageList, INT resourceId)
- {
- MLIMAGESOURCE_I src;
- ZeroMemory(&src, sizeof(MLIMAGESOURCE_I));
- src.type = SRC_TYPE_PNG_I;
- src.hInst = plugin.hDllInstance;
- src.lpszName = MAKEINTRESOURCEW(resourceId);
- return MLImageListI_Add(hmlilCheck, &src, MLIF_FILTER1_UID, 0);
- }
- static HBITMAP SkinnedMenuWnd_LoadPngResource(INT resourceId, COLORREF rgbBk, COLORREF rgbFg)
- {
- MLIMAGESOURCE_I imageSource;
- ZeroMemory(&imageSource, sizeof(MLIMAGESOURCE_I));
- imageSource.type = SRC_TYPE_PNG_I;
- imageSource.hInst = plugin.hDllInstance;
- imageSource.lpszName = MAKEINTRESOURCEW(resourceId);
- HBITMAP hbmp = MLImageLoaderI_LoadDib(&imageSource);
- if (NULL != hbmp)
- MLImageFilterI_Apply(hmlifMngr, &MLIF_FILTER1_UID, hbmp, rgbBk, rgbFg, NULL);
- return hbmp;
- }
- SkinnedMenuWnd::SkinnedMenuWnd(UINT menuExStyle, HMLIMGLST hmlil, INT forcedWidth, MENUCUSTOMIZEPROC _customProc, ULONG_PTR customParam) :
- SkinnedWnd(FALSE)
- {
- if (FAILED(SkinnedMenuThreadInfo::GetInstance(TRUE, &threadInfo)))
- threadInfo = NULL;
- hMenu = NULL;
- hOwner = NULL;
- this->menuExStyle = menuExStyle;
- this->hmlil = hmlil;
- this->lineWidth = forcedWidth;
- bRestoreShadow = FALSE;
- hBoldFont = NULL;
- menuFlags = 0;
- backBrush = NULL;
- borderPen = NULL;
- menuOrigBrush = NULL;
- skinnedItems = NULL;
- skinnedItemCount = 0;
- skinnedItemCursor = 0;
- prevSelectedItem = 0;
- shortcutCX = 0;
- textCX = 0;
- scrollBitmap = NULL;
- disabledScrollBitmap = NULL;
- this->customProc = _customProc;
- this->customParam = customParam;
- }
- SkinnedMenuWnd::~SkinnedMenuWnd(void)
- {
- SetOwnerWindow(NULL);
- if (hMenu)
- {
- MENUINFO mi = {0};
- mi.cbSize = sizeof(MENUINFO);
- mi.fMask = MIM_BACKGROUND;
- if (GetMenuInfo(hMenu, &mi))
- {
- mi.fMask = 0;
- if (menuOrigBrush != mi.hbrBack)
- {
- mi.hbrBack = menuOrigBrush;
- mi.fMask |= MIM_BACKGROUND;
- }
- if (0 != mi.fMask)
- SetMenuInfo(hMenu, &mi);
- }
- if (NULL != skinnedItems && skinnedItemCount > 0)
- {
- MENUITEMINFOW mii = {0};
- mii.cbSize = sizeof(MENUITEMINFOW);
- for (INT i = 0; i < skinnedItemCount; i++)
- {
- SkinnedItemRecord *record = &skinnedItems[i];
- if(FALSE == record->failed)
- {
- mii.fMask = MIIM_FTYPE | MIIM_ID | MIIM_BITMAP;
- if (FALSE != GetMenuItemInfoW(hMenu, i, TRUE, &mii))
- {
- mii.fMask = 0;
- if (FALSE != record->skinned)
- {
- mii.fMask |= (MIIM_FTYPE | MIIM_BITMAP);
- mii.fType &= ~MFT_OWNERDRAW;
- record->skinned = FALSE;
- }
- if (record->itemId != record->originalId &&
- record->itemId == mii.wID)
- {
- mii.fMask |= MIIM_ID;
- mii.wID = record->originalId;
- }
- if (NULL != threadInfo)
- {
- threadInfo->ReleaseId(record->itemId);
- if (record->itemId != record->originalId)
- threadInfo->ReleaseId(record->originalId);
- }
- if (0 != mii.fMask)
- {
- if (FALSE == SetMenuItemInfoW(hMenu, i, TRUE, &mii))
- {
- }
- }
- }
- }
- }
- }
- if (NULL != threadInfo)
- threadInfo->UnregisterMenu(hMenu);
- }
- if (NULL != skinnedItems)
- free(skinnedItems);
- if (hwnd && bRestoreShadow)
- {
- SetClassLongPtrW(hwnd, GCL_STYLE, GetClassLongPtrW(hwnd, GCL_STYLE) | 0x00020000/*CS_DROPSHADOW*/);
- }
- if (NULL != hBoldFont)
- DeleteObject(hBoldFont);
- if (NULL != backBrush)
- DeleteObject(backBrush);
- if (NULL != borderPen)
- DeleteObject(borderPen);
- if (NULL != scrollBitmap)
- DeleteObject(scrollBitmap);
- if (NULL != disabledScrollBitmap)
- DeleteObject(disabledScrollBitmap);
- if (NULL != threadInfo)
- {
- threadInfo->RemoveValidationHook(this);
- threadInfo->Release();
- }
- }
- HMENU SkinnedMenuWnd::GetMenuHandle()
- {
- return hMenu;
- }
- HWND SkinnedMenuWnd::GetOwnerWindow()
- {
- return hOwner;
- }
- HWND SkinnedMenuWnd::SetOwnerWindow(HWND hwndOwner)
- {
- if (hOwner == hwndOwner)
- return hOwner;
- HWND prevOwner = hOwner;
- if (NULL != hOwner &&
- 0 != (SMIF_REMOVEREFLECTOR & menuFlags))
- {
- RemoveReflector(hOwner);
- }
- menuFlags &= ~SMIF_REMOVEREFLECTOR;
- hOwner = hwndOwner;
- if (NULL != hOwner &&
- S_OK == InstallReflector(hOwner))
- {
- menuFlags |= SMIF_REMOVEREFLECTOR;
- }
- return prevOwner;
- }
- BOOL SkinnedMenuWnd::AttachMenu(HMENU hMenuToAttach)
- {
- MENUINFO mi = {0};
- MENUITEMINFOW mii = {0};
- if (NULL != hMenu ||
- NULL == hMenuToAttach)
- {
- return FALSE;
- }
- hMenu = hMenuToAttach;
- mi.cbSize = sizeof(MENUINFO);
- mi.fMask = MIM_BACKGROUND;
- if (GetMenuInfo(hMenu, &mi))
- {
- menuOrigBrush = mi.hbrBack;
- mi.fMask = 0;
- if (NULL == mi.hbrBack)
- {
- COLORREF rgb;
- if (0 != (SMS_SYSCOLORS & menuExStyle) ||
- FAILED(MLGetSkinColor(MLSO_MENU, MP_BACKGROUND, MBS_NORMAL, &rgb)))
- {
- rgb = GetSysColor(COLOR_MENU);
- }
- backBrush = CreateSolidBrush(rgb);
- mi.hbrBack = backBrush;
- mi.fMask |= MIM_BACKGROUND;
- }
- if (0 != mi.fMask)
- SetMenuInfo(hMenu, &mi);
- }
- if (NULL != threadInfo)
- threadInfo->RegisterMenu(hMenu, hwnd);
- mii.cbSize = sizeof(MENUITEMINFOW);
- INT count = GetMenuItemCount(hMenu);
- if (count > 0)
- {
- skinnedItems = (SkinnedItemRecord*)calloc(count, sizeof(SkinnedItemRecord));
- if (NULL != skinnedItems)
- {
- skinnedItemCount = count;
- }
- }
- if (NULL == skinnedItems)
- return FALSE;
- skinnedItemCursor = 0;
- for (int i = 0; i < count; i++)
- {
- SkinnedItemRecord *record = &skinnedItems[i];
- mii.fMask = MIIM_FTYPE | MIIM_ID | MIIM_BITMAP; // MIIM_BITMAP - keep it... this forces menu to call WM_MEASUREITEM
- if (FALSE != GetMenuItemInfoW(hMenu, i, TRUE, &mii))
- {
- record->originalId = mii.wID;
- record->itemId = record->originalId;
- if (NULL != threadInfo)
- threadInfo->ClaimId(record->originalId);
- if (0 == (MFT_OWNERDRAW & mii.fType))
- {
- mii.fType |= MFT_OWNERDRAW;
- mii.fMask &= ~MIIM_ID;
- // copes with separators and popup menus (menu and menuex types)
- if (0 == mii.wID || (UINT)-1 == mii.wID || 65535 == mii.wID)
- {
- if (NULL != threadInfo)
- {
- mii.wID = threadInfo->GetAvailableId();
- if ((unsigned int)-1 != mii.wID)
- {
- record->itemId = mii.wID;
- mii.fMask |= MIIM_ID;
- }
- else
- mii.wID = record->itemId;
- }
- }
- record->skinned = TRUE;
- if (FALSE == SetMenuItemInfoW(hMenu, i, TRUE, &mii))
- {
- record->skinned = FALSE;
- record->itemId = record->originalId;
- }
- else
- {
- if (record->itemId != record->originalId &&
- NULL != threadInfo)
- {
- threadInfo->ClaimId(record->itemId);
- }
- }
- }
- }
- else
- {
- record->failed = TRUE;
- }
- }
- return TRUE;
- }
- BOOL SkinnedMenuWnd::Attach(HWND hwndMenu, HWND hwndOwner)
- {
- menuFlags &= ~SMIF_BLOCKDRAW;
-
- if(!__super::Attach(hwndMenu))
- return FALSE;
- SetOwnerWindow(hwndOwner);
- DWORD windowStyle = GetWindowLongPtrW(hwnd, GWL_STYLE);
- DWORD windowStyleEx = GetWindowLongPtrW(hwnd, GWL_EXSTYLE);
- DWORD newStyle = windowStyle & ~(WS_BORDER | WS_THICKFRAME | WS_DLGFRAME);
- if (newStyle != windowStyle)
- SetWindowLongPtr(hwnd, GWL_STYLE, newStyle);
- newStyle = windowStyleEx & ~(WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE);
- if (newStyle != windowStyleEx)
- SetWindowLongPtr(hwnd, GWL_EXSTYLE, newStyle);
- if (0 == (SMS_SYSCOLORS & menuExStyle))
- {
- SetStyle(SWS_USESKINCOLORS, FALSE);
- }
- SetType(SKINNEDWND_TYPE_POPUPMENU);
- if (!hmlilCheck)
- hmlilCheck = MLImageListI_Create(16, 16, MLILC_COLOR24_I, 2, 1, 2, hmlifMngr);
- if ((SMS_FORCEWIDTH & menuExStyle) && lineWidth > 0)
- {
- lineWidth -= ((GetSystemMetrics(SM_CXMENUCHECK) - 1) + WASABI_API_APP->getScaleX(MENU_BORDER_WIDTH*2));
- if (lineWidth < 0) lineWidth = 0;
- }
- else lineWidth = 0;
- lineHeight = GetLineHeight();
- if (!hmlil || !MLImageListI_GetImageSize(hmlil, &imageWidth, &imageHeight)) { imageWidth = WASABI_API_APP->getScaleX(24); imageHeight = 0; }
- if (hmlilCheck)
- {
- INT imageCX, imageCY;
- if(MLImageListI_GetImageSize(hmlilCheck, &imageCX, &imageCY))
- {
- if (imageWidth < imageCX) imageWidth = imageCX;
- if (imageWidth < WASABI_API_APP->getScaleX(25)) imageWidth = WASABI_API_APP->getScaleX(25); // clamp to a min width to better match the OS
- if (imageHeight < imageCY) imageHeight = imageCY;
- }
- }
- if (lineHeight < (imageHeight + WASABI_API_APP->getScaleY(4))) lineHeight = (imageHeight + WASABI_API_APP->getScaleY(4));
- if ((SMS_DISABLESHADOW & menuExStyle))
- {
- UINT cs = GetClassLongPtrW(hwnd, GCL_STYLE);
- if (0x00020000/*CS_DROPSHADOW*/ & cs)
- {
- bRestoreShadow = TRUE;
- SetClassLongPtrW(hwnd, GCL_STYLE, cs & ~0x00020000/*CS_DROPSHADOW*/);
- }
- }
- return TRUE;
- }
- HPEN SkinnedMenuWnd::GetBorderPen(void)
- {
- if (NULL == borderPen)
- {
- COLORREF rgb;
- if (0 != (SMS_SYSCOLORS & menuExStyle))
- rgb = GetSysColor(COLOR_GRAYTEXT);
- else
- MLGetSkinColor(MLSO_MENU, MP_FRAME, 0, &rgb);
- borderPen = CreatePen(PS_SOLID, 0, rgb);
- }
- return borderPen;
- }
- INT SkinnedMenuWnd::GetLineHeight()
- {
- INT h = 0;
- HDC hdc = GetDCEx(hwnd, NULL, DCX_CACHE);
- if (hdc)
- {
- HFONT hf = GetMenuFont(TRUE);
- if (NULL != hf)
- {
- TEXTMETRICW tm = {0};
- HFONT hfo = (HFONT)SelectObject(hdc, hf);
- if (GetTextMetricsW(hdc, &tm)) h = tm.tmHeight + WASABI_API_APP->getScaleY(4);
- SelectObject(hdc, hfo);
- }
- ReleaseDC(hwnd, hdc);
- }
- return h;
- }
- HFONT SkinnedMenuWnd::GetMenuFont(BOOL fBold)
- {
- HFONT hFont = NULL;
- if (SMS_USESKINFONT & menuExStyle)
- {
- hFont = (HFONT)MlStockObjects_Get(SKIN_FONT);
- }
- if (NULL == hFont)
- hFont = (HFONT)MlStockObjects_Get(DEFAULT_FONT);
-
- if (FALSE != fBold)
- {
- if (NULL == hBoldFont)
- {
- LOGFONTW lf = {0};
- if (sizeof(LOGFONTW) == GetObjectW(hFont, sizeof(LOGFONTW), &lf))
- {
- if (lf.lfWeight < FW_BOLD)
- lf.lfWeight = FW_BOLD;
- hBoldFont = CreateFontIndirectW(&lf);
- }
- }
- if (NULL != hBoldFont)
- {
- hFont = hBoldFont;
- }
- }
- return hFont;
- }
- INT SkinnedMenuWnd::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS *pncsp)
- {
- DWORD windowStyle = GetWindowLongPtr(hwnd, GWL_STYLE);
- DWORD windowStyleEx = GetWindowLongPtr(hwnd, GWL_EXSTYLE);
- DWORD newStyle = windowStyle & ~(WS_BORDER | WS_THICKFRAME | WS_DLGFRAME);
- if (newStyle != windowStyle)
- SetWindowLongPtr(hwnd, GWL_STYLE, newStyle);
- newStyle = windowStyleEx & ~(WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE);
- if (newStyle != windowStyleEx)
- SetWindowLongPtr(hwnd, GWL_EXSTYLE, newStyle);
- LRESULT result = CallPrevWndProc(WM_NCCALCSIZE, (WPARAM)bCalcValidRects, (LPARAM)pncsp);
-
- InflateRect(&pncsp->rgrc[0], WASABI_API_APP->getScaleX(-MENU_BORDER_WIDTH), WASABI_API_APP->getScaleY(-MENU_BORDER_WIDTH));
- if (bCalcValidRects)
- {
- InflateRect(&pncsp->rgrc[1], WASABI_API_APP->getScaleX(-MENU_BORDER_WIDTH), WASABI_API_APP->getScaleY(-MENU_BORDER_WIDTH));
- InflateRect(&pncsp->rgrc[2], WASABI_API_APP->getScaleX(-MENU_BORDER_WIDTH), WASABI_API_APP->getScaleY(-MENU_BORDER_WIDTH));
- }
- return (INT)result;
- }
- void SkinnedMenuWnd::PaintScrollButton(HDC hdc, const RECT *prc, UINT scrollButton, BOOL buttonState)
- {
- COLORREF rgbBk, rgbFg;
- MLGetSkinColor(MLSO_MENU, MP_BACKGROUND, MBS_NORMAL, &rgbBk);
- MLGetSkinColor(MLSO_MENU, MP_TEXT, MTS_NORMAL, &rgbFg);
- HBITMAP hbmp;
- if (0 == (MENU_BUTTON_STATE_DISABLED & buttonState))
- {
- if (NULL == scrollBitmap)
- scrollBitmap = SkinnedMenuWnd_LoadPngResource(IDB_MENU_SCROLLARROW, rgbBk, rgbFg);
- hbmp = scrollBitmap;
- }
- else
- {
- if (NULL == disabledScrollBitmap)
- disabledScrollBitmap = SkinnedMenuWnd_LoadPngResource(IDB_MENU_SCROLLARROW_DISABLED, rgbBk, rgbFg);
- hbmp = disabledScrollBitmap;
- }
- BOOL imageFailed = TRUE;
- if (NULL != hbmp)
- {
- DIBSECTION bitmapInfo;
- if (!GetObjectW(hbmp, sizeof(bitmapInfo), &bitmapInfo))
- ZeroMemory(&bitmapInfo, sizeof(bitmapInfo));
- INT h = abs(bitmapInfo.dsBm.bmHeight);
- INT w = bitmapInfo.dsBm.bmWidth;
- if (h > 0 && w > 0)
- {
- INT x, y, nWidth, nHeight;
- x = prc->left + ((prc->right - prc->left) - w) / 2;
- y = prc->top + ((prc->bottom - prc->top) - h) / 2;
- if (MENU_BUTTON_SCROLLDOWN == scrollButton)
- {
- nWidth = -w;
- nHeight = h;
- x += w;
- }
- else
- {
- nWidth = w;
- nHeight = -h;
- y += h;
- }
- SetBkColor(hdc, rgbBk);
- ExtTextOut(hdc, 0, 0, ETO_OPAQUE, prc, NULL, 0, NULL);
- StretchDIBits(hdc, x, y, nWidth, nHeight, 0, 0, w, h, bitmapInfo.dsBm.bmBits,
- (BITMAPINFO*)&bitmapInfo.dsBmih, DIB_RGB_COLORS, SRCCOPY);
- imageFailed = FALSE;
- }
- }
- if (imageFailed)
- ExtTextOut(hdc, 0, 0, ETO_OPAQUE, prc, NULL, 0, NULL);
- }
- BOOL SkinnedMenuWnd::DrawScrollButton(HDC hdc, UINT scrollButton)
- {
- RECT rc, rcWindow, rcPaint;
- if (0 == scrollButton ||
- 0 == GetWindowRect(hwnd, &rcWindow) ||
- 0 == GetClientRect(hwnd, &rc))
- {
- return FALSE;
- }
- MapWindowPoints(hwnd, HWND_DESKTOP, (POINT*)&rc, 2);
-
- HDC hdcOwned = NULL;
- if (NULL == hdc)
- {
- hdcOwned = GetDCEx(hwnd, NULL, DCX_CACHE | DCX_WINDOW | DCX_CLIPSIBLINGS);
- hdc = hdcOwned;
-
- if (NULL == hdcOwned)
- return FALSE;
- }
- rcPaint.left = rc.left - rcWindow.left;
- rcPaint.right = rc.right - rcWindow.left;
- BOOL scrollEnabled;
- POINT ptTest;
- ptTest.x = rc.left + (rc.right - rc.left) / 2;
- if (0 != (MENU_BUTTON_SCROLLUP & scrollButton))
- {
- rcPaint.top = MENU_BORDER_WIDTH;
- rcPaint.bottom = rc.top - rcWindow.top;
- if (rcPaint.bottom > rcPaint.top && rcPaint.right > rcPaint.left)
- {
- ptTest.y = rc.top;
- scrollEnabled = (MenuItemFromPoint(hwnd, hMenu, ptTest) > 0);
- PaintScrollButton(hdc, &rcPaint, MENU_BUTTON_SCROLLUP, (scrollEnabled) ? 0 : MENU_BUTTON_STATE_DISABLED);
- }
- }
- if (0 != (MENU_BUTTON_SCROLLDOWN & scrollButton))
- {
- rcPaint.top = rc.bottom - rcWindow.top;
- rcPaint.bottom = (rcWindow.bottom - rcWindow.top) - MENU_BORDER_WIDTH;
- if (rcPaint.bottom > rcPaint.top && rcPaint.right > rcPaint.left)
- {
- ptTest.y = rc.bottom - WASABI_API_APP->getScaleY(1);
- INT last = MenuItemFromPoint(hwnd, hMenu, ptTest);
- scrollEnabled = FALSE;
- if (last >= 0)
- {
- INT count = GetMenuItemCount(hMenu);
- if (last != (count - 1))
- scrollEnabled = TRUE;
- }
- PaintScrollButton(hdc, &rcPaint, MENU_BUTTON_SCROLLDOWN, (scrollEnabled) ? 0 : MENU_BUTTON_STATE_DISABLED);
- }
- }
- if (NULL != hdcOwned)
- ReleaseDC(hwnd, hdcOwned);
- return TRUE;
- }
- void SkinnedMenuWnd::DrawBorder(HDC hdc)
- {
- RECT rc, rcWindow, rp;
- GetClientRect(hwnd, &rc);
- GetWindowRect(hwnd, &rcWindow);
- MapWindowPoints(hwnd, HWND_DESKTOP, (POINT*)&rc, 2);
- OffsetRect(&rc, -rcWindow.left, -rcWindow.top);
- OffsetRect(&rcWindow, -rcWindow.left, -rcWindow.top);
- SkinnedWnd::DrawBorder(hdc, &rcWindow, BORDER_FLAT, GetBorderPen());
- HBRUSH brushBk = SkinnedMenuWnd_GetBackBrush(hMenu);
- SetRect(&rp, rcWindow.left + 1, rcWindow.top + 1, rc.left, rcWindow.bottom - 1);
- FillRect(hdc, &rp, brushBk);
- SetRect(&rp, rc.left, rcWindow.top + 1, rc.right, rc.top);
- FillRect(hdc, &rp, brushBk);
- SetRect(&rp, rc.right, rcWindow.top + 1, rcWindow.right - 1, rcWindow.bottom - 1);
- FillRect(hdc, &rp, brushBk);
- SetRect(&rp, rc.left, rc.bottom, rc.right, rcWindow.bottom - 1);
- FillRect(hdc, &rp, brushBk);
- if ((rc.top - rcWindow.top) > MENU_BORDER_WIDTH || (rcWindow.bottom - rc.bottom) > MENU_BORDER_WIDTH)
- DrawScrollButton(hdc, MENU_BUTTON_SCROLLUP | MENU_BUTTON_SCROLLDOWN);
- }
- BOOL SkinnedMenuWnd::IsSkinnedItem(UINT itemId)
- {
- if (NULL == skinnedItems)
- return TRUE;
- if (skinnedItemCursor >= skinnedItemCount)
- skinnedItemCursor = 0;
- INT start = skinnedItemCursor;
- while(itemId != skinnedItems[skinnedItemCursor].itemId)
- {
- skinnedItemCursor++;
- if (skinnedItemCursor == skinnedItemCount)
- skinnedItemCursor = 0;
- if (skinnedItemCursor == start)
- {
- skinnedItemCursor = 0;
- return FALSE;
- }
- }
- return skinnedItems[skinnedItemCursor].skinned;
- }
- static void SkinnedMenuWnd_DrawFrame(HDC hdc, const RECT *prc, INT width, COLORREF rgbFrame)
- {
- if (width > 0)
- {
- COLORREF rgbOld = SetBkColor(hdc, rgbFrame);
- RECT rcPart;
- SetRect(&rcPart, prc->left, prc->top, prc->right, prc->top + width);
- ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rcPart, NULL, 0, NULL);
- SetRect(&rcPart, prc->left, prc->bottom - width, prc->right, prc->bottom);
- ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rcPart, NULL, 0, NULL);
- SetRect(&rcPart, prc->left, prc->top + width, prc->left + width, prc->bottom - width);
- ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rcPart, NULL, 0, NULL);
- SetRect(&rcPart, prc->right - width, prc->top + width, prc->right, prc->bottom - width);
- ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rcPart, NULL, 0, NULL);
- if (rgbOld != rgbFrame)
- SetBkColor(hdc, rgbOld);
- }
- }
- BOOL SkinnedMenuWnd::OnReflectedDrawItem(DRAWITEMSTRUCT *pdis)
- {
- if (0 != (SMIF_BLOCKDRAW & menuFlags))
- {
- ExcludeClipRect(pdis->hDC, pdis->rcItem.left, pdis->rcItem.top, pdis->rcItem.right, pdis->rcItem.bottom);
- }
- if (!IsSkinnedItem(pdis->itemID))
- return FALSE;
- MENUITEMINFOW mii = {0};
- wchar_t szText[256] = {0};
- INT imageCX, imageCY, realIndex;
- LONG imageTop;
- mii.cbSize = sizeof(MENUITEMINFO);
- mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_STATE | MIIM_SUBMENU;
- mii.cch = ARRAYSIZE(szText);
- mii.dwTypeData = szText;
- if (!GetMenuItemInfoW((HMENU)pdis->hwndItem, pdis->itemID, FALSE, &mii))
- mii.cch = 0;
- COLORREF rgbText, rgbTextBk, rgbTextFrame;
- if (0 != (SMS_SYSCOLORS & menuExStyle))
- {
- INT foreIndex = (0 != (MFS_GRAYED & mii.fState)) ? COLOR_GRAYTEXT : COLOR_MENUTEXT;
- INT backIndex = (0 != (ODS_SELECTED & pdis->itemState)) ? COLOR_HIGHLIGHT : COLOR_MENU;
- rgbText = GetSysColor(foreIndex);
- rgbTextBk = GetSysColor(backIndex);
- rgbTextFrame = rgbTextBk;
- }
- else
- {
- MLGetSkinColor(MLSO_MENU, MP_BACKGROUND, (0 != (ODS_SELECTED & pdis->itemState)) ? MBS_SELECTED : MBS_NORMAL, &rgbTextBk);
- MLGetSkinColor(MLSO_MENU, MP_TEXT, (0 != (MFS_GRAYED & mii.fState)) ? MTS_DISABLED : ((0 != (ODS_SELECTED & pdis->itemState)) ? MBS_SELECTED : MBS_NORMAL), &rgbText);
- rgbTextFrame = rgbTextBk;
- if (0 != (ODS_SELECTED & pdis->itemState))
- {
- MLGetSkinColor(MLSO_MENU, MP_BACKGROUND, MBS_SELECTEDFRAME, &rgbTextFrame);
- }
- }
- COLORREF origText = SetTextColor(pdis->hDC, rgbText);
- COLORREF origTextBk = SetBkColor(pdis->hDC, rgbTextBk);
- if (0 != (MFT_MENUBARBREAK & mii.fType))
- {
- RECT rect;
- if (FALSE != GetClientRect(hwnd, &rect))
- {
- COLORREF lineColor, prevColor;
- HBRUSH brush = SkinnedMenuWnd_GetBackBrush(hMenu);
- if(NULL == brush)
- brush = GetSysColorBrush(COLOR_WINDOW);
- rect.right = pdis->rcItem.left - WASABI_API_APP->getScaleX(1);
- rect.left = pdis->rcItem.left - WASABI_API_APP->getScaleX(2);
- FillRect(pdis->hDC, &rect, brush);
- if (0 != (SMS_SYSCOLORS & menuExStyle) ||
- FAILED(MLGetSkinColor(MLSO_MENU, MP_SEPARATOR, 0, &lineColor)))
- {
- lineColor = GetSysColor(COLOR_3DSHADOW);
- }
- prevColor = SetBkColor(pdis->hDC, lineColor);
- OffsetRect(&rect, -1, 0);
- ExtTextOut(pdis->hDC, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
- SetBkColor(pdis->hDC, prevColor);
- }
- }
- if (NULL != customProc)
- {
- INT customResult = customProc(MLMENU_ACTION_DRAWITEM, (HMENU)pdis->hwndItem, pdis->hDC, (LPARAM)pdis, customParam);
- if (MLMENU_WANT_DRAWPART != customResult && FALSE != customResult)
- return TRUE;
- }
- INT type = ((MFT_STRING | MFT_SEPARATOR) & mii.fType);
- switch(type)
- {
- case MFT_STRING:
- if (NULL == customProc ||
- FALSE == customProc(MLMENU_ACTION_DRAWBACK, (HMENU)pdis->hwndItem, pdis->hDC, (LPARAM)pdis, customParam))
- {
- ExtTextOutW(pdis->hDC, 0, 0, ETO_OPAQUE, &pdis->rcItem, NULL, 0, NULL);
- if (rgbTextFrame != rgbTextBk)
- {
- SkinnedMenuWnd_DrawFrame(pdis->hDC, &pdis->rcItem, 1, rgbTextFrame);
- }
- }
- if (NULL == customProc ||
- FALSE == customProc(MLMENU_ACTION_DRAWICON, (HMENU)pdis->hwndItem, pdis->hDC, (LPARAM)pdis, customParam))
- {
- if (hmlil)
- {
- if (MLImageListI_GetImageSize(hmlil, &imageCX, &imageCY))
- {
- imageTop = pdis->rcItem.top + (pdis->rcItem.bottom - pdis->rcItem.top - imageCY) / 2;
- if (imageTop < pdis->rcItem.top) imageTop = pdis->rcItem.top;
-
- INT index = MLImageListI_GetIndexFromTag(hmlil, pdis->itemID);
- if (-1 != index)
- {
- HIMAGELIST himl = MLImageListI_GetRealList(hmlil);
- realIndex = MLImageListI_GetRealIndex(hmlil, index, rgbTextBk, rgbText);
- if (-1 != realIndex)
- {
- ImageList_Draw(himl, realIndex, pdis->hDC, pdis->rcItem.left + WASABI_API_APP->getScaleX(1) + (imageWidth - imageCX) / 2, imageTop, ILD_NORMAL);
- }
- }
- }
- }
- else if ((MFS_CHECKED & mii.fState) && hmlilCheck)
- {
- if (0 != (MFT_RADIOCHECK & mii.fType))
- {
- if (-1 == imageRadioMark)
- imageRadioMark = SkinnedMenuWnd_AddPngResource(hmlilCheck, IDB_MENU_RADIOMARK);
- }
- else
- {
- if (-1 == imageCheckMark)
- imageCheckMark = SkinnedMenuWnd_AddPngResource(hmlilCheck, IDB_MENU_CHECKMARK);
- }
- if (MLImageListI_GetImageSize(hmlilCheck, &imageCX, &imageCY))
- {
- imageTop = pdis->rcItem.top + (pdis->rcItem.bottom - pdis->rcItem.top - imageCY) / 2;
- if (imageTop < pdis->rcItem.top) imageTop = pdis->rcItem.top;
- HIMAGELIST himl = MLImageListI_GetRealList(hmlilCheck);
- realIndex = MLImageListI_GetRealIndex(hmlilCheck, (MFT_RADIOCHECK & mii.fType) ? imageRadioMark : imageCheckMark, rgbTextBk, rgbText);
- if (-1 != realIndex)
- {
- ImageList_Draw(himl, realIndex, pdis->hDC, pdis->rcItem.left + WASABI_API_APP->getScaleX(1) + (imageWidth - imageCX) / 2, imageTop, ILD_NORMAL);
- }
- }
- }
- }
- if (NULL != mii.hSubMenu && hmlilCheck)
- {
- if (-1 == imageExpandArrow)
- imageExpandArrow = SkinnedMenuWnd_AddPngResource(hmlilCheck, IDB_MENU_EXPANDARROW);
- if (MLImageListI_GetImageSize(hmlilCheck, &imageCX, &imageCY))
- {
- imageTop = pdis->rcItem.top + (pdis->rcItem.bottom - pdis->rcItem.top - imageCY) / 2;
- if (imageTop < pdis->rcItem.top) imageTop = pdis->rcItem.top;
- HIMAGELIST himl = MLImageListI_GetRealList(hmlilCheck);
- realIndex = MLImageListI_GetRealIndex(hmlilCheck, imageExpandArrow, rgbTextBk, rgbText);
- if (-1 != realIndex)
- ImageList_Draw(himl, realIndex, pdis->hDC, pdis->rcItem.right - imageCX - WASABI_API_APP->getScaleX(1), imageTop, ILD_NORMAL);
- }
- }
- if (NULL == customProc ||
- FALSE == customProc(MLMENU_ACTION_DRAWTEXT, (HMENU)pdis->hwndItem, pdis->hDC, (LPARAM)pdis, customParam))
- {
- if (mii.cch)
- {
- RECT rt;
- CopyRect(&rt, &pdis->rcItem);
- if (imageWidth && imageHeight) rt.left += imageWidth + WASABI_API_APP->getScaleX(6);
- rt.right -= imageWidth;
- HFONT hFont = GetMenuFont(FALSE);
- HFONT originalFont = (NULL != hFont) ? (HFONT)SelectObject(pdis->hDC, hFont) : NULL;
- INT originalBkMode = SetBkMode(pdis->hDC, TRANSPARENT);
- UINT len = mii.cch;
- if (len > 0)
- {
- while(--len > 0 && L'\t' != mii.dwTypeData[len]);
- if (0 == len)
- len = mii.cch;
- }
- BOOL showPrefix = FALSE;
- if (!SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, &showPrefix, 0))
- showPrefix = FALSE;
- if (!showPrefix && 0 == (ODS_NOACCEL & pdis->itemState))
- showPrefix = TRUE;
- UINT drawtextFlags = DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOCLIP;
- if (!showPrefix)
- drawtextFlags |= 0x000100000; /*DT_HIDEPREFIX*/
- if (0 != (MFS_DEFAULT & mii.fState))
- {
- SetTextColor(pdis->hDC, BlendColors(rgbText, rgbTextBk, 110));
- OffsetRect(&rt, 1,0);
- DrawTextW(pdis->hDC, mii.dwTypeData, len, &rt, drawtextFlags);
- OffsetRect(&rt, -1,0);
- SetTextColor(pdis->hDC, rgbText);
- }
- DrawTextW(pdis->hDC, mii.dwTypeData, len, &rt, drawtextFlags);
- if (mii.cch > (len + 1))
- {
- len++;
- rt.left = rt.right - shortcutCX;
- SetTextColor(pdis->hDC, BlendColors(rgbText, rgbTextBk, 192));
- DrawTextW(pdis->hDC, mii.dwTypeData + len, mii.cch - len, &rt, DT_LEFT | DT_VCENTER | 0x000100000/*DT_HIDEPREFIX*/ | DT_SINGLELINE | DT_NOCLIP);
- }
- SelectObject(pdis->hDC, originalFont);
- if (TRANSPARENT != originalBkMode)
- SetBkMode(pdis->hDC, originalBkMode);
- }
- }
- ExcludeClipRect(pdis->hDC, pdis->rcItem.left + WASABI_API_APP->getScaleX(23),
- pdis->rcItem.top, pdis->rcItem.right, pdis->rcItem.bottom);
- break;
- case MFT_SEPARATOR:
- {
- COLORREF rgbSeparator;
- HPEN hPen, originalPen;
- INT y = (pdis->rcItem.top + (pdis->rcItem.bottom - pdis->rcItem.top) / 2);
- if (0 != (SMS_SYSCOLORS & menuExStyle) ||
- FAILED(MLGetSkinColor(MLSO_MENU, MP_SEPARATOR, 0, &rgbSeparator)))
- {
- rgbSeparator = GetSysColor(COLOR_3DSHADOW/*COLOR_GRAYTEXT*/);
- }
- hPen = CreatePen(PS_SOLID, 0, rgbSeparator);
- originalPen = (HPEN)SelectObject(pdis->hDC, hPen);
- ExtTextOutW(pdis->hDC, 0, 0, ETO_OPAQUE, &pdis->rcItem, NULL, 0, NULL);
- MoveToEx(pdis->hDC, pdis->rcItem.left + WASABI_API_APP->getScaleX(23), y, NULL);
- LineTo(pdis->hDC, pdis->rcItem.right, y);
- SelectObject(pdis->hDC, originalPen);
- DeleteObject(hPen);
- // draws a edge on the separator so it looks more like the OS when trying to 'fake it'
- if (0 != (SMS_SYSCOLORS & menuExStyle))
- {
- RECT bottomRect = pdis->rcItem;
- HBRUSH brush = GetSysColorBrush(COLOR_3DHIGHLIGHT);
-
- y += WASABI_API_APP->getScaleY(1);
- bottomRect.top = y;
- bottomRect.bottom = y + WASABI_API_APP->getScaleY(1);
- FillRect(pdis->hDC,&bottomRect, brush);
- }
- }
- ExcludeClipRect(pdis->hDC, pdis->rcItem.left + WASABI_API_APP->getScaleX(23),
- pdis->rcItem.top, pdis->rcItem.right, pdis->rcItem.bottom);
- break;
- }
- {
- COLORREF rgbSeparator;
- if (0 != (SMS_SYSCOLORS & menuExStyle) ||
- FAILED(MLGetSkinColor(MLSO_MENU, MP_SEPARATOR, 0, &rgbSeparator)))
- {
- rgbSeparator = GetSysColor(COLOR_3DSHADOW/*COLOR_GRAYTEXT*/);
- }
- HPEN hPen = CreatePen(PS_SOLID, 0, rgbSeparator);
- HPEN originalPen = (HPEN)SelectObject(pdis->hDC, hPen);
- MoveToEx(pdis->hDC, pdis->rcItem.left + WASABI_API_APP->getScaleX(22), pdis->rcItem.top, NULL);
- LineTo(pdis->hDC, pdis->rcItem.left + WASABI_API_APP->getScaleX(22), pdis->rcItem.top + (pdis->rcItem.bottom - pdis->rcItem.top));
- SelectObject(pdis->hDC, originalPen);
- DeleteObject(hPen);
- }
- if (origText != rgbText)
- SetTextColor(pdis->hDC, origText);
- if (origTextBk != rgbTextBk)
- SetBkColor(pdis->hDC, origTextBk);
- return TRUE;
- }
- BOOL SkinnedMenuWnd::OnReflectedMeasureItem(MEASUREITEMSTRUCT *pmis)
- {
- pmis->itemHeight = lineHeight;
- pmis->itemWidth = lineWidth;
- if (!IsSkinnedItem(pmis->itemID))
- return FALSE;
- HDC hdc = GetDCEx(hwnd, NULL, DCX_CACHE);
- if (NULL == hdc) return FALSE;
- MENUITEMINFOW mii = {0};
- wchar_t szText[128] = {0};
- mii.cbSize = sizeof(MENUITEMINFO);
- mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_STATE;
- mii.cch = ARRAYSIZE(szText);
- mii.dwTypeData = szText;
- if (!GetMenuItemInfoW(hMenu, pmis->itemID, FALSE, &mii))
- mii.cch = 0;
- HFONT originalFont = (HFONT)SelectObject(hdc, GetMenuFont(0 != (MFS_DEFAULT & mii.fState)));
- if (NULL == customProc ||
- FALSE == customProc(MLMENU_ACTION_MEASUREITEM, hMenu, hdc, (LPARAM)pmis, customParam))
- {
- if (0 == lineWidth || 0 == lineHeight)
- {
- INT type = ((MFT_STRING | MFT_SEPARATOR) & mii.fType);
- switch(type)
- {
- case MFT_STRING:
- if (mii.cch != 0)
- {
- SIZE sz;
- UINT len = mii.cch;
- while(--len > 0 && L'\t' != mii.dwTypeData[len]);
- if (0 == len) len = mii.cch;
- if (len != mii.cch)
- {
- szText[len] = L' ';
- if (GetTextExtentPoint32W(hdc, szText + len, mii.cch - len, &sz) &&
- shortcutCX < sz.cx)
- {
- shortcutCX = sz.cx;
- }
- }
- if (GetTextExtentPoint32W(hdc, szText, len, &sz))
- {
- if (textCX <= sz.cx)
- textCX = sz.cx;
- if (lineHeight < sz.cy)
- pmis->itemHeight = sz.cy + WASABI_API_APP->getScaleY(2);
-
- if (0 == lineWidth)
- pmis->itemWidth = textCX + shortcutCX + 8;
- }
- }
- if(imageHeight > (INT)(pmis->itemHeight + WASABI_API_APP->getScaleY(2))) pmis->itemHeight = imageHeight + WASABI_API_APP->getScaleY(2);
- if (0 == lineWidth && imageWidth) pmis->itemWidth += imageWidth;
- pmis->itemWidth -= (GetSystemMetrics(SM_CXMENUCHECK) - imageWidth - WASABI_API_APP->getScaleX(36));
- break;
- case MFT_SEPARATOR:
- pmis->itemHeight = WASABI_API_APP->getScaleY(7);
- break;
- }
- }
- }
- SelectObject(hdc, originalFont);
- ReleaseDC(hwnd, hdc);
- return TRUE;
- }
- void SkinnedMenuWnd::OnNcPaint(HRGN rgnUpdate)
- {
- if (0 != (SMIF_BLOCKDRAW & menuFlags))
- return;
- UINT flags = DCX_PARENTCLIP | DCX_WINDOW | DCX_CLIPSIBLINGS |
- DCX_INTERSECTUPDATE | DCX_VALIDATE;
- HDC hdc = GetDCEx(hwnd, ((HRGN)NULLREGION != rgnUpdate) ? rgnUpdate : NULL, flags);
- if (NULL == hdc)
- return;
- DrawBorder(hdc);
- ReleaseDC(hwnd, hdc);
- }
- LRESULT SkinnedMenuWnd::OnEraseBackground(HDC hdc)
- {
- HBRUSH brush;
- brush = SkinnedMenuWnd_GetBackBrush(hMenu);
- if (NULL != brush)
- {
- RECT rect;
- if (FALSE != GetClientRect(hwnd, &rect) &&
- FALSE != FillRect(hdc, &rect, brush))
- {
- return 1;
- }
- }
- return __super::WindowProc(WM_ERASEBKGND, (WPARAM)hdc, 0L);
- }
- void SkinnedMenuWnd::OnPrint(HDC hdc, UINT options)
- {
- if (0 != (PRF_CHECKVISIBLE & options))
- {
- DWORD windowStyle = GetWindowLongPtr(hwnd, GWL_STYLE);
- if (0 == (WS_VISIBLE & windowStyle))
- {
- return;
- }
- }
- if (0 != (PRF_NONCLIENT & options))
- {
- DrawBorder(hdc);
- }
- if (0 == ((PRF_ERASEBKGND | PRF_CLIENT) & options))
- {
- return;
- }
- POINT ptOrig;
- RECT rc, rcWindow;
- if (GetClientRect(hwnd, &rc) &&
- GetWindowRect(hwnd, &rcWindow))
- {
- MapWindowPoints(hwnd, HWND_DESKTOP, (POINT*)&rc, 2);
- }
- else
- {
- SetRectEmpty(&rc);
- SetRectEmpty(&rcWindow);
- }
- INT clipRegionCode;
- HRGN clipRegion = CreateRectRgn(0, 0, 0, 0);
- clipRegionCode = (NULL != clipRegion) ? GetClipRgn(hdc, clipRegion) : -1;
- OffsetViewportOrgEx(hdc, rc.left - rcWindow.left, rc.top - rcWindow.top, &ptOrig);
- if (-1 != clipRegionCode)
- {
- IntersectClipRect(hdc, 0, 0, rc.right - rc.left, rc.bottom - rc.top);
- }
- OffsetRect(&rc, -rc.left, -rc.top);
- if (0 != (PRF_ERASEBKGND & options))
- {
- MENUINFO mi = {0};
- mi.cbSize = sizeof(MENUINFO);
- mi.fMask = MIM_BACKGROUND;
- HBRUSH brushBk = NULL;
- if (GetMenuInfo(hMenu, &mi) && mi.hbrBack)
- brushBk = mi.hbrBack;
- if (NULL == brushBk)
- brushBk = GetSysColorBrush(COLOR_WINDOW);
- FillRect(hdc, &rc, brushBk);
- }
- if (0 != (PRF_CLIENT & options))
- {
- menuFlags &= ~SMIF_BLOCKDRAW;
- SendMessage(hwnd, WM_PRINTCLIENT, (WPARAM)hdc, (LPARAM)(~(PRF_NONCLIENT | PRF_ERASEBKGND) & options));
- menuFlags |= SMIF_BLOCKDRAW;
- }
- if (-1 != clipRegionCode)
- {
- SelectClipRgn(hdc, (0 != clipRegionCode) ? clipRegion : NULL);
- }
- if (NULL != clipRegion)
- DeleteObject(clipRegion);
-
- SetViewportOrgEx(hdc, ptOrig.x, ptOrig.y, NULL);
- SetTimer(hwnd, MTID_EX_UNBLOCKDRAW, 250, NULL);
- }
- LRESULT SkinnedMenuWnd::OnMenuSelect(UINT selectedItem)
- {
- if (((UINT)-1) != selectedItem)
- menuFlags &= ~SMIF_BLOCKDRAW;
- UINT updateScroll = 0;
- if (MHF_SCROLLUP == prevSelectedItem)
- updateScroll |= MENU_BUTTON_SCROLLUP;
- else if (MHF_SCROLLDOWN == prevSelectedItem)
- updateScroll |= MENU_BUTTON_SCROLLDOWN;
- switch(selectedItem)
- {
- case MHF_SCROLLUP:
- updateScroll |= MENU_BUTTON_SCROLLUP;
- break;
- case MHF_SCROLLDOWN:
- updateScroll |= MENU_BUTTON_SCROLLDOWN;
- break;
- }
- RECT rc;
- GetClientRect(hwnd, &rc);
- MapWindowPoints(hwnd, HWND_DESKTOP, (POINT*)&rc, 2);
- rc.top += WASABI_API_APP->getScaleY(1);
- INT item = MenuItemFromPoint(hwnd, hMenu, *((POINT*)&rc));
- LRESULT result;
- BOOL fInvalidate = FALSE;
- if (0 != updateScroll)
- {
- DWORD windowStyle = GetWindowLongPtr(hwnd, GWL_STYLE);
- SetWindowLongPtr(hwnd, GWL_STYLE, windowStyle & ~WS_VISIBLE);
- result = __super::WindowProc(MN_SELECTITEM, selectedItem, 0L);
- SetWindowLongPtr(hwnd, GWL_STYLE, windowStyle);
- if (MenuItemFromPoint(hwnd, hMenu, *((POINT*)&rc)) != item)
- {
- updateScroll = MENU_BUTTON_SCROLLUP | MENU_BUTTON_SCROLLDOWN;
- fInvalidate = TRUE;
- }
- }
- else
- {
- result = __super::WindowProc(MN_SELECTITEM, selectedItem, 0L);
- }
- prevSelectedItem = selectedItem;
- if (0 != updateScroll)
- {
- DrawScrollButton(NULL, updateScroll);
- if (FALSE != fInvalidate)
- {
- InvalidateRect(hwnd, NULL, FALSE);
- }
- }
- return result;
- }
- LRESULT SkinnedMenuWnd::CallHookedWindowProc(UINT uItem, BOOL fByPosition, UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- MENUITEMINFOW mii = {0};
- mii.cbSize = sizeof(mii);
- mii.fMask = MIIM_SUBMENU;
-
- if (FALSE != GetMenuItemInfoW(hMenu, uItem, fByPosition, &mii) &&
- NULL != mii.hSubMenu)
- {
- SkinnedMenu sm;
- sm.InitializeHook(NULL, (menuExStyle & ~SMS_FORCEWIDTH), hmlil, 0, customProc, customParam);
- return __super::WindowProc(uMsg, wParam, lParam);
- }
-
- return __super::WindowProc(uMsg, wParam, lParam);
- }
- INT SkinnedMenuWnd::FindHiliteItem(HMENU hMenu)
- {
- MENUITEMINFOW mii = {0};
- mii.cbSize = sizeof(MENUITEMINFOW);
- mii.fMask = MIIM_STATE;
- INT count = GetMenuItemCount(hMenu);
- for (INT i = 0; i < count; i++)
- {
- if (0 != GetMenuItemInfoW(hMenu, i, TRUE, &mii))
- {
- if (MFS_HILITE == ((MFS_HILITE | MFS_DISABLED | MFS_GRAYED) & mii.fState))
- return i;
- }
- }
- return -1;
- }
- LRESULT SkinnedMenuWnd::WindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- switch(uMsg)
- {
- case WM_ERASEBKGND:
- return OnEraseBackground((HDC)wParam);
- case REFLECTED_DRAWITEM:
- if (OnReflectedDrawItem((DRAWITEMSTRUCT*)((REFLECTPARAM*)lParam)->lParam))
- {
- ((REFLECTPARAM*)lParam)->result = TRUE;
- return TRUE;
- }
- break;
- case REFLECTED_MEASUREITEM:
- if (OnReflectedMeasureItem((MEASUREITEMSTRUCT*)((REFLECTPARAM*)lParam)->lParam))
- {
- ((REFLECTPARAM*)lParam)->result = TRUE;
- return TRUE;
- }
- break;
- case MN_SIZEWINDOW:
- {
- BOOL validateOwner = FALSE;
- if (NULL == hMenu)
- {
- textCX = 0;
- shortcutCX = 0;
- HMENU menuToAttach = (HMENU)SendMessageW(hwnd, MN_GETHMENU, 0, 0L);
- if (FALSE != AttachMenu(menuToAttach))
- validateOwner = TRUE;
- }
- if (NULL != threadInfo)
- {
- threadInfo->SetActiveMeasureMenu(hMenu);
- if (FALSE != validateOwner &&
- FALSE == threadInfo->SetValidationHook(this))
- {
- validateOwner = FALSE;
- }
- }
- LRESULT result = __super::WindowProc(uMsg, wParam, lParam);
- if (NULL != threadInfo)
- {
- threadInfo->SetActiveMeasureMenu(NULL);
- if (FALSE != validateOwner)
- threadInfo->RemoveValidationHook(this);
- }
- return result;
- }
- break;
- case MN_SELECTITEM:
- return OnMenuSelect((UINT)wParam);
- case MN_LBUTTONDBLCLK:
- case MN_LBUTTONDOWN:
- case MN_LBUTTONUP:
- menuFlags &= ~SMIF_BLOCKDRAW;
- switch(wParam)
- {
- case MHF_SCROLLUP:
- case MHF_SCROLLDOWN:
- {
- LRESULT result = __super::WindowProc(uMsg, wParam, lParam);
- DrawScrollButton(NULL, MENU_BUTTON_SCROLLDOWN | MENU_BUTTON_SCROLLUP);
- return result;
- }
- break;
- default:
- if (wParam >= 0)
- {
- return CallHookedWindowProc((UINT)wParam, TRUE, uMsg, wParam, lParam);
- }
- break;
- }
- break;
- case WM_TIMER:
- switch(wParam)
- {
- case MTID_OPENSUBMENU:
- {
- POINT pt;
- INT iItem;
- if (GetCursorPos(&pt) &&
- -1 != (iItem = MenuItemFromPoint(NULL, hMenu, pt)))
- {
- CallHookedWindowProc(iItem, TRUE, uMsg, wParam, lParam);
- return 0;
- }
- }
- break;
- case MHF_SCROLLUP:
- case MHF_SCROLLDOWN:
- __super::WindowProc(uMsg, wParam, lParam);
- DrawScrollButton(NULL, MENU_BUTTON_SCROLLDOWN | MENU_BUTTON_SCROLLUP);
- return 0;
- case MTID_EX_UNBLOCKDRAW:
- KillTimer(hwnd, wParam);
- menuFlags &= ~SMIF_BLOCKDRAW;
- return 0;
- }
- break;
- case WM_KEYDOWN:
- menuFlags &= ~SMIF_BLOCKDRAW;
- switch(wParam)
- {
- case VK_RETURN:
- case VK_RIGHT:
- {
- INT iItem = FindHiliteItem(hMenu);
- if (-1 != iItem)
- return CallHookedWindowProc(iItem, TRUE, uMsg, wParam, lParam);
- }
- break;
- case VK_UP:
- {
- RECT rc;
- GetClientRect(hwnd, &rc);
- MapWindowPoints(hwnd, HWND_DESKTOP, (POINT*)&rc, 2);
- rc.top += 1;
- INT iItem = MenuItemFromPoint(hwnd, hMenu, *((POINT*)&rc));
- if (iItem >= 0)
- {
- MENUITEMINFOW mii = {0};
- mii.cbSize = sizeof(MENUITEMINFOW);
- mii.fMask = MIIM_STATE;
- if (GetMenuItemInfoW(hMenu, iItem, TRUE, &mii) &&
- 0 != (MFS_HILITE & mii.fState))
- {
- DWORD windowStyle = GetWindowLongPtr(hwnd, GWL_STYLE);
- if (0 != (WS_VISIBLE & windowStyle))
- SetWindowLongPtr(hwnd, GWL_STYLE, windowStyle & ~WS_VISIBLE);
-
- __super::WindowProc(uMsg, wParam, lParam);
-
- if (0 != (WS_VISIBLE & windowStyle))
- {
- windowStyle = GetWindowLongPtr(hwnd, GWL_STYLE);
- if (0 == (WS_VISIBLE & windowStyle))
- {
- windowStyle |= WS_VISIBLE;
- SetWindowLongPtr(hwnd, GWL_STYLE, windowStyle);
- }
- INT iNew = MenuItemFromPoint(hwnd, hMenu, *((POINT*)&rc));
- if (iNew != iItem)
- {
- DrawScrollButton(NULL, MENU_BUTTON_SCROLLUP | MENU_BUTTON_SCROLLDOWN);
- InvalidateRect(hwnd, NULL, FALSE);
- }
- else
- {
- int iHilite = GetMenuItemCount(hMenu);
- while(0 < iHilite--)
- {
- if (FALSE != GetMenuItemInfoW(hMenu, iHilite, TRUE, &mii) &&
- 0 != (MFS_HILITE & mii.fState))
- {
- break;
- }
- }
- if (FALSE != GetMenuItemRect(hwnd, hMenu, iItem, &rc))
- {
- MapWindowPoints(HWND_DESKTOP, hwnd, (POINT*)&rc, 2);
- InvalidateRect(hwnd, &rc, FALSE);
- }
- if (iHilite != iItem &&
- FALSE != GetMenuItemRect(hwnd, hMenu, iHilite, &rc))
- {
- MapWindowPoints(HWND_DESKTOP, hwnd, (POINT*)&rc, 2);
- InvalidateRect(hwnd, &rc, FALSE);
- }
- }
- }
- return 0;
- }
- }
- }
- break;
- case VK_DOWN:
- {
- RECT rc;
- GetClientRect(hwnd, &rc);
- MapWindowPoints(hwnd, HWND_DESKTOP, (POINT*)&rc, 2);
- rc.top = rc.bottom - 1;
- INT item = MenuItemFromPoint(hwnd, hMenu, *((POINT*)&rc));
- if (item >= 0)
- {
- MENUITEMINFOW mii = {0};
- mii.cbSize = sizeof(MENUITEMINFOW);
- mii.fMask = MIIM_STATE;
- if (GetMenuItemInfoW(hMenu, item, TRUE, &mii) &&
- MFS_HILITE == ((MFS_HILITE | MFS_DISABLED | MFS_GRAYED) & mii.fState))
- {
- DWORD windowStyle = GetWindowLongPtr(hwnd, GWL_STYLE);
- SetWindowLongPtr(hwnd, GWL_STYLE, windowStyle & ~WS_VISIBLE);
- __super::WindowProc(uMsg, wParam, lParam);
- SetWindowLongPtr(hwnd, GWL_STYLE, windowStyle);
- INT iNew = MenuItemFromPoint(hwnd, hMenu, *((POINT*)&rc));
- if (iNew != item)
- {
- DrawScrollButton(NULL, MENU_BUTTON_SCROLLUP | MENU_BUTTON_SCROLLDOWN);
- InvalidateRect(hwnd, NULL, FALSE);
- }
- return 0;
- }
- }
- }
- break;
- }
- break;
- }
- return __super::WindowProc(uMsg, wParam, lParam);
- }
|