mirror of
https://github.com/reactos/reactos.git
synced 2024-11-24 20:13:31 +08:00
1892 lines
67 KiB
C
1892 lines
67 KiB
C
/*
|
|
* ReactOS
|
|
* Copyright (C) 2004, 2007 ReactOS Team
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*/
|
|
/*
|
|
* PROJECT: ReactOS Main Control Panel
|
|
* FILE: dll/cpl/main/mouse.c
|
|
* PURPOSE: Mouse Control Panel
|
|
* PROGRAMMER: Eric Kohl
|
|
* Johannes Anderwald
|
|
*/
|
|
|
|
// TODO:
|
|
// Add missing icons
|
|
|
|
#include "main.h"
|
|
|
|
#include <commdlg.h>
|
|
#include <cplext.h>
|
|
#include <tchar.h>
|
|
|
|
#define DEFAULT_DOUBLE_CLICK_SPEED 500
|
|
#define DEFAULT_CLICK_LOCK_TIME 2200
|
|
#define DEFAULT_MOUSE_SPEED 10
|
|
#define DEFAULT_MOUSE_ACCELERATION 1
|
|
#define DEFAULT_MOUSE_THRESHOLD1 6
|
|
#define DEFAULT_MOUSE_THRESHOLD2 10
|
|
#define MIN_DOUBLE_CLICK_SPEED 200
|
|
#define MAX_DOUBLE_CLICK_SPEED 900
|
|
#define DEFAULT_WHEEL_SCROLL_LINES 3
|
|
|
|
typedef struct _BUTTON_DATA
|
|
{
|
|
ULONG g_SwapMouseButtons;
|
|
ULONG g_OrigSwapMouseButtons;
|
|
ULONG g_DoubleClickSpeed; // = DEFAULT_DOUBLE_CLICK_SPEED;
|
|
ULONG g_OrigDoubleClickSpeed;
|
|
BOOL g_ClickLockEnabled; // = 0;
|
|
DWORD g_ClickLockTime; // = DEFAULT_CLICK_LOCK_TIME;
|
|
|
|
HICON hButtonLeft;
|
|
HICON hButtonRight;
|
|
|
|
HICON hIcon1;
|
|
HICON hIcon2;
|
|
BOOL bClicked;
|
|
} BUTTON_DATA, *PBUTTON_DATA;
|
|
|
|
|
|
typedef struct _POINTER_DATA
|
|
{
|
|
BOOL bCursorShadow;
|
|
BOOL bOrigCursorShadow;
|
|
|
|
INT cxCursor;
|
|
INT cyCursor;
|
|
} POINTER_DATA, *PPOINTER_DATA;
|
|
|
|
|
|
typedef struct _MOUSE_ACCEL
|
|
{
|
|
INT nThreshold1;
|
|
INT nThreshold2;
|
|
INT nAcceleration;
|
|
} MOUSE_ACCEL;
|
|
|
|
typedef struct _OPTION_DATA
|
|
{
|
|
ULONG ulMouseSpeed;
|
|
ULONG ulOrigMouseSpeed;
|
|
|
|
MOUSE_ACCEL MouseAccel;
|
|
MOUSE_ACCEL OrigMouseAccel;
|
|
|
|
BOOL bSnapToDefaultButton;
|
|
BOOL bOrigSnapToDefaultButton;
|
|
|
|
UINT uMouseTrails;
|
|
UINT uOrigMouseTrails;
|
|
|
|
BOOL bMouseVanish;
|
|
BOOL bOrigMouseVanish;
|
|
|
|
BOOL bMouseSonar;
|
|
BOOL bOrigMouseSonar;
|
|
} OPTION_DATA, *POPTION_DATA;
|
|
|
|
|
|
typedef struct _WHEEL_DATA
|
|
{
|
|
UINT uWheelScrollLines;
|
|
} WHEEL_DATA, *PWHEEL_DATA;
|
|
|
|
|
|
typedef struct _CURSOR_DATA
|
|
{
|
|
UINT uStringId;
|
|
UINT uDefaultCursorId;
|
|
LPTSTR lpValueName;
|
|
HCURSOR hCursor;
|
|
TCHAR szCursorName[MAX_PATH];
|
|
TCHAR szCursorPath[MAX_PATH];
|
|
} CURSOR_DATA, *PCURSOR_DATA;
|
|
|
|
|
|
CURSOR_DATA g_CursorData[] =
|
|
{{IDS_ARROW, 100/*OCR_NORMAL*/, _T("Arrow"), 0, _T(""), _T("")},
|
|
{IDS_HELP, 112/*OCR_HELP*/, _T("Help"), 0, _T(""), _T("")},
|
|
{IDS_APPSTARTING, 111/*OCR_APPSTARTING*/, _T("AppStarting"), 0, _T(""), _T("")},
|
|
{IDS_WAIT, 102/*OCR_WAIT*/, _T("Wait"), 0, _T(""), _T("")},
|
|
{IDS_CROSSHAIR, 103/*OCR_CROSS*/, _T("Crosshair"), 0, _T(""), _T("")},
|
|
{IDS_IBEAM, 101/*OCR_IBEAM*/, _T("IBeam"), 0, _T(""), _T("")},
|
|
{IDS_NWPEN, 113/*OCR_NWPEN*/, _T("NWPen"), 0, _T(""), _T("")},
|
|
{IDS_NO, 110/*OCR_NO*/, _T("No"), 0, _T(""), _T("")},
|
|
{IDS_SIZENS, 108/*OCR_SIZENS*/, _T("SizeNS"), 0, _T(""), _T("")},
|
|
{IDS_SIZEWE, 107/*OCR_SIZEWE*/, _T("SizeWE"), 0, _T(""), _T("")},
|
|
{IDS_SIZENWSE, 105/*OCR_SIZENWSE*/, _T("SizeNWSE"), 0, _T(""), _T("")},
|
|
{IDS_SIZENESW, 106/*OCR_SIZENESW*/, _T("SizeNESW"), 0, _T(""), _T("")},
|
|
{IDS_SIZEALL, 109/*OCR_SIZEALL*/, _T("SizeAll"), 0, _T(""), _T("")},
|
|
{IDS_UPARROW, 104/*OCR_UP*/, _T("UpArrow"), 0, _T(""), _T("")},
|
|
{IDS_HAND, 114/*OCR_HAND*/, _T("Hand"), 0, _T(""), _T("")}};
|
|
|
|
|
|
#if 0
|
|
static VOID
|
|
DebugMsg(LPTSTR fmt, ...)
|
|
{
|
|
TCHAR szBuffer[2048];
|
|
va_list marker;
|
|
|
|
va_start(marker, fmt);
|
|
_vstprintf(szBuffer, fmt, marker);
|
|
va_end(marker);
|
|
|
|
MessageBox(NULL, szBuffer, _T("Debug message"), MB_OK);
|
|
}
|
|
#endif
|
|
|
|
|
|
/* Property page dialog callback */
|
|
static INT_PTR CALLBACK
|
|
MouseHardwareProc(IN HWND hwndDlg,
|
|
IN UINT uMsg,
|
|
IN WPARAM wParam,
|
|
IN LPARAM lParam)
|
|
{
|
|
GUID Guids[1];
|
|
Guids[0] = GUID_DEVCLASS_MOUSE;
|
|
|
|
UNREFERENCED_PARAMETER(lParam);
|
|
UNREFERENCED_PARAMETER(wParam);
|
|
|
|
switch(uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
/* create the hardware page */
|
|
DeviceCreateHardwarePageEx(hwndDlg,
|
|
Guids,
|
|
sizeof(Guids) / sizeof(Guids[0]),
|
|
HWPD_STANDARDLIST);
|
|
break;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
static INT_PTR CALLBACK
|
|
ClickLockProc(IN HWND hwndDlg,
|
|
IN UINT uMsg,
|
|
IN WPARAM wParam,
|
|
IN LPARAM lParam)
|
|
{
|
|
HWND hDlgCtrl;
|
|
int pos;
|
|
static HICON hIcon;
|
|
|
|
PBUTTON_DATA pButtonData;
|
|
|
|
pButtonData = (PBUTTON_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
|
|
|
|
switch(uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
pButtonData = (PBUTTON_DATA)lParam;
|
|
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pButtonData);
|
|
|
|
hDlgCtrl = GetDlgItem(hwndDlg, IDC_SLIDER_CLICK_LOCK);
|
|
SendMessage(hDlgCtrl, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(0, 10));
|
|
pos = (pButtonData->g_ClickLockTime - 200) / 200;
|
|
SendMessage(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)pos);
|
|
|
|
hIcon = LoadImage(hApplet, MAKEINTRESOURCE(IDI_LOOK_KEY),
|
|
IMAGE_ICON, 16, 16, 0);
|
|
SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
|
|
return TRUE;
|
|
|
|
case WM_COMMAND:
|
|
if (LOWORD(wParam) == IDOK)
|
|
{
|
|
hDlgCtrl = GetDlgItem(hwndDlg, IDC_SLIDER_CLICK_LOCK);
|
|
pButtonData->g_ClickLockTime = (DWORD) (SendMessage(hDlgCtrl, TBM_GETPOS, 0, 0) * 200) + 200;
|
|
EndDialog(hwndDlg, TRUE);
|
|
if (hIcon) DestroyIcon(hIcon);
|
|
}
|
|
else if (LOWORD(wParam) == IDCANCEL)
|
|
{
|
|
EndDialog(hwndDlg, FALSE);
|
|
if (hIcon) DestroyIcon(hIcon);
|
|
}
|
|
break;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
static INT_PTR CALLBACK
|
|
ButtonProc(IN HWND hwndDlg,
|
|
IN UINT uMsg,
|
|
IN WPARAM wParam,
|
|
IN LPARAM lParam)
|
|
{
|
|
HWND hDlgCtrl;
|
|
LRESULT lResult;
|
|
LPPSHNOTIFY lppsn;
|
|
|
|
PBUTTON_DATA pButtonData;
|
|
|
|
pButtonData = (PBUTTON_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
|
|
|
|
switch (uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
pButtonData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BUTTON_DATA));
|
|
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pButtonData);
|
|
|
|
pButtonData->g_SwapMouseButtons = GetSystemMetrics(SM_SWAPBUTTON);
|
|
pButtonData->g_OrigSwapMouseButtons = pButtonData->g_SwapMouseButtons;
|
|
pButtonData->g_DoubleClickSpeed = GetDoubleClickTime();
|
|
pButtonData->g_OrigDoubleClickSpeed = pButtonData->g_DoubleClickSpeed;
|
|
|
|
/* Click lock time */
|
|
SystemParametersInfo(SPI_GETMOUSECLICKLOCK, 0, &pButtonData->g_ClickLockEnabled, 0);
|
|
SystemParametersInfo(SPI_GETMOUSECLICKLOCKTIME, 0, &pButtonData->g_ClickLockTime, 0);
|
|
|
|
/* Load mouse button icons */
|
|
pButtonData->hButtonLeft = LoadImage(hApplet, MAKEINTRESOURCE(IDI_MOUSE_LEFT), IMAGE_ICON, 48, 48, LR_DEFAULTCOLOR);
|
|
pButtonData->hButtonRight = LoadImage(hApplet, MAKEINTRESOURCE(IDI_MOUSE_RIGHT), IMAGE_ICON, 48, 48, LR_DEFAULTCOLOR);
|
|
|
|
/* Load folder icons */
|
|
pButtonData->hIcon1 = LoadImage(hApplet, MAKEINTRESOURCE(IDI_FOLDER_CLOSED), IMAGE_ICON, 48, 48, LR_DEFAULTCOLOR);
|
|
pButtonData->hIcon2 = LoadImage(hApplet, MAKEINTRESOURCE(IDI_FOLDER_OPEN), IMAGE_ICON, 48, 48, LR_DEFAULTCOLOR);
|
|
|
|
if (pButtonData->g_SwapMouseButtons)
|
|
{
|
|
SendDlgItemMessage(hwndDlg, IDC_SWAP_MOUSE_BUTTONS, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
|
|
SendDlgItemMessage(hwndDlg, IDC_IMAGE_SWAP_MOUSE, STM_SETIMAGE, IMAGE_ICON, (LPARAM)pButtonData->hButtonRight);
|
|
}
|
|
else
|
|
{
|
|
SendDlgItemMessage(hwndDlg, IDC_IMAGE_SWAP_MOUSE, STM_SETIMAGE, IMAGE_ICON, (LPARAM)pButtonData->hButtonLeft);
|
|
}
|
|
|
|
if (pButtonData->g_ClickLockEnabled)
|
|
{
|
|
hDlgCtrl = GetDlgItem(hwndDlg, IDC_CHECK_CLICK_LOCK);
|
|
SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
|
|
}
|
|
else
|
|
{
|
|
hDlgCtrl = GetDlgItem(hwndDlg, IDC_BUTTON_CLICK_LOCK);
|
|
EnableWindow(hDlgCtrl, FALSE);
|
|
}
|
|
|
|
hDlgCtrl = GetDlgItem(hwndDlg, IDC_SLIDER_DOUBLE_CLICK_SPEED);
|
|
SendMessage(hDlgCtrl, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(0, 14));
|
|
SendMessage(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, 14 - ((pButtonData->g_DoubleClickSpeed - 200) / 50));
|
|
|
|
|
|
SendDlgItemMessage(hwndDlg, IDC_IMAGE_DOUBLE_CLICK_SPEED, STM_SETIMAGE, IMAGE_ICON, (LPARAM)pButtonData->hIcon1);
|
|
pButtonData->bClicked = TRUE;
|
|
return TRUE;
|
|
|
|
case WM_DESTROY:
|
|
DestroyIcon(pButtonData->hButtonLeft);
|
|
DestroyIcon(pButtonData->hButtonRight);
|
|
DestroyIcon(pButtonData->hIcon1);
|
|
DestroyIcon(pButtonData->hIcon2);
|
|
HeapFree(GetProcessHeap(), 0, pButtonData);
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch(LOWORD(wParam))
|
|
{
|
|
case IDC_SWAP_MOUSE_BUTTONS:
|
|
lResult = SendMessage((HWND)lParam, BM_GETCHECK, (WPARAM)0, (LPARAM)0);
|
|
if (lResult == BST_CHECKED)
|
|
{
|
|
pButtonData->g_SwapMouseButtons = FALSE;
|
|
SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0);
|
|
SendDlgItemMessage(hwndDlg, IDC_IMAGE_SWAP_MOUSE, STM_SETIMAGE, IMAGE_ICON, (LPARAM)pButtonData->hButtonLeft);
|
|
}
|
|
else if (lResult == BST_UNCHECKED)
|
|
{
|
|
pButtonData->g_SwapMouseButtons = TRUE;
|
|
SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
|
|
SendDlgItemMessage(hwndDlg, IDC_IMAGE_SWAP_MOUSE, STM_SETIMAGE, IMAGE_ICON, (LPARAM)pButtonData->hButtonRight);
|
|
}
|
|
//SystemParametersInfo(SPI_SETMOUSEBUTTONSWAP, pButtonData->g_SwapMouseButtons, NULL, 0);
|
|
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
|
|
break;
|
|
|
|
case IDC_CHECK_CLICK_LOCK:
|
|
lResult = SendMessage((HWND)lParam, BM_GETCHECK, (WPARAM)0, (LPARAM)0);
|
|
hDlgCtrl = GetDlgItem(hwndDlg, IDC_BUTTON_CLICK_LOCK);
|
|
if (lResult == BST_CHECKED)
|
|
{
|
|
SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0);
|
|
pButtonData->g_ClickLockEnabled = FALSE;
|
|
EnableWindow(hDlgCtrl, FALSE);
|
|
}
|
|
else if (lResult == BST_UNCHECKED)
|
|
{
|
|
SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
|
|
pButtonData->g_ClickLockEnabled = TRUE;
|
|
EnableWindow(hDlgCtrl, TRUE);
|
|
}
|
|
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
|
|
break;
|
|
|
|
case IDC_BUTTON_CLICK_LOCK:
|
|
DialogBoxParam(hApplet, MAKEINTRESOURCE(IDD_CLICK_LOCK), hwndDlg, ClickLockProc, (LPARAM)pButtonData);
|
|
break;
|
|
|
|
case IDC_IMAGE_DOUBLE_CLICK_SPEED:
|
|
if (HIWORD(wParam) == STN_DBLCLK)
|
|
{
|
|
pButtonData->bClicked = !pButtonData->bClicked;
|
|
SendDlgItemMessage(hwndDlg, IDC_IMAGE_DOUBLE_CLICK_SPEED, STM_SETIMAGE, IMAGE_ICON,
|
|
(LPARAM)(pButtonData->bClicked ? pButtonData->hIcon1 : pButtonData->hIcon2));
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
lppsn = (LPPSHNOTIFY) lParam;
|
|
if (lppsn->hdr.code == PSN_APPLY)
|
|
{
|
|
if (pButtonData->g_OrigSwapMouseButtons != pButtonData->g_SwapMouseButtons)
|
|
{
|
|
pButtonData->g_OrigSwapMouseButtons = pButtonData->g_SwapMouseButtons;
|
|
SystemParametersInfo(SPI_SETMOUSEBUTTONSWAP, pButtonData->g_OrigSwapMouseButtons, NULL, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
|
|
|
|
}
|
|
SystemParametersInfo(SPI_SETDOUBLECLICKTIME, pButtonData->g_DoubleClickSpeed, NULL, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
|
|
//SetDoubleClickTime(pButtonData->g_DoubleClickSpeed);
|
|
|
|
#if (WINVER >= 0x0500)
|
|
SystemParametersInfo(SPI_SETMOUSECLICKLOCK, 0, UlongToPtr(pButtonData->g_ClickLockEnabled), SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
|
|
if (pButtonData->g_ClickLockEnabled)
|
|
SystemParametersInfo(SPI_SETMOUSECLICKLOCKTIME, pButtonData->g_ClickLockTime, NULL, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
|
|
#endif
|
|
}
|
|
else if (lppsn->hdr.code == PSN_RESET)
|
|
{
|
|
/* Reset swap mouse button setting */
|
|
SystemParametersInfo(SPI_SETMOUSEBUTTONSWAP, pButtonData->g_OrigSwapMouseButtons, NULL, 0);
|
|
|
|
/* Reset double click speed setting */
|
|
SystemParametersInfo(SPI_SETDOUBLECLICKTIME, pButtonData->g_OrigDoubleClickSpeed, NULL, 0);
|
|
//SetDoubleClickTime(pButtonData->g_OrigDoubleClickSpeed);
|
|
}
|
|
return TRUE;
|
|
|
|
case WM_HSCROLL:
|
|
if ((HWND)lParam == GetDlgItem(hwndDlg, IDC_SLIDER_DOUBLE_CLICK_SPEED))
|
|
{
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case TB_LINEUP:
|
|
case TB_LINEDOWN:
|
|
case TB_PAGEUP:
|
|
case TB_PAGEDOWN:
|
|
case TB_TOP:
|
|
case TB_BOTTOM:
|
|
case TB_ENDTRACK:
|
|
lResult = SendDlgItemMessage(hwndDlg, IDC_SLIDER_DOUBLE_CLICK_SPEED, TBM_GETPOS, 0, 0);
|
|
pButtonData->g_DoubleClickSpeed = (14 - (INT)lResult) * 50 + 200;
|
|
//SystemParametersInfo(SPI_SETDOUBLECLICKTIME, pButtonData->g_DoubleClickSpeed, NULL, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
|
|
SetDoubleClickTime(pButtonData->g_DoubleClickSpeed);
|
|
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
|
|
break;
|
|
|
|
case TB_THUMBTRACK:
|
|
pButtonData->g_DoubleClickSpeed = (14 - (INT)HIWORD(wParam)) * 50 + 200;
|
|
//SystemParametersInfo(SPI_SETDOUBLECLICKTIME, pButtonData->g_DoubleClickSpeed, NULL, 0);
|
|
SetDoubleClickTime(pButtonData->g_DoubleClickSpeed);
|
|
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
static VOID
|
|
CompressPath(LPTSTR lpShortPath, LPTSTR lpPath)
|
|
{
|
|
TCHAR szUserProfile[MAX_PATH];
|
|
TCHAR szSystemRoot[MAX_PATH];
|
|
TCHAR szProgramFiles[MAX_PATH];
|
|
DWORD dwUserProfile;
|
|
DWORD dwSystemRoot;
|
|
DWORD dwProgramFiles;
|
|
|
|
dwUserProfile = GetEnvironmentVariable(_T("USERPROFILE"), szUserProfile, MAX_PATH);
|
|
dwSystemRoot = GetEnvironmentVariable(_T("SystemRoot"), szSystemRoot, MAX_PATH);
|
|
dwProgramFiles = GetEnvironmentVariable(_T("ProgramFiles"), szProgramFiles, MAX_PATH);
|
|
|
|
if (dwUserProfile > 0 && _tcsncmp(lpPath, szUserProfile, dwUserProfile) == 0)
|
|
{
|
|
_tcscpy(lpShortPath, _T("%USERPROFILE%"));
|
|
_tcscat(lpShortPath, &lpPath[dwUserProfile]);
|
|
}
|
|
else if (dwSystemRoot > 0 && _tcsncmp(lpPath, szSystemRoot, dwSystemRoot) == 0)
|
|
{
|
|
_tcscpy(lpShortPath, _T("%SystemRoot%"));
|
|
_tcscat(lpShortPath, &lpPath[dwSystemRoot]);
|
|
}
|
|
else if (dwProgramFiles > 0 && _tcsncmp(lpPath, szProgramFiles, dwProgramFiles) == 0)
|
|
{
|
|
_tcscpy(lpShortPath, _T("%ProgramFiles%"));
|
|
_tcscat(lpShortPath, &lpPath[dwProgramFiles]);
|
|
}
|
|
else
|
|
{
|
|
_tcscpy(lpShortPath, lpPath);
|
|
}
|
|
}
|
|
|
|
|
|
static BOOL
|
|
EnumerateCursorSchemes(HWND hwndDlg)
|
|
{
|
|
HKEY hCursorKey;
|
|
DWORD dwIndex;
|
|
TCHAR szValueName[MAX_PATH];
|
|
DWORD dwValueName;
|
|
TCHAR szSystemScheme[MAX_PATH];
|
|
TCHAR szValueData[2000];
|
|
TCHAR szTempData[2000];
|
|
DWORD dwValueData;
|
|
LONG lError;
|
|
HWND hDlgCtrl;
|
|
LRESULT lResult;
|
|
|
|
hDlgCtrl = GetDlgItem(hwndDlg, IDC_COMBO_CURSOR_SCHEME);
|
|
SendMessage(hDlgCtrl, CB_RESETCONTENT, 0, 0);
|
|
|
|
/* Read the users cursor schemes */
|
|
lError = RegOpenKeyEx(HKEY_CURRENT_USER, _T("Control Panel\\Cursors\\Schemes"),
|
|
0, KEY_READ | KEY_QUERY_VALUE , &hCursorKey);
|
|
if (lError == ERROR_SUCCESS)
|
|
{
|
|
for (dwIndex = 0;; dwIndex++)
|
|
{
|
|
dwValueName = sizeof(szValueName) / sizeof(TCHAR);
|
|
dwValueData = sizeof(szValueData) / sizeof(TCHAR);
|
|
lError = RegEnumValue(hCursorKey, dwIndex, szValueName, &dwValueName,
|
|
NULL, NULL, (LPBYTE)szValueData, &dwValueData);
|
|
if (lError == ERROR_NO_MORE_ITEMS)
|
|
break;
|
|
|
|
ExpandEnvironmentStrings(szValueData, szTempData, 2000);
|
|
|
|
if (_tcslen(szTempData) > 0)
|
|
{
|
|
LPTSTR lpCopy, lpStart;
|
|
|
|
/* Remove quotation marks */
|
|
if (szTempData[0] == _T('"'))
|
|
{
|
|
lpStart = szTempData + 1;
|
|
szTempData[_tcslen(szTempData) - 1] = 0;
|
|
}
|
|
else
|
|
{
|
|
lpStart = szTempData;
|
|
}
|
|
|
|
lpCopy = _tcsdup(lpStart);
|
|
|
|
lResult = SendMessage(hDlgCtrl, CB_ADDSTRING, (WPARAM)0, (LPARAM)szValueName);
|
|
SendMessage(hDlgCtrl, CB_SETITEMDATA, (WPARAM)lResult, (LPARAM)lpCopy);
|
|
}
|
|
}
|
|
|
|
RegCloseKey(hCursorKey);
|
|
}
|
|
|
|
/* Read the system cursor schemes */
|
|
lError = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
|
_T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Control Panel\\Cursors\\Schemes"),
|
|
0, KEY_READ | KEY_QUERY_VALUE , &hCursorKey);
|
|
if (lError == ERROR_SUCCESS)
|
|
{
|
|
LoadString(hApplet, IDS_SYSTEM_SCHEME, szSystemScheme, MAX_PATH);
|
|
|
|
for (dwIndex = 0;; dwIndex++)
|
|
{
|
|
dwValueName = sizeof(szValueName) / sizeof(TCHAR);
|
|
dwValueData = sizeof(szValueData) / sizeof(TCHAR);
|
|
lError = RegEnumValue(hCursorKey, dwIndex, szValueName, &dwValueName,
|
|
NULL, NULL, (LPBYTE)szValueData, &dwValueData);
|
|
if (lError == ERROR_NO_MORE_ITEMS)
|
|
break;
|
|
|
|
if (_tcslen(szValueData) > 0)
|
|
{
|
|
LPTSTR lpCopy, lpStart;
|
|
|
|
/* Remove quotation marks */
|
|
if (szValueData[0] == _T('"'))
|
|
{
|
|
lpStart = szValueData + 1;
|
|
szValueData[_tcslen(szValueData) - 1] = 0;
|
|
}
|
|
else
|
|
{
|
|
lpStart = szValueData;
|
|
}
|
|
|
|
lpCopy = _tcsdup(lpStart);
|
|
|
|
_tcscat(szValueName, TEXT(" "));
|
|
_tcscat(szValueName, szSystemScheme);
|
|
|
|
lResult = SendMessage(hDlgCtrl, CB_ADDSTRING, (WPARAM)0, (LPARAM)szValueName);
|
|
SendMessage(hDlgCtrl, CB_SETITEMDATA, (WPARAM)lResult, (LPARAM)lpCopy);
|
|
}
|
|
}
|
|
|
|
RegCloseKey(hCursorKey);
|
|
}
|
|
|
|
/* Add the "(none)" entry */
|
|
LoadString(hApplet, IDS_NONE, szSystemScheme, MAX_PATH);
|
|
lResult = SendMessage(hDlgCtrl, CB_ADDSTRING, (WPARAM)0, (LPARAM)szSystemScheme);
|
|
SendMessage(hDlgCtrl, CB_SETITEMDATA, (WPARAM)lResult, (LPARAM)NULL);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
static VOID
|
|
RefreshCursorList(HWND hwndDlg, BOOL bInit)
|
|
{
|
|
INT index;
|
|
INT i;
|
|
INT nSel;
|
|
|
|
nSel = bInit ? 0 : SendDlgItemMessage(hwndDlg, IDC_LISTBOX_CURSOR, LB_GETCURSEL, 0, 0);
|
|
|
|
if (bInit)
|
|
{
|
|
SendDlgItemMessage(hwndDlg, IDC_LISTBOX_CURSOR, LB_RESETCONTENT, 0, 0);
|
|
for (index = IDS_ARROW, i = 0; index <= IDS_HAND; index++, i++)
|
|
{
|
|
LoadString(hApplet, index, g_CursorData[i].szCursorName, MAX_PATH);
|
|
SendDlgItemMessage(hwndDlg, IDC_LISTBOX_CURSOR, LB_ADDSTRING, 0, (LPARAM)i);
|
|
}
|
|
|
|
SendDlgItemMessage(hwndDlg, IDC_LISTBOX_CURSOR, LB_SETCURSEL, nSel, 0);
|
|
}
|
|
else
|
|
{
|
|
InvalidateRect(GetDlgItem(hwndDlg, IDC_LISTBOX_CURSOR), NULL, FALSE);
|
|
}
|
|
|
|
SendDlgItemMessage(hwndDlg, IDC_IMAGE_CURRENT_CURSOR, STM_SETIMAGE, IMAGE_CURSOR,
|
|
(LPARAM)g_CursorData[nSel].hCursor);
|
|
|
|
EnableWindow(GetDlgItem(hwndDlg,IDC_BUTTON_USE_DEFAULT_CURSOR), (g_CursorData[nSel].szCursorPath[0] != 0));
|
|
}
|
|
|
|
|
|
static BOOL
|
|
DeleteUserCursorScheme(HWND hwndDlg)
|
|
{
|
|
TCHAR szSchemeName[MAX_PATH];
|
|
TCHAR szTitle[128];
|
|
TCHAR szRawText[256];
|
|
TCHAR szText[256];
|
|
HWND hDlgCtrl;
|
|
HKEY hCuKey;
|
|
HKEY hCuCursorKey;
|
|
LONG lResult;
|
|
INT nSel;
|
|
|
|
hDlgCtrl = GetDlgItem(hwndDlg, IDC_COMBO_CURSOR_SCHEME);
|
|
nSel = SendMessage(hDlgCtrl, CB_GETCURSEL, 0, 0);
|
|
if (nSel == CB_ERR)
|
|
return FALSE;
|
|
|
|
SendMessage(hDlgCtrl, CB_GETLBTEXT, nSel, (LPARAM)szSchemeName);
|
|
|
|
LoadString(hApplet, IDS_REMOVE_TITLE, szTitle, 128);
|
|
LoadString(hApplet, IDS_REMOVE_TEXT, szRawText, 256);
|
|
|
|
_stprintf(szText, szRawText, szSchemeName);
|
|
|
|
/* Confirm scheme removal */
|
|
if (MessageBox(hwndDlg, szText, szTitle, MB_YESNO | MB_ICONQUESTION) == IDNO)
|
|
return TRUE;
|
|
|
|
if (RegOpenCurrentUser(KEY_READ | KEY_SET_VALUE, &hCuKey) != ERROR_SUCCESS)
|
|
return FALSE;
|
|
|
|
if (RegOpenKeyEx(hCuKey, _T("Control Panel\\Cursors\\Schemes"), 0, KEY_READ | KEY_SET_VALUE, &hCuCursorKey) != ERROR_SUCCESS)
|
|
{
|
|
RegCloseKey(hCuKey);
|
|
return FALSE;
|
|
}
|
|
|
|
lResult = RegDeleteValue(hCuCursorKey, szSchemeName);
|
|
|
|
RegCloseKey(hCuCursorKey);
|
|
RegCloseKey(hCuKey);
|
|
|
|
if (lResult == ERROR_SUCCESS)
|
|
{
|
|
SendMessage(hDlgCtrl, CB_DELETESTRING, nSel, 0);
|
|
SendMessage(hDlgCtrl, CB_SETCURSEL, (WPARAM)0, (LPARAM)0);
|
|
}
|
|
|
|
return (lResult == ERROR_SUCCESS);
|
|
}
|
|
|
|
|
|
static INT_PTR CALLBACK
|
|
SaveSchemeProc(IN HWND hwndDlg,
|
|
IN UINT uMsg,
|
|
IN WPARAM wParam,
|
|
IN LPARAM lParam)
|
|
{
|
|
LPTSTR pSchemeName;
|
|
|
|
switch (uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
pSchemeName = (LPTSTR)lParam;
|
|
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pSchemeName);
|
|
SendDlgItemMessage(hwndDlg, IDC_EDIT_SCHEME_NAME, WM_SETTEXT,
|
|
0, (LPARAM)pSchemeName);
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
if (LOWORD(wParam) == IDOK)
|
|
{
|
|
pSchemeName = (LPTSTR)GetWindowLongPtr(hwndDlg, DWLP_USER);
|
|
SendDlgItemMessage(hwndDlg, IDC_EDIT_SCHEME_NAME, WM_GETTEXT,
|
|
(WPARAM)MAX_PATH, (LPARAM)pSchemeName);
|
|
EndDialog(hwndDlg, TRUE);
|
|
}
|
|
else if (LOWORD(wParam) == IDCANCEL)
|
|
{
|
|
EndDialog(hwndDlg, FALSE);
|
|
}
|
|
break;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
static BOOL
|
|
SaveCursorScheme(HWND hwndDlg)
|
|
{
|
|
TCHAR szSystemScheme[MAX_PATH];
|
|
TCHAR szSchemeName[MAX_PATH];
|
|
TCHAR szNewSchemeName[MAX_PATH];
|
|
TCHAR szTempPath[MAX_PATH];
|
|
TCHAR szTitle[128];
|
|
TCHAR szText[256];
|
|
INT nSel;
|
|
INT index, i, nLength;
|
|
LPTSTR lpSchemeData;
|
|
HKEY hCuKey;
|
|
HKEY hCuCursorKey;
|
|
LONG lError = ERROR_SUCCESS;
|
|
BOOL bSchemeExists;
|
|
|
|
LoadString(hApplet, IDS_SYSTEM_SCHEME, szSystemScheme, MAX_PATH);
|
|
|
|
nSel = SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_GETCURSEL, 0, 0);
|
|
if (nSel == CB_ERR)
|
|
return FALSE;
|
|
|
|
if (nSel == 0)
|
|
{
|
|
szSchemeName[0] = 0;
|
|
szNewSchemeName[0] = 0;
|
|
}
|
|
else
|
|
{
|
|
SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_GETLBTEXT, nSel, (LPARAM)szNewSchemeName);
|
|
|
|
if (_tcsstr(szNewSchemeName, szSystemScheme))
|
|
{
|
|
szNewSchemeName[_tcslen(szNewSchemeName) - _tcslen(szSystemScheme) - 1] = 0;
|
|
}
|
|
}
|
|
|
|
/* Ask for a name for the new cursor scheme */
|
|
if (!DialogBoxParam(hApplet, MAKEINTRESOURCE(IDD_CURSOR_SCHEME_SAVEAS),
|
|
hwndDlg, SaveSchemeProc, (LPARAM)szNewSchemeName))
|
|
return TRUE;
|
|
|
|
/* Check all non-system schemes for the new name */
|
|
nSel = SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_GETCOUNT, 0, 0);
|
|
if (nSel == CB_ERR)
|
|
return FALSE;
|
|
|
|
bSchemeExists = FALSE;
|
|
for (i = 0; i < nSel; i++)
|
|
{
|
|
SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_GETLBTEXT, i, (LPARAM)szSchemeName);
|
|
if (_tcsstr(szSchemeName, szSystemScheme) == NULL)
|
|
{
|
|
if (_tcscmp(szSchemeName, szNewSchemeName) == 0)
|
|
{
|
|
bSchemeExists = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (bSchemeExists)
|
|
{
|
|
LoadString(hApplet, IDS_OVERWRITE_TITLE, szTitle, 128);
|
|
LoadString(hApplet, IDS_OVERWRITE_TEXT, szText, 256);
|
|
|
|
/* Confirm scheme overwrite */
|
|
if (MessageBox(hwndDlg, szText, szTitle, MB_YESNO | MB_ICONQUESTION) == IDNO)
|
|
return TRUE;
|
|
}
|
|
|
|
/* Save the cursor scheme */
|
|
nLength = 0;
|
|
for (index = IDS_ARROW, i = 0; index <= IDS_HAND; index++, i++)
|
|
{
|
|
if (i > 0)
|
|
nLength++;
|
|
nLength += _tcslen(g_CursorData[i].szCursorPath);
|
|
}
|
|
nLength++;
|
|
|
|
lpSchemeData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nLength * sizeof(TCHAR));
|
|
|
|
if(!lpSchemeData)
|
|
return FALSE;
|
|
|
|
for (index = IDS_ARROW, i = 0; index <= IDS_HAND; index++, i++)
|
|
{
|
|
CompressPath(szTempPath, g_CursorData[i].szCursorPath);
|
|
if (i > 0)
|
|
_tcscat(lpSchemeData, _T(","));
|
|
_tcscat(lpSchemeData, szTempPath);
|
|
}
|
|
|
|
if (RegOpenCurrentUser(KEY_READ | KEY_SET_VALUE, &hCuKey) != ERROR_SUCCESS)
|
|
{
|
|
HeapFree(GetProcessHeap(), 0, lpSchemeData);
|
|
return FALSE;
|
|
}
|
|
|
|
if (RegOpenKeyEx(hCuKey, _T("Control Panel\\Cursors\\Schemes"), 0, KEY_READ | KEY_SET_VALUE, &hCuCursorKey) != ERROR_SUCCESS)
|
|
{
|
|
RegCloseKey(hCuKey);
|
|
HeapFree(GetProcessHeap(), 0, lpSchemeData);
|
|
return FALSE;
|
|
}
|
|
|
|
lError = RegSetValueEx(hCuCursorKey, szNewSchemeName, 0,
|
|
REG_EXPAND_SZ, (LPBYTE)lpSchemeData,
|
|
(_tcslen(lpSchemeData) + 1) * sizeof(TCHAR));
|
|
|
|
RegCloseKey(hCuCursorKey);
|
|
RegCloseKey(hCuKey);
|
|
|
|
/* Add the new scheme to the scheme list and select it */
|
|
if (lError == ERROR_SUCCESS)
|
|
{
|
|
LPTSTR copy = _tcsdup(lpSchemeData);
|
|
|
|
nSel = SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_ADDSTRING, (WPARAM)0, (LPARAM)szNewSchemeName);
|
|
SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_SETITEMDATA, (WPARAM)nSel, (LPARAM)copy);
|
|
SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_SETCURSEL, (WPARAM)nSel, (LPARAM)0);
|
|
}
|
|
|
|
HeapFree(GetProcessHeap(), 0, lpSchemeData);
|
|
|
|
return (lError == ERROR_SUCCESS);
|
|
}
|
|
|
|
|
|
static BOOL
|
|
BrowseCursor(HWND hwndDlg)
|
|
{
|
|
TCHAR szFileName[MAX_PATH];
|
|
TCHAR szFilter[MAX_PATH];
|
|
TCHAR szTitle[MAX_PATH];
|
|
OPENFILENAME ofn;
|
|
INT nSel;
|
|
|
|
LoadString(hApplet, IDS_BROWSE_FILTER, szFilter, MAX_PATH);
|
|
LoadString(hApplet, IDS_BROWSE_TITLE, szTitle, MAX_PATH);
|
|
|
|
memset(szFileName, 0x0, sizeof(szFileName));
|
|
nSel = SendDlgItemMessage(hwndDlg, IDC_LISTBOX_CURSOR, LB_GETCURSEL, 0, 0);
|
|
if (nSel == LB_ERR)
|
|
{
|
|
MessageBox(hwndDlg, _T("LB_ERR"), _T(""), MB_ICONERROR);
|
|
return FALSE;
|
|
}
|
|
|
|
ZeroMemory(&ofn, sizeof(OPENFILENAME));
|
|
ofn.lStructSize = sizeof(OPENFILENAME);
|
|
ofn.hwndOwner = hwndDlg;
|
|
ofn.lpstrFilter = szFilter;
|
|
ofn.nFilterIndex = 1;
|
|
ofn.lpstrFile = szFileName;
|
|
ofn.nMaxFile = MAX_PATH;
|
|
ofn.lpstrInitialDir = _T("%WINDIR%\\Cursors");
|
|
ofn.lpstrTitle = szTitle;
|
|
ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
|
|
|
|
if (!GetOpenFileName(&ofn))
|
|
return FALSE;
|
|
|
|
/* Store the new cursor file path */
|
|
_tcsncpy(g_CursorData[nSel].szCursorPath, szFileName, MAX_PATH);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
static VOID
|
|
LoadCursorScheme(LPTSTR lpName, BOOL bSystem)
|
|
{
|
|
UINT index, i;
|
|
|
|
for (index = IDS_ARROW, i = 0; index <= IDS_HAND; index++, i++)
|
|
{
|
|
if (g_CursorData[i].hCursor != NULL)
|
|
{
|
|
DestroyCursor(g_CursorData[i].hCursor);
|
|
g_CursorData[i].hCursor = 0;
|
|
}
|
|
g_CursorData[i].szCursorPath[0] = 0;
|
|
}
|
|
|
|
if (lpName != NULL)
|
|
{
|
|
LPTSTR pStart = lpName;
|
|
LPTSTR pEnd = pStart;
|
|
INT nLength;
|
|
|
|
i = 0;
|
|
while (pEnd)
|
|
{
|
|
pEnd = _tcschr(pStart, _T(','));
|
|
if (pEnd)
|
|
nLength = ((INT_PTR)pEnd - (INT_PTR)pStart) / sizeof(TCHAR);
|
|
else
|
|
nLength = _tcslen(pStart);
|
|
|
|
_tcsncpy(g_CursorData[i].szCursorPath, pStart, nLength);
|
|
g_CursorData[i].szCursorPath[nLength] = 0;
|
|
|
|
pStart = pStart + (nLength + 1);
|
|
i++;
|
|
}
|
|
|
|
}
|
|
|
|
for (index = IDS_ARROW, i = 0; index <= IDS_HAND; index++, i++)
|
|
{
|
|
if (g_CursorData[i].szCursorPath[0] == 0)
|
|
g_CursorData[i].hCursor = (HCURSOR)LoadImage(NULL, MAKEINTRESOURCE(g_CursorData[i].uDefaultCursorId),
|
|
IMAGE_CURSOR, 0, 0,
|
|
LR_DEFAULTSIZE | LR_SHARED);
|
|
else
|
|
g_CursorData[i].hCursor = (HCURSOR)LoadImage(NULL, g_CursorData[i].szCursorPath,
|
|
IMAGE_CURSOR, 0, 0,
|
|
LR_LOADFROMFILE | LR_DEFAULTSIZE);
|
|
}
|
|
}
|
|
|
|
|
|
static VOID
|
|
ReloadCurrentCursorScheme(VOID)
|
|
{
|
|
UINT index, i;
|
|
|
|
for (index = IDS_ARROW, i = 0; index <= IDS_HAND; index++, i++)
|
|
{
|
|
if (g_CursorData[i].hCursor != NULL)
|
|
DestroyCursor(g_CursorData[i].hCursor);
|
|
|
|
if (g_CursorData[i].szCursorPath[0] == 0)
|
|
g_CursorData[i].hCursor = (HCURSOR)LoadImage(NULL, MAKEINTRESOURCE(g_CursorData[i].uDefaultCursorId),
|
|
IMAGE_CURSOR, 0, 0,
|
|
LR_DEFAULTSIZE | LR_SHARED);
|
|
else
|
|
g_CursorData[i].hCursor = (HCURSOR)LoadImage(NULL, g_CursorData[i].szCursorPath,
|
|
IMAGE_CURSOR, 0, 0,
|
|
LR_LOADFROMFILE | LR_DEFAULTSIZE);
|
|
}
|
|
}
|
|
|
|
|
|
static VOID
|
|
OnDrawItem(UINT idCtl,
|
|
LPDRAWITEMSTRUCT lpdis,
|
|
PPOINTER_DATA pPointerData)
|
|
{
|
|
RECT rc;
|
|
|
|
if (lpdis->itemState & ODS_SELECTED)
|
|
{
|
|
FillRect(lpdis->hDC,
|
|
&lpdis->rcItem,
|
|
(HBRUSH)(COLOR_HIGHLIGHT + 1));
|
|
SetBkColor(lpdis->hDC,
|
|
GetSysColor(COLOR_HIGHLIGHT));
|
|
SetTextColor(lpdis->hDC,
|
|
GetSysColor(COLOR_HIGHLIGHTTEXT));
|
|
}
|
|
else
|
|
{
|
|
FillRect(lpdis->hDC,
|
|
&lpdis->rcItem,
|
|
(HBRUSH)(COLOR_WINDOW + 1));
|
|
SetBkColor(lpdis->hDC,
|
|
GetSysColor(COLOR_WINDOW));
|
|
SetTextColor(lpdis->hDC,
|
|
GetSysColor(COLOR_WINDOWTEXT));
|
|
}
|
|
|
|
if (lpdis->itemID != (UINT)-1)
|
|
{
|
|
CopyRect(&rc, &lpdis->rcItem);
|
|
rc.left += 5;
|
|
DrawText(lpdis->hDC,
|
|
g_CursorData[lpdis->itemData].szCursorName,
|
|
-1,
|
|
&rc,
|
|
DT_SINGLELINE | DT_VCENTER | DT_LEFT);
|
|
|
|
if (g_CursorData[lpdis->itemData].hCursor != NULL)
|
|
{
|
|
DrawIcon(lpdis->hDC,
|
|
lpdis->rcItem.right - pPointerData->cxCursor - 4,
|
|
lpdis->rcItem.top + 2,
|
|
g_CursorData[lpdis->itemData].hCursor);
|
|
}
|
|
}
|
|
|
|
if (lpdis->itemState & ODS_FOCUS)
|
|
{
|
|
CopyRect(&rc, &lpdis->rcItem);
|
|
InflateRect(&rc, -1, -1);
|
|
DrawFocusRect(lpdis->hDC, &rc);
|
|
}
|
|
}
|
|
|
|
|
|
static VOID
|
|
LoadNewCursorScheme(HWND hwndDlg)
|
|
{
|
|
TCHAR buffer[MAX_PATH];
|
|
TCHAR szSystemScheme[MAX_PATH];
|
|
HWND hDlgCtrl;
|
|
BOOL bEnable;
|
|
LPTSTR lpName;
|
|
INT nSel;
|
|
|
|
nSel = SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_GETCURSEL, 0, 0);
|
|
if (nSel == CB_ERR)
|
|
return;
|
|
|
|
SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_GETLBTEXT, nSel, (LPARAM)buffer);
|
|
|
|
LoadString(hApplet, IDS_SYSTEM_SCHEME, szSystemScheme, MAX_PATH);
|
|
if (_tcsstr(buffer, szSystemScheme) || nSel == 0) // Avoid the default scheme - Can be deleted
|
|
bEnable = FALSE;
|
|
else
|
|
bEnable = TRUE;
|
|
|
|
/* Delete button */
|
|
hDlgCtrl = GetDlgItem(hwndDlg, IDC_BUTTON_DELETE_SCHEME);
|
|
EnableWindow(hDlgCtrl, bEnable);
|
|
|
|
lpName = (LPTSTR)SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_GETITEMDATA, nSel, 0);
|
|
LoadCursorScheme(lpName, !bEnable);
|
|
RefreshCursorList(hwndDlg, FALSE);
|
|
}
|
|
|
|
|
|
static VOID
|
|
LoadInitialCursorScheme(HWND hwndDlg)
|
|
{
|
|
TCHAR szSchemeName[MAX_PATH];
|
|
TCHAR szSystemScheme[MAX_PATH];
|
|
TCHAR szCursorPath[MAX_PATH];
|
|
HKEY hCursorKey;
|
|
LONG lError;
|
|
DWORD dwDataSize;
|
|
DWORD dwSchemeSource = 0;
|
|
UINT index, i;
|
|
DWORD dwType;
|
|
INT nSel;
|
|
|
|
for (index = IDS_ARROW, i = 0; index <= IDS_HAND; index++, i++)
|
|
{
|
|
g_CursorData[i].hCursor = 0;
|
|
g_CursorData[i].szCursorPath[0] = 0;
|
|
}
|
|
|
|
lError = RegOpenKeyEx(HKEY_CURRENT_USER,
|
|
_T("Control Panel\\Cursors"),
|
|
0,
|
|
KEY_READ | KEY_QUERY_VALUE,
|
|
&hCursorKey);
|
|
if (lError != ERROR_SUCCESS)
|
|
return;
|
|
|
|
dwDataSize = sizeof(DWORD);
|
|
lError = RegQueryValueEx(hCursorKey,
|
|
_T("Scheme Source"),
|
|
NULL,
|
|
NULL,
|
|
(LPBYTE)&dwSchemeSource,
|
|
&dwDataSize);
|
|
|
|
if (dwSchemeSource != 0)
|
|
{
|
|
dwDataSize = MAX_PATH * sizeof(TCHAR);
|
|
lError = RegQueryValueEx(hCursorKey,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
(LPBYTE)szSchemeName,
|
|
&dwDataSize);
|
|
|
|
for (index = IDS_ARROW, i = 0; index <= IDS_HAND; index++, i++)
|
|
{
|
|
dwDataSize = MAX_PATH * sizeof(TCHAR);
|
|
lError = RegQueryValueEx(hCursorKey,
|
|
g_CursorData[i].lpValueName,
|
|
NULL,
|
|
&dwType,
|
|
(LPBYTE)szCursorPath,
|
|
&dwDataSize);
|
|
if (lError == ERROR_SUCCESS)
|
|
{
|
|
if (dwType == REG_EXPAND_SZ)
|
|
{
|
|
ExpandEnvironmentStrings(szCursorPath, g_CursorData[i].szCursorPath, MAX_PATH);
|
|
}
|
|
else
|
|
{
|
|
_tcscpy(g_CursorData[i].szCursorPath, szCursorPath);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
RegCloseKey(hCursorKey);
|
|
|
|
ReloadCurrentCursorScheme();
|
|
RefreshCursorList(hwndDlg, TRUE);
|
|
|
|
/* Build the full scheme name */
|
|
if (dwSchemeSource == 0)
|
|
{
|
|
LoadString(hApplet, IDS_NONE, szSchemeName, MAX_PATH);
|
|
}
|
|
else if (dwSchemeSource == 2)
|
|
{
|
|
LoadString(hApplet, IDS_SYSTEM_SCHEME, szSystemScheme, MAX_PATH);
|
|
_tcsncat(szSchemeName, _T(" "), MAX_PATH - _tcslen(szSchemeName) - 1);
|
|
_tcsncat(szSchemeName, szSystemScheme, MAX_PATH - _tcslen(szSchemeName) - 1);
|
|
}
|
|
|
|
/* Search and select the current scheme name from the scheme list */
|
|
nSel = SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_FINDSTRINGEXACT, -1, (LPARAM)szSchemeName);
|
|
if (nSel != CB_ERR)
|
|
SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_SETCURSEL, (WPARAM)nSel, (LPARAM)0);
|
|
|
|
/* Enable /disable delete button */
|
|
EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_DELETE_SCHEME), (dwSchemeSource == 1));
|
|
}
|
|
|
|
|
|
static BOOL
|
|
ApplyCursorScheme(HWND hwndDlg)
|
|
{
|
|
TCHAR szSchemeName[MAX_PATH];
|
|
TCHAR szSystemScheme[MAX_PATH];
|
|
TCHAR szTempPath[MAX_PATH];
|
|
LPTSTR lpSchemeData;
|
|
DWORD dwNameLength;
|
|
DWORD dwSchemeSource;
|
|
UINT index, i;
|
|
HKEY hCursorKey;
|
|
INT nSel;
|
|
|
|
nSel = SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_GETCURSEL, 0, 0);
|
|
if (nSel == CB_ERR)
|
|
return FALSE;
|
|
|
|
lpSchemeData = (LPTSTR)SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_GETITEMDATA, nSel, 0);
|
|
if (lpSchemeData == NULL)
|
|
{
|
|
/* "None" cursor scheme */
|
|
dwSchemeSource = 0;
|
|
szSchemeName[0] = 0;
|
|
dwNameLength = 0;
|
|
}
|
|
else
|
|
{
|
|
SendDlgItemMessage(hwndDlg, IDC_COMBO_CURSOR_SCHEME, CB_GETLBTEXT, nSel, (LPARAM)szSchemeName);
|
|
LoadString(hApplet, IDS_SYSTEM_SCHEME, szSystemScheme, MAX_PATH);
|
|
|
|
if (_tcsstr(szSchemeName, szSystemScheme))
|
|
{
|
|
/* System scheme */
|
|
dwSchemeSource = 2;
|
|
szSchemeName[_tcslen(szSchemeName) - _tcslen(szSystemScheme) - 1] = 0;
|
|
}
|
|
else
|
|
{
|
|
/* User scheme */
|
|
dwSchemeSource = 1;
|
|
}
|
|
|
|
dwNameLength = (_tcslen(szSchemeName) + 1) * sizeof(TCHAR);
|
|
}
|
|
|
|
if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Control Panel\\Cursors"), 0,
|
|
KEY_READ | KEY_SET_VALUE, &hCursorKey) != ERROR_SUCCESS)
|
|
return FALSE;
|
|
|
|
RegSetValueEx(hCursorKey, NULL, 0, REG_SZ,
|
|
(LPBYTE)szSchemeName, dwNameLength);
|
|
|
|
RegSetValueEx(hCursorKey, _T("Scheme Source"), 0, REG_DWORD,
|
|
(LPBYTE)&dwSchemeSource, sizeof(DWORD));
|
|
|
|
for (index = IDS_ARROW, i = 0; index <= IDS_HAND; index++, i++)
|
|
{
|
|
CompressPath(szTempPath, g_CursorData[i].szCursorPath);
|
|
RegSetValueEx(hCursorKey, g_CursorData[i].lpValueName, 0,
|
|
REG_EXPAND_SZ, (LPBYTE)szTempPath,
|
|
(_tcslen(szTempPath) + 1) * sizeof(TCHAR));
|
|
}
|
|
|
|
RegCloseKey(hCursorKey);
|
|
|
|
/* Force the system to reload its cursors */
|
|
SystemParametersInfo(SPI_SETCURSORS, 0, NULL, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
static INT_PTR CALLBACK
|
|
PointerProc(IN HWND hwndDlg,
|
|
IN UINT uMsg,
|
|
IN WPARAM wParam,
|
|
IN LPARAM lParam)
|
|
{
|
|
PPOINTER_DATA pPointerData;
|
|
LPPSHNOTIFY lppsn;
|
|
INT nSel;
|
|
|
|
pPointerData = (PPOINTER_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
|
|
|
|
switch (uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
pPointerData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(POINTER_DATA));
|
|
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pPointerData);
|
|
|
|
pPointerData->cxCursor = GetSystemMetrics(SM_CXCURSOR);
|
|
pPointerData->cyCursor = GetSystemMetrics(SM_CYCURSOR);
|
|
|
|
EnumerateCursorSchemes(hwndDlg);
|
|
LoadInitialCursorScheme(hwndDlg);
|
|
|
|
/* Get cursor shadow setting */
|
|
SystemParametersInfo(SPI_GETCURSORSHADOW, 0, &pPointerData->bCursorShadow, 0);
|
|
pPointerData->bOrigCursorShadow = pPointerData->bCursorShadow;
|
|
|
|
if (pPointerData->bCursorShadow)
|
|
{
|
|
SendDlgItemMessage(hwndDlg, IDC_CHECK_CURSOR_SHADOW, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
|
|
}
|
|
|
|
if ((INT)wParam == IDC_LISTBOX_CURSOR)
|
|
return TRUE;
|
|
else
|
|
return FALSE;
|
|
|
|
case WM_MEASUREITEM:
|
|
((LPMEASUREITEMSTRUCT)lParam)->itemHeight = GetSystemMetrics(SM_CYCURSOR) + 4;
|
|
break;
|
|
|
|
case WM_DRAWITEM:
|
|
if (wParam == IDC_LISTBOX_CURSOR)
|
|
OnDrawItem((UINT)wParam, (LPDRAWITEMSTRUCT)lParam, pPointerData);
|
|
return TRUE;
|
|
|
|
case WM_DESTROY:
|
|
HeapFree(GetProcessHeap(), 0, pPointerData);
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
lppsn = (LPPSHNOTIFY) lParam;
|
|
if (lppsn->hdr.code == PSN_APPLY)
|
|
{
|
|
ApplyCursorScheme(hwndDlg);
|
|
//#if (WINVER >= 0x0500)
|
|
if (pPointerData->bOrigCursorShadow != pPointerData->bCursorShadow)
|
|
{
|
|
SystemParametersInfo(SPI_SETCURSORSHADOW, 0, UlongToPtr(pPointerData->bCursorShadow), SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
|
|
pPointerData->bOrigCursorShadow = pPointerData->bCursorShadow;
|
|
}
|
|
//#endif
|
|
return TRUE;
|
|
}
|
|
else if (lppsn->hdr.code == PSN_RESET)
|
|
{
|
|
//#if (WINVER >= 0x0500)
|
|
SystemParametersInfo(SPI_SETCURSORSHADOW, 0, UlongToPtr(pPointerData->bOrigCursorShadow), SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
|
|
//#endif
|
|
}
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case IDC_COMBO_CURSOR_SCHEME:
|
|
if (HIWORD(wParam) == CBN_SELENDOK)
|
|
{
|
|
LoadNewCursorScheme(hwndDlg);
|
|
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
|
|
}
|
|
break;
|
|
|
|
case IDC_LISTBOX_CURSOR:
|
|
switch (HIWORD(wParam))
|
|
{
|
|
case LBN_SELCHANGE:
|
|
nSel = SendMessage((HWND)lParam, LB_GETCURSEL, 0, 0);
|
|
|
|
if(nSel == LB_ERR)
|
|
break;
|
|
|
|
SendDlgItemMessage(hwndDlg, IDC_IMAGE_CURRENT_CURSOR, STM_SETIMAGE, IMAGE_CURSOR,
|
|
(LPARAM)g_CursorData[nSel].hCursor);
|
|
EnableWindow(GetDlgItem(hwndDlg,IDC_BUTTON_USE_DEFAULT_CURSOR),
|
|
(g_CursorData[nSel].szCursorPath[0] != 0));
|
|
break;
|
|
|
|
case LBN_DBLCLK:
|
|
if (BrowseCursor(hwndDlg))
|
|
{
|
|
/* Update cursor list and preview */
|
|
ReloadCurrentCursorScheme();
|
|
RefreshCursorList(hwndDlg, FALSE);
|
|
|
|
/* Enable the "Set Default" button */
|
|
EnableWindow(GetDlgItem(hwndDlg,IDC_BUTTON_USE_DEFAULT_CURSOR), TRUE);
|
|
|
|
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case IDC_BUTTON_SAVEAS_SCHEME:
|
|
SaveCursorScheme(hwndDlg);
|
|
break;
|
|
|
|
case IDC_BUTTON_USE_DEFAULT_CURSOR:
|
|
nSel = SendDlgItemMessage(hwndDlg, IDC_LISTBOX_CURSOR, LB_GETCURSEL, 0, 0);
|
|
if (nSel != LB_ERR)
|
|
{
|
|
/* Clean the path of the currently selected cursor */
|
|
memset(g_CursorData[nSel].szCursorPath, 0x0, MAX_PATH * sizeof(TCHAR));
|
|
|
|
/* Update cursor list and preview */
|
|
ReloadCurrentCursorScheme();
|
|
RefreshCursorList(hwndDlg, FALSE);
|
|
|
|
/* Disable the "Set Default" button */
|
|
EnableWindow(GetDlgItem(hwndDlg,IDC_BUTTON_USE_DEFAULT_CURSOR), FALSE);
|
|
|
|
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
|
|
}
|
|
break;
|
|
|
|
case IDC_BUTTON_BROWSE_CURSOR:
|
|
if (BrowseCursor(hwndDlg))
|
|
{
|
|
/* Update cursor list and preview */
|
|
ReloadCurrentCursorScheme();
|
|
RefreshCursorList(hwndDlg, FALSE);
|
|
|
|
/* Enable the "Set Default" button */
|
|
EnableWindow(GetDlgItem(hwndDlg,IDC_BUTTON_USE_DEFAULT_CURSOR), TRUE);
|
|
|
|
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
|
|
}
|
|
break;
|
|
|
|
case IDC_BUTTON_DELETE_SCHEME:
|
|
DeleteUserCursorScheme(hwndDlg);
|
|
break;
|
|
|
|
case IDC_CHECK_CURSOR_SHADOW:
|
|
if(IsDlgButtonChecked(hwndDlg, IDC_CHECK_CURSOR_SHADOW))
|
|
{
|
|
pPointerData->bCursorShadow = FALSE;
|
|
SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0);
|
|
//#if (WINVER >= 0x0500)
|
|
// SystemParametersInfo(SPI_SETCURSORSHADOW, 0, (PVOID)pPointerData->bCursorShadow, 0);
|
|
//#endif
|
|
// PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
|
|
}
|
|
else
|
|
{
|
|
pPointerData->bCursorShadow = TRUE;
|
|
SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
|
|
}
|
|
//#if (WINVER >= 0x0500)
|
|
//SystemParametersInfo(SPI_SETCURSORSHADOW, 0, (PVOID)pPointerData->bCursorShadow, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
|
|
//#endif
|
|
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
static INT_PTR CALLBACK
|
|
OptionProc(IN HWND hwndDlg,
|
|
IN UINT uMsg,
|
|
IN WPARAM wParam,
|
|
IN LPARAM lParam)
|
|
{
|
|
POPTION_DATA pOptionData;
|
|
HWND hDlgCtrl;
|
|
LPPSHNOTIFY lppsn;
|
|
|
|
pOptionData = (POPTION_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
|
|
|
|
switch(uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
pOptionData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(OPTION_DATA));
|
|
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pOptionData);
|
|
|
|
/* Get mouse sensitivity */
|
|
if (!SystemParametersInfo(SPI_GETMOUSESPEED, 0, &pOptionData->ulMouseSpeed, 0))
|
|
pOptionData->ulMouseSpeed = DEFAULT_MOUSE_SPEED;
|
|
pOptionData->ulOrigMouseSpeed = pOptionData->ulMouseSpeed;
|
|
|
|
|
|
if (!SystemParametersInfo(SPI_GETMOUSE, 0, &pOptionData->MouseAccel, 0))
|
|
{
|
|
pOptionData->MouseAccel.nAcceleration = DEFAULT_MOUSE_ACCELERATION;
|
|
pOptionData->MouseAccel.nThreshold1 = DEFAULT_MOUSE_THRESHOLD1;
|
|
pOptionData->MouseAccel.nThreshold2 = DEFAULT_MOUSE_THRESHOLD2;
|
|
}
|
|
pOptionData->OrigMouseAccel.nAcceleration = pOptionData->MouseAccel.nAcceleration;
|
|
pOptionData->OrigMouseAccel.nThreshold1 = pOptionData->MouseAccel.nThreshold1;
|
|
pOptionData->OrigMouseAccel.nThreshold2 = pOptionData->MouseAccel.nThreshold2;
|
|
|
|
/* Snap to default button */
|
|
SystemParametersInfo(SPI_GETSNAPTODEFBUTTON, 0, &pOptionData->bSnapToDefaultButton, 0);
|
|
pOptionData->bOrigSnapToDefaultButton = pOptionData->bSnapToDefaultButton;
|
|
|
|
/* Mouse trails */
|
|
SystemParametersInfo(SPI_GETMOUSETRAILS, 0, &pOptionData->uMouseTrails, 0);
|
|
pOptionData->uOrigMouseTrails = pOptionData->uMouseTrails;
|
|
|
|
/* Hide pointer while typing */
|
|
SystemParametersInfo(SPI_GETMOUSEVANISH, 0, &pOptionData->bMouseVanish, 0);
|
|
pOptionData->bOrigMouseVanish = pOptionData->bMouseVanish;
|
|
|
|
/* Show pointer with Ctrl-Key */
|
|
SystemParametersInfo(SPI_GETMOUSESONAR, 0, &pOptionData->bMouseSonar, 0);
|
|
pOptionData->bOrigMouseSonar = pOptionData->bMouseSonar;
|
|
|
|
/* Set mouse speed */
|
|
hDlgCtrl = GetDlgItem(hwndDlg, IDC_SLIDER_MOUSE_SPEED);
|
|
SendMessage(hDlgCtrl, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(1, 20));
|
|
SendMessage(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)pOptionData->ulMouseSpeed);
|
|
|
|
if (pOptionData->MouseAccel.nAcceleration)
|
|
{
|
|
hDlgCtrl = GetDlgItem(hwndDlg, IDC_CHECK_POINTER_PRECISION);
|
|
SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
|
|
}
|
|
|
|
if (pOptionData->bSnapToDefaultButton)
|
|
{
|
|
hDlgCtrl = GetDlgItem(hwndDlg, IDC_CHECK_SNAP_TO);
|
|
SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
|
|
}
|
|
|
|
/* Set mouse trail */
|
|
hDlgCtrl = GetDlgItem(hwndDlg, IDC_SLIDER_POINTER_TRAIL);
|
|
SendMessage(hDlgCtrl, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(0, 5));
|
|
if (pOptionData->uMouseTrails < 2)
|
|
{
|
|
SendMessage(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)5);
|
|
EnableWindow(hDlgCtrl, FALSE);
|
|
EnableWindow(GetDlgItem(hwndDlg, IDC_TEXT_TRAIL_SHORT), FALSE);
|
|
EnableWindow(GetDlgItem(hwndDlg, IDC_TEXT_TRAIL_LONG), FALSE);
|
|
}
|
|
else
|
|
{
|
|
SendDlgItemMessage(hwndDlg, IDC_CHECK_POINTER_TRAIL, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
|
|
SendMessage(hDlgCtrl, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)pOptionData->uMouseTrails - 2);
|
|
}
|
|
|
|
if (pOptionData->bMouseVanish)
|
|
{
|
|
hDlgCtrl = GetDlgItem(hwndDlg, IDC_CHECK_HIDE_POINTER);
|
|
SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
|
|
}
|
|
|
|
if (pOptionData->bMouseSonar)
|
|
{
|
|
hDlgCtrl = GetDlgItem(hwndDlg, IDC_CHECK_SHOW_POINTER);
|
|
SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
|
|
}
|
|
|
|
break;
|
|
|
|
case WM_DESTROY:
|
|
HeapFree(GetProcessHeap(), 0, pOptionData);
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch(LOWORD(wParam))
|
|
{
|
|
case IDC_CHECK_POINTER_PRECISION:
|
|
if(IsDlgButtonChecked(hwndDlg, IDC_CHECK_POINTER_PRECISION))
|
|
{
|
|
pOptionData->MouseAccel.nAcceleration = 0;
|
|
pOptionData->MouseAccel.nThreshold1 = 0;
|
|
pOptionData->MouseAccel.nThreshold2 = 0;
|
|
SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0);
|
|
}
|
|
else
|
|
{
|
|
pOptionData->MouseAccel.nAcceleration = 1;
|
|
pOptionData->MouseAccel.nThreshold1 = 6;
|
|
pOptionData->MouseAccel.nThreshold2 = 10;
|
|
SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
|
|
}
|
|
SystemParametersInfo(SPI_SETMOUSE, 0, &pOptionData->MouseAccel, 0);
|
|
break;
|
|
|
|
case IDC_CHECK_SNAP_TO:
|
|
if(IsDlgButtonChecked(hwndDlg, IDC_CHECK_SNAP_TO))
|
|
{
|
|
pOptionData->bSnapToDefaultButton = 0;
|
|
SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0);
|
|
}
|
|
else
|
|
{
|
|
pOptionData->bSnapToDefaultButton = 1;
|
|
SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
|
|
}
|
|
SystemParametersInfo(SPI_SETSNAPTODEFBUTTON, (UINT)pOptionData->bSnapToDefaultButton, 0, 0);
|
|
break;
|
|
|
|
case IDC_CHECK_POINTER_TRAIL:
|
|
hDlgCtrl = GetDlgItem(hwndDlg, IDC_SLIDER_POINTER_TRAIL);
|
|
if(IsDlgButtonChecked(hwndDlg, IDC_CHECK_POINTER_TRAIL))
|
|
{
|
|
SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0);
|
|
EnableWindow(hDlgCtrl, FALSE);
|
|
EnableWindow(GetDlgItem(hwndDlg, IDC_TEXT_TRAIL_SHORT), FALSE);
|
|
EnableWindow(GetDlgItem(hwndDlg, IDC_TEXT_TRAIL_LONG), FALSE);
|
|
pOptionData->uMouseTrails = 0;
|
|
}
|
|
else
|
|
{
|
|
SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
|
|
EnableWindow(hDlgCtrl, TRUE);
|
|
EnableWindow(GetDlgItem(hwndDlg, IDC_TEXT_TRAIL_SHORT), TRUE);
|
|
EnableWindow(GetDlgItem(hwndDlg, IDC_TEXT_TRAIL_LONG), TRUE);
|
|
pOptionData->uMouseTrails = (UINT)SendMessage(hDlgCtrl, TBM_GETPOS, 0, 0) + 2;
|
|
}
|
|
SystemParametersInfo(SPI_SETMOUSETRAILS, pOptionData->uMouseTrails, 0, 0);
|
|
break;
|
|
|
|
case IDC_CHECK_HIDE_POINTER:
|
|
if(IsDlgButtonChecked(hwndDlg, IDC_CHECK_HIDE_POINTER))
|
|
{
|
|
pOptionData->bMouseVanish = FALSE;
|
|
SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0);
|
|
}
|
|
else
|
|
{
|
|
pOptionData->bMouseVanish = TRUE;
|
|
SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
|
|
}
|
|
SystemParametersInfo(SPI_SETMOUSEVANISH, 0, IntToPtr(pOptionData->bMouseVanish), 0);
|
|
break;
|
|
|
|
case IDC_CHECK_SHOW_POINTER:
|
|
if(IsDlgButtonChecked(hwndDlg, IDC_CHECK_SHOW_POINTER))
|
|
{
|
|
pOptionData->bMouseSonar = FALSE;
|
|
SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0);
|
|
}
|
|
else
|
|
{
|
|
pOptionData->bMouseSonar = TRUE;
|
|
SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
|
|
}
|
|
SystemParametersInfo(SPI_SETMOUSESONAR, 0, IntToPtr(pOptionData->bMouseSonar), 0);
|
|
break;
|
|
|
|
}
|
|
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
lppsn = (LPPSHNOTIFY)lParam;
|
|
if (lppsn->hdr.code == PSN_APPLY)
|
|
{
|
|
/* Set mouse speed */
|
|
if (pOptionData->ulOrigMouseSpeed != pOptionData->ulMouseSpeed)
|
|
{
|
|
SystemParametersInfo(SPI_SETMOUSESPEED, 0, IntToPtr(pOptionData->ulMouseSpeed), SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
|
|
pOptionData->ulOrigMouseSpeed = pOptionData->ulMouseSpeed;
|
|
}
|
|
|
|
if (pOptionData->OrigMouseAccel.nAcceleration != pOptionData->MouseAccel.nAcceleration)
|
|
{
|
|
SystemParametersInfo(SPI_SETMOUSE, 0, &pOptionData->MouseAccel, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
|
|
pOptionData->OrigMouseAccel.nAcceleration = pOptionData->MouseAccel.nAcceleration;
|
|
pOptionData->OrigMouseAccel.nThreshold1 = pOptionData->MouseAccel.nThreshold1;
|
|
pOptionData->OrigMouseAccel.nThreshold2 = pOptionData->MouseAccel.nThreshold2;
|
|
}
|
|
|
|
|
|
/* Set snap to default button */
|
|
if (pOptionData->bOrigSnapToDefaultButton != pOptionData->bSnapToDefaultButton)
|
|
{
|
|
SystemParametersInfo(SPI_SETSNAPTODEFBUTTON, (UINT)pOptionData->bSnapToDefaultButton, 0, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
|
|
pOptionData->bOrigSnapToDefaultButton = pOptionData->bSnapToDefaultButton;
|
|
}
|
|
|
|
/* Set mouse trails setting */
|
|
if (pOptionData->uOrigMouseTrails != pOptionData->uMouseTrails)
|
|
{
|
|
SystemParametersInfo(SPI_SETMOUSETRAILS, pOptionData->uMouseTrails, 0, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
|
|
pOptionData->uOrigMouseTrails = pOptionData->uMouseTrails;
|
|
}
|
|
|
|
/* Hide pointer while typing */
|
|
if (pOptionData->bOrigMouseVanish != pOptionData->bMouseVanish)
|
|
{
|
|
SystemParametersInfo(SPI_SETMOUSEVANISH, 0, IntToPtr(pOptionData->bMouseVanish), SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
|
|
pOptionData->bOrigMouseVanish = pOptionData->bMouseVanish;
|
|
}
|
|
|
|
/* Show pointer with Ctrl-Key */
|
|
if (pOptionData->bOrigMouseSonar != pOptionData->bMouseSonar)
|
|
{
|
|
SystemParametersInfo(SPI_SETMOUSESONAR, 0, IntToPtr(pOptionData->bMouseSonar), SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
|
|
pOptionData->bOrigMouseSonar = pOptionData->bMouseSonar;
|
|
}
|
|
return TRUE;
|
|
}
|
|
else if (lppsn->hdr.code == PSN_RESET)
|
|
{
|
|
/* Set the original mouse speed */
|
|
SystemParametersInfo(SPI_SETMOUSESPEED, 0, IntToPtr(pOptionData->ulOrigMouseSpeed), 0);
|
|
SystemParametersInfo(SPI_SETMOUSE, 0, &pOptionData->OrigMouseAccel, 0);
|
|
SystemParametersInfo(SPI_SETSNAPTODEFBUTTON, (UINT)pOptionData->bOrigSnapToDefaultButton, 0, 0);
|
|
SystemParametersInfo(SPI_SETMOUSETRAILS, pOptionData->uOrigMouseTrails, 0, 0);
|
|
SystemParametersInfo(SPI_SETMOUSEVANISH, 0, IntToPtr(pOptionData->bOrigMouseVanish), 0);
|
|
SystemParametersInfo(SPI_SETMOUSESONAR, 0,IntToPtr(pOptionData->bOrigMouseSonar), 0);
|
|
}
|
|
break;
|
|
|
|
case WM_HSCROLL:
|
|
if ((HWND)lParam == GetDlgItem(hwndDlg, IDC_SLIDER_MOUSE_SPEED))
|
|
{
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case TB_LINEUP:
|
|
case TB_LINEDOWN:
|
|
case TB_PAGEUP:
|
|
case TB_PAGEDOWN:
|
|
case TB_TOP:
|
|
case TB_BOTTOM:
|
|
case TB_ENDTRACK:
|
|
pOptionData->ulMouseSpeed = (ULONG)SendDlgItemMessage(hwndDlg, IDC_SLIDER_MOUSE_SPEED, TBM_GETPOS, 0, 0);
|
|
SystemParametersInfo(SPI_SETMOUSESPEED, 0, IntToPtr(pOptionData->ulMouseSpeed), SPIF_SENDCHANGE);
|
|
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
|
|
break;
|
|
#if 0
|
|
case TB_THUMBTRACK:
|
|
pOptionData->ulMouseSpeed = (ULONG)HIWORD(wParam) + 1;
|
|
SystemParametersInfo(SPI_SETMOUSESPEED, 0, (PVOID)pOptionData->ulMouseSpeed, SPIF_SENDCHANGE);
|
|
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
|
|
break;
|
|
#endif
|
|
}
|
|
}
|
|
else if ((HWND)lParam == GetDlgItem(hwndDlg, IDC_SLIDER_POINTER_TRAIL))
|
|
{
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case TB_LINEUP:
|
|
case TB_LINEDOWN:
|
|
case TB_PAGEUP:
|
|
case TB_PAGEDOWN:
|
|
case TB_TOP:
|
|
case TB_BOTTOM:
|
|
case TB_ENDTRACK:
|
|
pOptionData->uMouseTrails = (ULONG)SendDlgItemMessage(hwndDlg, IDC_SLIDER_POINTER_TRAIL, TBM_GETPOS, 0, 0) + 2;
|
|
SystemParametersInfo(SPI_SETMOUSETRAILS, pOptionData->uMouseTrails, 0, SPIF_UPDATEINIFILE);
|
|
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
|
|
break;
|
|
|
|
case TB_THUMBTRACK:
|
|
pOptionData->uMouseTrails = (ULONG)HIWORD(wParam) + 2;
|
|
SystemParametersInfo(SPI_SETMOUSETRAILS, pOptionData->uMouseTrails, 0, SPIF_UPDATEINIFILE);
|
|
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
static VOID
|
|
ShowDialogWheelControls(HWND hwndDlg, UINT uWheelScrollLines, BOOL bInit)
|
|
{
|
|
HWND hDlgCtrl;
|
|
|
|
if (uWheelScrollLines != WHEEL_PAGESCROLL)
|
|
{
|
|
hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_WHEEL_SCROLL_LINES);
|
|
SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
|
|
|
|
hDlgCtrl = GetDlgItem(hwndDlg, IDC_EDIT_WHEEL_SCROLL_LINES);
|
|
EnableWindow(hDlgCtrl, TRUE);
|
|
|
|
hDlgCtrl = GetDlgItem(hwndDlg, IDC_UPDOWN_WHEEL_SCROLL_LINES);
|
|
EnableWindow(hDlgCtrl, TRUE);
|
|
|
|
hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_WHEEL_SCROLL_PAGE);
|
|
SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0);
|
|
}
|
|
else
|
|
{
|
|
hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_WHEEL_SCROLL_LINES);
|
|
SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0);
|
|
|
|
hDlgCtrl = GetDlgItem(hwndDlg, IDC_EDIT_WHEEL_SCROLL_LINES);
|
|
EnableWindow(hDlgCtrl, FALSE);
|
|
|
|
hDlgCtrl = GetDlgItem(hwndDlg, IDC_UPDOWN_WHEEL_SCROLL_LINES);
|
|
EnableWindow(hDlgCtrl, FALSE);
|
|
|
|
hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_WHEEL_SCROLL_PAGE);
|
|
SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);
|
|
|
|
/* Set the default scroll lines value */
|
|
if (bInit != FALSE)
|
|
SetDlgItemInt(hwndDlg, IDC_EDIT_WHEEL_SCROLL_LINES, DEFAULT_WHEEL_SCROLL_LINES, FALSE);
|
|
}
|
|
}
|
|
|
|
|
|
static INT_PTR CALLBACK
|
|
WheelProc(IN HWND hwndDlg,
|
|
IN UINT uMsg,
|
|
IN WPARAM wParam,
|
|
IN LPARAM lParam)
|
|
{
|
|
LPPSHNOTIFY lppsn;
|
|
PWHEEL_DATA pWheelData;
|
|
|
|
pWheelData = (PWHEEL_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
|
|
|
|
switch (uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
pWheelData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WHEEL_DATA));
|
|
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pWheelData);
|
|
|
|
/* Get wheel scroll lines */
|
|
SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &pWheelData->uWheelScrollLines, 0);
|
|
|
|
ShowDialogWheelControls(hwndDlg, pWheelData->uWheelScrollLines, TRUE);
|
|
SendDlgItemMessage(hwndDlg, IDC_UPDOWN_WHEEL_SCROLL_LINES, UDM_SETRANGE, 0, MAKELONG((short)100, (short)0));
|
|
if (pWheelData->uWheelScrollLines != WHEEL_PAGESCROLL)
|
|
{
|
|
SetDlgItemInt(hwndDlg, IDC_EDIT_WHEEL_SCROLL_LINES, pWheelData->uWheelScrollLines, FALSE);
|
|
}
|
|
return TRUE;
|
|
|
|
case WM_DESTROY:
|
|
HeapFree(GetProcessHeap(), 0, pWheelData);
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case IDC_RADIO_WHEEL_SCROLL_LINES:
|
|
pWheelData->uWheelScrollLines = GetDlgItemInt(hwndDlg, IDC_EDIT_WHEEL_SCROLL_LINES, NULL, FALSE);
|
|
ShowDialogWheelControls(hwndDlg, pWheelData->uWheelScrollLines, FALSE);
|
|
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
|
|
break;
|
|
|
|
case IDC_RADIO_WHEEL_SCROLL_PAGE:
|
|
pWheelData->uWheelScrollLines = WHEEL_PAGESCROLL;
|
|
ShowDialogWheelControls(hwndDlg, pWheelData->uWheelScrollLines, FALSE);
|
|
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
|
|
break;
|
|
|
|
case IDC_EDIT_WHEEL_SCROLL_LINES:
|
|
if (pWheelData && HIWORD(wParam) == EN_CHANGE)
|
|
{
|
|
pWheelData->uWheelScrollLines = GetDlgItemInt(hwndDlg, IDC_EDIT_WHEEL_SCROLL_LINES, NULL, FALSE);
|
|
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
lppsn = (LPPSHNOTIFY)lParam;
|
|
if (lppsn->hdr.code == PSN_APPLY)
|
|
{
|
|
SystemParametersInfo(SPI_SETWHEELSCROLLLINES, pWheelData->uWheelScrollLines,
|
|
0, SPIF_SENDCHANGE | SPIF_UPDATEINIFILE);
|
|
return TRUE;
|
|
}
|
|
break;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static int CALLBACK
|
|
PropSheetProc(HWND hwndDlg, UINT uMsg, LPARAM lParam)
|
|
{
|
|
// NOTE: This callback is needed to set large icon correctly.
|
|
HICON hIcon;
|
|
switch (uMsg)
|
|
{
|
|
case PSCB_INITIALIZED:
|
|
{
|
|
hIcon = LoadIconW(hApplet, MAKEINTRESOURCEW(IDC_CPLICON_1));
|
|
SendMessageW(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
|
|
break;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static const struct
|
|
{
|
|
WORD idDlg;
|
|
DLGPROC DlgProc;
|
|
UINT uiReplaceWith;
|
|
} PropPages[] =
|
|
{
|
|
{ IDD_PAGE_BUTTON, ButtonProc, CPLPAGE_MOUSE_BUTTONS },
|
|
{ IDD_PAGE_POINTER, PointerProc, 0 },
|
|
{ IDD_PAGE_OPTION, OptionProc, CPLPAGE_MOUSE_PTRMOTION },
|
|
{ IDD_PAGE_WHEEL, WheelProc, CPLPAGE_MOUSE_WHEEL },
|
|
{ IDD_HARDWARE, MouseHardwareProc, 0 },
|
|
};
|
|
|
|
LONG APIENTRY
|
|
MouseApplet(HWND hwnd, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
|
|
{
|
|
HPROPSHEETPAGE hpsp[MAX_CPL_PAGES];
|
|
PROPSHEETHEADER psh;
|
|
HPSXA hpsxa;
|
|
TCHAR Caption[256];
|
|
UINT i;
|
|
INT nPage = 0;
|
|
LONG ret;
|
|
|
|
UNREFERENCED_PARAMETER(lParam1);
|
|
UNREFERENCED_PARAMETER(lParam2);
|
|
UNREFERENCED_PARAMETER(uMsg);
|
|
UNREFERENCED_PARAMETER(hwnd);
|
|
|
|
if (uMsg == CPL_STARTWPARMSW && lParam2 != 0)
|
|
nPage = _wtoi((PWSTR)lParam2);
|
|
|
|
LoadString(hApplet, IDS_CPLNAME_1, Caption, sizeof(Caption) / sizeof(TCHAR));
|
|
|
|
ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
|
|
psh.dwSize = sizeof(PROPSHEETHEADER);
|
|
psh.dwFlags = PSH_PROPTITLE | PSH_USEICONID | PSH_USECALLBACK;
|
|
psh.hwndParent = hwnd;
|
|
psh.hInstance = hApplet;
|
|
psh.pszIcon = MAKEINTRESOURCEW(IDC_CPLICON_1);
|
|
psh.pszCaption = Caption;
|
|
psh.nStartPage = 0;
|
|
psh.phpage = hpsp;
|
|
psh.pfnCallback = PropSheetProc;
|
|
|
|
/* Load additional pages provided by shell extensions */
|
|
hpsxa = SHCreatePropSheetExtArray(HKEY_LOCAL_MACHINE, REGSTR_PATH_CONTROLSFOLDER TEXT("\\Mouse"), MAX_CPL_PAGES - psh.nPages);
|
|
|
|
for (i = 0; i != sizeof(PropPages) / sizeof(PropPages[0]); i++)
|
|
{
|
|
/* Override the background page if requested by a shell extension */
|
|
if (PropPages[i].uiReplaceWith != 0 && hpsxa != NULL &&
|
|
SHReplaceFromPropSheetExtArray(hpsxa, PropPages[i].uiReplaceWith, PropSheetAddPage, (LPARAM)&psh) != 0)
|
|
{
|
|
/* The shell extension added one or more pages to replace a page.
|
|
Don't create the built-in page anymore! */
|
|
continue;
|
|
}
|
|
|
|
InitPropSheetPage(&psh, PropPages[i].idDlg, PropPages[i].DlgProc);
|
|
}
|
|
|
|
if (hpsxa != NULL)
|
|
SHAddFromPropSheetExtArray(hpsxa, PropSheetAddPage, (LPARAM)&psh);
|
|
|
|
if (nPage != 0 && nPage <= psh.nPages)
|
|
psh.nStartPage = nPage;
|
|
|
|
ret = (LONG)(PropertySheet(&psh) != -1);
|
|
|
|
if (hpsxa != NULL)
|
|
SHDestroyPropSheetExtArray(hpsxa);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/* EOF */
|