mirror of
https://github.com/WinampDesktop/winamp.git
synced 2024-11-28 00:20:51 +01:00
660 lines
16 KiB
C++
660 lines
16 KiB
C++
/** (c) Nullsoft, Inc. C O N F I D E N T I A L
|
|
** Filename:
|
|
** Project:
|
|
** Description:
|
|
** Author:
|
|
** Created:
|
|
**/
|
|
|
|
#include "main.h"
|
|
#include <windows.h>
|
|
#include "strutil.h"
|
|
#include "../nu/ns_wc.h"
|
|
#include "plush/plush.h"
|
|
#include "../nu/AutoChar.h"
|
|
#include "../nu/AutoWide.h"
|
|
#include "WinampAttributes.h"
|
|
|
|
#undef GetSystemMetrics
|
|
|
|
int IsUrl(const char *url)
|
|
{
|
|
return !!strstr(url, "://");
|
|
}
|
|
|
|
|
|
void link_startsubclass(HWND hwndDlg, UINT id){
|
|
HWND ctrl = GetDlgItem(hwndDlg, id);
|
|
if(!GetPropW(ctrl, L"link_proc"))
|
|
{
|
|
SetPropW(ctrl, L"link_proc",
|
|
(HANDLE)SetWindowLongPtrW(ctrl, GWLP_WNDPROC, (LONG_PTR)link_handlecursor));
|
|
}
|
|
}
|
|
|
|
static HCURSOR link_hand_cursor;
|
|
LRESULT link_handlecursor(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
LRESULT ret = CallWindowProcW((WNDPROC)GetPropW(hwndDlg, L"link_proc"), hwndDlg, uMsg, wParam, lParam);
|
|
// override the normal cursor behaviour so we have a hand to show it is a link
|
|
if(uMsg == WM_SETCURSOR)
|
|
{
|
|
if((HWND)wParam == hwndDlg)
|
|
{
|
|
if(!link_hand_cursor)
|
|
{
|
|
link_hand_cursor = LoadCursor(NULL, IDC_HAND);
|
|
}
|
|
SetCursor(link_hand_cursor);
|
|
return TRUE;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
void link_handledraw(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
if (uMsg == WM_DRAWITEM)
|
|
{
|
|
DRAWITEMSTRUCT *di = (DRAWITEMSTRUCT *)lParam;
|
|
if (di->CtlType == ODT_BUTTON)
|
|
{
|
|
wchar_t wt[123] = {0};
|
|
int y;
|
|
RECT r;
|
|
HPEN hPen, hOldPen;
|
|
GetDlgItemTextW(hwndDlg, wParam, wt, sizeof(wt)/sizeof(wt[0]));
|
|
|
|
// draw text
|
|
SetTextColor(di->hDC, (di->itemState & ODS_SELECTED) ? RGB(220, 0, 0) : RGB(0, 0, 220));
|
|
r = di->rcItem;
|
|
// is used by the file types page to have a slimmer button so it doesn't override other
|
|
// characters which are otherwise drawn over by the size of the button needed for a link
|
|
if(GetPropW(di->hwndItem, L"slim"))
|
|
{
|
|
r.top -= 2;
|
|
}
|
|
r.left += 2;
|
|
DrawTextW(di->hDC, wt, -1, &r, DT_VCENTER | DT_SINGLELINE);
|
|
|
|
memset(&r, 0, sizeof(r));
|
|
DrawTextW(di->hDC, wt, -1, &r, DT_SINGLELINE | DT_CALCRECT);
|
|
|
|
// draw underline
|
|
y = di->rcItem.bottom - ((di->rcItem.bottom - di->rcItem.top) - (r.bottom - r.top)) / 2 - 1;
|
|
hPen = CreatePen(PS_SOLID, 0, (di->itemState & ODS_SELECTED) ? RGB(220, 0, 0) : RGB(0, 0, 220));
|
|
hOldPen = (HPEN) SelectObject(di->hDC, hPen);
|
|
MoveToEx(di->hDC, di->rcItem.left + 2, y, NULL);
|
|
LineTo(di->hDC, di->rcItem.right + 2 - ((di->rcItem.right - di->rcItem.left) - (r.right - r.left)), y);
|
|
SelectObject(di->hDC, hOldPen);
|
|
DeleteObject(hPen);
|
|
}
|
|
}
|
|
}
|
|
|
|
///////// if you update this, be sure to update the copy of it in $/winampa/winampicon.c
|
|
// thx.
|
|
int geticonid(int x)
|
|
{
|
|
switch (x) {
|
|
case 1: return IDI_FILEICON;
|
|
case 2: return IDI_FILEICON2;
|
|
case 3: return IDI_FILEICON3;
|
|
case 4: return IDI_FILEICON10;
|
|
case 5: return IDI_FILEICON5;
|
|
case 6: return IDI_FILEICON6;
|
|
case 7: return IDI_FILEICON7;
|
|
case 8: return IDI_FILEICON8;
|
|
case 9: return IDI_FILEICON9;
|
|
case 10: return IDI_FILEICON4;
|
|
case 11: return IDI_FILEICON11;
|
|
case 12: return ICON_TB1;
|
|
case 13: return -666;
|
|
default: return ICON_XP;
|
|
}
|
|
}
|
|
/*
|
|
void plSplineGetPoint(pl_Spline *s, float frame, float *out)
|
|
{
|
|
int i, i_1, i0, i1, i2;
|
|
float time1, time2, time3;
|
|
float t1, t2, t3, t4, u1, u2, u3, u4, v1, v2, v3;
|
|
float a, b, c, d;
|
|
|
|
float *keys = s->keys;
|
|
|
|
a = (1 - s->tens) * (1 + s->cont) * (1 + s->bias);
|
|
b = (1 - s->tens) * (1 - s->cont) * (1 - s->bias);
|
|
c = (1 - s->tens) * (1 - s->cont) * (1 + s->bias);
|
|
d = (1 - s->tens) * (1 + s->cont) * (1 - s->bias);
|
|
v1 = t1 = -a / 2.0f; u1 = a;
|
|
u2 = ( -6 - 2 * a + 2 * b + c) / 2.0f; v2 = (a - b) / 2.0f; t2 = (4 + a - b - c) / 2.0f;
|
|
t3 = ( -4 + b + c - d) / 2.0f;
|
|
u3 = (6 - 2 * b - c + d) / 2.0f;
|
|
v3 = b / 2.0f;
|
|
t4 = d / 2.0f; u4 = -t4;
|
|
|
|
i0 = (int) frame;
|
|
i_1 = i0 - 1;
|
|
while (i_1 < 0) i_1 += s->numKeys;
|
|
i1 = i0 + 1;
|
|
while (i1 >= s->numKeys) i1 -= s->numKeys;
|
|
i2 = i0 + 2;
|
|
while (i2 >= s->numKeys) i2 -= s->numKeys;
|
|
time1 = frame - (float) ((int) frame);
|
|
time2 = time1 * time1;
|
|
time3 = time2 * time1;
|
|
i0 *= s->keyWidth;
|
|
i1 *= s->keyWidth;
|
|
i2 *= s->keyWidth;
|
|
i_1 *= s->keyWidth;
|
|
for (i = 0; i < s->keyWidth; i ++)
|
|
{
|
|
a = t1 * keys[i + i_1] + t2 * keys[i + i0] + t3 * keys[i + i1] + t4 * keys[i + i2];
|
|
b = u1 * keys[i + i_1] + u2 * keys[i + i0] + u3 * keys[i + i1] + u4 * keys[i + i2];
|
|
c = v1 * keys[i + i_1] + v2 * keys[i + i0] + v3 * keys[i + i1];
|
|
*out++ = a * time3 + b * time2 + c * time1 + keys[i + i0];
|
|
}
|
|
}
|
|
*/
|
|
//int transAccel(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
//{
|
|
// HACCEL h;
|
|
// MSG msg;
|
|
// if (hwnd == hMainWindow) h = hAccel[0];
|
|
// else if (hwnd == hEQWindow) h = hAccel[1];
|
|
// else if (hwnd == hPLWindow) h = hAccel[2];
|
|
// // else if (hwnd==hMBWindow) h=hAccel[3];
|
|
// else if (hwnd == hVideoWindow || GetParent(hwnd) == hVideoWindow)
|
|
// {
|
|
// h = hAccel[0];
|
|
// }
|
|
// else
|
|
// {
|
|
// return 0;
|
|
// }
|
|
// msg.hwnd = hwnd;
|
|
// msg.lParam = lParam;
|
|
// msg.message = uMsg;
|
|
// msg.wParam = wParam;
|
|
// return TranslateAccelerator(hwnd, h, &msg);
|
|
//
|
|
//}
|
|
|
|
#include <pshpack4.h>
|
|
|
|
typedef struct
|
|
{
|
|
DWORD dwSize;
|
|
HANDLE hrasconn;
|
|
char szEntryName[256 + 1];
|
|
char szDeviceType[ 16 + 1 ];
|
|
char szDeviceName[ 128 + 1 ];
|
|
}
|
|
RASCONN ;
|
|
#include <poppack.h>
|
|
|
|
typedef DWORD (WINAPI *RASENUMCONNECTIONS)(RASCONN *lprasconn,
|
|
LPDWORD lpcb,
|
|
LPDWORD lpcConnections);
|
|
|
|
static int isRASActive()
|
|
{
|
|
int r = 0;
|
|
HINSTANCE h = LoadLibraryA("rasapi32.dll");
|
|
RASENUMCONNECTIONS RasEnumConnections;
|
|
RASCONN v = {sizeof(RASCONN), };
|
|
|
|
DWORD i = sizeof(v), o = 0;
|
|
|
|
if (!h) return 0;
|
|
RasEnumConnections = (RASENUMCONNECTIONS)GetProcAddress(h, "RasEnumConnectionsA");
|
|
if (RasEnumConnections && !RasEnumConnections(&v, &i, &o) && o) r = 1;
|
|
FreeModule(h);
|
|
return r;
|
|
}
|
|
|
|
int isInetAvailable(void)
|
|
{
|
|
if (config_inet_mode == 3)
|
|
{
|
|
if (isRASActive()) config_inet_mode = 1;
|
|
else config_inet_mode = 0;
|
|
return (1 == config_inet_mode);
|
|
}
|
|
if (config_inet_mode == 0) return 1;
|
|
if (config_inet_mode == 2) return 0;
|
|
return isRASActive();
|
|
}
|
|
|
|
unsigned int getDay(void)
|
|
{
|
|
unsigned int day = 0;
|
|
SYSTEMTIME tm, st = {0, };
|
|
FILETIME ft1, ft2;
|
|
ULARGE_INTEGER l1, l2;
|
|
GetSystemTime(&tm);
|
|
st.wYear = 1978;
|
|
st.wMonth = 10;
|
|
st.wDay = 14;
|
|
SystemTimeToFileTime(&tm, &ft1);
|
|
SystemTimeToFileTime(&st, &ft2);
|
|
memcpy(&l1, &ft1, sizeof(l1));
|
|
memcpy(&l2, &ft2, sizeof(l2));
|
|
day = (int) ((l1.QuadPart - l2.QuadPart) / (10 * 1000 * 1000) / (60 * 60 * 24));
|
|
return day;
|
|
}
|
|
|
|
void recent_add(const wchar_t *loc)
|
|
{
|
|
wchar_t ls[MAX_PATH] = {0};
|
|
_r_sW("RecentURL1", ls, MAX_PATH);
|
|
_w_sW("RecentURL1", loc);
|
|
|
|
if (wcscmp(ls, loc))
|
|
{
|
|
int x = 2;
|
|
while(1)
|
|
{
|
|
char s[123] = {0};
|
|
wchar_t temp[MAX_PATH] = {0};
|
|
StringCchPrintfA(s, 123, "RecentURL%d", x);
|
|
|
|
_r_sW(s, temp, MAX_PATH);
|
|
if (ls[0]) _w_sW(s, ls);
|
|
if (!_wcsicmp(temp, loc) || !temp[0])
|
|
break;
|
|
lstrcpynW(ls, temp, MAX_PATH);
|
|
x++;
|
|
}
|
|
}
|
|
}
|
|
|
|
#include <assert.h>
|
|
void getViewport(RECT *r, HWND wnd, int full, RECT *sr)
|
|
{
|
|
POINT *p = NULL;
|
|
if (p || sr || wnd)
|
|
{
|
|
HMONITOR hm = NULL;
|
|
|
|
if (sr)
|
|
hm = MonitorFromRect(sr, MONITOR_DEFAULTTONEAREST);
|
|
else if (wnd)
|
|
hm = MonitorFromWindow(wnd, MONITOR_DEFAULTTONEAREST);
|
|
else if (p)
|
|
hm = MonitorFromPoint(*p, MONITOR_DEFAULTTONEAREST);
|
|
|
|
if (hm)
|
|
{
|
|
MONITORINFOEXW mi;
|
|
memset(&mi, 0, sizeof(mi));
|
|
mi.cbSize = sizeof(mi);
|
|
|
|
if (GetMonitorInfoW(hm, &mi))
|
|
{
|
|
if (!full)
|
|
*r = mi.rcWork;
|
|
else
|
|
*r = mi.rcMonitor;
|
|
|
|
return ;
|
|
}
|
|
}
|
|
}
|
|
if (full)
|
|
{ // this might be borked =)
|
|
r->top = r->left = 0;
|
|
r->right = GetSystemMetrics(SM_CXSCREEN);
|
|
r->bottom = GetSystemMetrics(SM_CYSCREEN);
|
|
}
|
|
else
|
|
{
|
|
SystemParametersInfoW(SPI_GETWORKAREA, 0, r, 0);
|
|
}
|
|
}
|
|
|
|
BOOL windowOffScreen(HWND hwnd, POINT pt)
|
|
{
|
|
RECT r = {0}, wnd = {0}, sr = {0};
|
|
GetWindowRect(hwnd, &wnd);
|
|
sr.left = pt.x;
|
|
sr.top = pt.y;
|
|
sr.right = sr.left + (wnd.right - wnd.left);
|
|
sr.bottom = sr.top + (wnd.bottom - wnd.top);
|
|
getViewport(&r, hwnd, 0, &sr);
|
|
return !PtInRect(&r, pt);
|
|
}
|
|
|
|
void readwrite_client_uid(int isWrite, wchar_t uid_str[64])
|
|
{
|
|
HKEY hkey;
|
|
wchar_t path[MAX_PATH] = {0};
|
|
GetModuleFileNameW(0, path, MAX_PATH);
|
|
|
|
if (isWrite)
|
|
{
|
|
IFileTypeRegistrar *registrar=0;
|
|
if (GetRegistrar(®istrar, true) == 0 && registrar)
|
|
{
|
|
registrar->WriteClientUIDKey(path, uid_str);
|
|
registrar->Release();
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (!isWrite) *uid_str = 0;
|
|
if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Nullsoft\\Winamp", 0, 0, 0, KEY_READ, NULL, &hkey, NULL) == ERROR_SUCCESS)
|
|
{
|
|
DWORD s = 512, t = REG_SZ;
|
|
if (RegQueryValueExW(hkey, path, 0, &t, (LPBYTE)uid_str, &s) != ERROR_SUCCESS || t != REG_SZ) uid_str[0] = 0;
|
|
RegCloseKey(hkey);
|
|
}
|
|
}
|
|
|
|
|
|
BOOL read_compatmode()
|
|
{
|
|
HKEY hkey = NULL;
|
|
wchar_t path[MAX_PATH] = {0};
|
|
GetModuleFileNameW(0, path, MAX_PATH);
|
|
if (RegCreateKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers", 0, 0, 0, KEY_READ, NULL, &hkey, NULL) == ERROR_SUCCESS)
|
|
{
|
|
DWORD s = 512, t = REG_SZ;
|
|
wchar_t buf[128] = {0};
|
|
if (RegQueryValueExW(hkey, path, 0, &t, (LPBYTE)buf, &s) != ERROR_SUCCESS || t != REG_SZ) buf[0] = 0;
|
|
RegCloseKey(hkey);
|
|
|
|
wchar_t *p = buf, *fields[] = {L"256COLOR", L"640X480", L"DISABLETHEMES", L"$",
|
|
L"DISABLEDWM", L"DISABLEUSERCALLBACKEXCEPTION",
|
|
L"HIGHDPIAWARE", L"RUNASADMIN", L"IGNOREFREELIBRARY",
|
|
L"ELEVATECREATEPROCESS", L"#", L"~", L"PLACEHOLDERFILES"};
|
|
int fields_len[] = {8, 7, 13, 1, 10, 28, 12, 10, 17, 20, 1, 1, 16};
|
|
while (p && *p)
|
|
{
|
|
wchar_t *pp = p;
|
|
while (pp && *pp && *pp != L' ')
|
|
{
|
|
pp = CharNextW(pp);
|
|
}
|
|
|
|
wchar_t pp_old = (pp ? *pp : 0);
|
|
if (pp && *pp) *pp = 0;
|
|
|
|
bool found = false;
|
|
for (int i = 0; i < sizeof(fields)/sizeof(fields[0]); i++)
|
|
{
|
|
if (!wcsncmp(fields[i], p, fields_len[i]))
|
|
found = true;
|
|
}
|
|
if (!found)
|
|
return TRUE;
|
|
|
|
if (pp) *pp = pp_old;
|
|
if (!pp_old) break;
|
|
p = CharNextW(pp);
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL IsVista(void)
|
|
{
|
|
static INT fVista = -1;
|
|
|
|
if (-1 == fVista)
|
|
{
|
|
OSVERSIONINFO osver = {0};
|
|
osver.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
|
|
fVista = (::GetVersionEx(&osver) && osver.dwPlatformId == VER_PLATFORM_WIN32_NT && (osver.dwMajorVersion >= 6)) ? 1 : 0;
|
|
}
|
|
|
|
return (1 == fVista);
|
|
}
|
|
|
|
BOOL IsVistaOrLower(void)
|
|
{
|
|
static INT fVistaOrLower = -1;
|
|
|
|
if (-1 == fVistaOrLower)
|
|
{
|
|
OSVERSIONINFO osver = {0};
|
|
osver.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
|
|
fVistaOrLower = (::GetVersionEx(&osver) && osver.dwPlatformId == VER_PLATFORM_WIN32_NT &&
|
|
(osver.dwMajorVersion <= 5 || (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 0))) ? 1 : 0;
|
|
}
|
|
|
|
return (1 == fVistaOrLower);
|
|
}
|
|
|
|
BOOL IsWin8(void)
|
|
{
|
|
static INT fWin8 = -1;
|
|
|
|
if (-1 == fWin8)
|
|
{
|
|
OSVERSIONINFO osver = {0};
|
|
osver.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
|
|
fWin8 = ( ::GetVersionEx(&osver) && osver.dwPlatformId == VER_PLATFORM_WIN32_NT && (osver.dwMajorVersion > 6 || (osver.dwMajorVersion == 6 && osver.dwMinorVersion >= 2))) ? 1 : 0;
|
|
}
|
|
|
|
return (1 == fWin8);
|
|
}
|
|
|
|
//XP Theme crap
|
|
typedef HRESULT (WINAPI * ENABLETHEMEDIALOGTEXTURE)(HWND, DWORD);
|
|
|
|
int IsWinXPTheme(void)
|
|
{
|
|
static int previousRet = -1;
|
|
if (previousRet == -1)
|
|
{
|
|
BOOL bEnabled(FALSE);
|
|
OSVERSIONINFO vi;
|
|
|
|
vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
|
if (GetVersionEx(&vi) && (vi.dwMajorVersion > 5 || (vi.dwMajorVersion == 5 && vi.dwMinorVersion > 0)))
|
|
{
|
|
HINSTANCE dll = LoadLibraryW(TEXT("uxtheme.dll"));
|
|
if (dll)
|
|
{
|
|
BOOL (WINAPI *waIsAppThemed)(void);
|
|
BOOL (WINAPI *waIsThemeActive)(void);
|
|
waIsAppThemed = (BOOL (WINAPI *)())GetProcAddress(dll, "IsAppThemed");
|
|
waIsThemeActive = (BOOL (WINAPI *)())GetProcAddress(dll, "IsThemeActive");
|
|
|
|
if (waIsAppThemed && waIsThemeActive && waIsAppThemed() && waIsThemeActive())
|
|
{
|
|
HMODULE hComCtl = LoadLibraryW(TEXT("comctl32.dll"));
|
|
if (hComCtl)
|
|
{
|
|
HRESULT (CALLBACK *waDllGetVersion)(DLLVERSIONINFO*) = (HRESULT (CALLBACK *)(DLLVERSIONINFO*))GetProcAddress(hComCtl, "DllGetVersion");
|
|
if (waDllGetVersion)
|
|
{
|
|
DLLVERSIONINFO dllVer;
|
|
dllVer.cbSize = sizeof(DLLVERSIONINFO);
|
|
if (S_OK == waDllGetVersion(&dllVer) && dllVer.dwMajorVersion >= 6) bEnabled = TRUE;
|
|
}
|
|
FreeLibrary(hComCtl);
|
|
}
|
|
}
|
|
FreeLibrary(dll);
|
|
}
|
|
}
|
|
previousRet = bEnabled;
|
|
}
|
|
return previousRet;
|
|
}
|
|
|
|
void DoWinXPStyle(HWND tab)
|
|
{
|
|
WAEnableThemeDialogTexture(tab, ETDT_ENABLETAB);
|
|
}
|
|
|
|
HRESULT WAEnableThemeDialogTexture(HWND hwnd, DWORD dwFlags)
|
|
{
|
|
static int uxThemeTried = 0;
|
|
static ENABLETHEMEDIALOGTEXTURE pfnETDT = NULL;
|
|
|
|
if(!uxThemeTried)
|
|
{
|
|
HINSTANCE ux_hDll;
|
|
if ((ux_hDll = LoadLibraryA("uxtheme.dll")) != NULL)
|
|
pfnETDT = (ENABLETHEMEDIALOGTEXTURE)GetProcAddress(ux_hDll, "EnableThemeDialogTexture");
|
|
|
|
uxThemeTried = 1;
|
|
}
|
|
|
|
return (pfnETDT) ? pfnETDT(hwnd, dwFlags) : E_NOTIMPL;
|
|
}
|
|
|
|
typedef BOOL(WINAPI*ISCOMPOSITIONACTIVE)(VOID);
|
|
|
|
int IsAero(void)
|
|
{
|
|
static int uxTried = 0;
|
|
static ISCOMPOSITIONACTIVE IsAeroActive = 0;
|
|
if (!uxTried)
|
|
{
|
|
static HMODULE UXTHEME = 0;
|
|
if ((UXTHEME = LoadLibraryA("uxtheme.dll")) != NULL)
|
|
IsAeroActive = (ISCOMPOSITIONACTIVE)GetProcAddress(UXTHEME, "IsCompositionActive");
|
|
|
|
uxTried = 1;
|
|
}
|
|
if (IsAeroActive)
|
|
return !!IsAeroActive();
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
int IsCharSpace(char digit)
|
|
{
|
|
WORD type=0;
|
|
GetStringTypeEx(LOCALE_USER_DEFAULT, CT_CTYPE1, &digit, 1, &type);
|
|
return type&C1_SPACE;
|
|
}
|
|
|
|
int IsCharSpaceW(wchar_t digit)
|
|
{
|
|
WORD type=0;
|
|
GetStringTypeExW(LOCALE_USER_DEFAULT, CT_CTYPE1, &digit, 1, &type);
|
|
return type&C1_SPACE;
|
|
}
|
|
*/
|
|
LPCWSTR BuildFullPath(LPCWSTR pszPathRoot, LPCWSTR pszPath, LPWSTR pszDest, INT cchDest)
|
|
{
|
|
LPCWSTR pszFile;
|
|
if (!pszPath || !*pszPath)
|
|
{
|
|
pszDest[0] = 0x00;
|
|
return pszDest;
|
|
}
|
|
pszFile = PathFindFileNameW(pszPath);
|
|
if (pszFile != pszPath)
|
|
{
|
|
if (PathIsRelativeW(pszPath))
|
|
{
|
|
wchar_t szTemp[MAX_PATH] = {0};
|
|
PathCombineW(szTemp, pszPathRoot, pszPath);
|
|
PathCanonicalizeW(pszDest, szTemp);
|
|
}
|
|
else StringCchCopyW(pszDest, cchDest, pszPath);
|
|
}
|
|
else {
|
|
if (pszPathRoot && *pszPathRoot) PathCombineW(pszDest, pszPathRoot, pszPath);
|
|
else StringCchCopyW(pszDest, cchDest, pszPath);
|
|
}
|
|
|
|
return pszDest;
|
|
}
|
|
|
|
INT ComparePath(LPCWSTR pszPath1, LPCWSTR pszPath2, LPCWSTR pszPathRoot) // compares two pathes
|
|
{
|
|
INT cr;
|
|
DWORD lcid;
|
|
LPCWSTR pszFile1, pszFile2;
|
|
|
|
if (!pszPath1 || !pszPath2) return 0;
|
|
|
|
lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
|
|
|
|
pszFile1 = PathFindFileNameW(pszPath1);
|
|
pszFile2 = PathFindFileNameW(pszPath2);
|
|
|
|
cr = CompareStringW(lcid, NORM_IGNORECASE, pszFile1, -1, pszFile2, -1);
|
|
|
|
if (CSTR_EQUAL == cr && (pszFile1 != pszPath1 || pszFile2 != pszPath2))
|
|
{
|
|
wchar_t path1[MAX_PATH*2] = {0}, path2[MAX_PATH*2] = {0};
|
|
pszPath1 = BuildFullPath(pszPathRoot, pszPath1, path1, sizeof(path1)/sizeof(wchar_t));
|
|
pszPath2 = BuildFullPath(pszPathRoot, pszPath2, path2, sizeof(path2)/sizeof(wchar_t));
|
|
if (!pszPath1 || !pszPath2) return 0;
|
|
cr = CompareStringW(lcid, NORM_IGNORECASE, pszPath1, -1, path2, -1);
|
|
}
|
|
return cr;
|
|
}
|
|
|
|
BOOL DisabledWindow_OnMouseClick(HWND hwnd)
|
|
{
|
|
DWORD windowStyle = GetWindowLongPtrW(hwnd, GWL_STYLE);
|
|
if (WS_DISABLED != ((WS_CHILD | WS_DISABLED) & windowStyle))
|
|
return FALSE;
|
|
|
|
HWND hActive = GetActiveWindow();
|
|
HWND hPopup = GetWindow(hwnd, GW_ENABLEDPOPUP);
|
|
|
|
BOOL beepOk = (hPopup == hActive || hwnd == GetWindow(hActive, GW_OWNER));
|
|
if (!beepOk && NULL == hPopup)
|
|
{
|
|
for (HWND hWalker = hwnd; ;)
|
|
{
|
|
hWalker = GetWindow(hWalker, GW_OWNER);
|
|
if (NULL == hWalker || (0 != (WS_CHILD & GetWindowLongPtrW(hWalker, GWL_STYLE))))
|
|
break;
|
|
if (hActive == GetWindow(hWalker, GW_ENABLEDPOPUP))
|
|
{
|
|
beepOk = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (beepOk)
|
|
{
|
|
if (config_accessibility_modalflash.GetBool())
|
|
{
|
|
FLASHWINFO flashInfo;
|
|
flashInfo.cbSize = sizeof(FLASHWINFO);
|
|
flashInfo.hwnd = hActive;
|
|
flashInfo.dwFlags = FLASHW_CAPTION;
|
|
flashInfo.uCount = 2;
|
|
flashInfo.dwTimeout = 100;
|
|
|
|
FlashWindowEx(&flashInfo);
|
|
}
|
|
|
|
if (config_accessibility_modalbeep.GetBool())
|
|
MessageBeep(MB_OK);
|
|
}
|
|
else
|
|
{
|
|
for (HWND hWalker = hwnd; NULL == hPopup;)
|
|
{
|
|
hWalker = GetWindow(hWalker, GW_OWNER);
|
|
if (NULL == hWalker || (0 != (WS_CHILD & GetWindowLongPtrW(hWalker, GWL_STYLE))))
|
|
break;
|
|
hPopup = GetWindow(hWalker, GW_ENABLEDPOPUP);
|
|
}
|
|
|
|
SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE);
|
|
if (NULL != hPopup && hPopup != hwnd)
|
|
{
|
|
BringWindowToTop(hPopup);
|
|
SetActiveWindow(hPopup);
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
} |