mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1726 lines
51 KiB
1726 lines
51 KiB
/* SSDLG.C
|
|
**
|
|
** Copyright (C) Microsoft, 1999, All Rights Reserved.
|
|
**
|
|
** History:
|
|
** 18 Feb 94 (Tracy Sharpe) Added power management functionality.
|
|
** Commented out several pieces of code that weren't being
|
|
** used.
|
|
*/
|
|
#include <windows.h>
|
|
#include <commctrl.h>
|
|
#include <scrnsave.h>
|
|
#include "desk.h"
|
|
#include "deskid.h"
|
|
#include <shellapi.h>
|
|
#include "exe.h"
|
|
#include "deskid.h"
|
|
#include <regstr.h>
|
|
|
|
#define SFSE_SYSTEM 0
|
|
#define SFSE_PRG 1
|
|
#define SFSE_WINDOWS 2
|
|
#define SFSE_FILE 3
|
|
|
|
/* Local function prototypes... */
|
|
void NEAR PASCAL SearchForScrEntries ( UINT, LPCTSTR );
|
|
BOOL NEAR PASCAL FreeScrEntries ( void );
|
|
int NEAR PASCAL lstrncmp ( LPTSTR, LPTSTR, int );
|
|
LPTSTR NEAR PASCAL FileName ( LPTSTR szPath);
|
|
LPTSTR NEAR PASCAL StripPathName ( LPTSTR szPath);
|
|
LPTSTR NEAR PASCAL NiceName ( LPTSTR szPath);
|
|
|
|
void NEAR PASCAL AddBackslash(LPTSTR pszPath);
|
|
void NEAR PASCAL AppendPath(LPTSTR pszPath, LPTSTR pszSpec);
|
|
|
|
PTSTR NEAR PASCAL PerformCheck(LPTSTR, BOOL);
|
|
PTSTR NEAR PASCAL AllocStr(LPTSTR szCopy);
|
|
void NEAR PASCAL SaveIni(HWND hDlg);
|
|
void NEAR PASCAL DoScreenSaver(HWND hDlg, BOOL b);
|
|
|
|
void NEAR PASCAL ScreenSaver_AdjustTimeouts(HWND hWnd,int BaseControlID);
|
|
void NEAR PASCAL ScreenSaver_EnableDisableDelays(HWND hWnd,int BaseControlID);
|
|
void NEAR PASCAL EnableDisablePowerDelays(HWND hDlg);
|
|
void NEAR PASCAL EnableDisableSetPasswordBtn(HWND hDlg);
|
|
|
|
TCHAR szMethodName[] = TEXT("SCRNSAVE.EXE"); // Method entry
|
|
TCHAR szBuffer[BUFFER_SIZE]; // Shared buffer
|
|
TCHAR szSaverName[MAX_PATH]; // Screen Saver EXE
|
|
HICON hDefaultIcon;
|
|
HICON hIdleWildIcon;
|
|
BOOL bWasConfig=0; // We were configing the screen saver
|
|
HWND g_hwndTestButton;
|
|
HWND g_hwndLastFocus;
|
|
BOOL g_fPasswordWasPreviouslyEnabled = FALSE;
|
|
// Local global variables
|
|
|
|
HICON hIcons[MAX_METHODS];
|
|
UINT wNumMethods;
|
|
PTSTR aszMethods[MAX_METHODS];
|
|
PTSTR aszFiles[MAX_METHODS];
|
|
|
|
static const TCHAR c_szDemoParentClass[] = TEXT("SSDemoParent");
|
|
|
|
// static TCHAR szFileNameCopy[MAX_PATH];
|
|
static int g_iMethod;
|
|
static BOOL g_fPreviewActive;
|
|
static BOOL g_fAdapPwrMgnt = FALSE;
|
|
|
|
/*
|
|
* Registry value for the "Password Protected" check box
|
|
*
|
|
* These are different for NT and Win95 to keep screen
|
|
* savers built exclusivly for Win95 from trying to
|
|
* handle password checks. (NT does all password checking
|
|
* in the built in security system to maintain C2
|
|
* level security)
|
|
*/
|
|
|
|
#ifdef WINNT
|
|
# define SZ_USE_PASSWORD TEXT("ScreenSaverIsSecure")
|
|
# define PWRD_REG_TYPE REG_SZ
|
|
# define CCH_USE_PWRD_VALUE 2
|
|
# define CB_USE_PWRD_VALUE (CCH_USE_PWRD_VALUE * SIZEOF(TCHAR))
|
|
|
|
TCHAR gpwdRegYes[CCH_USE_PWRD_VALUE] = TEXT("1");
|
|
TCHAR gpwdRegNo[CCH_USE_PWRD_VALUE] = TEXT("0");
|
|
|
|
#define PasswdRegData(f) ((f) ? (PBYTE)gpwdRegYes : (PBYTE)gpwdRegNo)
|
|
|
|
#else
|
|
# define SZ_USE_PASSWORD REGSTR_VALUE_USESCRPASSWORD
|
|
# define PWRD_REG_TYPE REG_DWORD
|
|
# define CB_USE_PWRD_VALUE SIZEOF(DWORD)
|
|
|
|
DWORD gpwdRegYes = 1;
|
|
DWORD gpwdRegNo = 0;
|
|
|
|
#define PasswdRegData(f) ((f) ? (PBYTE)&gpwdRegYes : (PBYTE)&gpwdRegNo)
|
|
|
|
#endif
|
|
|
|
UDACCEL udAccel[] = {{0,1},{2,5},{4,30},{8,60}};
|
|
|
|
#include "..\..\..\inc\help.h"
|
|
|
|
const DWORD FAR aSaverHelpIds[] = {
|
|
IDC_NO_HELP_1, IDH_COMM_GROUPBOX,
|
|
IDC_CHOICES, IDH_DSKTPSCRSAVER_LISTBX,
|
|
IDC_SSDELAYLABEL, IDH_DSKTPSCRSAVER_WAIT,
|
|
IDC_SSDELAYSCALE, IDH_DSKTPSCRSAVER_WAIT,
|
|
IDC_SCREENSAVEDELAY, IDH_DSKTPSCRSAVER_WAIT,
|
|
IDC_SCREENSAVEARROW, IDH_DSKTPSCRSAVER_WAIT,
|
|
IDC_TEST, IDH_DSKTPSCRSAVER_TEST,
|
|
IDC_SETTING, IDH_DSKTPSCRSAVER_SETTINGS,
|
|
IDC_BIGICON, IDH_DSKTPSCRSAVER_MONITOR,
|
|
IDC_ENERGY_TEXT, IDH_COMM_GROUPBOX,
|
|
IDC_ENERGY_TEXT2, IDH_SCRSAVER_LOWPOWSTANDBY,
|
|
IDC_ENERGY_TEXT3, IDH_SCRSAVER_SHUTOFFPOW,
|
|
IDC_LOWPOWERSWITCH, IDH_SCRSAVER_LOWPOWSTANDBY,
|
|
IDC_LOWPOWERDELAY, IDH_SCRSAVER_LOWPOWSTANDBY,
|
|
IDC_LOWPOWERARROW, IDH_SCRSAVER_LOWPOWSTANDBY,
|
|
IDC_POWEROFFSWITCH, IDH_SCRSAVER_SHUTOFFPOW,
|
|
IDC_POWEROFFDELAY, IDH_SCRSAVER_SHUTOFFPOW,
|
|
IDC_POWEROFFARROW, IDH_SCRSAVER_SHUTOFFPOW,
|
|
IDC_ENERGYSTAR_BMP, IDH_SCRSAVER_GRAPHIC,
|
|
IDC_USEPASSWORD, IDH_COMM_PASSWDCHKBOX,
|
|
IDC_SETPASSWORD, IDH_COMM_PASSWDBUTT,
|
|
|
|
0, 0
|
|
};
|
|
|
|
//
|
|
// To simplify some things, the base control ID of a time control is associated
|
|
// with its corresponding SystemParametersInfo action codes.
|
|
//
|
|
|
|
typedef struct {
|
|
int taBaseControlID;
|
|
UINT taGetTimeoutAction;
|
|
UINT taSetTimeoutAction;
|
|
UINT taGetActiveAction;
|
|
UINT taSetActiveAction;
|
|
} TIMEOUT_ASSOCIATION;
|
|
|
|
//
|
|
// Except for the case of the "screen save" delay, each time grouping has three
|
|
// controls-- a switch to determine whether that time should be used or not and
|
|
// an edit box and an updown control to change the delay time. ("Screen save"
|
|
// is turned off my choosing (None) from the screen saver list) These three
|
|
// controls must be organized as follows:
|
|
//
|
|
|
|
#define BCI_DELAY 0
|
|
#define BCI_ARROW 1
|
|
#define BCI_SWITCH 2
|
|
|
|
//
|
|
// Associations between base control IDs and SystemParametersInfo action codes.
|
|
// The TA_* #defines are used as symbolic indexes into this array. Note that
|
|
// TA_SCREENSAVE is a special case-- it does NOT have a BCI_SWITCH.
|
|
//
|
|
|
|
#define TA_SCREENSAVE 0
|
|
#define TA_LOWPOWER 1
|
|
#define TA_POWEROFF 2
|
|
|
|
TIMEOUT_ASSOCIATION g_TimeoutAssociation[] = {
|
|
IDC_SCREENSAVEDELAY, SPI_GETSCREENSAVETIMEOUT, SPI_SETSCREENSAVETIMEOUT,
|
|
SPI_GETSCREENSAVEACTIVE, SPI_SETSCREENSAVEACTIVE,
|
|
IDC_LOWPOWERDELAY, SPI_GETLOWPOWERTIMEOUT, SPI_SETLOWPOWERTIMEOUT,
|
|
SPI_GETLOWPOWERACTIVE, SPI_SETLOWPOWERACTIVE,
|
|
IDC_POWEROFFDELAY, SPI_GETPOWEROFFTIMEOUT, SPI_SETPOWEROFFTIMEOUT,
|
|
SPI_GETPOWEROFFACTIVE, SPI_SETPOWEROFFACTIVE
|
|
};
|
|
|
|
int g_Timeout[] = {
|
|
0,
|
|
0,
|
|
0,
|
|
};
|
|
|
|
HBITMAP g_hbmDemo = NULL;
|
|
HBITMAP g_hbmEnergyStar = NULL;
|
|
BOOL g_bInitSS = TRUE; // assume we are in initialization process
|
|
BOOL g_bChangedSS = FALSE; // changes have been made
|
|
|
|
|
|
/*
|
|
* Win95 and NT store different values in different places of the registry to
|
|
* determine if the screen saver is secure or not.
|
|
*
|
|
* We can't really consolidate the two because the screen savers do different
|
|
* actions based on which key is set. Win95 screen savers do their own
|
|
* password checking, but NT must let the secure desktop winlogon code do it.
|
|
*
|
|
* Therefore to keep Win95 screen savers from requesting the password twice on
|
|
* NT, we use REGSTR_VALUE_USESCRPASSWORD == (REG_DWORD)1 on Win95 to indicate
|
|
* that a screen saver should check for the password, and
|
|
* "ScreenSaverIsSecure" == (REG_SZ)"1" on NT to indicate that WinLogon should
|
|
* check for a password.
|
|
*
|
|
* This function will deal with the differences.
|
|
*/
|
|
static BOOL IsPasswdSecure(HKEY hKey, LPTSTR szUsePW ) {
|
|
union {
|
|
DWORD dw;
|
|
TCHAR asz[4];
|
|
} uData;
|
|
|
|
DWORD dwSize, dwType;
|
|
BOOL fSecure = FALSE;
|
|
|
|
dwSize = SIZEOF(uData);
|
|
|
|
RegQueryValueEx(hKey,SZ_USE_PASSWORD,NULL, &dwType, (BYTE *)&uData, &dwSize);
|
|
|
|
switch( dwType ) {
|
|
case REG_DWORD:
|
|
fSecure = (uData.dw == 1);
|
|
break;
|
|
|
|
case REG_SZ:
|
|
fSecure = (uData.asz[0] == TEXT('1'));
|
|
break;
|
|
}
|
|
|
|
return fSecure;
|
|
}
|
|
|
|
|
|
static void NEAR
|
|
EnableDlgChild( HWND dlg, HWND kid, BOOL val )
|
|
{
|
|
if( !val && ( kid == GetFocus() ) )
|
|
{
|
|
// give prev tabstop focus
|
|
SendMessage( dlg, WM_NEXTDLGCTL, 1, 0L );
|
|
}
|
|
|
|
EnableWindow( kid, val );
|
|
}
|
|
|
|
static void NEAR
|
|
EnableDlgItem( HWND dlg, int idkid, BOOL val )
|
|
{
|
|
EnableDlgChild( dlg, GetDlgItem( dlg, idkid ), val );
|
|
}
|
|
|
|
HWND NEAR PASCAL GetSSDemoParent( HWND page )
|
|
{
|
|
static HWND parent = NULL;
|
|
|
|
if( !parent || !IsWindow( parent ) )
|
|
{
|
|
parent = CreateWindowEx( 0, c_szDemoParentClass,
|
|
g_szNULL, WS_CHILD | WS_CLIPCHILDREN, 0, 0, 0, 0,
|
|
GetDlgItem( page, IDC_BIGICON ), NULL, hInstance, NULL );
|
|
}
|
|
|
|
return parent;
|
|
}
|
|
|
|
void NEAR PASCAL ForwardSSDemoMsg(HWND hwnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
HWND hwndChild;
|
|
|
|
hwnd = GetSSDemoParent(hwnd);
|
|
|
|
for (hwndChild = GetWindow(hwnd, GW_CHILD); hwndChild != NULL;
|
|
hwndChild = GetWindow(hwndChild, GW_HWNDNEXT))
|
|
{
|
|
SendMessage(hwndChild, uMessage, wParam, lParam);
|
|
}
|
|
}
|
|
|
|
void NEAR PASCAL ParseSaverName( LPTSTR lpszName )
|
|
{
|
|
if( *lpszName == TEXT('\"') )
|
|
{
|
|
LPTSTR lpcSrc = lpszName + 1;
|
|
|
|
while( *lpcSrc && *lpcSrc != TEXT('\"') )
|
|
{
|
|
*lpszName++ = *lpcSrc++;
|
|
}
|
|
|
|
*lpszName = 0; // clear second quote
|
|
}
|
|
}
|
|
|
|
// YUCK:
|
|
// since our screen saver preview is in a different process,
|
|
// it is possible that we paint in the wrong order.
|
|
// this ugly hack makes sure the demo always paints AFTER the dialog
|
|
|
|
WNDPROC g_lpOldStaticProc = NULL;
|
|
|
|
LRESULT StaticSubclassProc(HWND wnd, UINT msg, WPARAM wp, LPARAM lp)
|
|
{
|
|
LRESULT result =
|
|
CallWindowProc(g_lpOldStaticProc, wnd, msg, wp, lp);
|
|
|
|
if (msg == WM_PAINT)
|
|
{
|
|
HWND demos = GetSSDemoParent(GetParent(wnd));
|
|
|
|
if (demos)
|
|
{
|
|
RedrawWindow(demos, NULL, NULL,
|
|
RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
BOOL NEAR PASCAL InitSSDialog(HWND hDlg)
|
|
{
|
|
WNDCLASS wc;
|
|
PTSTR pszMethod;
|
|
UINT wTemp,wLoop;
|
|
BOOL fContinue;
|
|
int Timeout;
|
|
int Active;
|
|
UINT Counter;
|
|
int ControlID;
|
|
int wMethod;
|
|
int ScreenSaveActive;
|
|
DWORD dwData=0,dwSize = sizeof(dwData);
|
|
HKEY hKey;
|
|
HWND hwnd;
|
|
|
|
if( !GetClassInfo( hInstance, c_szDemoParentClass, &wc ) )
|
|
{
|
|
// if two pages put one up, share one dc
|
|
wc.style = 0;
|
|
wc.lpfnWndProc = DefWindowProc;
|
|
wc.cbClsExtra = wc.cbWndExtra = 0;
|
|
wc.hInstance = hInstance;
|
|
wc.hIcon = (HICON)( wc.hCursor = NULL );
|
|
wc.hbrBackground = GetStockObject( BLACK_BRUSH );
|
|
wc.lpszMenuName = NULL;
|
|
wc.lpszClassName = c_szDemoParentClass;
|
|
|
|
if( !RegisterClass( &wc ) )
|
|
return FALSE;
|
|
}
|
|
|
|
// Fetch the timeout value from the win.ini and adjust between 1:00-60:00
|
|
for (Counter = 0; Counter < (sizeof(g_TimeoutAssociation) /
|
|
sizeof(TIMEOUT_ASSOCIATION)); Counter++) {
|
|
|
|
// Fetch the timeout value from the win.ini and adjust between 1:00-60:00
|
|
|
|
SystemParametersInfo(g_TimeoutAssociation[Counter].taGetTimeoutAction, 0,
|
|
&Timeout, 0);
|
|
|
|
/* The Win 3.1 guys decided that 0 is a valid ScreenSaveTimeOut value.
|
|
* This causes our screen savers not to kick in (who cares?). In any
|
|
* case, I changed this to allow 0 to go through. In this way, the
|
|
* user immediately sees that the value entered is not valid to fire
|
|
* off the screen saver--the OK button is disabled. I don't know if
|
|
* I fully agree with this solution--it is just the minimal amount of
|
|
* code. The optimal solution would be to ask the 3.1 guys why 0 is
|
|
* valid? -cjp
|
|
*/
|
|
Timeout = min(max(Timeout, 1), MAX_MINUTES * 60);
|
|
|
|
//
|
|
// Convert Timeout to minutes, rounding up.
|
|
//
|
|
|
|
Timeout = (Timeout + 59) / 60;
|
|
g_Timeout[Counter] = Timeout;
|
|
|
|
//
|
|
// The base control id specifies the edit control id.
|
|
//
|
|
|
|
ControlID = g_TimeoutAssociation[Counter].taBaseControlID;
|
|
|
|
/* Set the maximum length of all of the fields... */
|
|
SendDlgItemMessage(hDlg, ControlID, EM_LIMITTEXT, 2, 0);
|
|
|
|
SystemParametersInfo(g_TimeoutAssociation[Counter].taGetActiveAction,
|
|
0, &Active, SPIF_UPDATEINIFILE);
|
|
|
|
if (Counter != TA_SCREENSAVE) {
|
|
|
|
CheckDlgButton(hDlg, ControlID + BCI_SWITCH, Active);
|
|
}
|
|
else {
|
|
ScreenSaveActive = Active;
|
|
}
|
|
|
|
SetDlgItemInt(hDlg, ControlID, Timeout, FALSE);
|
|
|
|
//
|
|
// The associated up/down control id must be one after the edit control
|
|
// id.
|
|
//
|
|
|
|
ControlID++;
|
|
|
|
SendDlgItemMessage(hDlg, ControlID, UDM_SETRANGE, 0,
|
|
MAKELPARAM(MAX_MINUTES, MIN_MINUTES));
|
|
SendDlgItemMessage(hDlg, ControlID, UDM_SETACCEL, 4,
|
|
(LPARAM)(LPUDACCEL)udAccel);
|
|
|
|
}
|
|
|
|
// Find the name of the exe used as a screen saver. "" means that the
|
|
// default screen saver will be used
|
|
|
|
GetPrivateProfileString(g_szBoot, szMethodName, g_szNULL, szSaverName,
|
|
ARRAYSIZE(szSaverName), g_szSystemIni);
|
|
|
|
ParseSaverName( szSaverName ); // remove quotes and params
|
|
|
|
/* Copy all of the variables into their copies... */
|
|
// lstrcpy(szFileNameCopy, szSaverName);
|
|
|
|
/* Load in the default icon... */
|
|
hDefaultIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDS_ICON));
|
|
|
|
/* Find the methods to save the screen. If the method that was
|
|
selected is not found, the program will assume that the
|
|
first method in the list will be the one that is elected... */
|
|
wNumMethods = 0;
|
|
wMethod = -1;
|
|
|
|
SearchForScrEntries(SFSE_PRG,NULL);
|
|
SearchForScrEntries(SFSE_SYSTEM,NULL);
|
|
SearchForScrEntries(SFSE_WINDOWS,NULL);
|
|
SearchForScrEntries(SFSE_FILE,szSaverName);
|
|
|
|
/* Set up the combo box for the different fields... */
|
|
SendDlgItemMessage(hDlg, IDC_CHOICES, CB_ADDSTRING, 0, (LONG)g_szNone);
|
|
for (wTemp = 0; wTemp < wNumMethods; wTemp++)
|
|
{
|
|
/* Lock down the information and pass it to the combo box... */
|
|
pszMethod = aszMethods[wTemp];
|
|
wLoop = SendDlgItemMessage(hDlg,IDC_CHOICES,CB_ADDSTRING,0,
|
|
(LONG)(pszMethod+1));
|
|
SendDlgItemMessage(hDlg,IDC_CHOICES,CB_SETITEMDATA,wLoop,
|
|
(DWORD)wTemp);
|
|
|
|
/* If we have the correct item, keep a copy so we can select it
|
|
out of the combo box... */
|
|
// check for filename only as well as full path name
|
|
|
|
if( !lstrcmpi( FileName( aszFiles[ wTemp ] ),
|
|
FileName( szSaverName ) ) )
|
|
{
|
|
wMethod = wTemp;
|
|
lstrcpy(szBuffer, pszMethod + 1);
|
|
}
|
|
}
|
|
|
|
if (!ScreenSaveActive)
|
|
wMethod = -1;
|
|
|
|
/* Attempt to select the string we recieved from the
|
|
system.ini entry. If there is no match, select the
|
|
first item from the list... */
|
|
if ((wMethod == -1) || (wNumMethods == 0))
|
|
{
|
|
fContinue = TRUE;
|
|
//
|
|
// fix pszMethod not being init'd when no .SCR
|
|
// files are found anywhere (this is a hack because
|
|
// I don't want to figure this garbage out)
|
|
// THIS ISN'T NEEDED! NO MORE FORWARD REFERENCES TO IT!
|
|
// pszMethod = g_szNULL;
|
|
}
|
|
else
|
|
{
|
|
if (SendDlgItemMessage(hDlg, IDC_CHOICES, CB_SELECTSTRING, (WPARAM)-1,
|
|
(LONG)szBuffer) == CB_ERR)
|
|
fContinue = TRUE;
|
|
else
|
|
fContinue = FALSE;
|
|
}
|
|
if(fContinue)
|
|
{
|
|
SendDlgItemMessage(hDlg,IDC_CHOICES,CB_SETCURSEL,0,0l);
|
|
lstrcpy(szSaverName,g_szNULL);
|
|
wMethod = -1;
|
|
}
|
|
|
|
g_hbmDemo = LoadMonitorBitmap( TRUE );
|
|
|
|
if (g_hbmDemo)
|
|
SendDlgItemMessage(hDlg,IDC_BIGICON,STM_SETIMAGE, IMAGE_BITMAP,(DWORD)g_hbmDemo);
|
|
|
|
#ifndef WINNT
|
|
g_fAdapPwrMgnt = QueryAdapterPwrMgnt();
|
|
#else
|
|
//BUGBUG - put this back in once we get the power management stuff worked out
|
|
// 07-Apr-1995 JonPa
|
|
//#pragma message( __FILE__"(443): warning !!!! : remove this #ifdef when user implements api" )
|
|
g_fAdapPwrMgnt = FALSE;
|
|
#endif
|
|
|
|
g_hbmEnergyStar = LoadImage( hInstance, MAKEINTRESOURCE( IDB_ENERGYSTAR ),
|
|
IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS );
|
|
|
|
if( g_hbmEnergyStar )
|
|
{
|
|
SendDlgItemMessage( hDlg, IDC_ENERGYSTAR_BMP, STM_SETIMAGE,
|
|
IMAGE_BITMAP, (LPARAM)g_hbmEnergyStar );
|
|
}
|
|
|
|
// Hide/Disable the energy related controls if the adaptor/monitor does not
|
|
// support power mgnt.
|
|
EnableDisablePowerDelays(hDlg);
|
|
|
|
// initialize the password checkbox
|
|
if (RegOpenKey(HKEY_CURRENT_USER,REGSTR_PATH_SCREENSAVE,&hKey) == ERROR_SUCCESS) {
|
|
if (IsPasswdSecure(hKey, SZ_USE_PASSWORD ))
|
|
g_fPasswordWasPreviouslyEnabled = TRUE;
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
// subclass the static control so we can synchronize painting
|
|
hwnd = GetDlgItem(hDlg, IDC_BIGICON);
|
|
if (hwnd)
|
|
{
|
|
g_lpOldStaticProc = (WNDPROC)GetWindowLong(hwnd, GWL_WNDPROC);
|
|
SetWindowLong(hwnd, GWL_WNDPROC, (LONG)(WNDPROC)StaticSubclassProc);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void NEAR PASCAL SetNewSSDemo(HWND hDlg, int iMethod)
|
|
{
|
|
HBITMAP hbmOld;
|
|
POINT ptIcon;
|
|
HWND hwndDemo;
|
|
HWND hwndC;
|
|
HICON hicon;
|
|
|
|
RECT rc = {MON_X, MON_Y, MON_X+MON_DX, MON_Y+MON_DY};
|
|
|
|
hwndDemo = GetSSDemoParent( hDlg );
|
|
|
|
// blank out the background with dialog color
|
|
hbmOld = SelectObject(g_hdcMem, g_hbmDemo);
|
|
FillRect(g_hdcMem, &rc, GetSysColorBrush(COLOR_DESKTOP));
|
|
SelectObject(g_hdcMem, hbmOld);
|
|
|
|
// kill the old one dammit kill it kill it kill kill kill
|
|
while( hwndC = GetWindow( hwndDemo, GW_CHILD ) )
|
|
SendMessage(hwndC, WM_CLOSE, 0, 0);
|
|
Yield(); // paranoid
|
|
Yield(); // really paranoid
|
|
ShowWindow(hwndDemo, SW_HIDE);
|
|
g_fPreviewActive = FALSE;
|
|
|
|
if (iMethod >= 0 && aszMethods[iMethod][0] == TEXT('P'))
|
|
{
|
|
RECT rc;
|
|
BITMAP bm;
|
|
UpdateWindow(hDlg);
|
|
//UpdateWindow(GetDlgItem(hDlg, IDC_BIGICON));
|
|
|
|
GetObject(g_hbmDemo, sizeof(bm), &bm);
|
|
GetClientRect(GetDlgItem(hDlg, IDC_BIGICON), &rc);
|
|
rc.left = ( rc.right - bm.bmWidth ) / 2 + MON_X;
|
|
rc.top = ( rc.bottom - bm.bmHeight ) / 2 + MON_Y;
|
|
MoveWindow(hwndDemo, rc.left, rc.top, MON_DX, MON_DY, FALSE);
|
|
wsprintf(szBuffer, TEXT("%s /p %d"), szSaverName, hwndDemo);
|
|
if (WinExecN(szBuffer, SW_NORMAL) > 32)
|
|
{
|
|
ShowWindow(hwndDemo, SW_SHOWNA);
|
|
g_fPreviewActive = TRUE;
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (iMethod != -1)
|
|
{
|
|
ptIcon.x = GetSystemMetrics(SM_CXICON);
|
|
ptIcon.y = GetSystemMetrics(SM_CYICON);
|
|
|
|
// draw the icon double size
|
|
Assert(ptIcon.y*2 <= MON_DY);
|
|
Assert(ptIcon.x*2 <= MON_DX);
|
|
|
|
hicon = hIcons[iMethod];
|
|
|
|
if (hicon == NULL && aszMethods[iMethod][0] == TEXT('I'))
|
|
hicon = hIdleWildIcon;
|
|
if (hicon == NULL)
|
|
hicon = hDefaultIcon;
|
|
|
|
hbmOld = SelectObject(g_hdcMem, g_hbmDemo);
|
|
DrawIconEx(g_hdcMem,
|
|
MON_X + (MON_DX-ptIcon.x*2)/2,
|
|
MON_Y + (MON_DY-ptIcon.y*2)/2,
|
|
hicon, ptIcon.x*2, ptIcon.y*2, 0, NULL, DI_NORMAL);
|
|
SelectObject(g_hdcMem, hbmOld);
|
|
}
|
|
|
|
InvalidateRect(GetDlgItem(hDlg, IDC_BIGICON), NULL, FALSE);
|
|
}
|
|
|
|
static void NEAR PASCAL SS_SomethingChanged(HWND hDlg)
|
|
{
|
|
if (!g_bInitSS)
|
|
{
|
|
SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0L);
|
|
}
|
|
}
|
|
|
|
static void NEAR PASCAL SetScreenSaverPassword(HWND hDlg, int iMethod)
|
|
{
|
|
if (iMethod >= 0 && aszMethods[iMethod][0] == TEXT('P'))
|
|
{
|
|
wsprintf(szBuffer, TEXT("%s /a %u"), szSaverName, GetParent(hDlg));
|
|
WinExecN(szBuffer, SW_NORMAL);
|
|
}
|
|
}
|
|
|
|
|
|
BOOL APIENTRY ScreenSaverDlgProc(HWND hDlg, UINT message , WPARAM wParam, LPARAM lParam)
|
|
{
|
|
NMHDR FAR *lpnm;
|
|
PTSTR pszMethod;
|
|
int wTemp;
|
|
int wMethod;
|
|
BOOL fEnable;
|
|
|
|
switch(message)
|
|
{
|
|
case WM_NOTIFY:
|
|
lpnm = (NMHDR FAR *)lParam;
|
|
switch(lpnm->code)
|
|
{
|
|
case PSN_APPLY:
|
|
/* Make sure the time we have is the last one entered... */
|
|
SendMessage(hDlg, WM_COMMAND, MAKELONG( IDC_SCREENSAVEDELAY, EN_KILLFOCUS),
|
|
(LPARAM)GetDlgItem(hDlg, IDC_SCREENSAVEDELAY));
|
|
|
|
/* Try to save the current settings... */
|
|
SaveIni(hDlg);
|
|
|
|
/////RETTRUE(hDlg)
|
|
break;
|
|
|
|
// nothing to do on cancel...
|
|
case PSN_RESET:
|
|
if (g_fPreviewActive)
|
|
SetNewSSDemo(hDlg, -1);
|
|
break;
|
|
|
|
case PSN_KILLACTIVE:
|
|
if (g_fPreviewActive)
|
|
SetNewSSDemo(hDlg, -1);
|
|
break;
|
|
|
|
case PSN_SETACTIVE:
|
|
EnableDisablePowerDelays(hDlg);
|
|
|
|
if (!g_fPreviewActive)
|
|
{
|
|
g_bInitSS = TRUE;
|
|
SendMessage(hDlg, WM_COMMAND, MAKELONG(IDC_CHOICES, CBN_SELCHANGE),
|
|
(LPARAM)GetDlgItem(hDlg, IDC_CHOICES));
|
|
g_bInitSS = FALSE;
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case WM_INITDIALOG:
|
|
g_bInitSS = TRUE;
|
|
InitSSDialog(hDlg);
|
|
g_bInitSS = FALSE;
|
|
break;
|
|
|
|
case WM_DISPLAYCHANGE:
|
|
case WM_SYSCOLORCHANGE: {
|
|
HBITMAP hbm;
|
|
|
|
hbm = g_hbmDemo;
|
|
|
|
g_hbmDemo = LoadMonitorBitmap( TRUE );
|
|
|
|
if (g_hbmDemo) {
|
|
// Got a new bitmap, use it and delete the old one.
|
|
SendDlgItemMessage(hDlg,IDC_BIGICON,STM_SETIMAGE, IMAGE_BITMAP,(DWORD)g_hbmDemo);
|
|
if (hbm) {
|
|
DeleteObject(hbm);
|
|
}
|
|
} else {
|
|
// Couldn't get a new bitmap, just reuse the old one
|
|
g_hbmDemo = hbm;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
|
|
case WM_DESTROY:
|
|
FreeScrEntries();
|
|
if (g_fPreviewActive)
|
|
SetNewSSDemo(hDlg, -1);
|
|
if (g_hbmDemo)
|
|
{
|
|
SendDlgItemMessage(hDlg,IDC_BIGICON,STM_SETIMAGE,IMAGE_BITMAP,
|
|
(LPARAM)NULL);
|
|
DeleteObject(g_hbmDemo);
|
|
}
|
|
if (g_hbmEnergyStar)
|
|
{
|
|
SendDlgItemMessage(hDlg,IDC_ENERGYSTAR_BMP,STM_SETIMAGE,
|
|
IMAGE_BITMAP, (LPARAM)NULL);
|
|
DeleteObject(g_hbmEnergyStar);
|
|
}
|
|
break;
|
|
|
|
case WM_VSCROLL:
|
|
if (LOWORD(wParam) == SB_THUMBPOSITION)
|
|
ScreenSaver_AdjustTimeouts(hDlg, GetDlgCtrlID((HWND)lParam) - BCI_ARROW);
|
|
break;
|
|
|
|
case WM_HELP:
|
|
WinHelp((HWND) ((LPHELPINFO) lParam)->hItemHandle, NULL,
|
|
HELP_WM_HELP, (DWORD)aSaverHelpIds);
|
|
break;
|
|
|
|
case WM_CONTEXTMENU: // right mouse click
|
|
WinHelp((HWND) wParam, NULL, HELP_CONTEXTMENU,
|
|
(DWORD) aSaverHelpIds);
|
|
break;
|
|
|
|
case WM_QUERYNEWPALETTE:
|
|
case WM_PALETTECHANGED:
|
|
ForwardSSDemoMsg(hDlg, message, wParam, lParam);
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch(LOWORD(wParam))
|
|
{
|
|
/* Check for a selection change in the combo box. If there is
|
|
one, then update the method number as well as the
|
|
configure button... */
|
|
case IDC_CHOICES:
|
|
if(HIWORD(wParam) == CBN_SELCHANGE)
|
|
{
|
|
/* Dump the name of the current selection into
|
|
the buffer... */
|
|
wTemp = SendDlgItemMessage(hDlg,IDC_CHOICES,
|
|
CB_GETCURSEL,0,0l);
|
|
if(wTemp)
|
|
{
|
|
wMethod = SendDlgItemMessage(hDlg,IDC_CHOICES,
|
|
CB_GETITEMDATA,wTemp,0l);
|
|
|
|
/* Grey the button accordingly... */
|
|
pszMethod = aszMethods[wMethod];
|
|
if(pszMethod[0] == TEXT('C') || // can config
|
|
pszMethod[0] == TEXT('I') || // IdleWild
|
|
pszMethod[0] == TEXT('P') ) // can preview
|
|
EnableDlgItem(hDlg,IDC_SETTING, TRUE);
|
|
else
|
|
EnableDlgItem(hDlg,IDC_SETTING, FALSE);
|
|
|
|
|
|
#ifndef WINNT // All screen savers on NT can use password protection
|
|
if(pszMethod[0] == TEXT('P')) // is a Win32 4.0 saver
|
|
{
|
|
#endif
|
|
EnableDlgItem(hDlg,IDC_USEPASSWORD, TRUE);
|
|
CheckDlgButton( hDlg, IDC_USEPASSWORD,
|
|
g_fPasswordWasPreviouslyEnabled );
|
|
EnableDisableSetPasswordBtn(hDlg);
|
|
#ifndef WINNT // All screen savers on NT can use password protection
|
|
}
|
|
else
|
|
{
|
|
g_fPasswordWasPreviouslyEnabled =
|
|
IsDlgButtonChecked( hDlg, IDC_USEPASSWORD );
|
|
CheckDlgButton( hDlg, IDC_USEPASSWORD, FALSE );
|
|
EnableDlgItem(hDlg,IDC_USEPASSWORD,FALSE);
|
|
EnableDlgItem(hDlg,IDC_SETPASSWORD,FALSE);
|
|
}
|
|
#endif
|
|
|
|
/* For fun, create an extra copy of
|
|
szSaverName... */
|
|
pszMethod = aszFiles[wMethod];
|
|
lstrcpy(szSaverName,pszMethod);
|
|
|
|
fEnable = TRUE;
|
|
}
|
|
else
|
|
{
|
|
wMethod = -1;
|
|
lstrcpy(szSaverName, g_szNULL);
|
|
|
|
EnableDlgItem(hDlg,IDC_SETTING,FALSE);
|
|
EnableDlgItem(hDlg,IDC_USEPASSWORD,FALSE);
|
|
#ifndef WINNT
|
|
EnableDlgItem(hDlg,IDC_SETPASSWORD,FALSE);
|
|
#endif
|
|
|
|
fEnable = FALSE;
|
|
}
|
|
|
|
// Following are enabled as a group... (oh really?)
|
|
EnableDlgItem(hDlg,IDC_SSDELAYLABEL,fEnable);
|
|
EnableDlgItem(hDlg,IDC_SCREENSAVEDELAY,fEnable);
|
|
EnableDlgItem(hDlg,IDC_SCREENSAVEARROW,fEnable);
|
|
EnableDlgItem(hDlg,IDC_SSDELAYSCALE,fEnable);
|
|
EnableDlgItem(hDlg,IDC_TEST,fEnable);
|
|
|
|
g_iMethod = (int)wMethod;
|
|
SetNewSSDemo(hDlg, wMethod);
|
|
SS_SomethingChanged(hDlg);
|
|
}
|
|
break;
|
|
|
|
/* If the edit box loses focus, translate... */
|
|
case IDC_SCREENSAVEDELAY:
|
|
case IDC_LOWPOWERDELAY:
|
|
case IDC_POWEROFFDELAY:
|
|
if (HIWORD(wParam) == EN_KILLFOCUS)
|
|
ScreenSaver_AdjustTimeouts(hDlg, LOWORD(wParam));
|
|
break;
|
|
|
|
case IDC_LOWPOWERSWITCH:
|
|
case IDC_POWEROFFSWITCH:
|
|
if (HIWORD(wParam) == BN_CLICKED) {
|
|
|
|
ScreenSaver_EnableDisableDelays(hDlg, (int) LOWORD(wParam) -
|
|
BCI_SWITCH);
|
|
SS_SomethingChanged(hDlg);
|
|
}
|
|
break;
|
|
|
|
/* If the user wishes to test... */
|
|
case IDC_TEST:
|
|
switch( HIWORD( wParam ) )
|
|
{
|
|
case BN_CLICKED:
|
|
DoScreenSaver(hDlg,TRUE);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
/* Tell the DLL that it can do the configure... */
|
|
case IDC_SETTING:
|
|
if (HIWORD(wParam) == BN_CLICKED) {
|
|
DoScreenSaver(hDlg,FALSE);
|
|
break;
|
|
}
|
|
|
|
case IDC_USEPASSWORD:
|
|
if (HIWORD(wParam) == BN_CLICKED) {
|
|
|
|
g_fPasswordWasPreviouslyEnabled =
|
|
IsDlgButtonChecked( hDlg, IDC_USEPASSWORD );
|
|
EnableDisableSetPasswordBtn(hDlg);
|
|
SS_SomethingChanged(hDlg);
|
|
break;
|
|
}
|
|
|
|
case IDC_SETPASSWORD:
|
|
if (HIWORD(wParam) == BN_CLICKED) {
|
|
|
|
// ask new savers to change passwords
|
|
wTemp = SendDlgItemMessage(hDlg,IDC_CHOICES,
|
|
CB_GETCURSEL,0,0l);
|
|
if(wTemp)
|
|
{
|
|
SetScreenSaverPassword(hDlg,
|
|
(int)SendDlgItemMessage(hDlg,IDC_CHOICES,
|
|
CB_GETITEMDATA,wTemp,0l));
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case WM_CTLCOLORSTATIC:
|
|
if( (HWND)lParam == GetSSDemoParent( hDlg ) )
|
|
{
|
|
return (BOOL)GetStockObject( NULL_BRUSH );
|
|
}
|
|
break;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* ScreenSaver_AdjustTimeouts
|
|
*
|
|
* DESCRIPTION:
|
|
* Called whenever the user adjusts the delay of one of the time controls.
|
|
* Adjusts the delays of the other time controls such that the screen saver
|
|
* delay is less than the low power delay and that the low power delay is
|
|
* less than the power off delay.
|
|
*
|
|
* PARAMETERS:
|
|
* hWnd, handle of ScreenSaver window.
|
|
* BaseControlID, base control ID of the radio, edit, and arrow time control
|
|
* combination.
|
|
*
|
|
*******************************************************************************/
|
|
|
|
VOID
|
|
NEAR PASCAL
|
|
ScreenSaver_AdjustTimeouts(
|
|
HWND hWnd,
|
|
int BaseControlID
|
|
)
|
|
{
|
|
|
|
BOOL fTranslated;
|
|
int Timeout;
|
|
int NewTimeout;
|
|
|
|
//
|
|
// Get the new timeout for this time control and validate it's contents.
|
|
//
|
|
|
|
Timeout = (int) GetDlgItemInt(hWnd, BaseControlID + BCI_DELAY, &fTranslated,
|
|
FALSE);
|
|
Timeout = min(max(Timeout, 1), MAX_MINUTES);
|
|
SetDlgItemInt(hWnd, BaseControlID + BCI_DELAY, (UINT) Timeout, FALSE);
|
|
|
|
//
|
|
// Check the new value of this time control against the other timeouts,
|
|
// adjust their values if necessary. Be careful when changing the order
|
|
// of these conditionals.
|
|
//
|
|
|
|
if (BaseControlID == IDC_SCREENSAVEDELAY) {
|
|
|
|
if (g_Timeout[TA_SCREENSAVE] != Timeout) {
|
|
|
|
g_Timeout[TA_SCREENSAVE] = Timeout;
|
|
|
|
SS_SomethingChanged(hWnd);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (Timeout < g_Timeout[TA_SCREENSAVE]) {
|
|
|
|
g_Timeout[TA_SCREENSAVE] = Timeout;
|
|
SetDlgItemInt(hWnd, IDC_SCREENSAVEDELAY, (UINT) Timeout, FALSE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (BaseControlID == IDC_POWEROFFDELAY) {
|
|
|
|
if (g_Timeout[TA_POWEROFF] != Timeout) {
|
|
|
|
g_Timeout[TA_POWEROFF] = Timeout;
|
|
|
|
SS_SomethingChanged(hWnd);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (Timeout > g_Timeout[TA_POWEROFF]) {
|
|
|
|
g_Timeout[TA_POWEROFF] = Timeout;
|
|
SetDlgItemInt(hWnd, IDC_POWEROFFDELAY, (UINT) Timeout, FALSE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (BaseControlID == IDC_LOWPOWERDELAY) {
|
|
|
|
if (g_Timeout[TA_LOWPOWER] != Timeout) {
|
|
|
|
g_Timeout[TA_LOWPOWER] = Timeout;
|
|
|
|
SS_SomethingChanged(hWnd);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
NewTimeout = min(max(g_Timeout[TA_LOWPOWER], g_Timeout[TA_SCREENSAVE]),
|
|
g_Timeout[TA_POWEROFF]);
|
|
|
|
if (NewTimeout != g_Timeout[TA_LOWPOWER]) {
|
|
|
|
g_Timeout[TA_LOWPOWER] = Timeout;
|
|
SetDlgItemInt(hWnd, IDC_LOWPOWERDELAY, (UINT) NewTimeout, FALSE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* ScreenSaver_EnableDisableDelays
|
|
*
|
|
* DESCRIPTION:
|
|
* Called whenever the user clicks one of the time controls. Enables or
|
|
* disables the "buddy" edit and arrow controls.
|
|
*
|
|
* PARAMETERS:
|
|
* hWnd, handle of ScreenSaver window.
|
|
* BaseControlID, base control ID of the radio, edit, and arrow time control
|
|
* combination.
|
|
*
|
|
*******************************************************************************/
|
|
|
|
void NEAR PASCAL ScreenSaver_EnableDisableDelays(HWND hWnd,int BaseControlID)
|
|
{
|
|
BOOL fEnable;
|
|
|
|
fEnable = (IsDlgButtonChecked(hWnd, BaseControlID + BCI_SWITCH) == 1);
|
|
|
|
EnableDlgItem(hWnd, BaseControlID + BCI_DELAY, fEnable);
|
|
EnableDlgItem(hWnd, BaseControlID + BCI_ARROW, fEnable);
|
|
|
|
}
|
|
|
|
void NEAR PASCAL EnableDisablePowerDelays(HWND hDlg)
|
|
{
|
|
|
|
int i;
|
|
BOOL fDPMS;
|
|
static idCtrls[] = { IDC_ENERGY_TEXT,
|
|
IDC_ENERGY_TEXT2,
|
|
IDC_ENERGY_TEXT3,
|
|
IDC_ENERGYSTAR_BMP,
|
|
IDC_LOWPOWERDELAY+BCI_DELAY,
|
|
IDC_LOWPOWERDELAY+BCI_ARROW,
|
|
IDC_LOWPOWERDELAY+BCI_SWITCH,
|
|
IDC_POWEROFFDELAY+BCI_DELAY,
|
|
IDC_POWEROFFDELAY+BCI_ARROW,
|
|
IDC_POWEROFFDELAY+BCI_SWITCH,
|
|
0 };
|
|
|
|
for (i = 0; idCtrls[i] != 0; i++)
|
|
ShowWindow( GetDlgItem( hDlg, idCtrls[i] ), g_fAdapPwrMgnt ? SW_SHOWNA : SW_HIDE );
|
|
|
|
if( g_fAdapPwrMgnt )
|
|
{
|
|
#ifdef LATER
|
|
//11-Jul-1995 JonPa BUGBUG use this when we get DPMS for NT
|
|
fDPMS = GetMonitorDPMS();
|
|
#else
|
|
fDPMS = FALSE;
|
|
#endif
|
|
|
|
// Enable/Disable the power related timer switches based on Monitor
|
|
// DPMS capability
|
|
EnableDlgItem(hDlg,IDC_ENERGY_TEXT, fDPMS);
|
|
EnableDlgItem(hDlg,IDC_LOWPOWERDELAY+BCI_SWITCH, fDPMS);
|
|
EnableDlgItem(hDlg,IDC_POWEROFFDELAY+BCI_SWITCH, fDPMS);
|
|
|
|
// If DPMS compliant, enable/disable the other power timer values
|
|
// based on the switch setting, otherwise disable everything
|
|
|
|
if (fDPMS)
|
|
{
|
|
ScreenSaver_EnableDisableDelays(hDlg,IDC_LOWPOWERDELAY);
|
|
ScreenSaver_EnableDisableDelays(hDlg,IDC_POWEROFFDELAY);
|
|
}
|
|
else
|
|
{
|
|
EnableDlgItem(hDlg,IDC_LOWPOWERDELAY+BCI_DELAY, FALSE);
|
|
EnableDlgItem(hDlg,IDC_LOWPOWERDELAY+BCI_ARROW, FALSE);
|
|
EnableDlgItem(hDlg,IDC_POWEROFFDELAY+BCI_DELAY, FALSE);
|
|
EnableDlgItem(hDlg,IDC_POWEROFFDELAY+BCI_ARROW, FALSE);
|
|
}
|
|
}
|
|
}
|
|
|
|
// keep the "set password" button enabled/disabled
|
|
// according to whether "use password" is checked or not
|
|
void NEAR PASCAL EnableDisableSetPasswordBtn(HWND hDlg)
|
|
{
|
|
BOOL fEnable = IsDlgButtonChecked( hDlg,IDC_USEPASSWORD );
|
|
|
|
#ifndef WINNT
|
|
EnableDlgItem( hDlg, IDC_SETPASSWORD, fEnable );
|
|
#endif
|
|
}
|
|
|
|
/* This routine will search for entries that are screen savers. The directory
|
|
searched is either the system directory (.. */
|
|
|
|
void NEAR PASCAL SearchForScrEntries(UINT wDir, LPCTSTR file)
|
|
{
|
|
TCHAR szPath[MAX_PATH];
|
|
TCHAR szPath2[MAX_PATH];
|
|
HANDLE hfind;
|
|
WIN32_FIND_DATA fd;
|
|
|
|
// don't do any work if no space left
|
|
if( wNumMethods >= MAX_METHODS )
|
|
return;
|
|
|
|
/* Get the directory where the program resides... */
|
|
GetModuleFileName(hInstance, szPath, ARRAYSIZE(szPath));
|
|
StripPathName(szPath);
|
|
|
|
switch ( wDir )
|
|
{
|
|
case SFSE_WINDOWS:
|
|
/* Search the windows directory and place the path with the \ in
|
|
the szPath variable... */
|
|
GetWindowsDirectory(szPath2, ARRAYSIZE(szPath2));
|
|
|
|
sfseSanityCheck:
|
|
/* if same dir as where it was launched, don't search again */
|
|
if (!lstrcmpi(szPath, szPath2))
|
|
return;
|
|
|
|
lstrcpy(szPath, szPath2);
|
|
break;
|
|
|
|
case SFSE_SYSTEM:
|
|
/* Search the system directory and place the path with the \ in
|
|
the szPath variable... */
|
|
GetSystemDirectory(szPath2, ARRAYSIZE(szPath2));
|
|
goto sfseSanityCheck;
|
|
|
|
case SFSE_FILE:
|
|
/* Search the directory containing 'file' */
|
|
lstrcpy(szPath2, file);
|
|
StripPathName(szPath2);
|
|
goto sfseSanityCheck;
|
|
}
|
|
|
|
AppendPath(szPath, TEXT("*.scr"));
|
|
|
|
if( ( hfind = FindFirstFile( szPath, &fd ) ) != INVALID_HANDLE_VALUE )
|
|
{
|
|
StripPathName(szPath);
|
|
|
|
do
|
|
{
|
|
PTSTR pszDesc;
|
|
BOOL fLFN;
|
|
|
|
fLFN = !(fd.cAlternateFileName[0] == 0 ||
|
|
lstrcmp(fd.cFileName, fd.cAlternateFileName) == 0);
|
|
|
|
lstrcpy(szPath2, szPath);
|
|
AppendPath(szPath2, fd.cFileName);
|
|
|
|
// Note: PerformCheck does an alloc
|
|
if( ( pszDesc = PerformCheck( szPath2, fLFN ) ) != NULL )
|
|
{
|
|
BOOL bAdded = FALSE;
|
|
UINT i;
|
|
|
|
for( i = 0; i < wNumMethods; i++ )
|
|
{
|
|
if( !lstrcmpi( pszDesc, aszMethods[ i ] ) )
|
|
{
|
|
bAdded = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if( !bAdded )
|
|
{
|
|
PTSTR pszEntries;
|
|
|
|
// COMPATIBILITY: always use short name
|
|
// otherwise some apps fault when peeking at SYSTEM.INI
|
|
if( fLFN )
|
|
{
|
|
lstrcpy(szPath2, szPath);
|
|
AppendPath(szPath2, fd.cAlternateFileName);
|
|
}
|
|
|
|
if( ( pszEntries = AllocStr( szPath2 ) ) != NULL )
|
|
{
|
|
if (pszDesc[0] != TEXT('P'))
|
|
hIcons[wNumMethods] = ExtractIcon(hInstance, szPath2, 0);
|
|
else
|
|
hIcons[wNumMethods] = NULL;
|
|
|
|
aszMethods[wNumMethods] = pszDesc;
|
|
aszFiles[wNumMethods] = pszEntries;
|
|
wNumMethods++;
|
|
bAdded = TRUE;
|
|
}
|
|
}
|
|
|
|
if( !bAdded )
|
|
LocalFree((HLOCAL)pszDesc);
|
|
}
|
|
|
|
} while( FindNextFile( hfind, &fd ) && ( wNumMethods < MAX_METHODS ) );
|
|
|
|
FindClose(hfind);
|
|
}
|
|
return;
|
|
}
|
|
|
|
//
|
|
// This routine checks a given file to see if it is indeed a screen saver
|
|
// executable...
|
|
//
|
|
// a valid screen saver exe has the following description line:
|
|
//
|
|
// SCRNSAVE [c] : description :
|
|
//
|
|
// SCRNSAVE is a required name that indicates a screen saver.
|
|
//
|
|
PTSTR NEAR PASCAL PerformCheck(LPTSTR lpszFilename, BOOL fLFN)
|
|
{
|
|
int i;
|
|
TCHAR chConfig=TEXT('C'); // assume configure
|
|
LPTSTR pch;
|
|
DWORD dw;
|
|
WORD Version;
|
|
WORD Magic;
|
|
|
|
/* Get the description... */
|
|
|
|
pch = szBuffer + 1;
|
|
|
|
//
|
|
// if we have a LFN (Long File Name) dont bother getting the
|
|
// exe descrription
|
|
//
|
|
dw = GetExeInfo(lpszFilename, pch, ARRAYSIZE(szBuffer)-1, fLFN ? GEI_EXPVER : GEI_DESCRIPTION);
|
|
Version = HIWORD(dw);
|
|
Magic = LOWORD(dw);
|
|
|
|
if (dw == 0)
|
|
return NULL;
|
|
|
|
if (Magic == PEMAGIC || fLFN)
|
|
{
|
|
BOOL fGotName = FALSE;
|
|
|
|
if (!fLFN) {
|
|
HANDLE hSaver;
|
|
//
|
|
// We have a 32 bit screen saver with a short name, look for an NT style
|
|
// decription in it's string table
|
|
//
|
|
if (hSaver = LoadLibrary (lpszFilename)) {
|
|
if (LoadString (hSaver, IDS_DESCRIPTION, pch, ARRAYSIZE(szBuffer) - (szBuffer - pch))) {
|
|
fGotName = TRUE;
|
|
}
|
|
FreeLibrary (hSaver);
|
|
}
|
|
}
|
|
|
|
if (!fGotName) {
|
|
//
|
|
// we have a LFN (LongFileName) or a Win32 screen saver,
|
|
// Win32 exe's in general dont have a description field so
|
|
// we assume they can configure. We also try to build
|
|
// a "nice" name for it.
|
|
//
|
|
lstrcpy(pch, lpszFilename);
|
|
|
|
pch = FileName(pch); // strip path part
|
|
|
|
if ( ((TCHAR)CharUpper((LPTSTR)(pch[0]))) == TEXT('S') && ((TCHAR)CharUpper((LPTSTR)(pch[1]))) == TEXT('S')) // map SSBEZIER.SCR to BEZIER.SCR
|
|
pch+=2;
|
|
|
|
pch = NiceName(pch); // map BEZIER.SCR to Bezier
|
|
}
|
|
}
|
|
else
|
|
{
|
|
LPTSTR pchTemp;
|
|
|
|
//
|
|
// we have a 8.3 file name 16bit screen saveer, parse the
|
|
// description string from the exehdr
|
|
//
|
|
/* Check to make sure that at least the 11 characters needed for info
|
|
are there... */
|
|
if (lstrlen(pch) < 9)
|
|
return NULL;
|
|
|
|
/* Check the first 8 characters for the string... */
|
|
if (lstrncmp(TEXT("SCRNSAVE"), pch, 8))
|
|
return NULL;
|
|
|
|
// If successful, allocate enough space for the string and copy the
|
|
// string to the new one...
|
|
|
|
pch = pch + 8; // skip over 'SCRNSAVE'
|
|
|
|
while (*pch==TEXT(' ')) // advance over white space
|
|
pch++;
|
|
|
|
if (*pch==TEXT('C') || *pch==TEXT('c')) // parse the configure flag
|
|
{
|
|
chConfig = TEXT('C');
|
|
pch++;
|
|
}
|
|
|
|
if (*pch==TEXT('X') || *pch==TEXT('x')) // parse the don't configure flag
|
|
chConfig = *pch++;
|
|
|
|
// we might be pointing at a name or separation goop
|
|
pchTemp = pch; // remember this spot
|
|
|
|
while (*pch && *pch!=TEXT(':')) // find separator
|
|
pch++;
|
|
|
|
while (*pch==TEXT(':') || *pch==TEXT(' ')) // advance over whtspc/last colon
|
|
pch++;
|
|
|
|
// if we haven't found a name yet fall back on the saved location
|
|
if (!*pch)
|
|
pch = pchTemp;
|
|
|
|
while (*pch==TEXT(':') || *pch==TEXT(' ')) // re-advance over whtspc
|
|
pch++;
|
|
|
|
/* In case the screen saver has version information information
|
|
embedded after the name, check to see if there is a colon TEXT(':')
|
|
in the description and replace it with a NULL... */
|
|
|
|
for (i=0; pch[i]; i++) //
|
|
{
|
|
#ifdef DBCS
|
|
if (IsDBCSLeadByte(pch[i]))
|
|
{
|
|
i++;
|
|
}
|
|
else
|
|
#endif
|
|
if (pch[i]==TEXT(':'))
|
|
pch[i]=0;
|
|
}
|
|
// Space is OK for DBCS (FE)
|
|
while(i>0 && pch[i-1]==TEXT(' ')) // remove trailing space
|
|
pch[--i]=0;
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
if (Magic == PEMAGIC)
|
|
lstrcat(pch, TEXT(" (32-bit)")); // add techy stuff.
|
|
else
|
|
lstrcat(pch, TEXT(" (16-bit)"));
|
|
|
|
if (Version == 0x030A)
|
|
lstrcat(pch, TEXT(" (3.10)"));
|
|
|
|
if (Version == 0x0400)
|
|
lstrcat(pch, TEXT(" (4.00)"));
|
|
#endif
|
|
//
|
|
// assume any Win32 4.0 screen saver can do Preview mode
|
|
//
|
|
if (chConfig == TEXT('C') && Version >= 0x0400 && Magic == PEMAGIC)
|
|
chConfig = TEXT('P'); // mark as configurable/preview
|
|
|
|
pch[-1] = chConfig;
|
|
return AllocStr(pch-1);
|
|
}
|
|
|
|
|
|
BOOL NEAR PASCAL FreeScrEntries( void )
|
|
{
|
|
UINT wLoop;
|
|
|
|
for(wLoop = 0; wLoop < wNumMethods; wLoop++)
|
|
{
|
|
if(aszMethods[wLoop] != NULL)
|
|
LocalFree((HANDLE)aszMethods[wLoop]);
|
|
if(aszFiles[wLoop] != NULL)
|
|
LocalFree((HANDLE)aszFiles[wLoop]);
|
|
if(hIcons[wLoop] != NULL)
|
|
FreeResource(hIcons[wLoop]);
|
|
}
|
|
|
|
if (hDefaultIcon)
|
|
FreeResource(hDefaultIcon);
|
|
|
|
if (hIdleWildIcon)
|
|
FreeResource(hIdleWildIcon);
|
|
|
|
hDefaultIcon=hIdleWildIcon=NULL;
|
|
wNumMethods = 0;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
int NEAR PASCAL lstrncmp( LPTSTR lpszString1, LPTSTR lpszString2, int nNum )
|
|
{
|
|
/* While we can still compare characters, compare. If the strings are
|
|
of different lengths, characters will be different... */
|
|
while(nNum)
|
|
{
|
|
if(*lpszString1 != *lpszString2)
|
|
return *lpszString1 - *lpszString2;
|
|
lpszString1++;
|
|
lpszString2++;
|
|
nNum--;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
void NEAR PASCAL SaveIni(HWND hDlg )
|
|
{
|
|
LPTSTR pszMethod;
|
|
int wMethod,wTemp;
|
|
UINT Counter;
|
|
HKEY hKey;
|
|
|
|
/* Find the current method selection... */
|
|
wTemp = 0;
|
|
if(wNumMethods)
|
|
{
|
|
/* Dump the name of the current selection into the buffer... */
|
|
wTemp = SendDlgItemMessage(hDlg,IDC_CHOICES,CB_GETCURSEL,0,0l);
|
|
if(wTemp)
|
|
{
|
|
BOOL hasspace = FALSE;
|
|
LPTSTR pc;
|
|
|
|
wMethod = SendDlgItemMessage(hDlg,IDC_CHOICES,CB_GETITEMDATA,
|
|
wTemp,0l);
|
|
|
|
/* Dump the method name into the buffer... */
|
|
pszMethod = aszFiles[wMethod];
|
|
|
|
for( pc = pszMethod; *pc; pc++ )
|
|
{
|
|
if( *pc == TEXT(' ') )
|
|
{
|
|
hasspace = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if( hasspace )
|
|
{
|
|
// if we need to add quotes we'll need two sets
|
|
// because GetBlahBlahProfileBlah APIs strip quotes
|
|
wsprintf(szBuffer,TEXT("\"\"%s\"\""), pszMethod);
|
|
}
|
|
else
|
|
lstrcpy(szBuffer, pszMethod);
|
|
}
|
|
else
|
|
szBuffer[0] = TEXT('\0');
|
|
}
|
|
else
|
|
szBuffer[0] = TEXT('\0');
|
|
/* Save the buffer... */
|
|
WritePrivateProfileString(g_szBoot, szMethodName,
|
|
(szBuffer[0] != TEXT('\0') ? szBuffer : NULL), g_szSystemIni);
|
|
|
|
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, wTemp, NULL, SPIF_UPDATEINIFILE);
|
|
|
|
for (Counter = 0; Counter < (sizeof(g_TimeoutAssociation) /
|
|
sizeof(TIMEOUT_ASSOCIATION)); Counter++) {
|
|
|
|
SystemParametersInfo(g_TimeoutAssociation[Counter].taSetTimeoutAction,
|
|
(UINT) (g_Timeout[Counter] * 60), NULL, SPIF_UPDATEINIFILE);
|
|
|
|
if (Counter != TA_SCREENSAVE) {
|
|
|
|
SystemParametersInfo(g_TimeoutAssociation[Counter].taSetActiveAction,
|
|
IsDlgButtonChecked(hDlg,
|
|
g_TimeoutAssociation[Counter].taBaseControlID + BCI_SWITCH),
|
|
NULL, SPIF_UPDATEINIFILE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// save the state of the TEXT("use password") checkbox
|
|
if (RegCreateKey(HKEY_CURRENT_USER,REGSTR_PATH_SCREENSAVE,&hKey) == ERROR_SUCCESS) {
|
|
|
|
RegSetValueEx(hKey,SZ_USE_PASSWORD, 0, PWRD_REG_TYPE,
|
|
PasswdRegData(IsDlgButtonChecked(hDlg,IDC_USEPASSWORD)),
|
|
CB_USE_PWRD_VALUE);
|
|
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
/* Broadcast a WM_WININICHANGE message... */
|
|
SendNotifyMessage(HWND_BROADCAST, WM_WININICHANGE, 0, (LONG)g_szWindows);
|
|
}
|
|
|
|
/*
|
|
* Thread for DoScreenSaver()
|
|
*/
|
|
typedef struct {
|
|
HWND hDlg;
|
|
TCHAR szCmdLine[1];
|
|
} SSRUNDATA, *LPSSRUNDATA;
|
|
|
|
DWORD RunScreenSaverThread( LPVOID lpv ) {
|
|
BOOL bSvrState;
|
|
LPSSRUNDATA lpssrd;
|
|
HWND hwndSettings, hwndPreview;
|
|
STARTUPINFO StartupInfo;
|
|
PROCESS_INFORMATION ProcessInformation;
|
|
HINSTANCE hiThd;
|
|
TCHAR szPath[MAX_PATH];
|
|
|
|
// Lock ourselves in mem so we don't fault if app unloads us
|
|
GetModuleFileName(hInstance, szPath, ARRAYSIZE(szPath));
|
|
hiThd = LoadLibrary( szPath );
|
|
|
|
lpssrd = (LPSSRUNDATA)lpv;
|
|
|
|
hwndSettings = GetDlgItem( lpssrd->hDlg, IDC_SETTING);
|
|
hwndPreview = GetDlgItem( lpssrd->hDlg, IDC_TEST);
|
|
|
|
|
|
// Save previous screen saver state
|
|
SystemParametersInfo( SPI_GETSCREENSAVEACTIVE,0, &bSvrState, FALSE);
|
|
|
|
// Disable current screen saver
|
|
if( bSvrState )
|
|
SystemParametersInfo( SPI_SETSCREENSAVEACTIVE,FALSE, NULL, FALSE );
|
|
|
|
// Stop the miniture preview screen saver
|
|
if (g_fPreviewActive)
|
|
SetNewSSDemo( lpssrd->hDlg, -1);
|
|
|
|
// Exec the screen saver and wait for it to die
|
|
ZeroMemory(&StartupInfo,sizeof(StartupInfo));
|
|
StartupInfo.cb = sizeof(StartupInfo);
|
|
StartupInfo.dwFlags = STARTF_USESHOWWINDOW;
|
|
StartupInfo.wShowWindow = (WORD)SW_NORMAL;
|
|
|
|
if (CreateProcess( NULL, lpssrd->szCmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &StartupInfo, &ProcessInformation )){
|
|
WaitForSingleObject( ProcessInformation.hProcess, INFINITE );
|
|
CloseHandle(ProcessInformation.hProcess);
|
|
CloseHandle(ProcessInformation.hThread);
|
|
}
|
|
|
|
// Restore Screen saver state
|
|
if( bSvrState )
|
|
SystemParametersInfo( SPI_SETSCREENSAVEACTIVE, bSvrState, NULL, FALSE );
|
|
|
|
// Restart miniture preview
|
|
PostMessage( lpssrd->hDlg, WM_COMMAND, MAKELONG(IDC_CHOICES, CBN_SELCHANGE),
|
|
(LPARAM)GetDlgItem( lpssrd->hDlg, IDC_CHOICES));
|
|
|
|
// Enable setting and preview buttons
|
|
EnableWindow( hwndSettings, TRUE );
|
|
EnableWindow( hwndPreview, TRUE );
|
|
|
|
LocalFree( lpv );
|
|
|
|
if (hiThd)
|
|
FreeLibraryAndExitThread( hiThd, 0 );
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/* This routine actually calls the screen saver... */
|
|
|
|
void NEAR PASCAL DoScreenSaver(HWND hWnd, BOOL fSaver )
|
|
{
|
|
LPSSRUNDATA lpssrd;
|
|
DWORD id;
|
|
HANDLE hThd;
|
|
HWND hwndSettings, hwndPreview;
|
|
|
|
if(szSaverName[0] == TEXT('\0'))
|
|
return;
|
|
|
|
if(fSaver)
|
|
wsprintf(szBuffer,TEXT("%s /s"), szSaverName);
|
|
else {
|
|
wsprintf(szBuffer,TEXT("%s /c:%lu"), szSaverName, (DWORD)hWnd);
|
|
}
|
|
|
|
lpssrd = LocalAlloc( LMEM_FIXED, sizeof(*lpssrd) + (lstrlen(szBuffer)+1) * sizeof(TCHAR) );
|
|
if (lpssrd == NULL)
|
|
return;
|
|
|
|
lpssrd->hDlg = hWnd;
|
|
lstrcpy( lpssrd->szCmdLine, szBuffer );
|
|
|
|
// Disable setting and preview buttons
|
|
hwndSettings = GetDlgItem( hWnd, IDC_SETTING);
|
|
hwndPreview = GetDlgItem( hWnd, IDC_TEST);
|
|
|
|
EnableWindow( hwndSettings, FALSE );
|
|
EnableWindow( hwndPreview, FALSE );
|
|
|
|
hThd = CreateThread(NULL, 0, RunScreenSaverThread, lpssrd, 0, &id);
|
|
if (hThd != NULL) {
|
|
CloseHandle(hThd);
|
|
} else {
|
|
// Exec failed, re-enable setting and preview buttons and clean up thread params
|
|
EnableWindow( hwndSettings, TRUE );
|
|
EnableWindow( hwndPreview, TRUE );
|
|
LocalFree( lpssrd );
|
|
}
|
|
}
|
|
|
|
|
|
#define SLASH(c) ((c) == TEXT('/') || (c) == TEXT('\\'))
|
|
|
|
LPTSTR NEAR PASCAL FileName(LPTSTR szPath)
|
|
{
|
|
LPTSTR sz;
|
|
|
|
for (sz=szPath; *sz; sz++)
|
|
;
|
|
#ifdef DBCS
|
|
for (; sz>szPath && !SLASH(*sz) && *sz!=TEXT(':'); sz=CharPrev(szPath, sz))
|
|
#else
|
|
for (; sz>=szPath && !SLASH(*sz) && *sz!=TEXT(':'); sz--)
|
|
#endif
|
|
;
|
|
#ifdef DBCS
|
|
if ( !IsDBCSLeadByte(*sz) && (SLASH(*sz) || *sz == TEXT(':')) )
|
|
sz = CharNext(sz);
|
|
return sz;
|
|
#else
|
|
return ++sz;
|
|
#endif
|
|
}
|
|
|
|
void NEAR PASCAL AddBackslash(LPTSTR pszPath)
|
|
{
|
|
#ifdef DBCS
|
|
LPTSTR lpsz = &pszPath[lstrlen(pszPath)];
|
|
lpsz = CharPrev(pszPath, lpsz);
|
|
if ( *lpsz != TEXT('\\') )
|
|
#else
|
|
if( pszPath[ lstrlen( pszPath ) - 1 ] != TEXT('\\') )
|
|
#endif
|
|
lstrcat( pszPath, TEXT("\\") );
|
|
}
|
|
|
|
|
|
LPTSTR NEAR PASCAL StripPathName(LPTSTR szPath)
|
|
{
|
|
LPTSTR sz;
|
|
#ifdef DBCS
|
|
LPTSTR szFile;
|
|
#endif
|
|
sz = FileName(szPath);
|
|
|
|
#ifdef DBCS
|
|
szFile = sz;
|
|
if ( szFile >szPath+1 )
|
|
{
|
|
szFile = CharPrev( szPath, szFile );
|
|
if (SLASH(*szFile))
|
|
{
|
|
szFile = CharPrev(szPath, szFile);
|
|
if (*szFile != TEXT(':'))
|
|
sz--;
|
|
}
|
|
}
|
|
#else
|
|
if (sz > szPath+1 && SLASH(sz[-1]) && sz[-2] != TEXT(':'))
|
|
sz--;
|
|
#endif
|
|
|
|
*sz = 0;
|
|
return szPath;
|
|
}
|
|
|
|
void NEAR PASCAL AppendPath(LPTSTR pszPath, LPTSTR pszSpec)
|
|
{
|
|
AddBackslash(pszPath);
|
|
lstrcat(pszPath, pszSpec);
|
|
}
|
|
|
|
|
|
PTSTR NEAR PASCAL AllocStr(LPTSTR szCopy)
|
|
{
|
|
PTSTR sz;
|
|
|
|
if (sz = (PTSTR)LocalAlloc(LPTR, sizeof(TCHAR) * (lstrlen(szCopy)+1)))
|
|
lstrcpy(sz,szCopy);
|
|
|
|
return sz;
|
|
}
|
|
|
|
LPTSTR NEAR PASCAL NiceName(LPTSTR szPath)
|
|
{
|
|
LPTSTR sz;
|
|
LPTSTR lpsztmp;
|
|
|
|
sz = FileName(szPath);
|
|
|
|
for(lpsztmp = sz; *lpsztmp && *lpsztmp != TEXT('.'); lpsztmp = CharNext(lpsztmp))
|
|
;
|
|
*lpsztmp = TEXT('\0');
|
|
|
|
if (IsCharUpper(sz[0]) && IsCharUpper(sz[1]))
|
|
{
|
|
CharLower(sz);
|
|
CharUpperBuff(sz, 1);
|
|
}
|
|
|
|
return sz;
|
|
}
|