winamp/Src/Winamp/updateService.cpp
2024-09-24 14:54:57 +02:00

233 lines
4.9 KiB
C++

#include "main.h"
#include "./updateService.h"
#include "./api.h"
#include "./externalCOM.h"
#include "../omBrowser/obj_ombrowser.h"
#include "../omBrowser/ifc_omservice.h"
#include "../omBrowser/browserPopup.h"
#include "../omBrowser/ifc_omdebugconfig.h"
HRESULT ServiceSubclass_Attach(HWND hwnd, UpdateService *service);
UpdateService::UpdateService(obj_ombrowser *browserObject, LPWSTR pszUrl)
: ref(1), url(pszUrl), browserManager(browserObject)
{
if (NULL != browserManager)
browserManager->AddRef();
}
UpdateService::~UpdateService()
{
Finish();
}
HRESULT UpdateService::CreateInstance(LPCSTR pszUrl, UpdateService **instance)
{
if (NULL == instance)
return E_POINTER;
*instance = NULL;
waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(OBJ_OmBrowser);
if (NULL == sf) return E_FAIL;
obj_ombrowser *browserManager = reinterpret_cast<obj_ombrowser*>(sf->getInterface());
sf->Release();
if (NULL == browserManager)
return E_NOINTERFACE;
HRESULT hr = browserManager->Initialize(NULL, hMainWindow);
if (SUCCEEDED(hr))
{
LPWSTR url = NULL;
if (NULL != pszUrl)
{
UINT cchUrlMax = MultiByteToWideChar(CP_UTF8, 0, pszUrl, -1, NULL, 0);
if (0 != cchUrlMax)
{
cchUrlMax++;
url = (LPWSTR)calloc(cchUrlMax, sizeof(WCHAR));
if (NULL == url) hr = E_OUTOFMEMORY;
else
{
if (0 == MultiByteToWideChar(CP_UTF8, 0, pszUrl, -1, url, cchUrlMax))
hr = E_FAIL;
}
}
}
if (SUCCEEDED(hr))
{
*instance = new UpdateService(browserManager, url);
if (NULL == *instance)
{
if (NULL != url) free(url);
hr = E_OUTOFMEMORY;
}
}
}
browserManager->Release();
return hr;
}
size_t UpdateService::AddRef()
{
return InterlockedIncrement((LONG*)&ref);
}
size_t UpdateService::Release()
{
if (0 == ref)
return ref;
LONG r = InterlockedDecrement((LONG*)&ref);
if (0 == r)
delete(this);
return r;
}
int UpdateService::QueryInterface(GUID interface_guid, void **object)
{
if (NULL == object) return E_POINTER;
if (IsEqualIID(interface_guid, IFC_OmService))
*object = static_cast<ifc_omservice*>(this);
else
{
*object = NULL;
return E_NOINTERFACE;
}
if (NULL == *object)
return E_UNEXPECTED;
AddRef();
return S_OK;
}
unsigned int UpdateService::GetId()
{
return 505;
}
HRESULT UpdateService::GetName(wchar_t *pszBuffer, int cchBufferMax)
{
getStringW(IDS_WINAMP_UPDATE, pszBuffer, cchBufferMax);
return S_OK;
}
HRESULT UpdateService::GetUrl(wchar_t *pszBuffer, int cchBufferMax)
{
return StringCchCopyExW(pszBuffer, cchBufferMax, url, NULL, NULL, STRSAFE_IGNORE_NULLS );
}
HRESULT UpdateService::GetIcon(wchar_t *pszBuffer, int cchBufferMax)
{
return E_NOTIMPL;
}
HRESULT UpdateService::GetExternal(IDispatch **ppDispatch)
{
if (NULL == ppDispatch)
return E_POINTER;
ExternalCOM *external;
HRESULT hr = JSAPI1_GetExternal(&external);
if (FAILED(hr)) external = NULL;
*ppDispatch = (IDispatch*)external;
return S_OK;
}
HRESULT UpdateService::Show()
{
if (NULL == browserManager)
return E_UNEXPECTED;
LONG cx = 300;
LONG cy = 200;
RECT centerRect;
HWND hCenter = (NULL != g_dialog_box_parent) ? g_dialog_box_parent : hMainWindow;
if (NULL == hCenter ||
0 == GetWindowRect(hCenter, &centerRect) ||
((centerRect.right - centerRect.left) < cx) ||
((centerRect.bottom - centerRect.top) < cy))
{
HMONITOR hMonitor = MonitorFromWindow(hCenter, MONITOR_DEFAULTTONEAREST);
MONITORINFO info;
info.cbSize = sizeof(info);
if (NULL != hMonitor && 0 != GetMonitorInfo(hMonitor, &info))
CopyRect(&centerRect, &info.rcWork);
else
SetRectEmpty(&centerRect);
}
LONG x = centerRect.left + (centerRect.right - centerRect.left - cx)/2;
LONG y = centerRect.top + (centerRect.bottom - centerRect.top - cy)/2;
if (x < centerRect.left) x = centerRect.left;
if (y < centerRect.top) y = centerRect.top;
UINT popupFlags = NBCS_NOTOOLBAR | NBCS_NOSTATUSBAR | NBCS_DIALOGMODE | NBCS_BLOCKPOPUP;
ifc_omdebugconfig *debugConfig;
if (SUCCEEDED(browserManager->GetConfig(&IFC_OmDebugConfig, (void**)&debugConfig)))
{
if (S_OK == debugConfig->GetMenuFilterEnabled())
popupFlags |= NBCS_DISABLECONTEXTMENU;
debugConfig->Release();
}
HWND hPopup;
HRESULT hr = browserManager->CreatePopup(this, x, y, cx, cy, hMainWindow, NULL, popupFlags, &hPopup);
if (SUCCEEDED(hr))
{
if (FAILED(ServiceSubclass_Attach(hPopup, this)))
{
ShowWindowAsync(hPopup, SW_SHOWNORMAL);
}
}
return hr;
}
HRESULT UpdateService::Finish()
{
if (NULL != browserManager)
{
browserManager->Finish();
browserManager->Release();
browserManager = NULL;
}
if (NULL != url)
{
free(url);
url = NULL;
}
return S_OK;
}
#define CBCLASS UpdateService
START_DISPATCH;
CB(ADDREF, AddRef)
CB(RELEASE, Release)
CB(QUERYINTERFACE, QueryInterface)
CB(API_GETID, GetId)
CB(API_GETNAME, GetName)
CB(API_GETURL, GetUrl)
CB(API_GETICON, GetIcon)
CB(API_GETEXTERNAL, GetExternal)
END_DISPATCH;
#undef CBCLASS