|
|
/*
File: main.cpp Project: Universal Joystick Control Panel OLE Client Author: Brycej Date: 02/28/95 Comments:
Copyright (c) 1995, Microsoft Corporation */
//#pragma pack (8)
#include <afxcmn.h>
#include <cpl.h>
#include "cpanel.h"
#include "resource.h"
// Windows bug 578471 -- remove from server
//#include "creditst.h" // for the Credit Dialog!
#define JOYSTICK_CPL 0
#define MAX_CPL_PAGES 6
HINSTANCE ghInstance;
extern WCHAR *pwszTypeArray[MAX_DEVICES]; extern WCHAR *pwszGameportDriverArray[MAX_GLOBAL_PORT_DRIVERS]; extern WCHAR *pwszGameportBus[MAX_BUSSES]; // List of enumerated gameport buses
extern BYTE nGamingDevices; // Gaming Devices Enumeration Counter
extern BYTE nGameportDriver; // Global Port Driver Enumeration Counter
extern BYTE nGameportBus; // Gameport Bus Enumeration Counter
extern short nFlags; // State Flags the CPL defined in CPANEL.H
static void AddPage(LPPROPSHEETHEADER ppsh, short nTemplateID, int nTabID, DLGPROC pfn);
static void DoProperties(HWND hWnd, UINT nStartPage); void WINAPI ShowJoyCPL(HWND); void ParseArgs(HWND hDlg, LPTSTR lpArgList); INT_PTR CALLBACK SplashDialogProc(HWND hDlg, ULONG uMsg, WPARAM wParam, LPARAM lParam);
// From AppMan.cpp
//extern HRESULT AppManInit();
// Windows bug 578471 -- remove from server
// From Retrocfg.cpp
//extern HRESULT DVoiceCPLInit();
//extern INT_PTR CALLBACK RetrofitProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
//extern INT_PTR RetrofitDestroyHandler(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
BYTE nID, nStartPageDef, nStartPageCPL;
BOOL WINAPI DllMain(HANDLE hModule, ULONG uReason, LPVOID pv) { switch( uReason ) { case DLL_PROCESS_ATTACH: ghInstance = (HINSTANCE)hModule;
// needed because CEdit will Assert without this line!!!
afxCurrentInstanceHandle = ghInstance; afxCurrentResourceHandle = ghInstance; break;
// case DLL_PROCESS_DETACH:
// ClearArrays();
case DLL_THREAD_ATTACH: DisableThreadLibraryCalls((HMODULE)hModule); case DLL_THREAD_DETACH: break; } return(TRUE); }
/*
function: CPlApplet() comments: Entry point for control panel applets. */ LONG WINAPI CPlApplet(HWND hWnd, UINT uMsg, LPARAM lParam1, LPARAM lParam2) { switch( uMsg ) { case CPL_INIT: return(1);
case CPL_GETCOUNT: return(1);
case CPL_INQUIRE: ((LPCPLINFO)lParam2)->idIcon = IDI_CPANEL; ((LPCPLINFO)lParam2)->idName = IDS_GEN_CPANEL_TITLE; ((LPCPLINFO)lParam2)->idInfo = IDS_GEN_CPANEL_INFO; ((LPCPLINFO)lParam2)->lData = 0; return(1);
case CPL_DBLCLK: nID = (NUMJOYDEVS<<1);
// Applet icon double clicked -- invoke property sheet with
// The first property sheet page on top.
DoProperties(hWnd, 0); break;
/*
* This function requires Windows 2000. Not available on Win9x. */ case CPL_STARTWPARMS: // Same as CPL_DBLCLK, but lParam2 is a long pointer to
// a string of extra directions that are to be supplied to
// the property sheet that is to be initiated.
// The arguments are as follows:
// @nCPLDialog Index, nStartPageCPL, nStartPageDef
// Don't do anything if there are no arguments!
if( *(LPTSTR)lParam2 ) ParseArgs(hWnd, (LPTSTR)lParam2); return(TRUE); // return non-zero to indicate message handled
case CPL_EXIT: case CPL_STOP: break; }
return(0); }
/*
Function: DoProperties(HWND hWnd, UINT nStartPage) Arguements: hWnd - Handle to Main Window nStartPage - Page number to start */ static void DoProperties(HWND hWnd, UINT nStartPage) { static HWND hPrevHwnd; static HANDLE hMutex = CreateMutex(NULL, TRUE, MUTEX_NAME);
if( GetLastError() == ERROR_ALREADY_EXISTS ) { SetForegroundWindow(hPrevHwnd); } else { hPrevHwnd = hWnd;
nFlags = (GetVersion() < 0x80000000) ? ON_NT : 0;
HPROPSHEETPAGE *pPages = new (HPROPSHEETPAGE[MAX_CPL_PAGES]); ASSERT (pPages);
LPPROPSHEETHEADER ppsh = new (PROPSHEETHEADER); ASSERT(ppsh);
ZeroMemory(ppsh, sizeof(PROPSHEETHEADER));
ppsh->dwSize = sizeof(PROPSHEETHEADER); ppsh->dwFlags = PSH_NOAPPLYNOW | PSH_USEICONID; ppsh->hwndParent = hWnd; ppsh->hInstance = ghInstance; ppsh->pszCaption = MAKEINTRESOURCE(IDS_GEN_CPANEL_TITLE); ppsh->pszIcon = MAKEINTRESOURCE(IDI_CPANEL); ppsh->nStartPage = nStartPage; ppsh->phpage = pPages;
AddPage(ppsh, IDD_CPANEL, IDS_GENERAL_TAB, CPanelProc); AddPage(ppsh, IDD_ADVANCED, IDS_ADVANCED_TAB, AdvancedProc);
// Windows bug 578471 -- remove from server
// if( SUCCEEDED ( DVoiceCPLInit() )) {
// AddPage(ppsh, IDD_PROP_RETROFIT, IDS_DVOICE_TAB, RetrofitProc);
// }
// if( SUCCEEDED ( AppManInit() ) ) {
// AddPage(ppsh, IDD_APPMAN, IDS_APPMAN_TAB, AppManProc);
// AddPage(ppsh, IDD_APPMAN_LOCKING, IDS_APPMANLOCK_TAB, AppManLockProc);
// }
#ifdef SYMANTIC_MAPPER
AddPage(ppsh, IDD_SMAPPER, ID_SMAPPER_TAB, SMapperProc); #endif // SYMANTIC_MAPPER
// trap for return...
VERIFY(PropertySheet(ppsh) != -1);
if( pPages ) delete[] (pPages);
if( ppsh ) delete (ppsh);
ReleaseMutex(hMutex); CloseHandle(hMutex);
// Windows bug 578471 -- remove from server
// Ensure voice is always cleaned up
//RetrofitDestroyHandler( NULL, 0, 0, 0 );
ClearArrays(); } }
static void AddPage(LPPROPSHEETHEADER ppsh, short nTemplateID, int nTabID, DLGPROC pfn) { if( ppsh->nPages < MAX_CPL_PAGES ) { LPPROPSHEETPAGE ppsp = new (PROPSHEETPAGE); ASSERT(ppsp);
ZeroMemory(ppsp, sizeof(PROPSHEETPAGE));
ppsp->dwSize = sizeof(PROPSHEETPAGE); ppsp->pszTitle = MAKEINTRESOURCE(nTabID); ppsp->hInstance = ghInstance; ppsp->pfnDlgProc = pfn; ppsp->pszTemplate = MAKEINTRESOURCE(nTemplateID);
ppsh->phpage[ppsh->nPages] = CreatePropertySheetPage(ppsp);
if( ppsp ) delete (ppsp);
if( ppsh->phpage[ppsh->nPages] ) ppsh->nPages++; } } // AddPage
// DO NOT REMOVE THIS!!!
// This is here because the games group loads the CPL from the exported function
// If you remove this Hellbender, Monster Truck Maddness, CART, etc will fail to
// load the Joystick CPL!!!
// DO NOT REMOVE THIS!!!
void WINAPI ShowJoyCPL(HWND hWnd) { nID = (NUMJOYDEVS<<1);
DoProperties(hWnd, 0); }
void LaunchExtention(HWND hWnd) { // These are defined in CPANEL.CPP
extern LPDIRECTINPUT lpDIInterface; extern IDirectInputJoyConfig* pDIJoyConfig;
HRESULT hr = DirectInputCreate(ghInstance, DIRECTINPUT_VERSION, &lpDIInterface, NULL);
if( FAILED(hr) ) return;
// Call CreateJoyConfigInterface!
if( SUCCEEDED(lpDIInterface->QueryInterface(IID_IDirectInputJoyConfig, (LPVOID*)&pDIJoyConfig)) ) { // Create a pJoy and populate it's GUID from GetTypeInfo
PJOY pJoy = new (JOY); ASSERT (pJoy);
pJoy->ID = nID;
DIJOYCONFIG_DX5 JoyConfig;
JoyConfig.dwSize = sizeof (DIJOYCONFIG_DX5);
if( SUCCEEDED(pDIJoyConfig->GetConfig(nID, (LPDIJOYCONFIG)&JoyConfig, DIJC_REGHWCONFIGTYPE)) ) { LPDIJOYTYPEINFO_DX5 pdiJoyTypeInfo = new (DIJOYTYPEINFO_DX5); ASSERT (pdiJoyTypeInfo);
pdiJoyTypeInfo->dwSize = sizeof (DIJOYTYPEINFO_DX5);
hr = pDIJoyConfig->GetTypeInfo(JoyConfig.wszType, (LPDIJOYTYPEINFO)pdiJoyTypeInfo, DITC_CLSIDCONFIG);
if( !IsEqualIID(pdiJoyTypeInfo->clsidConfig, GUID_NULL) ) pJoy->clsidPropSheet = pdiJoyTypeInfo->clsidConfig;
if( pdiJoyTypeInfo ) delete (pdiJoyTypeInfo);
}
if( SUCCEEDED(hr) ) Launch(hWnd, pJoy, nStartPageDef);
if( pJoy ) delete (pJoy);
// release the DI JoyConfig interface pointer
if( pDIJoyConfig ) { pDIJoyConfig->Release(); pDIJoyConfig = 0; } }
// release the DI Device interface pointer
if( lpDIInterface ) { lpDIInterface->Release(); lpDIInterface = 0; } }
void ParseArgs(HWND hDlg, LPTSTR lpArgList) { BOOL bShowCPL = TRUE;
// Check for '-', as they may not want to show the CPL!
if( *lpArgList == '-' ) { bShowCPL = FALSE; *lpArgList++; }
nStartPageCPL = nStartPageCPL = nStartPageDef = 0;
// parse command line for nStartPageCPL!
while( *lpArgList && (*lpArgList != ',') ) { nStartPageCPL *= 10; nStartPageCPL += *lpArgList++ - '0'; }
// check to make sure nStartPageCPL is within range!
if( bShowCPL ) { if( nStartPageCPL > MAX_CPL_PAGES ) { #ifdef _DEBUG
OutputDebugString(TEXT("JOY.CPL: Command line requested an invalid start page, reset to default!\n")); #endif
// NUMJOYDEVS is used to send the user to the Add dialog on start-up!
if( nStartPageCPL != NUMJOYDEVS ) nStartPageCPL = 0; } }
// Only continue if you have something further to parse!
if( *lpArgList == ',' ) { *lpArgList++;
nID = 0;
// Parse for ID's
while( *lpArgList && (*lpArgList != ',') ) { nID *= 10; nID += *lpArgList++ - '0'; }
// Check for error cases!
if( (nID < 1) || (nID > NUMJOYDEVS) ) { #ifdef _DEBUG
OutputDebugString(TEXT("JOY.CPL: Command line Device ID out of range!\n")); #endif
nID = (NUMJOYDEVS<<1);
return; }
// Decrement to internal zero based ID
nID--;
// Don't parse what you don't have!
if( *lpArgList == ',' ) { *lpArgList++;
// Lastly, parse for nStartPageDef!
while( *lpArgList && (*lpArgList != ',') ) { nStartPageDef *= 10; nStartPageDef += *lpArgList++ - '0'; } } } else { nID = (NUMJOYDEVS<<1); }
// Done with the parsing...
// Time to get to work!
// if we're not showing the CPL...
if( !bShowCPL ) { // check to make sure the next value is a 1
// we may want to have further negative arguments :)
switch( nStartPageCPL ) { case 1: // Invalid ID...
if( nID > NUMJOYDEVS ) return; LaunchExtention(hDlg); break;
#ifdef WE_CAN_HAVE_CREDITS
case 60: // If they ask for the splash, they don't get the CPL!
DialogBox( ghInstance, (PTSTR)IDD_SPLASH, hDlg, SplashDialogProc ); break; #endif
}
} else { DoProperties(NULL, nStartPageCPL); } }
#ifdef WE_CAN_HAVE_CREDITS
INT_PTR CALLBACK SplashDialogProc(HWND hDlg, ULONG uMsg, WPARAM wParam, LPARAM lParam) { static CCreditStatic *pStatic;
switch( uMsg ) { case WM_INITDIALOG: { pStatic = new (CCreditStatic); ASSERT (pStatic);
CWnd *pCWnd = new (CWnd); ASSERT (pCWnd);
pCWnd->Attach(hDlg);
pStatic->SubclassDlgItem(IDC_MYSTATIC, pCWnd);
if( pCWnd ) { pCWnd->Detach(); delete (pCWnd); pCWnd = 0; }
LPTSTR lpStr = new (TCHAR[MAX_STR_LEN]); ASSERT (lpStr);
// The Credits come in two lines!
BYTE nStrLen = (BYTE)LoadString(ghInstance, IDS_SPLASH, lpStr, MAX_STR_LEN); LoadString(ghInstance, IDS_SPLASH1, &lpStr[nStrLen], MAX_STR_LEN-nStrLen);
pStatic->SetCredits(lpStr);
if( lpStr ) { delete[] (lpStr); lpStr = 0; }
pStatic->StartScrolling(); } return(TRUE); // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE}
case WM_COMMAND: switch( LOWORD(wParam) ) { case IDOK: EndDialog(hDlg, LOWORD(wParam)); break; } break;
// case WM_TIMER:
//SendDlgItemMessage(hDlg, IDC_STATIC, WM_TIMER, 0, 0);
// pStatic->OnTimer(150); //DISPLAY_TIMER_ID
// break;
case WM_DESTROY: if( pStatic ) { delete (pStatic); pStatic = 0; } break; }
return(0); } #endif
|