Source code of Windows XP (NT5)
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.

479 lines
12 KiB

  1. /*
  2. File: main.cpp
  3. Project: Universal Joystick Control Panel OLE Client
  4. Author: Brycej
  5. Date: 02/28/95
  6. Comments:
  7. Copyright (c) 1995, Microsoft Corporation
  8. */
  9. //#pragma pack (8)
  10. #include <afxcmn.h>
  11. #include <cpl.h>
  12. #include "cpanel.h"
  13. #include "resource.h"
  14. #include "creditst.h" // for the Credit Dialog!
  15. #define JOYSTICK_CPL 0
  16. #define MAX_CPL_PAGES 6
  17. HINSTANCE ghInstance;
  18. extern WCHAR *pwszTypeArray[MAX_DEVICES];
  19. extern WCHAR *pwszGameportDriverArray[MAX_GLOBAL_PORT_DRIVERS];
  20. extern WCHAR *pwszGameportBus[MAX_BUSSES]; // List of enumerated gameport buses
  21. extern BYTE nGamingDevices; // Gaming Devices Enumeration Counter
  22. extern BYTE nGameportDriver; // Global Port Driver Enumeration Counter
  23. extern BYTE nGameportBus; // Gameport Bus Enumeration Counter
  24. extern short nFlags; // State Flags the CPL defined in CPANEL.H
  25. static void AddPage(LPPROPSHEETHEADER ppsh, short nTemplateID, int nTabID, DLGPROC pfn);
  26. static void DoProperties(HWND hWnd, UINT nStartPage);
  27. void WINAPI ShowJoyCPL(HWND);
  28. void ParseArgs(HWND hDlg, LPTSTR lpArgList);
  29. BOOL WINAPI SplashDialogProc(HWND hDlg, ULONG uMsg, WPARAM wParam, LPARAM lParam);
  30. // From AppMan.cpp
  31. //extern HRESULT AppManInit();
  32. // From Retrocfg.cpp
  33. extern HRESULT DVoiceCPLInit();
  34. extern INT_PTR CALLBACK RetrofitProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
  35. extern INT_PTR RetrofitDestroyHandler(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
  36. BYTE nID, nStartPageDef, nStartPageCPL;
  37. BOOL WINAPI DllMain(HANDLE hModule, ULONG uReason, LPVOID pv)
  38. {
  39. switch( uReason )
  40. {
  41. case DLL_PROCESS_ATTACH:
  42. ghInstance = (HINSTANCE)hModule;
  43. // needed because CEdit will Assert without this line!!!
  44. afxCurrentInstanceHandle = ghInstance;
  45. afxCurrentResourceHandle = ghInstance;
  46. break;
  47. // case DLL_PROCESS_DETACH:
  48. // ClearArrays();
  49. case DLL_THREAD_ATTACH:
  50. DisableThreadLibraryCalls((HMODULE)hModule);
  51. case DLL_THREAD_DETACH:
  52. break;
  53. }
  54. return(TRUE);
  55. }
  56. /*
  57. function: CPlApplet()
  58. comments:
  59. Entry point for control panel applets.
  60. */
  61. LONG WINAPI CPlApplet(HWND hWnd, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
  62. {
  63. switch( uMsg )
  64. {
  65. case CPL_INIT:
  66. return(1);
  67. case CPL_GETCOUNT:
  68. return(1);
  69. case CPL_INQUIRE:
  70. ((LPCPLINFO)lParam2)->idIcon = IDI_CPANEL;
  71. ((LPCPLINFO)lParam2)->idName = IDS_GEN_CPANEL_TITLE;
  72. ((LPCPLINFO)lParam2)->idInfo = IDS_GEN_CPANEL_INFO;
  73. ((LPCPLINFO)lParam2)->lData = 0;
  74. return(1);
  75. case CPL_DBLCLK:
  76. nID = (NUMJOYDEVS<<1);
  77. // Applet icon double clicked -- invoke property sheet with
  78. // The first property sheet page on top.
  79. DoProperties(hWnd, 0);
  80. break;
  81. /*
  82. * This function requires Windows 2000. Not available on Win9x.
  83. */
  84. case CPL_STARTWPARMS:
  85. // Same as CPL_DBLCLK, but lParam2 is a long pointer to
  86. // a string of extra directions that are to be supplied to
  87. // the property sheet that is to be initiated.
  88. // The arguments are as follows:
  89. // @nCPLDialog Index, nStartPageCPL, nStartPageDef
  90. // Don't do anything if there are no arguments!
  91. if( *(LPTSTR)lParam2 )
  92. ParseArgs(hWnd, (LPTSTR)lParam2);
  93. return(TRUE); // return non-zero to indicate message handled
  94. case CPL_EXIT:
  95. case CPL_STOP:
  96. break;
  97. }
  98. return(0);
  99. }
  100. /*
  101. Function: DoProperties(HWND hWnd, UINT nStartPage)
  102. Arguements: hWnd - Handle to Main Window
  103. nStartPage - Page number to start
  104. */
  105. static void DoProperties(HWND hWnd, UINT nStartPage)
  106. {
  107. static HWND hPrevHwnd;
  108. static HANDLE hMutex = CreateMutex(NULL, TRUE, MUTEX_NAME);
  109. if( GetLastError() == ERROR_ALREADY_EXISTS )
  110. {
  111. SetForegroundWindow(hPrevHwnd);
  112. } else
  113. {
  114. hPrevHwnd = hWnd;
  115. nFlags = (GetVersion() < 0x80000000) ? ON_NT : 0;
  116. HPROPSHEETPAGE *pPages = new (HPROPSHEETPAGE[MAX_CPL_PAGES]);
  117. ASSERT (pPages);
  118. LPPROPSHEETHEADER ppsh = new (PROPSHEETHEADER);
  119. ASSERT(ppsh);
  120. ZeroMemory(ppsh, sizeof(PROPSHEETHEADER));
  121. ppsh->dwSize = sizeof(PROPSHEETHEADER);
  122. ppsh->dwFlags = PSH_NOAPPLYNOW | PSH_USEICONID;
  123. ppsh->hwndParent = hWnd;
  124. ppsh->hInstance = ghInstance;
  125. ppsh->pszCaption = MAKEINTRESOURCE(IDS_GEN_CPANEL_TITLE);
  126. ppsh->pszIcon = MAKEINTRESOURCE(IDI_CPANEL);
  127. ppsh->nStartPage = nStartPage;
  128. ppsh->phpage = pPages;
  129. AddPage(ppsh, IDD_CPANEL, IDS_GENERAL_TAB, (DLGPROC)CPanelProc);
  130. AddPage(ppsh, IDD_ADVANCED, IDS_ADVANCED_TAB, (DLGPROC)AdvancedProc);
  131. if( SUCCEEDED ( DVoiceCPLInit() )) {
  132. AddPage(ppsh, IDD_PROP_RETROFIT, IDS_DVOICE_TAB, (DLGPROC) RetrofitProc);
  133. }
  134. // if( SUCCEEDED ( AppManInit() ) ) {
  135. // AddPage(ppsh, IDD_APPMAN, IDS_APPMAN_TAB, (DLGPROC)AppManProc);
  136. // AddPage(ppsh, IDD_APPMAN_LOCKING, IDS_APPMANLOCK_TAB, (DLGPROC) AppManLockProc);
  137. // }
  138. #ifdef SYMANTIC_MAPPER
  139. AddPage(ppsh, IDD_SMAPPER, ID_SMAPPER_TAB, (DLGPROC)SMapperProc);
  140. #endif // SYMANTIC_MAPPER
  141. // trap for return...
  142. VERIFY(PropertySheet(ppsh) != -1);
  143. if( pPages )
  144. delete[] (pPages);
  145. if( ppsh )
  146. delete (ppsh);
  147. ReleaseMutex(hMutex);
  148. CloseHandle(hMutex);
  149. // Ensure voice is always cleaned up
  150. RetrofitDestroyHandler( NULL, 0, 0, 0 );
  151. ClearArrays();
  152. }
  153. }
  154. static void AddPage(LPPROPSHEETHEADER ppsh, short nTemplateID, int nTabID, DLGPROC pfn)
  155. {
  156. if( ppsh->nPages < MAX_CPL_PAGES )
  157. {
  158. LPPROPSHEETPAGE ppsp = new (PROPSHEETPAGE);
  159. ASSERT(ppsp);
  160. ZeroMemory(ppsp, sizeof(PROPSHEETPAGE));
  161. ppsp->dwSize = sizeof(PROPSHEETPAGE);
  162. ppsp->pszTitle = MAKEINTRESOURCE(nTabID);
  163. ppsp->hInstance = ghInstance;
  164. ppsp->pfnDlgProc = pfn;
  165. ppsp->pszTemplate = MAKEINTRESOURCE(nTemplateID);
  166. ppsh->phpage[ppsh->nPages] = CreatePropertySheetPage(ppsp);
  167. if( ppsp )
  168. delete (ppsp);
  169. if( ppsh->phpage[ppsh->nPages] )
  170. ppsh->nPages++;
  171. }
  172. } // AddPage
  173. // DO NOT REMOVE THIS!!!
  174. // This is here because the games group loads the CPL from the exported function
  175. // If you remove this Hellbender, Monster Truck Maddness, CART, etc will fail to
  176. // load the Joystick CPL!!!
  177. // DO NOT REMOVE THIS!!!
  178. void WINAPI ShowJoyCPL(HWND hWnd)
  179. {
  180. nID = (NUMJOYDEVS<<1);
  181. DoProperties(hWnd, 0);
  182. }
  183. void LaunchExtention(HWND hWnd)
  184. {
  185. // These are defined in CPANEL.CPP
  186. extern LPDIRECTINPUT lpDIInterface;
  187. extern IDirectInputJoyConfig* pDIJoyConfig;
  188. HRESULT hr = DirectInputCreate(ghInstance, DIRECTINPUT_VERSION, &lpDIInterface, NULL);
  189. if( FAILED(hr) ) return;
  190. // Call CreateJoyConfigInterface!
  191. if( SUCCEEDED(lpDIInterface->QueryInterface(IID_IDirectInputJoyConfig, (LPVOID*)&pDIJoyConfig)) )
  192. {
  193. // Create a pJoy and populate it's GUID from GetTypeInfo
  194. PJOY pJoy = new (JOY);
  195. ASSERT (pJoy);
  196. pJoy->ID = nID;
  197. DIJOYCONFIG_DX5 JoyConfig;
  198. JoyConfig.dwSize = sizeof (DIJOYCONFIG_DX5);
  199. if( SUCCEEDED(pDIJoyConfig->GetConfig(nID, (LPDIJOYCONFIG)&JoyConfig, DIJC_REGHWCONFIGTYPE)) )
  200. {
  201. LPDIJOYTYPEINFO_DX5 pdiJoyTypeInfo = new (DIJOYTYPEINFO_DX5);
  202. ASSERT (pdiJoyTypeInfo);
  203. pdiJoyTypeInfo->dwSize = sizeof (DIJOYTYPEINFO_DX5);
  204. hr = pDIJoyConfig->GetTypeInfo(JoyConfig.wszType, (LPDIJOYTYPEINFO)pdiJoyTypeInfo, DITC_CLSIDCONFIG);
  205. if( !IsEqualIID(pdiJoyTypeInfo->clsidConfig, GUID_NULL) )
  206. pJoy->clsidPropSheet = pdiJoyTypeInfo->clsidConfig;
  207. if( pdiJoyTypeInfo )
  208. delete (pdiJoyTypeInfo);
  209. }
  210. if( SUCCEEDED(hr) )
  211. Launch(hWnd, pJoy, nStartPageDef);
  212. if( pJoy )
  213. delete (pJoy);
  214. // release the DI JoyConfig interface pointer
  215. if( pDIJoyConfig )
  216. {
  217. pDIJoyConfig->Release();
  218. pDIJoyConfig = 0;
  219. }
  220. }
  221. // release the DI Device interface pointer
  222. if( lpDIInterface )
  223. {
  224. lpDIInterface->Release();
  225. lpDIInterface = 0;
  226. }
  227. }
  228. void ParseArgs(HWND hDlg, LPTSTR lpArgList)
  229. {
  230. BOOL bShowCPL = TRUE;
  231. // Check for '-', as they may not want to show the CPL!
  232. if( *lpArgList == '-' )
  233. {
  234. bShowCPL = FALSE;
  235. *lpArgList++;
  236. }
  237. nStartPageCPL = nStartPageCPL = nStartPageDef = 0;
  238. // parse command line for nStartPageCPL!
  239. while( *lpArgList && (*lpArgList != ',') )
  240. {
  241. nStartPageCPL *= 10;
  242. nStartPageCPL += *lpArgList++ - '0';
  243. }
  244. // check to make sure nStartPageCPL is within range!
  245. if( bShowCPL ) {
  246. if( nStartPageCPL > MAX_CPL_PAGES )
  247. {
  248. #ifdef _DEBUG
  249. OutputDebugString(TEXT("JOY.CPL: Command line requested an invalid start page, reset to default!\n"));
  250. #endif
  251. // NUMJOYDEVS is used to send the user to the Add dialog on start-up!
  252. if( nStartPageCPL != NUMJOYDEVS )
  253. nStartPageCPL = 0;
  254. }
  255. }
  256. // Only continue if you have something further to parse!
  257. if( *lpArgList == ',' )
  258. {
  259. *lpArgList++;
  260. nID = 0;
  261. // Parse for ID's
  262. while( *lpArgList && (*lpArgList != ',') )
  263. {
  264. nID *= 10;
  265. nID += *lpArgList++ - '0';
  266. }
  267. // Check for error cases!
  268. if( (nID < 1) || (nID > NUMJOYDEVS) )
  269. {
  270. #ifdef _DEBUG
  271. OutputDebugString(TEXT("JOY.CPL: Command line Device ID out of range!\n"));
  272. #endif
  273. nID = (NUMJOYDEVS<<1);
  274. return;
  275. }
  276. // Decrement to internal zero based ID
  277. nID--;
  278. // Don't parse what you don't have!
  279. if( *lpArgList == ',' )
  280. {
  281. *lpArgList++;
  282. // Lastly, parse for nStartPageDef!
  283. while( *lpArgList && (*lpArgList != ',') )
  284. {
  285. nStartPageDef *= 10;
  286. nStartPageDef += *lpArgList++ - '0';
  287. }
  288. }
  289. } else {
  290. nID = (NUMJOYDEVS<<1);
  291. }
  292. // Done with the parsing...
  293. // Time to get to work!
  294. // if we're not showing the CPL...
  295. if( !bShowCPL )
  296. {
  297. // check to make sure the next value is a 1
  298. // we may want to have further negative arguments :)
  299. switch( nStartPageCPL )
  300. {
  301. case 1:
  302. // Invalid ID...
  303. if( nID > NUMJOYDEVS ) return;
  304. LaunchExtention(hDlg);
  305. break;
  306. #ifdef WE_CAN_HAVE_CREDITS
  307. case 60:
  308. // If they ask for the splash, they don't get the CPL!
  309. DialogBox( ghInstance, (PTSTR)IDD_SPLASH, hDlg, (DLGPROC)SplashDialogProc );
  310. break;
  311. #endif
  312. }
  313. } else {
  314. DoProperties(NULL, nStartPageCPL);
  315. }
  316. }
  317. #ifdef WE_CAN_HAVE_CREDITS
  318. BOOL WINAPI SplashDialogProc(HWND hDlg, ULONG uMsg, WPARAM wParam, LPARAM lParam)
  319. {
  320. static CCreditStatic *pStatic;
  321. switch( uMsg )
  322. {
  323. case WM_INITDIALOG:
  324. {
  325. pStatic = new (CCreditStatic);
  326. ASSERT (pStatic);
  327. CWnd *pCWnd = new (CWnd);
  328. ASSERT (pCWnd);
  329. pCWnd->Attach(hDlg);
  330. pStatic->SubclassDlgItem(IDC_MYSTATIC, pCWnd);
  331. if( pCWnd )
  332. {
  333. pCWnd->Detach();
  334. delete (pCWnd);
  335. pCWnd = 0;
  336. }
  337. LPTSTR lpStr = new (TCHAR[MAX_STR_LEN]);
  338. ASSERT (lpStr);
  339. // The Credits come in two lines!
  340. BYTE nStrLen = (BYTE)LoadString(ghInstance, IDS_SPLASH, lpStr, MAX_STR_LEN);
  341. LoadString(ghInstance, IDS_SPLASH1, &lpStr[nStrLen], MAX_STR_LEN-nStrLen);
  342. pStatic->SetCredits(lpStr);
  343. if( lpStr )
  344. {
  345. delete[] (lpStr);
  346. lpStr = 0;
  347. }
  348. pStatic->StartScrolling();
  349. }
  350. return(TRUE); // return TRUE unless you set the focus to a control
  351. // EXCEPTION: OCX Property Pages should return FALSE}
  352. case WM_COMMAND:
  353. switch( LOWORD(wParam) )
  354. {
  355. case IDOK:
  356. EndDialog(hDlg, LOWORD(wParam));
  357. break;
  358. }
  359. break;
  360. // case WM_TIMER:
  361. //SendDlgItemMessage(hDlg, IDC_STATIC, WM_TIMER, 0, 0);
  362. // pStatic->OnTimer(150); //DISPLAY_TIMER_ID
  363. // break;
  364. case WM_DESTROY:
  365. if( pStatic )
  366. {
  367. delete (pStatic);
  368. pStatic = 0;
  369. }
  370. break;
  371. }
  372. return(0);
  373. }
  374. #endif