Files
BuildTools
Qt
Src
Agave
Components
Elevator
Mastering
Plugins
ReplayGainAnalysis
WAT
Wasabi
Wasabi2
Winamp
aacPlus
aacdec
aacdec-mft
adpcm
alac
albumart
apev2
auth
bmp
burnlib
codesign
config
devices
external_dependencies
f263
filereader
freetypewac
gif
gracenote
h264
h264dec
id3v2
ie_plugin
installer
jpeg
libvp6
libvpShared
mp3-mpg123
mp4v
mpeg4dec
nde
nprt_plugin
ns-eel
ns-eel2
nsavi
nsmkv
nsutil
nsv
nsvdec_vp3
nsvdec_vp5
nsvdec_vp6
nswasabi
nu
omBrowser
localization
resources
addressEncoder.cpp
addressEncoder.h
browser.cpp
browser.h
browserClass.cpp
browserClass.h
browserFactory.cpp
browserFactory.h
browserHost.cpp
browserHost.h
browserInternal.cpp
browserInternal.h
browserObject.cpp
browserObject.h
browserPopup.cpp
browserPopup.h
browserRegistry.cpp
browserRegistry.h
browserThread.cpp
browserThread.h
browserUiCommon.cpp
browserUiCommon.h
browserUiHook.cpp
browserUiHook.h
browserUiInternal.h
browserView.cpp
browserView.h
browserWndEnum.cpp
browserWndEnum.h
browserWndRecord.cpp
browserWndRecord.h
cacheDownloader.cpp
cacheDownloader.h
cacheGroup.cpp
cacheGroup.h
cacheManager.cpp
cacheManager.h
cacheRecord.cpp
cacheRecord.h
common.h
component.cpp
component.h
configIni.cpp
configIni.h
curtain.cpp
curtain.h
enumAsync.cpp
enumAsync.h
enumIniFile.cpp
enumIniFile.h
enumXmlBuffer.cpp
enumXmlBuffer.h
enumXmlFile.cpp
enumXmlFile.h
errorPages.rc
flagTracker.cpp
flagTracker.h
graphics.cpp
graphics.h
graphicsObject.cpp
graphicsObject.h
ieversion.cpp
ieversion.h
ifc_imageloader.h
ifc_menucustomizer.h
ifc_mlnavigationcallback.h
ifc_mlnavigationhelper.h
ifc_ombrowserclass.h
ifc_ombrowserconfig.h
ifc_ombrowserevent.h
ifc_ombrowsereventmngr.h
ifc_ombrowserregistry.h
ifc_ombrowserwndenum.h
ifc_ombrowserwndmngr.h
ifc_omcachecallback.h
ifc_omcachegroup.h
ifc_omcachemanager.h
ifc_omcacherecord.h
ifc_omconfig.h
ifc_omconfigcallback.h
ifc_omdebugconfig.h
ifc_omfilestorage.h
ifc_omgraphics.h
ifc_omservice.h
ifc_omservicecommand.h
ifc_omservicecopier.h
ifc_omservicedetails.h
ifc_omserviceeditor.h
ifc_omserviceenum.h
ifc_omserviceevent.h
ifc_omserviceeventmngr.h
ifc_omservicehost.h
ifc_omservicehostext.h
ifc_omservicemanager.h
ifc_omstatusbarconfig.h
ifc_omstorage.h
ifc_omstorageasync.h
ifc_omstorageenum.h
ifc_omstorageext.h
ifc_omstoragehandler.h
ifc_omstoragehandlerenum.h
ifc_omstoragehelper.h
ifc_omtoolbarconfig.h
ifc_omutility.h
ifc_omwebstorage.h
ifc_omxmlserviceenum.h
ifc_skinhelper.h
ifc_skinnedbrowser.h
ifc_skinnedmenu.h
ifc_skinnedrating.h
ifc_travelloghelper.h
ifc_wasabihelper.h
ifc_winamphook.h
internetFeatures.cpp
internetFeatures.h
loaderIni.cpp
loaderIni.h
main.cpp
main.h
menu.cpp
menu.h
mlNavigationHelper.cpp
mlNavigationHelper.h
obj_ombrowser.h
omBrowser.rc
omBrowser.sln
omBrowser.vcxproj
omBrowser.vcxproj.filters
options.cpp
options.h
optionsDebug.cpp
optionsHook.cpp
optionsHook.h
optionsInfo.cpp
optionsUi.cpp
png.rc
pngLoader.cpp
pngLoader.h
ratingMenu.cpp
ratingMenu.h
ratingMenuCustomizer.cpp
ratingMenuCustomizer.h
resource.h
service.cpp
service.h
serviceDetails.cpp
serviceDispatch.cpp
serviceEditor.cpp
serviceEventMngr.cpp
serviceFactory.cpp
serviceFactory.h
serviceList.cpp
serviceList.h
serviceManager.cpp
serviceManager.h
skinHelper.cpp
skinHelper.h
statusbar.cpp
statusbar.h
storageDwnld.cpp
storageDwnld.h
storageEnum.cpp
storageEnum.h
storageHandler.cpp
storageHandler.h
storageHandlerEnum.cpp
storageHandlerEnum.h
storageHelper.cpp
storageHelper.h
storageIni.cpp
storageIni.h
storageUrl.cpp
storageUrl.h
storageXml.cpp
storageXml.h
stringBuilder.cpp
stringBuilder.h
toolbar.cpp
toolbar.h
toolbarAddress.cpp
toolbarAddress.h
toolbarButton.cpp
toolbarButton.h
toolbarEditbox.cpp
toolbarEditbox.h
toolbarItem.cpp
toolbarItem.h
toolbarProgress.cpp
toolbarProgress.h
toolbarRating.cpp
toolbarRating.h
toolbarStatic.cpp
toolbarStatic.h
travelLogHelper.cpp
travelLogHelper.h
utility.cpp
utility.h
utilityFactory.cpp
utilityFactory.h
version.rc2
wasabiHelper.cpp
wasabiHelper.h
winampHook.cpp
winampHook.h
xmlResponseParser.cpp
xmlResponseParser.h
xmlServiceParser.cpp
xmlServiceParser.h
pcm
pfc
playlist
plist
png
replicant
resources
tagz
tataki
theora
timer
vlb
vp32
vp6
vp8x
wbm
winampAll
winampa
xml
xspf
vcpkg-ports
.gitignore
LICENSE.md
README.md
automate-git.py
cef_x86.bat
install-packages.cmd
vcpkg_version_finder.py
winampAll_2019.sln
winamp/Src/omBrowser/winampHook.cpp
2024-09-24 14:54:57 +02:00

288 lines
7.3 KiB
C++

#include "main.h"
#include "./winampHook.h"
#include "./ifc_winamphook.h"
#include "../winamp/wa_ipc.h"
#include <windows.h>
#define WINAMP_REFRESHSKIN 40291
#define WHPROCRECOVERY L"WaHookProcRecovery"
static ATOM WAWNDATOM = 0;
#define GetWinampHook(__hwnd) ((WinampHook*)GetProp((__hwnd), MAKEINTATOM(WAWNDATOM)))
WinampHook::WinampHook(HWND hwndWinamp)
: ref(1), hwnd(hwndWinamp), originalProc(NULL), flags(0), lastCookie(0)
{
}
WinampHook::~WinampHook()
{
DetachFromWinamp();
if (0 != WAWNDATOM)
{
GlobalDeleteAtom(WAWNDATOM);
WAWNDATOM = 0;
}
}
HRESULT WinampHook::CreateInstance(HWND hwndWinamp, WinampHook **instance)
{
if (NULL == instance) return E_POINTER;
*instance = NULL;
if (NULL == hwndWinamp || FALSE == IsWindow(hwndWinamp))
return E_INVALIDARG;
*instance = new WinampHook(hwndWinamp);
if (NULL == *instance) return E_OUTOFMEMORY;
return S_OK;
}
ULONG WinampHook::AddRef()
{
return InterlockedIncrement((LONG*)&ref);
}
ULONG WinampHook::Release()
{
if (0 == ref)
return ref;
LONG r = InterlockedDecrement((LONG*)&ref);
if (0 == r)
delete(this);
return r;
}
HRESULT WinampHook::RegisterCallback(ifc_winamphook *callback, UINT *cookie)
{
if (NULL == cookie) return E_POINTER;
*cookie = 0;
if (NULL == callback) return E_INVALIDARG;
if (FAILED(AttachToWinamp()))
return E_UNEXPECTED;
*cookie = ++lastCookie;
callbackMap.insert({ *cookie, callback });
callback->AddRef();
return S_OK;
}
HRESULT WinampHook::UnregisterCallback(UINT cookie)
{
if (0 == cookie) return E_INVALIDARG;
for(CallbackMap::iterator iter = callbackMap.begin(); iter != callbackMap.end(); iter++)
{
if (cookie == iter->first)
{
ifc_winamphook *hook = iter->second;
callbackMap.erase(iter);
if (NULL != hook)
hook->Release();
return S_OK;
}
}
return S_FALSE;
}
HWND WinampHook::GetWinamp()
{
return hwnd;
}
LRESULT WinampHook::CallPrevWinampProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (NULL == originalProc || NULL == hwnd) return 0;
return (0 != (flagUnicode & flags)) ?
CallWindowProcW(originalProc, hwnd, uMsg, wParam, lParam) :
CallWindowProcA(originalProc, hwnd, uMsg, wParam, lParam);
}
LRESULT WinampHook::CallDefWinampProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (NULL == hwnd) return 0;
return (0 != (flagUnicode & flags)) ?
DefWindowProcW(hwnd, uMsg, wParam, lParam) :
DefWindowProcA(hwnd, uMsg, wParam, lParam);
}
HRESULT WinampHook::AttachToWinamp()
{
if (NULL == hwnd || !IsWindow(hwnd)) return E_UNEXPECTED;
if (0 == WAWNDATOM)
{
WAWNDATOM = GlobalAddAtom(L"WinampHook");
if (0 == WAWNDATOM) return E_FAIL;
}
WinampHook *hookInstance = GetWinampHook(hwnd);
if (this == hookInstance) return S_FALSE;
if (NULL != hookInstance || NULL != originalProc)
return E_FAIL;
flags = 0;
if (IsWindowUnicode(hwnd)) flags |= flagUnicode;
originalProc = (WNDPROC)(LONG_PTR)SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONGX86)(LONG_PTR)WinampWindowProc);
if (NULL == originalProc || FALSE == SetProp(hwnd, MAKEINTATOM(WAWNDATOM), this))
{
if (NULL != originalProc)
SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONGX86)(LONG_PTR)originalProc);
return E_FAIL;
}
return S_OK;
}
HRESULT WinampHook::DetachFromWinamp()
{
if (NULL == hwnd || !IsWindow(hwnd)) return E_UNEXPECTED;
if (0 == WAWNDATOM) return E_FAIL;
for(CallbackMap::iterator iter = callbackMap.begin(); iter != callbackMap.end(); iter++)
{
if (NULL != iter->second)
iter->second->Release();
}
callbackMap.clear();
WinampHook *hookInstance = GetWinampHook(hwnd);
if (this != hookInstance) return E_FAIL;
RemoveProp(hwnd, MAKEINTATOM(WAWNDATOM));
WNDPROC currentProc = (WNDPROC)(LONG_PTR)GetWindowLongPtr(hwnd, GWLP_WNDPROC);
if (currentProc == WinampWindowProc)
{
SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONGX86)(LONG_PTR)originalProc);
}
else
{
SetProp(hwnd, WHPROCRECOVERY, (HANDLE)originalProc);
}
originalProc = NULL;
flags = 0;
return S_OK;
}
LRESULT WinampHook::OnWinampDestroy()
{
WNDPROC proc = originalProc;
DetachFromWinamp();
return (IsWindowUnicode(hwnd)) ?
CallWindowProcW(proc, hwnd, WM_DESTROY, 0, 0L) :
CallWindowProcA(proc, hwnd, WM_DESTROY, 0, 0L);
}
LRESULT WinampHook::OnWinampIPC(UINT commandId, WPARAM param)
{
switch(commandId)
{
case IPC_CB_RESETFONT:
for(CallbackMap::iterator iter = callbackMap.begin(); iter != callbackMap.end(); iter++)
if (NULL != iter->second) iter->second->ResetFont();
break;
case IPC_HOOK_OKTOQUIT:
for(CallbackMap::iterator iter = callbackMap.begin(); iter != callbackMap.end(); iter++)
if (NULL != iter->second && S_FALSE == iter->second->IsQuitAllowed()) return 0;
break;
case IPC_SKIN_CHANGED:
{
WCHAR szBuffer[MAX_PATH*2] = {0};
SENDWAIPC(hwnd, IPC_GETSKINW, szBuffer);
for(CallbackMap::iterator iter = callbackMap.begin(); iter != callbackMap.end(); iter++)
if (NULL != iter->second) iter->second->SkinChanged(szBuffer);
}
break;
case IPC_FF_ONCOLORTHEMECHANGED:
if (FALSE != IS_INTRESOURCE(param))
param = 0L;
for(CallbackMap::iterator iter = callbackMap.begin(); iter != callbackMap.end(); iter++)
if (NULL != iter->second) iter->second->SkinColorChange((LPCWSTR)param);
break;
case IPC_FILE_TAG_MAY_HAVE_UPDATED:
{
WCHAR szBuffer[MAX_PATH*2] = {0};
param = (0 != MultiByteToWideChar(CP_ACP, 0, (char*)param, -1, szBuffer, ARRAYSIZE(szBuffer))) ?
(WPARAM)szBuffer : 0L;
for(CallbackMap::iterator iter = callbackMap.begin(); iter != callbackMap.end(); iter++)
if (NULL != iter->second) iter->second->FileMetaChange((LPCWSTR)param);
}
break;
case IPC_FILE_TAG_MAY_HAVE_UPDATEDW:
for(CallbackMap::iterator iter = callbackMap.begin(); iter != callbackMap.end(); iter++)
if (NULL != iter->second) iter->second->FileMetaChange((LPCWSTR)param);
break;
}
return CallPrevWinampProc(WM_WA_IPC, param, (LPARAM)commandId);
}
void WinampHook::OnWinampCommand(UINT commandId, UINT controlId, HWND hControl)
{
switch(commandId)
{
case WINAMP_REFRESHSKIN:
for(CallbackMap::iterator iter = callbackMap.begin(); iter != callbackMap.end(); iter++)
if (NULL != iter->second) iter->second->SkinChanging();
break;
}
}
void WinampHook::OnSysColorChange()
{
for(CallbackMap::iterator iter = callbackMap.begin(); iter != callbackMap.end(); iter++)
if (NULL != iter->second) iter->second->SysColorChange();
}
LRESULT WinampHook::WindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_DESTROY: return OnWinampDestroy();
case WM_WA_IPC: return OnWinampIPC((UINT)lParam, wParam);
case WM_COMMAND: OnWinampCommand(LOWORD(wParam), HIWORD(wParam), (HWND)lParam); break;
case WM_SYSCOLORCHANGE: OnSysColorChange(); break;
}
return CallPrevWinampProc(uMsg, wParam, lParam);
}
static LRESULT CALLBACK WinampWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
WinampHook *hookInstance = GetWinampHook(hwnd);
if (NULL == hookInstance)
{
WNDPROC recovery = (WNDPROC)GetProp(hwnd, WHPROCRECOVERY);
if (NULL != recovery)
{
return (IsWindowUnicode(hwnd)) ?
CallWindowProcW(recovery, hwnd, uMsg, wParam, lParam) :
CallWindowProcA(recovery, hwnd, uMsg, wParam, lParam);
}
return (IsWindowUnicode(hwnd)) ?
DefWindowProcW(hwnd, uMsg, wParam, lParam) :
DefWindowProcA(hwnd, uMsg, wParam, lParam);
}
return hookInstance->WindowProc(uMsg, wParam, lParam);
}