windows-nt/Source/XPSP1/NT/multimedia/directx/gamectrl/client/main.cpp

480 lines
12 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*
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"
#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);
BOOL WINAPI SplashDialogProc(HWND hDlg, ULONG uMsg, WPARAM wParam, LPARAM lParam);
// From AppMan.cpp
//extern HRESULT AppManInit();
// 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, (DLGPROC)CPanelProc);
AddPage(ppsh, IDD_ADVANCED, IDS_ADVANCED_TAB, (DLGPROC)AdvancedProc);
if( SUCCEEDED ( DVoiceCPLInit() )) {
AddPage(ppsh, IDD_PROP_RETROFIT, IDS_DVOICE_TAB, (DLGPROC) RetrofitProc);
}
// if( SUCCEEDED ( AppManInit() ) ) {
// AddPage(ppsh, IDD_APPMAN, IDS_APPMAN_TAB, (DLGPROC)AppManProc);
// AddPage(ppsh, IDD_APPMAN_LOCKING, IDS_APPMANLOCK_TAB, (DLGPROC) AppManLockProc);
// }
#ifdef SYMANTIC_MAPPER
AddPage(ppsh, IDD_SMAPPER, ID_SMAPPER_TAB, (DLGPROC)SMapperProc);
#endif // SYMANTIC_MAPPER
// trap for return...
VERIFY(PropertySheet(ppsh) != -1);
if( pPages )
delete[] (pPages);
if( ppsh )
delete (ppsh);
ReleaseMutex(hMutex);
CloseHandle(hMutex);
// 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, (DLGPROC)SplashDialogProc );
break;
#endif
}
} else {
DoProperties(NULL, nStartPageCPL);
}
}
#ifdef WE_CAN_HAVE_CREDITS
BOOL WINAPI 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