Initial community commit
This commit is contained in:
parent
537bcbc862
commit
fc06254474
16440 changed files with 4239995 additions and 2 deletions
941
Src/Winamp/application.cpp
Normal file
941
Src/Winamp/application.cpp
Normal file
|
@ -0,0 +1,941 @@
|
|||
/** (c) Nullsoft, Inc. C O N F I D E N T I A L
|
||||
** Filename: application.cpp
|
||||
** Project: Winamp 5
|
||||
** Description: Winamp's implementation of Wasabi's Application API.
|
||||
** Also includes the main message loop.
|
||||
** Author: Ben Allison benski@nullsoft.com
|
||||
** Created:
|
||||
**/
|
||||
#include "main.h"
|
||||
#include "application.h"
|
||||
#include "../nu/AutoWide.h"
|
||||
#include "api.h"
|
||||
#include "../nu/ns_wc.h"
|
||||
|
||||
#define WIDEN2(x) L ## x
|
||||
#define WIDEN(x) WIDEN2(x)
|
||||
|
||||
static UINT WINAMP_WM_DIRECT_MOUSE_WHEEL = WM_NULL;
|
||||
static ATOM DIRECT_MOUSE_WHEEL_CONVERT_TO_MOUSE_WHEEL = 0;
|
||||
|
||||
static BOOL DirectMouseWheel_RegisterMessage()
|
||||
{
|
||||
WINAMP_WM_DIRECT_MOUSE_WHEEL = RegisterWindowMessageW(L"WINAMP_WM_DIRECT_MOUSE_WHEEL");
|
||||
if (WM_NULL == WINAMP_WM_DIRECT_MOUSE_WHEEL)
|
||||
return FALSE;
|
||||
|
||||
if (NULL != application)
|
||||
application->DirectMouseWheel_InitBlackList();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL
|
||||
IsDirectMouseWheelMessage(const UINT uMsg)
|
||||
{
|
||||
if (WM_NULL == WINAMP_WM_DIRECT_MOUSE_WHEEL)
|
||||
{
|
||||
if (FALSE == DirectMouseWheel_RegisterMessage())
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return (WINAMP_WM_DIRECT_MOUSE_WHEEL == uMsg);
|
||||
}
|
||||
|
||||
BOOL
|
||||
DirectMouseWheel_EnableConvertToMouseWheel(HWND hwnd, BOOL enable)
|
||||
{
|
||||
if (FALSE != enable)
|
||||
{
|
||||
if (0 == DIRECT_MOUSE_WHEEL_CONVERT_TO_MOUSE_WHEEL)
|
||||
{
|
||||
DIRECT_MOUSE_WHEEL_CONVERT_TO_MOUSE_WHEEL = GlobalAddAtomW(L"DIRECT_MOUSE_WHEEL_CONVERT_TO_MOUSE_WHEEL");
|
||||
if (0 == DIRECT_MOUSE_WHEEL_CONVERT_TO_MOUSE_WHEEL)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (0 == SetPropW(hwnd, (const wchar_t*)MAKEINTATOM(DIRECT_MOUSE_WHEEL_CONVERT_TO_MOUSE_WHEEL), (HANDLE)1))
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (0 != DIRECT_MOUSE_WHEEL_CONVERT_TO_MOUSE_WHEEL)
|
||||
RemovePropW(hwnd, (const wchar_t*)MAKEINTATOM(DIRECT_MOUSE_WHEEL_CONVERT_TO_MOUSE_WHEEL));
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL
|
||||
DirectMouseWheel_IsConvertToMouseWheelEnabled(HWND hwnd)
|
||||
{
|
||||
return(0 != DIRECT_MOUSE_WHEEL_CONVERT_TO_MOUSE_WHEEL &&
|
||||
NULL != GetPropW(hwnd, (const wchar_t*)MAKEINTATOM(DIRECT_MOUSE_WHEEL_CONVERT_TO_MOUSE_WHEEL)));
|
||||
}
|
||||
|
||||
Application::Application()
|
||||
: shuttingdown(0), activeDialog(NULL), machineID(GUID_NULL), userID(GUID_NULL), sessionID(GUID_NULL),
|
||||
threadStorageIndex(TLS_OUT_OF_INDEXES), messageHook(NULL), disableMessageHook(false)
|
||||
{
|
||||
tlsIndex = TlsAlloc();
|
||||
}
|
||||
|
||||
Application::~Application()
|
||||
{
|
||||
if (NULL != messageHook)
|
||||
{
|
||||
UnhookWindowsHookEx(messageHook);
|
||||
messageHook = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
const wchar_t *Application::main_getAppName()
|
||||
{
|
||||
return WIDEN(APP_NAME);
|
||||
}
|
||||
|
||||
const wchar_t *Application::main_getVersionString()
|
||||
{
|
||||
return WIDEN(APP_NAME) L" " WIDEN(APP_VERSION_STRING);
|
||||
}
|
||||
|
||||
const wchar_t *Application::main_getVersionNumString()
|
||||
{
|
||||
return WIDEN(APP_VERSION);
|
||||
}
|
||||
|
||||
unsigned int Application::main_getBuildNumber()
|
||||
{
|
||||
return BUILD_NUMBER;
|
||||
}
|
||||
|
||||
// a guid for our app : {4BE592C7-6937-426a-A388-ACF0EBC88E93}
|
||||
static const GUID WinampGUID =
|
||||
{
|
||||
0x4be592c7, 0x6937, 0x426a, { 0xa3, 0x88, 0xac, 0xf0, 0xeb, 0xc8, 0x8e, 0x93 }
|
||||
};
|
||||
|
||||
GUID Application::main_getGUID()
|
||||
{
|
||||
return WinampGUID;
|
||||
}
|
||||
|
||||
HANDLE Application::main_getMainThreadHandle()
|
||||
{
|
||||
if (hMainThread == 0)
|
||||
return (HANDLE)0;
|
||||
HANDLE h = (HANDLE)0;
|
||||
DuplicateHandle(GetCurrentProcess(), hMainThread, GetCurrentProcess(), &h, 0, FALSE, DUPLICATE_SAME_ACCESS);
|
||||
return h;
|
||||
}
|
||||
|
||||
HINSTANCE Application::main_gethInstance()
|
||||
{
|
||||
return hMainInstance;
|
||||
}
|
||||
|
||||
const wchar_t *Application::main_getCommandLine()
|
||||
{
|
||||
return GetCommandLineW();
|
||||
}
|
||||
|
||||
void Application::main_shutdown(int deferred)
|
||||
{
|
||||
|
||||
int x = static_cast<int>(SendMessageW(hMainWindow, WM_WA_IPC, 0, IPC_IS_EXIT_ENABLED));
|
||||
|
||||
if (!x)
|
||||
return;
|
||||
|
||||
shuttingdown = 1;
|
||||
|
||||
SendMessageW(hMainWindow, WM_CLOSE, 0, 0);
|
||||
}
|
||||
|
||||
void Application::main_cancelShutdown()
|
||||
{
|
||||
shuttingdown = 0;
|
||||
}
|
||||
|
||||
int Application::main_isShuttingDown()
|
||||
{
|
||||
return shuttingdown;
|
||||
}
|
||||
|
||||
const wchar_t *Application::path_getAppPath()
|
||||
{
|
||||
return PROGDIR;
|
||||
}
|
||||
|
||||
const wchar_t *Application::path_getUserSettingsPath()
|
||||
{
|
||||
return CONFIGDIR;
|
||||
}
|
||||
|
||||
const wchar_t *Application::path_getSkinSettingsPath()
|
||||
{
|
||||
return SKINDIR;
|
||||
}
|
||||
|
||||
int Application::app_getInitCount()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Application::app_addMessageProcessor(api_messageprocessor *processor)
|
||||
{
|
||||
messageProcessors.push_back(processor);
|
||||
}
|
||||
|
||||
void Application::app_removeMessageProcessor(api_messageprocessor *processor)
|
||||
{
|
||||
//messageProcessors.eraseAll(processor);
|
||||
auto it = messageProcessors.begin();
|
||||
while (it != messageProcessors.end())
|
||||
{
|
||||
if (*it != processor)
|
||||
{
|
||||
it++;
|
||||
continue;
|
||||
}
|
||||
|
||||
it = messageProcessors.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
void Application::app_addModelessDialog(HWND hwnd)
|
||||
{
|
||||
OutputDebugStringA( "[Error] 'app_addModelessDialog' removed! Use 'ActiveDialog_Register' instead!\r\n" );
|
||||
}
|
||||
|
||||
void Application::app_removeModelessDialog(HWND hwnd)
|
||||
{
|
||||
OutputDebugStringA( "[Error] 'app_removeModelessDialog' removed!Use 'ActiveDialog_Unregister' instead!\r\n" );
|
||||
}
|
||||
|
||||
void Application::app_addAccelerators(HWND hwnd, HACCEL *phAccel, INT cAccel, UINT translateMode)
|
||||
{
|
||||
AccelMap::iterator accelIterator;
|
||||
ACCELNODE *pList;
|
||||
|
||||
if (accelerators.size() > 0)
|
||||
{
|
||||
accelIterator = accelerators.end();
|
||||
do
|
||||
{
|
||||
accelIterator--;
|
||||
if (!IsWindow(accelIterator->first))
|
||||
{
|
||||
//app_removeAccelerators(accelIterator->first);
|
||||
ACCELNODE* pList, * pNode;
|
||||
pList = accelIterator->second;
|
||||
while (pList)
|
||||
{
|
||||
pNode = pList;
|
||||
pList = (pList->pNext) ? pList->pNext : NULL;
|
||||
free(pNode);
|
||||
}
|
||||
accelIterator = accelerators.erase(accelIterator);
|
||||
}
|
||||
} while (accelIterator != accelerators.begin() && accelIterator != accelerators.end());
|
||||
}
|
||||
|
||||
if (!IsWindow(hwnd) || !phAccel || cAccel <= 0) return;
|
||||
|
||||
accelIterator = accelerators.find(hwnd);
|
||||
if(accelIterator != accelerators.end())
|
||||
pList = accelIterator->second;
|
||||
else
|
||||
{
|
||||
pList = (ACCELNODE*)calloc(1, sizeof(ACCELNODE));
|
||||
if(pList)
|
||||
{
|
||||
accelerators.insert({hwnd, pList});
|
||||
}
|
||||
}
|
||||
if (!pList) return;
|
||||
while (pList->pNext) pList = pList->pNext;
|
||||
|
||||
while(cAccel--)
|
||||
{
|
||||
if (*phAccel)
|
||||
{
|
||||
ACCELNODE *pNode;
|
||||
if (pList->hAccel)
|
||||
{
|
||||
pNode = (ACCELNODE*)calloc(1, sizeof(ACCELNODE));
|
||||
pNode->pNext = NULL;
|
||||
pList->pNext = pNode;
|
||||
pList = pNode;
|
||||
}
|
||||
else pNode = pList;
|
||||
|
||||
pNode->hAccel = *phAccel;
|
||||
pNode->translateMode = translateMode;
|
||||
|
||||
}
|
||||
phAccel++;
|
||||
}
|
||||
}
|
||||
|
||||
void Application::app_removeAccelerators(HWND hwnd)
|
||||
{
|
||||
AccelMap::iterator iter = accelerators.find(hwnd);
|
||||
if(iter == accelerators.end())
|
||||
return;
|
||||
|
||||
ACCELNODE *pList, *pNode;
|
||||
pList = iter->second;
|
||||
while(pList)
|
||||
{
|
||||
pNode = pList;
|
||||
pList = (pList->pNext) ? pList->pNext : NULL;
|
||||
free(pNode);
|
||||
}
|
||||
accelerators.erase(hwnd);
|
||||
}
|
||||
|
||||
int Application::app_getAccelerators(HWND hwnd, HACCEL *phAccel, INT cchAccelMax, BOOL bGlobal)
|
||||
{
|
||||
|
||||
if (!hwnd || 0 == accelerators.size()) return 0;
|
||||
if ((!phAccel && cchAccelMax) || (phAccel && !cchAccelMax)) return 0;
|
||||
|
||||
AccelMap::iterator accelIterator = accelerators.end();
|
||||
INT count = 0;
|
||||
|
||||
do
|
||||
{
|
||||
accelIterator--;
|
||||
for (ACCELNODE *pNode = accelIterator->second; NULL != pNode; pNode = pNode->pNext)
|
||||
{
|
||||
if (accelIterator->first == hwnd ||
|
||||
(bGlobal && (TRANSLATE_MODE_GLOBAL == pNode->translateMode ||
|
||||
(TRANSLATE_MODE_CHILD == pNode->translateMode && IsChild(accelIterator->first, hwnd)))))
|
||||
{
|
||||
if (phAccel && cchAccelMax)
|
||||
{
|
||||
*phAccel = pNode->hAccel;
|
||||
phAccel++;
|
||||
cchAccelMax--;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (accelIterator != accelerators.begin() && (!phAccel || cchAccelMax));
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
void Application::app_registerGlobalWindow(HWND hwnd)
|
||||
{
|
||||
for (std::vector<HWND>::const_iterator e = globalWindows.begin(); e != globalWindows.end(); e++)
|
||||
{
|
||||
if (*e == hwnd) return;
|
||||
}
|
||||
globalWindows.push_back(hwnd);
|
||||
}
|
||||
|
||||
void Application::app_unregisterGlobalWindow(HWND hwnd)
|
||||
{
|
||||
for (std::vector<HWND>::iterator e = globalWindows.begin(); e != globalWindows.end(); e++)
|
||||
{
|
||||
if (*e == hwnd)
|
||||
{
|
||||
globalWindows.erase(e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool Application::FilterMessage(MSG *msg) // returns 1 if you should Dispatch the message, will handle TranslateMessage for you
|
||||
{
|
||||
if (msg->hwnd != NULL && msg->hwnd != hMainWindow && msg->hwnd != hEQWindow // && msg.hwnd != hMBWindow
|
||||
&& msg->hwnd != hPLWindow && msg->hwnd != hVideoWindow)
|
||||
{
|
||||
HWND hWndParent = NULL;
|
||||
HWND temphwnd = msg->hwnd;
|
||||
if (GetClassLong(temphwnd, GCW_ATOM) == (INT)32770)
|
||||
hWndParent = temphwnd;
|
||||
|
||||
/*while (*/temphwnd = GetParent(temphwnd)/*)*/ ;
|
||||
{
|
||||
if (GetClassLong(temphwnd, GCW_ATOM) == (INT)32770)
|
||||
hWndParent = temphwnd;
|
||||
}
|
||||
|
||||
if (NULL != hWndParent)
|
||||
{
|
||||
BOOL processed;
|
||||
|
||||
disableMessageHook = true;
|
||||
processed = IsDialogMessageW(hWndParent, msg);
|
||||
disableMessageHook = false;
|
||||
|
||||
if (FALSE != processed)
|
||||
return true;
|
||||
}
|
||||
|
||||
//if (msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN ||
|
||||
// msg->message == WM_KEYUP || msg->message == WM_SYSKEYUP)
|
||||
//{
|
||||
//if (IsChild(hMBWindow,msg.hwnd) && TranslateAccelerator(hMBWindow,hAccel[3],&msg)) continue;
|
||||
TranslateMessage(msg);
|
||||
//}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool Application::isGlobalWindow(HWND hwnd)
|
||||
{
|
||||
for (std::vector<HWND>::const_iterator e = globalWindows.begin(); e != globalWindows.end(); e++)
|
||||
{
|
||||
if (*e == hwnd || IsChild(*e, hwnd)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Application::app_translateAccelerators(MSG *msg)
|
||||
{
|
||||
if (accelerators.size() > 0)
|
||||
{
|
||||
AccelMap::iterator accelIterator = accelerators.end();
|
||||
do
|
||||
{
|
||||
accelIterator--;
|
||||
for (ACCELNODE *pNode = accelIterator->second; NULL != pNode; pNode = pNode->pNext)
|
||||
{
|
||||
if (((TRANSLATE_MODE_GLOBAL == pNode->translateMode && isGlobalWindow(msg->hwnd)) ||
|
||||
accelIterator->first == msg->hwnd ||
|
||||
(TRANSLATE_MODE_CHILD == pNode->translateMode && IsChild(accelIterator->first, msg->hwnd))) &&
|
||||
TranslateAcceleratorW(accelIterator->first, pNode->hAccel, msg))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (accelIterator != accelerators.begin());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
Application::DirectMouseWheel_RegisterSkipClass(ATOM klass)
|
||||
{
|
||||
size_t index;
|
||||
|
||||
if (klass < 0xC000)
|
||||
return false;
|
||||
|
||||
index = directMouseWheelBlackList.size();
|
||||
while(index--)
|
||||
{
|
||||
if (directMouseWheelBlackList[index] == klass)
|
||||
return false;
|
||||
}
|
||||
|
||||
directMouseWheelBlackList.push_back(klass);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
Application::DirectMouseWheel_UnregisterSkipClass(ATOM klass)
|
||||
{
|
||||
size_t index;
|
||||
|
||||
if (klass < 0xC000)
|
||||
return false;
|
||||
|
||||
index = directMouseWheelBlackList.size();
|
||||
while(index--)
|
||||
{
|
||||
if (directMouseWheelBlackList[index] == klass)
|
||||
{
|
||||
directMouseWheelBlackList.erase(directMouseWheelBlackList.begin() + index);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
Application::DirectMouseWheel_EnableConvertToMouseWheel(HWND hwnd, BOOL enable)
|
||||
{
|
||||
return (0 != ::DirectMouseWheel_EnableConvertToMouseWheel(hwnd, enable));
|
||||
}
|
||||
|
||||
void
|
||||
Application::DirectMouseWheel_InitBlackList()
|
||||
{
|
||||
size_t index;
|
||||
WNDCLASSW klassInfo;
|
||||
ATOM klassAtom;
|
||||
|
||||
const static LPCWSTR defaultBlackListNames[] =
|
||||
{
|
||||
L"msctls_trackbar32",
|
||||
L"msctls_updown32",
|
||||
L"SysHeader32",
|
||||
};
|
||||
|
||||
const static ATOM defaultBlackListAtoms[] =
|
||||
{
|
||||
0xC017, // button
|
||||
0xC018, // edit
|
||||
0xC019, // static
|
||||
0xC01C, // combobox
|
||||
};
|
||||
|
||||
for (index = 0; index < ARRAYSIZE(defaultBlackListAtoms); index++)
|
||||
{
|
||||
directMouseWheelBlackList.push_back(defaultBlackListAtoms[index]);
|
||||
}
|
||||
|
||||
for (index = 0; index < ARRAYSIZE(defaultBlackListNames); index++)
|
||||
{
|
||||
klassAtom = (ATOM)GetClassInfoW(NULL, defaultBlackListNames[index], &klassInfo);
|
||||
if (0 != klassAtom)
|
||||
directMouseWheelBlackList.push_back(klassAtom);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Application::DirectMouseWheel_ProccessMessage(MSG *msg)
|
||||
{
|
||||
HWND targetWindow;
|
||||
ATOM targetAtom;
|
||||
DWORD targetProcessId;
|
||||
POINT mousePoint;
|
||||
size_t index, listSize;
|
||||
|
||||
if (msg->message != WM_MOUSEWHEEL)
|
||||
return false;
|
||||
|
||||
if (WM_NULL == WINAMP_WM_DIRECT_MOUSE_WHEEL)
|
||||
{
|
||||
if (FALSE == DirectMouseWheel_RegisterMessage())
|
||||
return false;
|
||||
}
|
||||
|
||||
POINTSTOPOINT(mousePoint, msg->lParam);
|
||||
targetWindow = WindowFromPoint(mousePoint);
|
||||
|
||||
if (NULL == targetWindow || targetWindow == msg->hwnd)
|
||||
return false;
|
||||
|
||||
GetWindowThreadProcessId(targetWindow, &targetProcessId);
|
||||
if (targetProcessId != GetCurrentProcessId())
|
||||
return false;
|
||||
|
||||
if (FALSE == IsWindowEnabled(targetWindow))
|
||||
return false;
|
||||
|
||||
listSize = directMouseWheelBlackList.size();
|
||||
index = 0;
|
||||
|
||||
while(index != listSize)
|
||||
{
|
||||
targetAtom = (ATOM)GetClassLongPtrW(targetWindow, GCW_ATOM);
|
||||
for(index = 0; index < listSize; index++)
|
||||
{
|
||||
if (targetAtom == directMouseWheelBlackList[index])
|
||||
{
|
||||
targetWindow = GetAncestor(targetWindow, GA_PARENT);
|
||||
if (NULL == targetWindow || targetWindow == msg->hwnd)
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (FALSE != DirectMouseWheel_IsConvertToMouseWheelEnabled(targetWindow))
|
||||
{
|
||||
SendMessageW(targetWindow, WM_MOUSEWHEEL, msg->wParam, msg->lParam);
|
||||
return true;
|
||||
}
|
||||
else if (0 != SendMessageW(targetWindow, WINAMP_WM_DIRECT_MOUSE_WHEEL, msg->wParam, msg->lParam))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
HWND ActiveChildWindowFromPoint( HWND hwnd, POINTS cursor_s, const int *controls, size_t controlsCount )
|
||||
{
|
||||
POINT pt;
|
||||
RECT controlRect;
|
||||
HWND controlWindow;
|
||||
|
||||
POINTSTOPOINT( pt, cursor_s );
|
||||
|
||||
while ( controlsCount-- )
|
||||
{
|
||||
controlWindow = GetDlgItem( hwnd, controls[ controlsCount ] );
|
||||
|
||||
if ( controlWindow != NULL && GetClientRect( controlWindow, &controlRect ) != FALSE )
|
||||
{
|
||||
MapWindowPoints( controlWindow, HWND_DESKTOP, (POINT *) &controlRect, 2 );
|
||||
|
||||
if ( PtInRect( &controlRect, pt ) != FALSE )
|
||||
{
|
||||
unsigned long windowStyle = (unsigned long) GetWindowLongPtrW( controlWindow, GWL_STYLE );
|
||||
|
||||
if ( ( ( WS_VISIBLE | WS_DISABLED ) & windowStyle ) == WS_VISIBLE )
|
||||
return controlWindow;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BOOL DirectMouseWheel_ProcessDialogMessage(HWND hwnd, unsigned int uMsg, WPARAM wParam, LPARAM lParam, const int controls[], int controlslen)
|
||||
{
|
||||
if (FALSE != ::IsDirectMouseWheelMessage(uMsg))
|
||||
{
|
||||
HWND targetWindow = ::ActiveChildWindowFromPoint(hwnd, MAKEPOINTS(lParam), controls, controlslen);
|
||||
if (NULL != targetWindow)
|
||||
{
|
||||
SendMessageW(targetWindow, WM_MOUSEWHEEL, wParam, lParam);
|
||||
SetWindowLongPtrW(hwnd, DWLP_MSGRESULT, (long)TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL Application::DirectMouseWheel_ProcessDialogMessage(HWND hwnd, unsigned int uMsg, WPARAM wParam, LPARAM lParam, const int controls[], int controlslen)
|
||||
{
|
||||
return ::DirectMouseWheel_ProcessDialogMessage(hwnd, uMsg, wParam, lParam, controls, controlslen);
|
||||
}
|
||||
|
||||
void Application::ActiveDialog_Register(HWND hwnd)
|
||||
{
|
||||
activeDialog = hwnd;
|
||||
}
|
||||
|
||||
void Application::ActiveDialog_Unregister(HWND hwnd)
|
||||
{
|
||||
if (hwnd == activeDialog)
|
||||
activeDialog = NULL;
|
||||
}
|
||||
|
||||
HWND Application::ActiveDialog_Get()
|
||||
{
|
||||
return activeDialog;
|
||||
}
|
||||
|
||||
/* Plugins can register a 'Message Processor' to tap into the main message loop
|
||||
for some purposes (Dialog message handling, ActiveX/ATL/COM, wxWidgets)
|
||||
this is the only way to make sure all messages are processed correctly
|
||||
@see api_application::app_addMessageProcessor() and api_messageprocessor.h
|
||||
*/
|
||||
|
||||
bool Application::ProcessMessageLight( MSG *msg )
|
||||
{
|
||||
/* messageProcessors is the list of registered Message Processors */
|
||||
for ( api_messageprocessor *processor : messageProcessors )
|
||||
{
|
||||
disableMessageHook = true;
|
||||
|
||||
if ( processor->ProcessMessage( msg ) ) // it'll return true if it wants to eat the message
|
||||
{
|
||||
disableMessageHook = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
disableMessageHook = false;
|
||||
|
||||
if ( false != DirectMouseWheel_ProccessMessage( msg ) )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Application::ProcessMessage( MSG *msg )
|
||||
{
|
||||
if ( ProcessMessageLight( msg ) != false )
|
||||
return true;
|
||||
|
||||
if ( ( msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN ) && app_translateAccelerators( msg ) )
|
||||
return true;
|
||||
|
||||
|
||||
if ( activeDialog != NULL )
|
||||
{
|
||||
disableMessageHook = true;
|
||||
|
||||
if ( IsDialogMessageW( activeDialog, msg ) != FALSE )
|
||||
{
|
||||
disableMessageHook = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
disableMessageHook = false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
intptr_t Application::app_messageLoopStep()
|
||||
{
|
||||
MSG msg;
|
||||
|
||||
if (PeekMessageW(&msg, NULL, 0, 0, TRUE))
|
||||
{
|
||||
if (msg.message == WM_QUIT)
|
||||
{
|
||||
PostQuitMessage((int)msg.wParam);
|
||||
return msg.wParam ; // abandoned due to WM_QUIT
|
||||
}
|
||||
|
||||
if (!ProcessMessage(&msg) && !FilterMessage(&msg))
|
||||
DispatchMessageW(&msg);
|
||||
|
||||
if (WM_NCDESTROY == msg.message)
|
||||
DirectMouseWheel_EnableConvertToMouseWheel(msg.hwnd, FALSE);
|
||||
|
||||
return msg.wParam;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CALLBACK Application::MessageHookProc( INT code, WPARAM wParam, LPARAM lParam )
|
||||
{
|
||||
if ( application == NULL || application->messageHook == NULL )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( application->disableMessageHook == false )
|
||||
{
|
||||
switch ( code )
|
||||
{
|
||||
case MSGF_DIALOGBOX:
|
||||
case MSGF_MESSAGEBOX:
|
||||
if ( false != application->ProcessMessageLight( (MSG *) lParam ) )
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
application->disableMessageHook = false;
|
||||
|
||||
return CallNextHookEx( application->messageHook, code, wParam, lParam );
|
||||
}
|
||||
|
||||
WPARAM Application::MessageLoop()
|
||||
{
|
||||
if ( messageHook == NULL )
|
||||
messageHook = SetWindowsHookEx( WH_MSGFILTER, MessageHookProc, NULL, GetCurrentThreadId() );
|
||||
|
||||
for ( ;;)
|
||||
{
|
||||
DWORD dwStatus = MsgWaitForMultipleObjectsEx( 0, NULL, INFINITE, QS_ALLINPUT, MWMO_ALERTABLE | MWMO_INPUTAVAILABLE );
|
||||
|
||||
if ( dwStatus == WAIT_OBJECT_0 )
|
||||
{
|
||||
MSG msg;
|
||||
while ( PeekMessageW( &msg, NULL, 0, 0, PM_REMOVE ) )
|
||||
{
|
||||
if ( msg.message == WM_QUIT )
|
||||
return msg.wParam;
|
||||
|
||||
if ( !ProcessMessage( &msg ) && !FilterMessage( &msg ) )
|
||||
DispatchMessageW( &msg );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WPARAM WinampMessageLoop()
|
||||
{
|
||||
return WASABI_API_APP->MessageLoop();
|
||||
}
|
||||
|
||||
const wchar_t *Application::path_getWorkingPath()
|
||||
{
|
||||
return config_cwd;
|
||||
}
|
||||
|
||||
void Application::path_setWorkingPath(const wchar_t *newPath)
|
||||
{
|
||||
StringCchCopyW(config_cwd, MAX_PATH, newPath);
|
||||
}
|
||||
|
||||
/*
|
||||
int Application::GetMachineID(GUID *id)
|
||||
{
|
||||
// TODO: stuff this in the registry
|
||||
if (machineID == GUID_NULL)
|
||||
{
|
||||
if (!GetPrivateProfileStruct(app_name, "mid", (LPVOID)&machineID, sizeof(machineID), INI_FILE) || machineID == GUID_NULL)
|
||||
{
|
||||
UuidCreate(&machineID);
|
||||
WritePrivateProfileStruct(app_name, "mid", (LPVOID)&machineID, sizeof(machineID), INI_FILE);
|
||||
}
|
||||
}
|
||||
|
||||
*id = machineID;
|
||||
return API_APPLICATION_SUCCESS;
|
||||
}
|
||||
*/
|
||||
int Application::GetUserID(GUID *id)
|
||||
{
|
||||
if (userID == GUID_NULL)
|
||||
{
|
||||
config_uid_ft = (char)GetPrivateProfileIntW(L"Winamp", L"uid_ft", 0, INI_FILE);
|
||||
|
||||
wchar_t uid_str[512] = {0};
|
||||
if (!GetPrivateProfileStructA(app_name, "uid", (LPVOID)&userID, sizeof(userID), INI_FILEA) || userID == GUID_NULL)
|
||||
{
|
||||
// attempt to restore the client uid after an uninstall, lost config file, etc
|
||||
readwrite_client_uid(0, uid_str);
|
||||
if (uid_str[0])
|
||||
{
|
||||
WritePrivateProfileStringW(AutoWide(app_name), L"uid", uid_str, INI_FILE);
|
||||
}
|
||||
|
||||
if (!GetPrivateProfileStructA(app_name, "uid", (LPVOID)&userID, sizeof(userID), INI_FILEA) || userID == GUID_NULL)
|
||||
{
|
||||
UuidCreate(&userID);
|
||||
WritePrivateProfileStructA(app_name, "uid", (LPVOID)&userID, sizeof(userID), INI_FILEA);
|
||||
GetPrivateProfileStringW(AutoWide(app_name), L"uid", L"", uid_str, ARRAYSIZE(uid_str), INI_FILE);
|
||||
readwrite_client_uid(1, uid_str);
|
||||
// if done then no need to re-do it at a later point
|
||||
config_uid_ft = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// and just to make sure, if this is like a new run then we'll need to force into the registry
|
||||
if (!config_uid_ft)
|
||||
{
|
||||
config_uid_ft = 1;
|
||||
GetPrivateProfileStringW(AutoWide(app_name), L"uid", L"", uid_str, ARRAYSIZE(uid_str), INI_FILE);
|
||||
readwrite_client_uid(1, uid_str);
|
||||
}
|
||||
}
|
||||
|
||||
*id = userID;
|
||||
|
||||
return API_APPLICATION_SUCCESS;
|
||||
}
|
||||
|
||||
int Application::GetSessionID(GUID *id)
|
||||
{
|
||||
if (sessionID == GUID_NULL)
|
||||
UuidCreate(&sessionID);
|
||||
|
||||
*id = sessionID;
|
||||
return API_APPLICATION_SUCCESS;
|
||||
}
|
||||
|
||||
size_t Application::AllocateThreadStorage()
|
||||
{
|
||||
return (size_t)InterlockedIncrement(&threadStorageIndex);
|
||||
}
|
||||
|
||||
void *Application::GetThreadStorage(size_t index)
|
||||
{
|
||||
std::vector<void*> *ptrlist = (std::vector<void*> *)TlsGetValue(tlsIndex);
|
||||
if (!ptrlist)
|
||||
return 0;
|
||||
|
||||
if ((index+1) > ptrlist->size())
|
||||
return 0;
|
||||
|
||||
return ptrlist->at(index);
|
||||
}
|
||||
|
||||
void Application::SetThreadStorage(size_t index, void *value)
|
||||
{
|
||||
std::vector<void*> *ptrlist = (std::vector<void*> *)TlsGetValue(tlsIndex);
|
||||
if (!ptrlist)
|
||||
{
|
||||
ptrlist = new std::vector<void*>;
|
||||
TlsSetValue(tlsIndex, ptrlist);
|
||||
}
|
||||
size_t ptrlist_size = ptrlist->size();
|
||||
if ((index+1) > ptrlist_size)
|
||||
{
|
||||
ptrlist->reserve(index+1);
|
||||
for (size_t i=ptrlist_size;i<=index;i++)
|
||||
{
|
||||
ptrlist->push_back(0);
|
||||
}
|
||||
}
|
||||
ptrlist->at(index) = value;
|
||||
}
|
||||
|
||||
const wchar_t *Application::getATFString()
|
||||
{
|
||||
return config_titlefmt;
|
||||
}
|
||||
|
||||
int Application::getScaleX(int x)
|
||||
{
|
||||
return ScaleX(x);
|
||||
}
|
||||
|
||||
int Application::getScaleY(int y)
|
||||
{
|
||||
return ScaleY(y);
|
||||
}
|
||||
|
||||
#define CBCLASS Application
|
||||
START_DISPATCH;
|
||||
CB(API_APPLICATION_MAIN_GETAPPNAME, main_getAppName)
|
||||
CB(API_APPLICATION_MAIN_GETVERSIONSTRING, main_getVersionString)
|
||||
CB(API_APPLICATION_MAIN_GETVERSIONSTRING2, main_getVersionNumString)
|
||||
CB(API_APPLICATION_MAIN_GETBUILDNUMBER, main_getBuildNumber)
|
||||
CB(API_APPLICATION_MAIN_GETGUID, main_getGUID)
|
||||
CB(API_APPLICATION_MAIN_GETMAINTHREADHANDLE, main_getMainThreadHandle)
|
||||
CB(API_APPLICATION_MAIN_GETHINSTANCE, main_gethInstance)
|
||||
CB(API_APPLICATION_MAIN_GETCOMMANDLINE, main_getCommandLine)
|
||||
VCB(API_APPLICATION_MAIN_SHUTDOWN, main_shutdown)
|
||||
VCB(API_APPLICATION_MAIN_CANCELSHUTDOWN, main_cancelShutdown)
|
||||
CB(API_APPLICATION_MAIN_ISSHUTTINGDOWN, main_isShuttingDown)
|
||||
CB(API_APPLICATION_PATH_GETAPPPATH, path_getAppPath)
|
||||
CB(API_APPLICATION_PATH_GETUSERSETTINGSPATH, path_getUserSettingsPath)
|
||||
CB(API_APPLICATION_PATH_GETSKINSETTINGSPATH, path_getSkinSettingsPath)
|
||||
CB(API_APPLICATION_APP_GETINITCOUNT, app_getInitCount)
|
||||
CB(API_APPLICATION_APP_MESSAGELOOPSTEP, app_messageLoopStep)
|
||||
VCB(API_APPLICATION_APP_ADDMESSAGEPROCESSOR, app_addMessageProcessor)
|
||||
VCB(API_APPLICATION_APP_REMOVEMESSAGEPROCESSOR, app_removeMessageProcessor)
|
||||
VCB(API_APPLICATION_APP_ADDMODELESSDIALOG, app_addModelessDialog)
|
||||
VCB(API_APPLICATION_APP_REMOVEMODELESSDIALOG, app_removeModelessDialog)
|
||||
VCB(API_APPLICATION_APP_ADDACCELERATORS, app_addAccelerators)
|
||||
VCB(API_APPLICATION_APP_REMOVEACCELERATORS, app_removeAccelerators)
|
||||
CB(API_APPLICATION_APP_TRANSLATEACCELERATORS, app_translateAccelerators);
|
||||
CB(API_APPLICATION_APP_GETACCELERATORS, app_getAccelerators);
|
||||
VCB(API_APPLICATION_APP_REGISTERGLOBALWINDOW, app_registerGlobalWindow);
|
||||
VCB(API_APPLICATION_APP_UNREGISTERGLOBALWINDOW, app_unregisterGlobalWindow);
|
||||
CB(API_APPLICATION_PATH_GETWORKINGPATH, path_getWorkingPath);
|
||||
VCB(API_APPLICATION_PATH_SETWORKINGPATH, path_setWorkingPath);
|
||||
CB(API_APPLICATION_DIRECTMOUSEWHEEL_REGISTERSKIPCLASS, DirectMouseWheel_RegisterSkipClass);
|
||||
CB(API_APPLICATION_DIRECTMOUSEWHEEL_UNREGISTERSKIPCLASS, DirectMouseWheel_UnregisterSkipClass);
|
||||
CB(API_APPLICATION_DIRECTMOUSEWHEEL_ENABLECONVERTTOMOUSEWHEEL, DirectMouseWheel_EnableConvertToMouseWheel);
|
||||
CB(API_APPLICATION_DIRECTMOUSEWHEEL_PROCESSDIALOGMESSAGE, DirectMouseWheel_ProcessDialogMessage);
|
||||
VCB(API_APPLICATION_ACTIVEDIALOG_REGISTER, ActiveDialog_Register);
|
||||
VCB(API_APPLICATION_ACTIVEDIALOG_UNREGISTER, ActiveDialog_Unregister);
|
||||
CB(API_APPLICATION_ACTIVEDIALOG_GET, ActiveDialog_Get);
|
||||
/*
|
||||
CB(API_APPLICATION_GETMACHINEID, GetMachineID);
|
||||
*/
|
||||
CB(API_APPLICATION_GETUSERID, GetUserID);
|
||||
CB(API_APPLICATION_GETSESSIONID, GetSessionID);
|
||||
CB(API_APPLICATION_ALLOCATETHREADSTORAGE, AllocateThreadStorage);
|
||||
CB(API_APPLICATION_GETTHREADSTORAGE, GetThreadStorage);
|
||||
VCB(API_APPLICATION_SETTHREADSTORAGE, SetThreadStorage);
|
||||
CB(API_APPLICATION_GETATFSTRING, getATFString);
|
||||
CB(API_APPLICATION_GETSCALEX, getScaleX);
|
||||
CB(API_APPLICATION_GETSCALEY, getScaleY);
|
||||
END_DISPATCH;
|
||||
#undef CBCLASS
|
Loading…
Add table
Add a link
Reference in a new issue