| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331 | #include "main.h"#include "./travelLogHelper.h"#include "./graphics.h"#include "./resource.h"#include "./ifc_skinhelper.h"#include "./ifc_imageloader.h"#include "./menu.h"#include "../Plugins/General/gen_ml/ml_ipc_0313.h"#include <exdisp.h>#include <tlogstg.h>#define TRAVELLOGPOPUP_MAXCHARWIDTH			42TravelLogHelper::TravelLogHelper(IWebBrowser2 *pWeb) 	: ref(1), pWeb2(pWeb), bitmap(NULL), pixelData(NULL), firstFwd(FALSE), entriesCount(0), backEntry(-1){	if (NULL != pWeb2)		pWeb2->AddRef();}TravelLogHelper::~TravelLogHelper(){	if (NULL != pWeb2)		pWeb2->Release();	if (NULL != bitmap)		DeleteObject(bitmap);}HRESULT TravelLogHelper::CreateInstance(IWebBrowser2 *pWeb2, TravelLogHelper **instance){	if (NULL == instance) return E_POINTER;	*instance = NULL;	if (NULL == pWeb2)		return E_INVALIDARG;	*instance = new TravelLogHelper(pWeb2);	if (NULL == *instance) return E_OUTOFMEMORY;	return S_OK;}size_t TravelLogHelper::AddRef(){	return InterlockedIncrement((LONG*)&ref);}size_t TravelLogHelper::Release(){	if (0 == ref)		return ref;		LONG r = InterlockedDecrement((LONG*)&ref);	if (0 == r)		delete(this);		return r;}int TravelLogHelper::QueryInterface(GUID interface_guid, void **object){	if (NULL == object) return E_POINTER;	if (IsEqualIID(interface_guid, IFC_TravelLogHelper))		*object = static_cast<ifc_travelloghelper*>(this);	else if (IsEqualIID(interface_guid, IFC_MenuCustomizer))		*object = static_cast<ifc_menucustomizer*>(this);	else	{		*object = NULL;		return E_NOINTERFACE;	}	if (NULL == *object)		return E_UNEXPECTED;	AddRef();	return S_OK;}HRESULT	TravelLogHelper::QueryStorage(ITravelLogStg **ppLog){	HRESULT hr;	if (NULL == ppLog)		return E_POINTER;	*ppLog = NULL;	if (NULL == pWeb2) return E_UNEXPECTED;	IServiceProvider *pProvider;	hr = pWeb2->QueryInterface(IID_IServiceProvider, (void**)&pProvider);	if (SUCCEEDED(hr))	{		hr = pProvider->QueryService(SID_STravelLogCursor, ppLog);		pProvider->Release();	}	return hr;}BOOL TravelLogHelper::DrawIcon(HMENU menuInstance, HDC hdc, DRAWITEMSTRUCT *pdis){	if (0 == (ODS_SELECTED & pdis->itemState))		return FALSE;		LONG entry = pdis->itemID - 101;	if (entry < 0 || ((ULONG)entry) > entriesCount)		return FALSE;	BOOL fForward = (FALSE != firstFwd) ? TRUE : FALSE;	if (-1 != backEntry && entry >= backEntry)		fForward = !fForward;	if (NULL == bitmap)	{		ifc_omimageloader *imageLoader;		if (SUCCEEDED(Plugin_QueryImageLoader(Plugin_GetInstance(), MAKEINTRESOURCE(IDR_MENUARROW_IMAGE), FALSE, &imageLoader)))		{			if (SUCCEEDED(imageLoader->LoadBitmapEx(&bitmap, &header, &pixelData)))			{							if (header.biHeight < 0) header.biHeight = -header.biHeight;				Image_Colorize((BYTE*)pixelData, header.biWidth, header.biHeight, 						header.biBitCount, GetBkColor(hdc), GetTextColor(hdc), TRUE);			}			imageLoader->Release();		}	}		BOOL resultOk = FALSE;	if (NULL != bitmap)	{		INT cx = header.biWidth/2;		INT cy = header.biHeight;		if (cy < 0) cy = -cy;		INT side = (pdis->rcItem.bottom - pdis->rcItem.top - 2);		if (cy < side) side = cy;		INT top = pdis->rcItem.top + ((pdis->rcItem.bottom - pdis->rcItem.top) - side)/2;		INT left = pdis->rcItem.left + (GetSystemMetrics(SM_CXMENUCHECK) - side)/2 + 3;		resultOk = StretchDIBits(hdc, left, top, side, side, 					((FALSE != fForward) ? cx : 0), 0, cx, cy, pixelData, (BITMAPINFO*)&header, DIB_RGB_COLORS, SRCCOPY);	}	return resultOk;}INT TravelLogHelper::CustomDraw(HMENU menuInstance, INT action, HDC hdc, LPARAM param){	switch(action)	{		case MLMENU_ACTION_DRAWITEM:			return MLMENU_WANT_DRAWPART;		case MLMENU_ACTION_DRAWICON:			return DrawIcon(menuInstance, hdc, (DRAWITEMSTRUCT*)param);	}	return FALSE;}HRESULT TravelLogHelper::ShowPopup(UINT fuFlags, INT x, INT y, HWND hwnd, LPTPMPARAMS lptpm){	HRESULT hr;	ITravelLogStg *pLog;	hr = QueryStorage(&pLog);	if (FAILED(hr) || NULL == pLog) return hr;		DWORD entriesMax;	if (FAILED(pLog->GetCount(TLEF_RELATIVE_FORE | TLEF_RELATIVE_BACK, &entriesMax)))		entriesMax = 0;	ITravelLogEntry **entries = NULL;	INT selectedEntry = -1;	firstFwd = (0 == (TPM_BOTTOMALIGN & fuFlags));	entriesCount = 0;	backEntry = -1;	if (0 != entriesMax)	{		entries = (ITravelLogEntry**)calloc(entriesMax, sizeof(ITravelLogEntry*));		if (NULL != entries)		{			IEnumTravelLogEntry *pEnum = NULL;			TLENUMF tlenum = (0 != (TPM_BOTTOMALIGN & fuFlags)) ? TLEF_RELATIVE_BACK : TLEF_RELATIVE_FORE;			if (SUCCEEDED(pLog->EnumEntries(tlenum, &pEnum)))			{				ULONG fetched;				pEnum->Reset();				pEnum->Next(entriesMax - entriesCount, &entries[entriesCount], &fetched);				if (0 != fetched)				{					ITravelLogEntry *t, **l, **r;					for (l = &entries[entriesCount], r = &entries[entriesCount + fetched - 1]; l < r; l++, r--)					{						t = *l;						*l = *r;						*r = t;					}					entriesCount += fetched;				}				pEnum->Release();			}			tlenum = (0 != (TLEF_RELATIVE_FORE & tlenum)) ?						((tlenum & ~TLEF_RELATIVE_FORE) | TLEF_RELATIVE_BACK) :						tlenum = ((tlenum & ~TLEF_RELATIVE_BACK) | TLEF_RELATIVE_FORE);			if (SUCCEEDED(pLog->EnumEntries(tlenum, &pEnum)))			{				ULONG fetched;				pEnum->Reset();				pEnum->Next(entriesMax - entriesCount, &entries[entriesCount], &fetched);				if (0 != fetched)				{					backEntry = entriesCount;					entriesCount += fetched;				}				pEnum->Release();			}		}		if (entriesCount > 0)		{			HMENU hMenu = CreatePopupMenu();			if (NULL != hMenu)			{				MENUITEMINFOW mii = {0};				mii.cbSize = sizeof(MENUITEMINFOW);				mii.fMask = MIIM_STRING | MIIM_ID | MIIM_STATE;				mii.fState = MFS_ENABLED | MFS_UNCHECKED;											for (ULONG i = 0; i < entriesCount; i++)				{					if (NULL != entries[i])					{						LPWSTR pszTitle;						if (SUCCEEDED(entries[i]->GetTitle(&pszTitle)) && NULL != pszTitle)						{							INT cchTitle = lstrlen(pszTitle);							if (cchTitle > TRAVELLOGPOPUP_MAXCHARWIDTH)							{								pszTitle[TRAVELLOGPOPUP_MAXCHARWIDTH] = L'\0';								for (INT k = 0; k < 3; k++)									pszTitle[TRAVELLOGPOPUP_MAXCHARWIDTH - 1 - k] = L'.'; 							}							mii.dwTypeData = pszTitle;							mii.wID = 101 + i;							InsertMenuItem(hMenu, i, TRUE, &mii);							CoTaskMemFree(pszTitle);						}					}				}				{ // insert current page					WCHAR szBuffer[256] = {0};					Plugin_LoadString(IDS_CURRENT_PAGE, szBuffer, ARRAYSIZE(szBuffer));					mii.dwTypeData = szBuffer;					mii.fMask = MIIM_STRING | MIIM_ID | MIIM_STATE | MIIM_FTYPE;					mii.fState = MFS_ENABLED | MFS_DEFAULT | MFS_CHECKED;					mii.fType = MFT_STRING | MFT_RADIOCHECK;					mii.wID = 100;					if (-1 == backEntry)						InsertMenuItem(hMenu, GetMenuItemCount(hMenu), TRUE, &mii);					else						InsertMenuItem(hMenu, 101 + backEntry, FALSE, &mii);				}																HANDLE hHook = Menu_InitializeHook(hwnd, this);									UINT commandId = TrackPopupMenuEx(hMenu, fuFlags | TPM_RETURNCMD, x, y, hwnd, lptpm);				if (NULL != hHook) Menu_RemoveHook(hHook);				if (commandId > 100 && commandId <= (100 + entriesCount))					selectedEntry = commandId - 101;				DestroyMenu(hMenu);			}		}	}		if (-1 != selectedEntry && NULL != entries[selectedEntry])	{		pLog->TravelTo(entries[selectedEntry]);	}	if (NULL != entries)	{		for (ULONG i = 0; i < entriesCount; i++)		{			if (NULL != entries[i]) entries[i]->Release();		}		free(entries);	}	pLog->Release();	return hr;}#define CBCLASS TravelLogHelperSTART_MULTIPATCH; START_PATCH(MPIID_TRAVELLOGHELPER)  M_CB(MPIID_TRAVELLOGHELPER, ifc_travelloghelper, ADDREF, AddRef);  M_CB(MPIID_TRAVELLOGHELPER, ifc_travelloghelper, RELEASE, Release);  M_CB(MPIID_TRAVELLOGHELPER, ifc_travelloghelper, QUERYINTERFACE, QueryInterface);  M_CB(MPIID_TRAVELLOGHELPER, ifc_travelloghelper, API_QUERYSTORAGE, QueryStorage);  M_CB(MPIID_TRAVELLOGHELPER, ifc_travelloghelper, API_SHOWPOPUP, ShowPopup); NEXT_PATCH(MPIID_MENUCUSTOMIZER)  M_CB(MPIID_MENUCUSTOMIZER, ifc_menucustomizer, ADDREF, AddRef);  M_CB(MPIID_MENUCUSTOMIZER, ifc_menucustomizer, RELEASE, Release);  M_CB(MPIID_MENUCUSTOMIZER, ifc_menucustomizer, QUERYINTERFACE, QueryInterface);	  M_CB(MPIID_MENUCUSTOMIZER, ifc_menucustomizer, API_CUSTOMDRAW, CustomDraw); END_PATCHEND_MULTIPATCH;#undef CBCLASS
 |