|
|
/*++
Copyright (c) 1994-1998, Microsoft Corporation All rights reserved.
Module Name:
mouseptr.c
Abstract:
This module contains the routines for the Mouse Pointer Property Sheet page.
Revision History:
--*/
//
// Include Files.
//
#include "main.h"
#include "rc.h"
#include "mousehlp.h"
#include <regstr.h>
//
// From shell\inc\shsemip.h
//
#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
//
// Constant Declarations.
//
#define gcxAvgChar 8
#define MAX_SCHEME_NAME_LEN 64
#define MAX_SCHEME_SUFFIX 32 // length of " (system scheme)" - update if more space is needed
#define OVERWRITE_TITLE 32 // length of title for the confirm overwrite dialog
#define OVERWRITE_MSG 200 // length of the message for the overwrite dialog
#define PM_NEWCURSOR (WM_USER + 1)
#define PM_PAUSEANIMATION (WM_USER + 2)
#define PM_UNPAUSEANIMATION (WM_USER + 3)
#define ID_PREVIEWTIMER 1
#define CCH_ANISTRING 80
#define CIF_FILE 0x0001
#define CIF_MODIFIED 0x0002
#define CIF_SHARED 0x0004
#define IDT_BROWSE 1
//
// Typedef Declarations.
//
typedef struct _CURSOR_INFO { DWORD fl; HCURSOR hcur; int ccur; int icur; TCHAR szFile[MAX_PATH]; } CURSOR_INFO, *PCURSOR_INFO;
#pragma pack(2)
typedef struct tagNEWHEADER { WORD reserved; WORD rt; WORD cResources; } NEWHEADER, *LPNEWHEADER; #pragma pack()
typedef struct { UINT idVisName; int idResource; int idDefResource; LPTSTR pszIniName; TCHAR szVisName[MAX_PATH]; } CURSORDESC, *PCURSORDESC;
//
// Structure that contains data used within a preview window. This
// data is unique for each preview window, and is used to optimize
// the painting.
//
typedef struct { HDC hdcMem; HBITMAP hbmMem; HBITMAP hbmOld; PCURSOR_INFO pcuri; } PREVIEWDATA, *PPREVIEWDATA;
typedef struct _MOUSEPTRBR { HWND hDlg; CURSOR_INFO curi; } MOUSEPTRBR, *PMOUSEPTRBR;
//
// Global Variables.
//
extern HINSTANCE g_hInst; // from main.c
int gcxCursor, gcyCursor; HWND ghwndDlg, ghwndFile, ghwndFileH, ghwndTitle, ghwndTitleH; HWND ghwndCreator, ghwndCreatorH, ghwndCursors, ghwndPreview, ghwndSchemeCB; HBRUSH ghbrHighlight, ghbrHighlightText, ghbrWindow, ghbrButton;
UINT guTextHeight = 0; UINT guTextGap = 0;
COLORREF gcrHighlightText;
TCHAR gszFileName2[MAX_PATH];
UINT wBrowseHelpMessage;
LPTSTR gszFileNotFound = NULL; LPTSTR gszBrowse = NULL; LPTSTR gszFilter = NULL;
TCHAR gszNoMem[256] = TEXT("No Memory");
HHOOK ghhkMsgFilter; // hook handle for message filter function
static const TCHAR szRegStr_Setup[] = REGSTR_PATH_SETUP TEXT("\\Setup"); static const TCHAR szSharedDir[] = TEXT("SharedDir");
BOOL gfCursorShadow = FALSE;
//
// Make sure you add new cursors to the end of this array.
// Otherwise the cursor schemes will not work
//
CURSORDESC gacd[] = { { IDS_ARROW, OCR_NORMAL, OCR_ARROW_DEFAULT, TEXT("Arrow"), TEXT("") }, { IDS_HELPCUR, OCR_HELP, OCR_HELP_DEFAULT, TEXT("Help"), TEXT("") }, { IDS_APPSTARTING, OCR_APPSTARTING, OCR_APPSTARTING_DEFAULT, TEXT("AppStarting"), TEXT("") }, { IDS_WAIT, OCR_WAIT, OCR_WAIT_DEFAULT, TEXT("Wait"), TEXT("") }, { IDS_CROSS, OCR_CROSS, OCR_CROSS_DEFAULT, TEXT("Crosshair"), TEXT("") }, { IDS_IBEAM, OCR_IBEAM, OCR_IBEAM_DEFAULT, TEXT("IBeam"), TEXT("") }, { IDS_NWPEN, OCR_NWPEN, OCR_NWPEN_DEFAULT, TEXT("NWPen"), TEXT("") }, { IDS_NO, OCR_NO, OCR_NO_DEFAULT, TEXT("No"), TEXT("") }, { IDS_SIZENS, OCR_SIZENS, OCR_SIZENS_DEFAULT, TEXT("SizeNS"), TEXT("") }, { IDS_SIZEWE, OCR_SIZEWE, OCR_SIZEWE_DEFAULT, TEXT("SizeWE"), TEXT("") }, { IDS_SIZENWSE, OCR_SIZENWSE, OCR_SIZENWSE_DEFAULT, TEXT("SizeNWSE"), TEXT("") }, { IDS_SIZENESW, OCR_SIZENESW, OCR_SIZENESW_DEFAULT, TEXT("SizeNESW"), TEXT("") }, { IDS_SIZEALL, OCR_SIZEALL, OCR_SIZEALL_DEFAULT, TEXT("SizeAll"), TEXT("") }, { IDS_UPARROW, OCR_UP, OCR_UPARROW_DEFAULT, TEXT("UpArrow"), TEXT("") }, { IDS_HANDCUR, OCR_HAND, OCR_HAND_DEFAULT, TEXT("Hand"), TEXT("") }, };
#define CCURSORS (sizeof(gacd) / sizeof(gacd[0]))
CURSOR_INFO acuri[CCURSORS];
//
// Registry Keys.
//
const TCHAR szCursorSubdir[] = TEXT("Cursors"); const TCHAR szCursorRegPath[] = REGSTR_PATH_CURSORS;
static const TCHAR c_szRegPathCursors[] = REGSTR_PATH_CURSORS; static const TCHAR c_szSchemes[] = TEXT("Schemes");
static const TCHAR c_szRegPathCursorSchemes[] = REGSTR_PATH_CURSORS TEXT( "\\Schemes" );
//
// Strings used to read from the combo box must be larger than max length.
//
TCHAR gszSchemeName[MAX_SCHEME_SUFFIX + MAX_SCHEME_NAME_LEN + 1]; // used to store selected scheme name for saving
int iSchemeLocation; // used to store scheme location (HKCU vs HKLM)
static const TCHAR c_szRegPathSystemSchemes[] = REGSTR_PATH_SETUP TEXT("\\Control Panel\\Cursors\\Schemes"); TCHAR szSystemScheme[MAX_SCHEME_SUFFIX]; TCHAR szNone[MAX_SCHEME_NAME_LEN + 1]; const TCHAR szSchemeSource[] = TEXT("Scheme Source");
TCHAR gszPreviousScheme[MAX_SCHEME_SUFFIX + MAX_SCHEME_NAME_LEN + 1]; // used to tell if a different scheme is selected
#define ID_NONE_SCHEME 0
#define ID_USER_SCHEME 1
#define ID_OS_SCHEME 2
//
// Context Help Ids.
//
const static DWORD aMousePtrHelpIDs[] = { IDC_GROUPBOX_1, IDH_COMM_GROUPBOX, ID_SCHEMECOMBO, IDH_MOUSE_POINT_SCHEME, ID_SAVESCHEME, IDH_MOUSE_POINT_SAVEAS, ID_REMOVESCHEME, IDH_MOUSE_POINT_DEL, ID_PREVIEW, IDH_MOUSE_POINT_PREVIEW, ID_CURSORLIST, IDH_MOUSE_POINT_LIST, ID_DEFAULT, IDH_MOUSE_POINT_DEFAULT, ID_BROWSE, IDH_MOUSE_POINT_BROWSE, ID_CURSORSHADOW, IDH_MOUSE_CURSORSHADOW,
0, 0 };
const static DWORD aMousePtrBrowseHelpIDs[] = { IDC_GROUPBOX_1, IDH_MOUSE_POINT_PREVIEW, ID_CURSORPREVIEW, IDH_MOUSE_POINT_PREVIEW,
0, 0 };
const static DWORD aHelpIDs[] = { ID_SCHEMEFILENAME, IDH_MOUSE_NEW_SCHEME_NAME,
0, 0 };
//
// Forward Declarations.
//
void LoadCursorSet(HWND hwnd);
void CreateBrushes(void);
LPTSTR GetResourceString(HINSTANCE hmod,int id);
void DrawCursorListItem(DRAWITEMSTRUCT *pdis);
BOOL GetCursorFromFile(CURSOR_INFO *pcuri);
BOOL Browse(HWND hwndOwner);
void CleanUpEverything(void);
VOID UpdateCursorList(void);
VOID NextFrame(HWND hwnd);
void HourGlass(BOOL fOn);
BOOL TryToLoadCursor( HWND hwnd, int i, CURSOR_INFO *pcuri);
BOOL LoadScheme(void);
BOOL SaveScheme(void);
BOOL SaveSchemeAs(void);
void SaveCurSchemeName(void);
BOOL RemoveScheme(void);
BOOL InitSchemeComboBox(void);
BOOL SchemeUpdate(int i);
LPTSTR MakeFilename(LPTSTR sz);
INT_PTR CALLBACK SaveSchemeDlgProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
void CurStripBlanks(LPTSTR pszString);
int SystemOrUser(TCHAR *pszSchemeName);
BOOL UnExpandPath( LPTSTR pszPath );
////////////////////////////////////////////////////////////////////////////
//
// RegisterPointerStuff
//
////////////////////////////////////////////////////////////////////////////
BOOL RegisterPointerStuff( HINSTANCE hi) { gcxCursor = GetSystemMetrics(SM_CXCURSOR); gcyCursor = GetSystemMetrics(SM_CYCURSOR);
return (TRUE); }
////////////////////////////////////////////////////////////////////////////
//
// InitCursorsShadow
//
////////////////////////////////////////////////////////////////////////////
void InitCursorShadow(HWND hwnd) { BOOL fPalette; HDC hdc; int nCommand;
hdc = GetDC(NULL); fPalette = (GetDeviceCaps(hdc, NUMCOLORS) != -1); ReleaseDC(NULL, hdc);
if (!fPalette) { nCommand = SW_SHOW; } else { nCommand = SW_HIDE; } ShowWindow(GetDlgItem(hwnd, ID_CURSORSHADOW), nCommand);
if (nCommand == SW_SHOW) { SystemParametersInfo(SPI_GETCURSORSHADOW, 0, (PVOID)&gfCursorShadow, 0); CheckDlgButton(hwnd, ID_CURSORSHADOW, gfCursorShadow); } }
////////////////////////////////////////////////////////////////////////////
//
// InitCursorsDlg
//
////////////////////////////////////////////////////////////////////////////
BOOL InitCursorsDlg( HWND hwnd) { int i;
ghwndDlg = hwnd; gszPreviousScheme[0] = TEXT('\0');
//
// Register the help message from the File Open (Browse) dialog.
//
wBrowseHelpMessage = RegisterWindowMessage(HELPMSGSTRING);
//
// Load Strings.
//
if (gszFileNotFound == NULL) { gszFileNotFound = GetResourceString(g_hInst, IDS_CUR_BADFILE);
if (gszFileNotFound == NULL) { return (FALSE); } }
if (gszBrowse == NULL) { gszBrowse = GetResourceString(g_hInst, IDS_CUR_BROWSE);
if (gszBrowse == NULL) { return (FALSE); } }
#ifdef WINNT
if (gszFilter == NULL) { gszFilter = GetResourceString(g_hInst, IDS_ANICUR_FILTER);
if (!gszFilter) { return (FALSE); } } #else
if (gszFilter == NULL) { HDC dc = GetDC(NULL); BOOL fAni = (GetDeviceCaps(dc, CAPS1) & C1_COLORCURSOR) != 0;
ReleaseDC(NULL, dc);
gszFilter = GetResourceString( g_hInst, fAni ? IDS_ANICUR_FILTER : IDS_CUR_FILTER );
if (!gszFilter) { return (FALSE); } } #endif
//
// Load description strings from the resource file.
//
for (i = 0; i < CCURSORS; i++) { if ((!gacd[i].idVisName) || (LoadString( g_hInst, gacd[i].idVisName, gacd[i].szVisName, ARRAYSIZE(gacd[i].szVisName) ) <= 0)) { //
// Show something.
//
lstrcpy(gacd[i].szVisName, gacd[i].pszIniName); } }
//
// As an optimization, remember the window handles of the cursor
// information fields.
//
ghwndPreview = GetDlgItem(hwnd, ID_PREVIEW); ghwndFile = GetDlgItem(hwnd, ID_FILE); ghwndFileH = GetDlgItem(hwnd, ID_FILEH); ghwndTitle = GetDlgItem(hwnd, ID_TITLE); ghwndTitleH = GetDlgItem(hwnd, ID_TITLEH); ghwndCreator = GetDlgItem(hwnd, ID_CREATOR); ghwndCreatorH = GetDlgItem(hwnd, ID_CREATORH); ghwndCursors = GetDlgItem(hwnd, ID_CURSORLIST); ghwndSchemeCB = GetDlgItem(hwnd, ID_SCHEMECOMBO);
//
// Create some brushes we'll be using.
//
CreateBrushes();
//
// Initialize the scheme combo box.
//
InitSchemeComboBox();
//
// Pre-clear the cursor info array.
//
ZeroMemory(&acuri, sizeof(acuri));
//
// Load the cursors.
//
LoadCursorSet(hwnd);
//
// Force an update of the preview window and the cursor details.
//
UpdateCursorList();
InitCursorShadow(hwnd);
return (TRUE); }
////////////////////////////////////////////////////////////////////////////
//
// LoadCursorSet
//
////////////////////////////////////////////////////////////////////////////
void LoadCursorSet( HWND hwnd) { CURSOR_INFO *pcuri; HKEY hkCursors; int i;
if (RegOpenKey( HKEY_CURRENT_USER, szCursorRegPath, &hkCursors ) != ERROR_SUCCESS) { hkCursors = NULL; }
for (pcuri = &acuri[0], i = 0; i < CCURSORS; i++, pcuri++) { if ( hkCursors ) { DWORD dwType; DWORD dwCount = sizeof(pcuri->szFile);
DWORD dwErr = RegQueryValueEx( hkCursors, gacd[i].pszIniName, NULL, &dwType, (LPBYTE)pcuri->szFile, &dwCount );
if (dwErr == ERROR_SUCCESS) { if (TryToLoadCursor(hwnd, i, pcuri)) { goto EverythingWorked; } } }
// This is actually the failure case. We load the default cursor.
pcuri->hcur = (HCURSOR)LoadImage( NULL, MAKEINTRESOURCE(gacd[i].idResource), IMAGE_CURSOR, 0, 0, LR_SHARED | LR_DEFAULTSIZE | LR_ENVSUBST );
pcuri->fl |= CIF_SHARED;
EverythingWorked:
SendMessage(ghwndCursors, LB_ADDSTRING, 0, (LPARAM)gacd[i].szVisName); SendMessage(ghwndCursors, LB_SETITEMDATA, i, i); }
if (hkCursors) { RegCloseKey(hkCursors); }
SendMessage(ghwndCursors, LB_SETCURSEL, 0, 0); }
////////////////////////////////////////////////////////////////////////////
//
// CreateBrushes
//
// Creates the brushes that are used to paint within the Cursors applet.
//
////////////////////////////////////////////////////////////////////////////
VOID CreateBrushes() { ghbrHighlight = GetSysColorBrush(COLOR_HIGHLIGHT); gcrHighlightText = GetSysColor(COLOR_HIGHLIGHTTEXT); ghbrHighlightText = GetSysColorBrush(COLOR_HIGHLIGHTTEXT); ghbrWindow = GetSysColorBrush(COLOR_WINDOW); ghbrButton = GetSysColorBrush(COLOR_BTNFACE); }
////////////////////////////////////////////////////////////////////////////
//
// GetResourceString
//
// Gets a string out of the resource file.
//
////////////////////////////////////////////////////////////////////////////
LPTSTR GetResourceString( HINSTANCE hmod, int id) { TCHAR szBuffer[256]; LPTSTR psz; int cch;
if ((cch = LoadString(hmod, id, szBuffer, ARRAYSIZE(szBuffer))) == 0) { return (NULL); }
psz = LocalAlloc(LPTR, (cch + 1) * sizeof(TCHAR));
if (psz != NULL) { int i;
for (i = 0; i <= cch; i++) { psz[i] = (szBuffer[i] == TEXT('\1')) ? TEXT('\0') : szBuffer[i]; } }
return (psz); }
////////////////////////////////////////////////////////////////////////////
//
// FreeItemCursor
//
////////////////////////////////////////////////////////////////////////////
void FreeItemCursor( CURSOR_INFO *pcuri) { if (pcuri->hcur) { if (!(pcuri->fl & CIF_SHARED)) { DestroyCursor(pcuri->hcur); } pcuri->hcur = NULL; } }
////////////////////////////////////////////////////////////////////////////
//
// MousePtrDlg
//
////////////////////////////////////////////////////////////////////////////
INT_PTR CALLBACK MousePtrDlg( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { CURSOR_INFO *pcuri; HKEY hkCursors; int i;
switch (msg) { case ( WM_INITDIALOG ) : { return InitCursorsDlg(hwnd); } case ( WM_DISPLAYCHANGE ) : { InitCursorShadow(hwnd); SHPropagateMessage(hwnd, msg, wParam, lParam, TRUE); break; } case ( WM_MEASUREITEM ) : { ((MEASUREITEMSTRUCT *)lParam)->itemHeight = gcyCursor + 2; break; } case ( WM_DRAWITEM ) : { DrawCursorListItem((DRAWITEMSTRUCT *)lParam); break; } case ( WM_COMMAND ) : { switch (LOWORD(wParam)) { case ( ID_SCHEMECOMBO ) : { switch (HIWORD(wParam)) { case ( CBN_SELCHANGE ) : { LoadScheme(); break; } } break; } case ( ID_DEFAULT ) : { //
// Throw away any fancy new cursor and replace it with
// the system's original.
//
i = (int)SendMessage(ghwndCursors, LB_GETCURSEL, 0, 0);
pcuri = &acuri[i];
if (!(pcuri->fl & CIF_FILE)) { break; } pcuri->fl = CIF_MODIFIED;
SendMessage(GetParent(hwnd), PSM_CHANGED, (WPARAM)hwnd, 0L);
FreeItemCursor(pcuri);
pcuri->hcur = (HCURSOR)LoadImage( NULL, MAKEINTRESOURCE(gacd[i].idDefResource), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_ENVSUBST );
*pcuri->szFile = TEXT('\0');
EnableWindow(GetDlgItem(hwnd, ID_SAVESCHEME), TRUE);
UpdateCursorList();
break; } case ( ID_CURSORLIST ) : { switch (HIWORD(wParam)) { case ( LBN_SELCHANGE ) : { i = (int)SendMessage((HWND)lParam, LB_GETCURSEL, 0, 0); pcuri = &acuri[i];
//
// Show a preview (including animation) in the
// preview window.
//
SendMessage( ghwndPreview, STM_SETICON, (WPARAM)pcuri->hcur, 0L );
//
// Enable the "Set Default" button if the cursor
// is from a file.
//
EnableWindow( GetDlgItem(hwnd, ID_DEFAULT), (pcuri->fl & CIF_FILE ) ? TRUE : FALSE ); break; } case ( LBN_DBLCLK ) : { Browse(hwnd); break; } } break; } case ( ID_BROWSE ) : { Browse(hwnd); break; } case ( ID_SAVESCHEME ) : { SaveSchemeAs(); break; } case ( ID_REMOVESCHEME ) : { RemoveScheme(); break; } case ( ID_CURSORSHADOW ) : { gfCursorShadow = IsDlgButtonChecked(hwnd, ID_CURSORSHADOW); SendMessage(GetParent(hwnd), PSM_CHANGED, (WPARAM)hwnd, 0L); break; } } break; } case ( WM_NOTIFY ) : { switch(((NMHDR *)lParam)->code) { case ( PSN_APPLY ) : { //
// Change cursor to hour glass.
//
HourGlass(TRUE);
// Set cursor shadow
SystemParametersInfo( SPI_SETCURSORSHADOW, 0, IntToPtr(gfCursorShadow), SPIF_UPDATEINIFILE);
//
// Save the modified scheme, order of calls important.
//
SaveCurSchemeName();
//
// Set the system cursors.
//
if (RegCreateKey( HKEY_CURRENT_USER, szCursorRegPath, &hkCursors ) == ERROR_SUCCESS) { for (pcuri = &acuri[0], i = 0; i < CCURSORS; i++, pcuri++) { if (pcuri->fl & CIF_MODIFIED) { LPCTSTR data; UINT count;
// Always unexpand before we save a filename
UnExpandPath(pcuri->szFile);
data = (pcuri->fl & CIF_FILE) ? pcuri->szFile : TEXT(""); count = (pcuri->fl & CIF_FILE) ? (lstrlen(pcuri->szFile) + 1) * sizeof(TCHAR) : sizeof(TCHAR);
RegSetValueEx( hkCursors, gacd[i].pszIniName, 0L, REG_EXPAND_SZ, (CONST LPBYTE)data, count ); } }
RegCloseKey(hkCursors);
SystemParametersInfo( SPI_SETCURSORS, 0, 0, SPIF_SENDCHANGE ); }
HourGlass(FALSE); break; } default : { return (FALSE); } } break; } case ( WM_SYSCOLORCHANGE ) : { gcrHighlightText = GetSysColor(COLOR_HIGHLIGHTTEXT); SHPropagateMessage(hwnd, msg, wParam, lParam, TRUE); break; }
case ( WM_WININICHANGE ) : { SHPropagateMessage(hwnd, msg, wParam, lParam, TRUE); break; }
case ( WM_DESTROY ) : { //
// Clean up global allocs.
//
CleanUpEverything();
if (gszFileNotFound != NULL) { LocalFree(gszFileNotFound); gszFileNotFound = NULL; }
if (gszBrowse != NULL) { LocalFree(gszBrowse); gszBrowse = NULL; }
if (gszFilter != NULL) { LocalFree(gszFilter); gszFilter = NULL; } break; } case ( WM_HELP ) : { WinHelp( ((LPHELPINFO)lParam)->hItemHandle, HELP_FILE, HELP_WM_HELP, (DWORD_PTR)(LPTSTR)aMousePtrHelpIDs ); break; } case ( WM_CONTEXTMENU ) : { WinHelp( (HWND)wParam, HELP_FILE, HELP_CONTEXTMENU, (DWORD_PTR)(LPVOID)aMousePtrHelpIDs ); break; } default : { return (FALSE); } }
return (TRUE); }
////////////////////////////////////////////////////////////////////////////
//
// DrawCursorListItem
//
////////////////////////////////////////////////////////////////////////////
void DrawCursorListItem( DRAWITEMSTRUCT *pdis) { CURSOR_INFO *pcuri; COLORREF clrOldText, clrOldBk; RECT rc; DWORD dwLayout;
if (!guTextHeight || !guTextGap) { TEXTMETRIC tm;
tm.tmHeight = 0; GetTextMetrics(pdis->hDC, &tm);
if (tm.tmHeight < 0) { tm.tmHeight *= -1; } guTextHeight = (UINT)tm.tmHeight; guTextGap = (UINT)tm.tmAveCharWidth; }
pcuri = &acuri[pdis->itemData];
if (pdis->itemState & ODS_SELECTED) { clrOldText = SetTextColor(pdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); clrOldBk = SetBkColor(pdis->hDC, GetSysColor(COLOR_HIGHLIGHT)); } else { clrOldText = SetTextColor(pdis->hDC, GetSysColor(COLOR_WINDOWTEXT)); clrOldBk = SetBkColor(pdis->hDC, GetSysColor(COLOR_WINDOW)); }
ExtTextOut( pdis->hDC, pdis->rcItem.left + guTextGap, // fudge factor
(pdis->rcItem.top + pdis->rcItem.bottom - guTextHeight) / 2, ETO_OPAQUE, &pdis->rcItem, gacd[pdis->itemData].szVisName, lstrlen(gacd[pdis->itemData].szVisName), NULL );
if (pcuri->hcur != NULL) { dwLayout = GetLayout(pdis->hDC); SetLayout(pdis->hDC, dwLayout | LAYOUT_BITMAPORIENTATIONPRESERVED); DrawIcon( pdis->hDC, pdis->rcItem.right - (gcxCursor + guTextGap), pdis->rcItem.top + 1, pcuri->hcur ); SetLayout(pdis->hDC, dwLayout); }
if (pdis->itemState & ODS_FOCUS) { CopyRect(&rc, &pdis->rcItem); InflateRect(&rc, -1, -1); DrawFocusRect(pdis->hDC, &rc); }
SetTextColor(pdis->hDC, clrOldText); SetBkColor(pdis->hDC, clrOldBk); }
////////////////////////////////////////////////////////////////////////////
//
// TryToLoadCursor
//
////////////////////////////////////////////////////////////////////////////
BOOL TryToLoadCursor( HWND hwnd, int i, CURSOR_INFO *pcuri) { BOOL fRet = TRUE; BOOL bCustom = (*pcuri->szFile != 0);
if (bCustom && !GetCursorFromFile(pcuri)) { HWND hwndControl = GetParent(hwnd); LPTSTR pszText; LPTSTR pszFilename;
//
// MakeFilename returns the address of a global, so we don't
// need to free pszFilename.
//
pszFilename = MakeFilename(pcuri->szFile);
pszText = LocalAlloc( LPTR, (lstrlen(gszFileNotFound) + lstrlen(gacd[i].szVisName) + lstrlen(pszFilename) + 1) * sizeof(TCHAR) );
if (pszText == NULL) { return (FALSE); }
wsprintf(pszText, gszFileNotFound, pszFilename, gacd[i].szVisName);
MessageBeep(MB_ICONEXCLAMATION);
MessageBox(hwndControl, pszText, NULL, MB_ICONEXCLAMATION | MB_OK);
pcuri->fl = CIF_MODIFIED;
SendMessage(GetParent(hwnd), PSM_CHANGED, (WPARAM)hwnd, 0L);
bCustom = FALSE;
LocalFree(pszText); }
if (!bCustom) { FreeItemCursor(pcuri);
pcuri->hcur = (HCURSOR)LoadImage( NULL, MAKEINTRESOURCE(gacd[i].idDefResource), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_ENVSUBST );
*pcuri->szFile = TEXT('\0');
EnableWindow(GetDlgItem(hwnd, ID_SAVESCHEME), TRUE); UpdateCursorList(); }
return (pcuri->hcur != NULL); }
////////////////////////////////////////////////////////////////////////////
//
// GetCursorFromFile
//
////////////////////////////////////////////////////////////////////////////
BOOL GetCursorFromFile( CURSOR_INFO *pcuri) { pcuri->fl = 0; pcuri->hcur = (HCURSOR)LoadImage( NULL, MakeFilename(pcuri->szFile), IMAGE_CURSOR, 0, 0, LR_LOADFROMFILE | LR_DEFAULTSIZE | LR_ENVSUBST );
if (pcuri->hcur) { pcuri->fl |= CIF_FILE; }
return (pcuri->hcur != NULL); }
////////////////////////////////////////////////////////////////////////////
//
// MousePtrBrowsePreview
//
////////////////////////////////////////////////////////////////////////////
void MousePtrBrowsePreview( HWND hDlg) { PMOUSEPTRBR pPtrBr; HCURSOR hcurOld;
pPtrBr = (PMOUSEPTRBR)GetWindowLongPtr(hDlg, DWLP_USER);
hcurOld = pPtrBr->curi.hcur;
CommDlg_OpenSave_GetFilePath( GetParent(hDlg), pPtrBr->curi.szFile, ARRAYSIZE(pPtrBr->curi.szFile) );
if (!GetCursorFromFile(&pPtrBr->curi)) { pPtrBr->curi.hcur = NULL; }
SendDlgItemMessage( hDlg, ID_CURSORPREVIEW, STM_SETICON, (WPARAM)pPtrBr->curi.hcur, 0L );
if (hcurOld) { DestroyCursor(hcurOld); } }
////////////////////////////////////////////////////////////////////////////
//
// MousePtrBrowseNotify
//
////////////////////////////////////////////////////////////////////////////
BOOL MousePtrBrowseNotify( HWND hDlg, LPOFNOTIFY pofn) { switch (pofn->hdr.code) { case ( CDN_SELCHANGE ) : { //
// Don't show the cursor until the user stops moving around.
//
if (SetTimer(hDlg, IDT_BROWSE, 250, NULL)) { //
// Don't destroy the old cursor.
//
SendDlgItemMessage( hDlg, ID_CURSORPREVIEW, STM_SETICON, 0, 0L ); } else { MousePtrBrowsePreview(hDlg); } break; } }
return (TRUE); }
////////////////////////////////////////////////////////////////////////////
//
// MousePtrBrowseDlgProc
//
////////////////////////////////////////////////////////////////////////////
INT_PTR CALLBACK MousePtrBrowseDlgProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case ( WM_INITDIALOG ) : { PMOUSEPTRBR pPtrBr = (PMOUSEPTRBR)((LPOPENFILENAME)lParam)->lCustData;
if (pPtrBr) { pPtrBr->hDlg = hDlg; }
SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR) pPtrBr); break; } case ( WM_DESTROY ) : { KillTimer(hDlg, IDT_BROWSE);
//
// Don't destroy the old cursor.
//
SendDlgItemMessage(hDlg, ID_CURSORPREVIEW, STM_SETICON, 0, 0L); break; } case ( WM_TIMER ) : { KillTimer(hDlg, IDT_BROWSE);
MousePtrBrowsePreview(hDlg); break; } case ( WM_NOTIFY ) : { return (MousePtrBrowseNotify(hDlg, (LPOFNOTIFY) lParam)); } case ( WM_HELP ) : { WinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle, HELP_FILE, HELP_WM_HELP, (DWORD_PTR)(LPTSTR)aMousePtrBrowseHelpIDs ); break; } case ( WM_CONTEXTMENU ) : { WinHelp( (HWND)wParam, HELP_FILE, HELP_CONTEXTMENU, (DWORD_PTR)(LPVOID)aMousePtrBrowseHelpIDs ); break; } default : { return (FALSE); } }
return (TRUE); }
////////////////////////////////////////////////////////////////////////////
//
// Browse
//
// Browse the file system for a new cursor for the selected item.
//
////////////////////////////////////////////////////////////////////////////
BOOL Browse(HWND hwndOwner) { static TCHAR szCustomFilter[80] = TEXT(""); static TCHAR szStartDir[MAX_PATH] = TEXT("");
OPENFILENAME ofn; CURSOR_INFO curi; int i; BOOL fRet = FALSE; MOUSEPTRBR sPtrBr;
if (!*szStartDir) { HKEY key = NULL;
if (RegOpenKey(HKEY_LOCAL_MACHINE, szRegStr_Setup, &key) == ERROR_SUCCESS) { LONG len = sizeof(szStartDir) / sizeof(szStartDir[0]);
if (RegQueryValueEx( key, szSharedDir, NULL, NULL, (LPBYTE)szStartDir, &len ) != ERROR_SUCCESS) { *szStartDir = TEXT('\0'); }
RegCloseKey(key); }
if (!*szStartDir) { if (0 == GetWindowsDirectory(szStartDir, MAX_PATH)) { goto Error; } }
PathAppend(szStartDir, szCursorSubdir); }
curi.szFile[0] = TEXT('\0');
sPtrBr.curi.szFile[0] = TEXT('\0'); sPtrBr.curi.hcur = NULL;
ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = hwndOwner; ofn.hInstance = g_hInst; ofn.lpstrFilter = gszFilter; ofn.lpstrCustomFilter = szCustomFilter; ofn.nMaxCustFilter = ARRAYSIZE(szCustomFilter); ofn.nFilterIndex = 1; ofn.lpstrFile = curi.szFile; ofn.nMaxFile = ARRAYSIZE(curi.szFile); ofn.lpstrFileTitle = NULL; ofn.nMaxFileTitle = 0; ofn.lpstrInitialDir = szStartDir; ofn.lpstrTitle = gszBrowse; ofn.Flags = OFN_EXPLORER | OFN_ENABLETEMPLATE | OFN_ENABLEHOOK | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; ofn.lpstrDefExt = NULL; ofn.lpfnHook = MousePtrBrowseDlgProc; ofn.lpTemplateName = MAKEINTRESOURCE(DLG_MOUSE_POINTER_BROWSE); ofn.lCustData = (LPARAM)(PMOUSEPTRBR)&sPtrBr;
fRet = GetOpenFileName(&ofn);
if (!fRet) { goto brErrExit; } // we got a valid value, save the current location
GetCurrentDirectory(ARRAYSIZE(szStartDir), szStartDir);
fRet = FALSE;
//
// We have probably already gotten this cursor.
//
if (lstrcmpi(curi.szFile, sPtrBr.curi.szFile) == 0) { if (!sPtrBr.curi.hcur) { goto brErrExit; }
curi = sPtrBr.curi;
//
// Clear this so it will not get destroyed in the cleanup code.
//
sPtrBr.curi.hcur = NULL; } else { //
// The user must have typed in a name.
//
if (!GetCursorFromFile(&curi)) { goto brErrExit; } }
//
// Convert mapped drive letters to UNC.
//
#ifdef UNICODE
if (curi.szFile[1] == TEXT(':')) #else
if (!IsDBCSLeadByte(curi.szFile[0]) && (curi.szFile[1] == TEXT(':'))) #endif
{ TCHAR szDrive[3]; TCHAR szNet[MAX_PATH]; int lenNet = ARRAYSIZE(szNet);
lstrcpyn(szDrive, curi.szFile, ARRAYSIZE(szDrive));
if ((WNetGetConnection(szDrive, szNet, &lenNet) == NO_ERROR) && (szNet[0] == TEXT('\\')) && (szNet[1] == TEXT('\\'))) { lstrcat(szNet, curi.szFile + 2); lstrcpy(curi.szFile, szNet); } }
i = (int)SendMessage(ghwndCursors, LB_GETCURSEL, 0, 0);
curi.fl |= CIF_MODIFIED;
SendMessage(GetParent(ghwndDlg), PSM_CHANGED, (WPARAM)ghwndDlg, 0L);
EnableWindow(GetDlgItem(ghwndDlg, ID_SAVESCHEME), TRUE);
//
// Destroy the old cursor before we retain the new one.
//
FreeItemCursor(acuri + i);
acuri[i] = curi;
UpdateCursorList();
fRet = TRUE;
brErrExit: if (sPtrBr.curi.hcur) { DestroyCursor(sPtrBr.curi.hcur); }
Error: return (fRet); }
////////////////////////////////////////////////////////////////////////////
//
// CleanUpEverything
//
// Destroy all the outstanding cursors.
//
////////////////////////////////////////////////////////////////////////////
void CleanUpEverything() { CURSOR_INFO *pcuri; int i;
for (pcuri = &acuri[0], i = 0; i < CCURSORS; i++, pcuri++) { FreeItemCursor(pcuri); } }
////////////////////////////////////////////////////////////////////////////
//
// UpdateCursorList
//
// Force the Cursor ListBox to repaint and the cursor information below the
// listbox to be refreshed as well.
//
////////////////////////////////////////////////////////////////////////////
VOID UpdateCursorList() { int i = (int)SendMessage(ghwndCursors, LB_GETCURSEL, 0, 0); PCURSOR_INFO pcuri = ((i >= 0) ? &acuri[i] : NULL); HCURSOR hcur = pcuri ? pcuri->hcur : NULL; HWND hDefaultButton = GetDlgItem(ghwndDlg, ID_DEFAULT); BOOL fEnableDefaultButton = (pcuri && (pcuri->fl & CIF_FILE));
InvalidateRect(ghwndCursors, NULL, FALSE);
SendMessage(ghwndPreview, STM_SETICON, (WPARAM)hcur, 0L);
if (!fEnableDefaultButton && (GetFocus() == hDefaultButton)) { SendMessage(ghwndDlg, WM_NEXTDLGCTL, (WPARAM)ghwndCursors, TRUE); }
EnableWindow(hDefaultButton, fEnableDefaultButton); }
////////////////////////////////////////////////////////////////////////////
//
// SaveSchemeAs
//
////////////////////////////////////////////////////////////////////////////
BOOL SaveSchemeAs() { BOOL fSuccess = TRUE;
//
// Dialog proc returns TRUE & sets gszSchemeName to filename entered
// on OK.
//
if (DialogBox( g_hInst, MAKEINTRESOURCE(DLG_MOUSE_POINTER_SCHEMESAVE), ghwndDlg, SaveSchemeDlgProc )) { fSuccess = SaveScheme();
if (fSuccess) { int index = (int)SendMessage( ghwndSchemeCB, CB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)gszSchemeName ); //
// If not found, add it.
//
if (index < 0) { index = (int)SendMessage( ghwndSchemeCB, CB_ADDSTRING, 0, (LPARAM)gszSchemeName ); }
//
// Select the name.
//
SendMessage(ghwndSchemeCB, CB_SETCURSEL, (WPARAM) index, 0);
//
// Since this is now a user saved scheme, activate the delete
// button.
//
EnableWindow(GetDlgItem(ghwndDlg, ID_REMOVESCHEME), TRUE); } }
return (fSuccess); }
////////////////////////////////////////////////////////////////////////////
//
// SubstituteString
//
// Replaces the string pszRemove with the string pszReplace in the
// string pszInput and places the output in pszResult. Only looks
// at the begining of the input string.
//
////////////////////////////////////////////////////////////////////////////
BOOL SubstituteString(LPCTSTR pszInput, LPCTSTR pszRemove, LPCTSTR pszReplace, LPTSTR pszResult, UINT cchResult) { DWORD cchRemove = lstrlen(pszRemove);
if (CompareString(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, pszRemove, cchRemove, pszInput, cchRemove) == 2) { if (lstrlen(pszInput) + cchRemove < cchResult) { lstrcpy(pszResult, pszReplace); lstrcat(pszResult, pszInput + cchRemove); return TRUE; } } return FALSE; }
BOOL UnExpandPath( LPTSTR pszPath ) { static TCHAR szUserProfile[MAX_PATH]; static TCHAR szSystemRoot[MAX_PATH]; static TCHAR szProgramFiles[MAX_PATH]; static BOOL bInit = FALSE; TCHAR szUnexpandedFilename[MAX_PATH];
if ( !bInit ) { ExpandEnvironmentStrings( TEXT("%USERPROFILE%"), szUserProfile, ARRAYSIZE(szUserProfile) ); ExpandEnvironmentStrings( TEXT("%SYSTEMROOT%"), szSystemRoot, ARRAYSIZE(szSystemRoot) ); ExpandEnvironmentStrings( TEXT("%ProgramFiles%"), szProgramFiles, ARRAYSIZE(szProgramFiles) ); bInit = TRUE; }
if (!SubstituteString(pszPath, szUserProfile, TEXT("%USERPROFILE%"), szUnexpandedFilename, ARRAYSIZE(szUnexpandedFilename))) { if (!SubstituteString(pszPath, szSystemRoot, TEXT("%SYSTEMROOT%"), szUnexpandedFilename, ARRAYSIZE(szUnexpandedFilename))) { if (!SubstituteString(pszPath, szProgramFiles, TEXT("%ProgramFiles%"), szUnexpandedFilename, ARRAYSIZE(szUnexpandedFilename))) { return FALSE; } } } lstrcpy(pszPath, szUnexpandedFilename); return TRUE; }
////////////////////////////////////////////////////////////////////////////
//
// SaveScheme
//
////////////////////////////////////////////////////////////////////////////
BOOL SaveScheme() { BOOL fSuccess = FALSE;
if (*gszSchemeName) { const BUFFER_SIZE = CCURSORS * (MAX_PATH + 1) + 1; LPTSTR pszBuffer = (LPTSTR)LocalAlloc( LMEM_FIXED, BUFFER_SIZE * sizeof(TCHAR) );
HKEY hk; int i;
if (!pszBuffer) { return (FALSE); }
pszBuffer[0] = TEXT('\0');
for (i = 0; i < CCURSORS; i++) { if (i) { lstrcat(pszBuffer, TEXT(",")); }
// Replace path with evnironment variables.
UnExpandPath(acuri[i].szFile);
lstrcat(pszBuffer, acuri[i].szFile); }
if (RegCreateKey( HKEY_CURRENT_USER, c_szRegPathCursors, &hk ) == ERROR_SUCCESS) { HKEY hks;
if (RegCreateKey(hk, c_szSchemes, &hks) == ERROR_SUCCESS) { LPTSTR pszOldValue = (LPTSTR)LocalAlloc( LMEM_FIXED, BUFFER_SIZE * sizeof(TCHAR) ); if (NULL != pszOldValue) { DWORD dwType; DWORD dwSize = BUFFER_SIZE*sizeof(TCHAR); BOOL bSave = FALSE;
int ret = RegQueryValueEx(hks, gszSchemeName, NULL, &dwType, (LPBYTE)pszOldValue, &dwSize);
//
// If the key already exists, ask to confirm the overwrite.
//
if (ret == ERROR_SUCCESS && (dwType==REG_SZ || dwType==REG_EXPAND_SZ)) { // only need to save if value is different from old value
if (lstrcmp(pszOldValue,pszBuffer)!=0) { TCHAR szTitle[OVERWRITE_TITLE]; TCHAR szMsg[OVERWRITE_MSG]; LoadString(g_hInst, IDS_OVERWRITE_TITLE, szTitle, OVERWRITE_TITLE); LoadString(g_hInst, IDS_OVERWRITE_MSG, szMsg, OVERWRITE_MSG);
if (MessageBox( ghwndDlg, szMsg, szTitle, MB_ICONQUESTION | MB_YESNO ) == IDYES) { //
// Overwrite confirmed. Safe to save.
//
bSave = TRUE; } } else { // no need to save since the new value is the same as the old value.
fSuccess = TRUE; } } else { //
// The key doesn't exist, so it's safe to create it.
//
bSave = TRUE; }
if (bSave) { if (RegSetValueEx( hks, gszSchemeName, 0, REG_EXPAND_SZ, (LPBYTE)pszBuffer, (lstrlen(pszBuffer) + 1) * sizeof(TCHAR) ) == ERROR_SUCCESS) { fSuccess = TRUE; } }
LocalFree( pszOldValue ); }
RegCloseKey(hks); }
RegCloseKey(hk); }
LocalFree(pszBuffer); }
return (fSuccess); }
////////////////////////////////////////////////////////////////////////////
//
// SaveCurSchemeName
//
////////////////////////////////////////////////////////////////////////////
void SaveCurSchemeName() { HKEY hk;
if (RegCreateKey( HKEY_CURRENT_USER, c_szRegPathCursors, &hk ) == ERROR_SUCCESS) { int index = (int)SendMessage(ghwndSchemeCB, CB_GETCURSEL, 0, 0L);
SendMessage( ghwndSchemeCB, CB_GETLBTEXT, (WPARAM)index, (LPARAM)gszSchemeName ); //
// Exclude the "none" pattern.
//
if (lstrcmpi(gszSchemeName, szNone) == 0) { *gszSchemeName = 0; iSchemeLocation = ID_NONE_SCHEME; } else { iSchemeLocation = SystemOrUser(gszSchemeName); }
RegSetValue( hk, NULL, REG_SZ, gszSchemeName, (lstrlen(gszSchemeName) + 1) * sizeof(TCHAR) );
RegSetValueEx( hk, szSchemeSource, 0, REG_DWORD, (unsigned char *)&iSchemeLocation, sizeof(iSchemeLocation) );
RegCloseKey(hk);
if (iSchemeLocation == ID_USER_SCHEME) { SaveScheme(); } } }
////////////////////////////////////////////////////////////////////////////
//
// LoadScheme
//
// This is called whenever a selection is made from the schemes combo box.
//
////////////////////////////////////////////////////////////////////////////
BOOL LoadScheme() { const BUFFER_SIZE = CCURSORS * (MAX_PATH + 1) + 1; TCHAR pszSchemeName[MAX_SCHEME_SUFFIX + MAX_SCHEME_NAME_LEN + 1]; LPTSTR pszBuffer; BOOL fSuccess = FALSE; int index, ret; HKEY hk;
//
// Allocate buffer for cursor paths.
//
pszBuffer = (LPTSTR)LocalAlloc(LMEM_FIXED, BUFFER_SIZE * sizeof(TCHAR)); if (pszBuffer == NULL) { return (FALSE); }
HourGlass(TRUE);
*pszBuffer = *pszSchemeName = 0;
index = (int)SendMessage(ghwndSchemeCB, CB_GETCURSEL, 0, 0L);
//
// Get current scheme name.
//
SendMessage( ghwndSchemeCB, CB_GETLBTEXT, (WPARAM)index, (LPARAM)pszSchemeName );
// Get the text for the item at index, compare to the previous value to see
// if it changed. We can't simply compare the previous index because new items
// get inserted into the list so the index can change and still be the same or
// can be different when nothing has changed.
if ( 0 == lstrcmp(gszPreviousScheme, pszSchemeName) ) { LocalFree(pszBuffer); // nothing to do, we're loading the already selected scheme
return FALSE; }
// We're loading a different scheme, enable the apply button.
SendMessage(GetParent(ghwndDlg), PSM_CHANGED, (WPARAM)ghwndDlg, 0L); lstrcpy(gszPreviousScheme, pszSchemeName);
//
// Exclude the "none" pattern.
//
if (lstrcmpi(pszSchemeName, szNone) != 0) { //
// If we have an os scheme, then search for the scheme in HKLM,
// otherwise look in HKCU.
//
if ((((ret = SystemOrUser(pszSchemeName)) == ID_OS_SCHEME) ? (RegOpenKey(HKEY_LOCAL_MACHINE, c_szRegPathSystemSchemes, &hk)) : (RegOpenKey(HKEY_CURRENT_USER, c_szRegPathCursorSchemes, &hk))) == ERROR_SUCCESS) { DWORD len = BUFFER_SIZE * sizeof(TCHAR);
if (RegQueryValueEx( hk, pszSchemeName, 0, NULL, (LPBYTE)pszBuffer, &len ) == ERROR_SUCCESS) { fSuccess = TRUE; // can be reset to FALSE below
}
RegCloseKey(hk); } } else { //
// "none" pattern is a valid choice.
//
ret = ID_NONE_SCHEME; fSuccess = TRUE; }
if (fSuccess) { LPTSTR pszNextFile, pszFile = pszBuffer; BOOL fEOL = FALSE; int i = 0;
//
// Remove an enclosing pair of double quotes from the list
// of cusor file names associated with the scheme.
//
// Why? On 3/29/00 someone changed the setup file accessor.inx
// placing double quotes around some of the cursor scheme reg values
// in HKLM. We'll fix the setup file but we should handle this
// case for all those who have already installed using that
// setup file.
//
if (TEXT('"') == *pszFile) { const LPTSTR pszLastChar = pszFile + lstrlen(pszFile) - 1; if (TEXT('"') == *pszLastChar && pszLastChar > pszFile) { //
// Increment passed first dbl quote and truncate
// string before the last.
//
pszFile++; *pszLastChar = TEXT('\0'); } }
//
// Parse string of format TEXT("filename1, filename2, filename3...")
// into cursor info array.
//
do { while (*pszFile && (*pszFile == TEXT(' ') || *pszFile == TEXT('\t') || *pszFile == TEXT('\n'))) { pszFile++; }
pszNextFile = pszFile;
while (*pszNextFile != TEXT('\0')) { if (*pszNextFile == TEXT(',')) { break; }
pszNextFile = CharNext(pszNextFile); }
if (*pszNextFile == TEXT('\0')) { fEOL = TRUE; } else { *pszNextFile = TEXT('\0'); }
if (lstrcmp(pszFile, acuri[i].szFile)) { //
// It's different than current, update.
//
lstrcpy(acuri[i].szFile, pszFile);
fSuccess &= SchemeUpdate(i); }
pszFile = pszNextFile;
if (!fEOL) { pszFile++; // skip TEXT('\0') and move to next path
}
i++;
} while (i < CCURSORS); }
LocalFree(pszBuffer);
UpdateCursorList();
EnableWindow(GetDlgItem(ghwndDlg, ID_REMOVESCHEME), (ret == ID_USER_SCHEME));
HourGlass(FALSE);
return (fSuccess); }
////////////////////////////////////////////////////////////////////////////
//
// SchemeUpdate
//
// Updates the cursor at index i in acuri.
//
////////////////////////////////////////////////////////////////////////////
BOOL SchemeUpdate(int i) { BOOL fSuccess = TRUE;
if (acuri[i].hcur) { FreeItemCursor(acuri + i); }
//
// If TEXT("Set Default").
//
if (*(acuri[i].szFile) == TEXT('\0')) { acuri[i].hcur = (HCURSOR)LoadImage( NULL, MAKEINTRESOURCE(gacd[i].idDefResource), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_ENVSUBST ); acuri[i].fl = 0; } else { fSuccess = TryToLoadCursor(ghwndDlg, i, &acuri[i]); }
acuri[i].fl |= CIF_MODIFIED;
return (fSuccess); }
////////////////////////////////////////////////////////////////////////////
//
// RemoveScheme
//
////////////////////////////////////////////////////////////////////////////
BOOL RemoveScheme() { //
// Only user schemes can be removed, so this only needs to
// be MAX_SCHEME_NAME_LEN + 1 long.
//
TCHAR szSchemeName[MAX_SCHEME_NAME_LEN + 1]; int index; HKEY hk;
index = (int)SendMessage(ghwndSchemeCB, CB_GETCURSEL, 0, 0L);
//
// Get current scheme name.
//
SendMessage( ghwndSchemeCB, CB_GETLBTEXT, (WPARAM)index, (LPARAM)szSchemeName );
//
// Exclude the "none" pattern from removal.
//
if (lstrcmpi(szSchemeName, szNone) == 0) { return (FALSE); }
//
// HACK: assume deleting noname needs no confirmation -
// this is because the scheme won't save properly anyway.
//
if (*szSchemeName) { TCHAR RemoveMsg[MAX_PATH]; TCHAR DialogMsg[MAX_PATH];
LoadString(g_hInst, IDS_REMOVESCHEME, RemoveMsg, MAX_PATH);
wsprintf(DialogMsg, RemoveMsg, (LPTSTR)szSchemeName);
LoadString(g_hInst, IDS_NAME, RemoveMsg, MAX_PATH);
if (MessageBox( ghwndDlg, DialogMsg, RemoveMsg, MB_ICONQUESTION | MB_YESNO ) != IDYES) { return (TRUE); } }
if (RegOpenKey( HKEY_CURRENT_USER, c_szRegPathCursors, &hk ) == ERROR_SUCCESS) { HKEY hks;
if (RegOpenKey(hk, c_szSchemes, &hks) == ERROR_SUCCESS) { RegDeleteValue(hks, szSchemeName); RegCloseKey(hks); }
RegCloseKey(hk); }
//
// Delete from list box.
//
index = (int)SendMessage( ghwndSchemeCB, CB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)szSchemeName );
SendMessage(ghwndSchemeCB, CB_DELETESTRING, (WPARAM)index, 0);
SendMessage(ghwndSchemeCB, CB_SETCURSEL, 0, 0); SendMessage(ghwndDlg, WM_NEXTDLGCTL, 1, 0L);
EnableWindow(GetDlgItem(ghwndDlg, ID_REMOVESCHEME), FALSE); return TRUE; }
////////////////////////////////////////////////////////////////////////////
//
// InitSchemeComboBox
//
////////////////////////////////////////////////////////////////////////////
BOOL InitSchemeComboBox() { TCHAR pszSchemeName[MAX_SCHEME_NAME_LEN + 1]; TCHAR pszDefaultSchemeName[MAX_SCHEME_NAME_LEN + 1]; TCHAR pszLongName[MAX_SCHEME_SUFFIX + MAX_SCHEME_NAME_LEN + 1]; int index; HKEY hk; DWORD len;
LoadString(g_hInst, IDS_NONE, szNone, ARRAYSIZE(szNone)); LoadString(g_hInst, IDS_SUFFIX, szSystemScheme, ARRAYSIZE(szSystemScheme));
if (RegOpenKey(HKEY_CURRENT_USER, c_szRegPathCursors, &hk) == ERROR_SUCCESS) { HKEY hks;
//
// Enumerate the schemes.
//
if (RegOpenKey(hk, c_szSchemes, &hks) == ERROR_SUCCESS) { DWORD i;
for (i = 0; ;i++) { LONG ret;
//
// Reset each pass.
//
len = ARRAYSIZE(pszSchemeName);
ret = RegEnumValue( hks, i, pszSchemeName, &len, NULL, NULL, NULL, NULL );
if (ret == ERROR_MORE_DATA) { continue; }
if (ret != ERROR_SUCCESS) { break; }
//
// HACK to keep "NONE" pure.
//
if (lstrcmpi(pszSchemeName, szNone) != 0) { SendMessage( ghwndSchemeCB, CB_ADDSTRING, 0, (LPARAM)pszSchemeName ); } }
//
// At this point, all of the user defined scheme names have been
// added to the combo box.
//
RegCloseKey(hks); }
//
// Get name of current one.
//
// Reset again.
//
len = sizeof(pszDefaultSchemeName);
RegQueryValue(hk, NULL, pszDefaultSchemeName, &len);
//
// Try to read the value of Scheme Source. If this value doesn't
// exist, then we have a pre NT 5.0 implementation, so all schemes
// will be user schemes.
//
len = sizeof(iSchemeLocation); if (RegQueryValueEx( hk, szSchemeSource, NULL, NULL, (unsigned char *)&iSchemeLocation, &len ) != ERROR_SUCCESS) { iSchemeLocation = ID_USER_SCHEME; }
RegCloseKey(hk); }
//
// Now add the system defined pointer schemes.
//
if (RegOpenKey(HKEY_LOCAL_MACHINE, c_szRegPathSystemSchemes, &hk) == ERROR_SUCCESS) { DWORD i;
for (i = 0; ;i++) { LONG ret;
//
// Reset each pass.
//
len = ARRAYSIZE(pszSchemeName);
ret = RegEnumValue( hk, i, pszSchemeName, &len, NULL, NULL, NULL, NULL );
//
// If the Scheme name is longer than the allowed length, skip it.
//
if (ret == ERROR_MORE_DATA) { continue; }
//
// If there's an error, then we're done.
//
if (ret != ERROR_SUCCESS) { break; }
//
// When we add the system identifier to the string, it could be
// longer than MAX_SCHEME_NAME, however we only want to read
// max length from the registry.
//
lstrcpy(pszLongName, pszSchemeName); lstrcat(pszLongName, szSystemScheme); SendMessage(ghwndSchemeCB, CB_ADDSTRING, 0, (LPARAM)pszLongName); }
RegCloseKey(hk); }
//
// Add the "none" scheme.
//
SendMessage(ghwndSchemeCB, CB_INSERTSTRING, 0, (LPARAM)szNone);
//
// Try to find current one in the combobox.
//
lstrcpy(pszLongName, pszDefaultSchemeName); if (iSchemeLocation == ID_OS_SCHEME) { lstrcat(pszLongName, szSystemScheme); } index = (int)SendMessage( ghwndSchemeCB, CB_FINDSTRINGEXACT, 0xFFFF, (LPARAM)pszLongName );
//
// If found, select it.
//
if (index < 0) // if we are on the None scheme
{ iSchemeLocation = ID_NONE_SCHEME; index = 0; }
// We keep around a selection indicator so we know when selection has changed.
// Initialize that value here.
lstrcpy(gszPreviousScheme, pszLongName);
SendMessage(ghwndSchemeCB, CB_SETCURSEL, (WPARAM)index, 0);
EnableWindow( GetDlgItem(ghwndDlg, ID_REMOVESCHEME), (iSchemeLocation == ID_USER_SCHEME) );
return (TRUE); }
////////////////////////////////////////////////////////////////////////////
//
// SaveSchemeDlgProc
//
////////////////////////////////////////////////////////////////////////////
INT_PTR CALLBACK SaveSchemeDlgProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { TCHAR szSchemeName[MAX_SCHEME_SUFFIX + MAX_SCHEME_NAME_LEN + 1];
switch (message) { case ( WM_INITDIALOG ) : { HourGlass(TRUE);
GetWindowText(ghwndSchemeCB, szSchemeName, ARRAYSIZE(szSchemeName));
//
// CANNOT SAVE "NONE" SCHEME.
//
if (lstrcmpi(szSchemeName, szNone) == 0) { *szSchemeName = 0; }
iSchemeLocation = SystemOrUser(szSchemeName);
SetDlgItemText(hWnd, ID_SCHEMEFILENAME, szSchemeName);
SendDlgItemMessage(hWnd, ID_SCHEMEFILENAME, EM_SETSEL, 0, 32767);
SendDlgItemMessage( hWnd, ID_SCHEMEFILENAME, EM_LIMITTEXT, MAX_SCHEME_NAME_LEN, 0L );
EnableWindow(GetDlgItem(hWnd, IDOK), szSchemeName[0] != TEXT('\0'));
HourGlass(FALSE); return (TRUE); } case ( WM_HELP ) : { WinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle, HELP_FILE, HELP_WM_HELP, (DWORD_PTR)(LPTSTR)aHelpIDs ); return (TRUE); } case ( WM_CONTEXTMENU ) : { WinHelp( (HWND)wParam, HELP_FILE, HELP_CONTEXTMENU, (DWORD_PTR)(LPVOID)aHelpIDs ); return (TRUE); } case ( WM_COMMAND ) : { switch (LOWORD(wParam)) { case ( ID_SCHEMEFILENAME ) : { if (HIWORD(wParam) == EN_CHANGE) { //
// CANNOT SAVE "NONE" SCHEME
// cannot save a scheme ending with szSystemScheme
//
EnableWindow( GetDlgItem(hWnd, IDOK), ((GetDlgItemText( hWnd, ID_SCHEMEFILENAME, szSchemeName, ARRAYSIZE(szSchemeName) ) > 0) && (lstrcmpi(szSchemeName, szNone) != 0) && (SystemOrUser(szSchemeName) != ID_OS_SCHEME)) ); } break; } case ( IDOK ) : { GetDlgItemText( hWnd, ID_SCHEMEFILENAME, szSchemeName, MAX_SCHEME_NAME_LEN + 1 );
CurStripBlanks(szSchemeName);
if (*szSchemeName == TEXT('\0')) { MessageBeep(0); break; }
lstrcpy(gszSchemeName, szSchemeName);
// fall through...
} case ( IDCANCEL ) : { EndDialog(hWnd, LOWORD(wParam) == IDOK); return (TRUE); } } } }
//
// Didn't process a message.
//
return (FALSE); }
////////////////////////////////////////////////////////////////////////////
//
// MakeFilename
//
// Returns Filename with a default path in system directory if no path
// is already specified.
//
////////////////////////////////////////////////////////////////////////////
LPTSTR MakeFilename( LPTSTR sz) { TCHAR szTemp[MAX_PATH];
ExpandEnvironmentStrings(sz, szTemp, MAX_PATH);
if (szTemp[0] == TEXT('\\') || szTemp[1] == TEXT(':')) { lstrcpy(gszFileName2, szTemp);
return (gszFileName2); } else { GetSystemDirectory(gszFileName2, ARRAYSIZE(gszFileName2));
lstrcat(gszFileName2, TEXT("\\")); lstrcat(gszFileName2, szTemp);
return (gszFileName2); } }
////////////////////////////////////////////////////////////////////////////
//
// CurStripBlanks
//
// Strips leading and trailing blanks from a string.
// Alters the memory where the string sits.
//
////////////////////////////////////////////////////////////////////////////
void CurStripBlanks(LPTSTR pszString) { LPTSTR pszPosn;
//
// Strip leading blanks.
//
pszPosn = pszString;
while (*pszPosn == TEXT(' ')) { pszPosn++; }
if (pszPosn != pszString) { lstrcpy(pszString, pszPosn); }
//
// Strip trailing blanks.
//
if ((pszPosn = pszString + lstrlen(pszString)) != pszString) { pszPosn = CharPrev(pszString, pszPosn);
while (*pszPosn == TEXT(' ')) { pszPosn = CharPrev(pszString, pszPosn); }
pszPosn = CharNext(pszPosn);
*pszPosn = TEXT('\0'); } }
////////////////////////////////////////////////////////////////////////////
//
// SystemOrUser
//
// Attempts to determine if the scheme name selected from the combo
// box ends with the string szSystemScheme and retuns ID_OS_SCHEME
// if it does, ID_USER_SCHEME if it doesn't.
//
////////////////////////////////////////////////////////////////////////////
int SystemOrUser(TCHAR *pszSchemeName) { TCHAR *pszSN; int lenSS, lenSN; int i;
lenSS = lstrlen(szSystemScheme); lenSN = lstrlen(pszSchemeName);
if (lenSN <= lenSS) { return (ID_USER_SCHEME); }
pszSN = pszSchemeName + (lenSN - lenSS);
//
// If these strings are different, it's a user scheme.
//
if (lstrcmpi(pszSN, szSystemScheme)) { return (ID_USER_SCHEME); }
//
// For system schemes, this function also removes the
// szSystemScheme string from the end.
//
*pszSN = TEXT('\0');
return (ID_OS_SCHEME); }
|