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.

530 lines
13 KiB

  1. //****************************************************************************
  2. //
  3. // File: joytest.c
  4. // Content: Joystick test dialog
  5. // History:
  6. // Date By Reason
  7. // ==== == ======
  8. // 11-dec-94 craige split out of joycpl.c; some tweaks
  9. // 15-dec-94 craige allow N joysticks
  10. // 4/2/97 a-kirkh allow N buttons
  11. //
  12. // Copyright (c) Microsoft Corporation 1994-1995
  13. //
  14. //****************************************************************************
  15. #include "stdafx.h"
  16. #include "pov.h"
  17. #include "assert.h"
  18. #include "joycpl.h"
  19. #include "resource.h"
  20. #include "joyarray.h" // Help array
  21. #include "baseids.h"
  22. #include "comstr.h"
  23. LRESULT SetJoyInfo(UINT nID, LPCSTR szOEMKey);
  24. // ADDED BY CML 2/20/96
  25. LPGLOBALVARS gpgv;
  26. BOOL fIsSideWinder = FALSE;
  27. // END ADD
  28. // Context sensitive help stuff!
  29. static void OnContextMenu(WPARAM wParam);
  30. extern const DWORD gaHelpIDs[];
  31. extern USHORT gnID; // ID as sent from Client via SetID
  32. /*
  33. * variables used by test process
  34. */
  35. typedef struct
  36. {
  37. LPGLOBALVARS pgv;
  38. MMRESULT mmr_capture;
  39. HWND hwnd;
  40. BOOL bHasTimer;
  41. BOOL bUseTimer;
  42. int iButtonShift;
  43. JOYINFOEX ji;
  44. } test_vars, *LPTESTVARS;
  45. /*
  46. * fillButton - light up a specific button
  47. */
  48. static void fillButton( LPGLOBALVARS pgv, HWND hwnd, int id, BOOL isup )
  49. {
  50. HWND hwb;
  51. RECT r;
  52. HDC hdc;
  53. assert(pgv);
  54. assert(hwnd);
  55. hwb = GetDlgItem( hwnd, id );
  56. ASSERT (::IsWindow(hwb));
  57. if( hwb == NULL )
  58. {
  59. return;
  60. }
  61. hdc = GetDC( hwb );
  62. if( hdc == NULL )
  63. {
  64. return;
  65. }
  66. GetClientRect( hwb, &r );
  67. if( isup )
  68. {
  69. FillRect( hdc, &r, pgv->pjd->hbUp );
  70. } else
  71. {
  72. FillRect( hdc, &r, pgv->pjd->hbDown );
  73. }
  74. ReleaseDC( hwb, hdc );
  75. } /* fillButton */
  76. // doTestButton - try to light the relevant buttons
  77. static void doTestButton( LPTESTVARS ptv, HWND hwnd, LPJOYINFOEX pji )
  78. {
  79. assert(ptv);
  80. assert(pji);
  81. // ADDED BY CML 2/21/96
  82. if( ptv->ji.dwButtons != pji->dwButtons )
  83. {
  84. BYTE nIndex;
  85. HWND hCtrl;
  86. HICON hIconOn, hIconOff;
  87. UINT nButtons = ptv->pgv->joyHWCurr.hws.dwNumButtons;
  88. for( BYTE i=0; i<nButtons; i++ )
  89. {
  90. nIndex = i << 1;
  91. hIconOn = LoadIcon(GetWindowInstance(hwnd), (PSTR)IDI_BUTTON1OFF+nIndex);
  92. hIconOff = LoadIcon(GetWindowInstance(hwnd), (PSTR)IDI_BUTTON1OFF+(nIndex+1));
  93. hCtrl = GetDlgItem(hwnd, IDC_TESTJOYBTNICON1+i);
  94. ASSERT (::IsWindow(hCtrl));
  95. Static_SetIcon(hCtrl, (pji->dwButtons & 1<<i) ? hIconOn : hIconOff);
  96. }
  97. }
  98. ptv->ji.dwButtons = pji->dwButtons;
  99. // END ADD
  100. } /* doTestButton */
  101. // doTestPOV - try to light the POV indicators
  102. static void doTestPOV( LPTESTVARS ptv, HWND hwnd, LPJOYINFOEX pji )
  103. {
  104. assert(ptv);
  105. assert(hwnd);
  106. assert(pji);
  107. if( ptv->ji.dwPOV != pji->dwPOV )
  108. {
  109. if( pji->dwPOV != JOY_POVCENTERED )
  110. SetDegrees(pji->dwPOV);
  111. else
  112. SetDegrees(-1);
  113. ptv->ji.dwPOV = pji->dwPOV;
  114. }
  115. } /* doTestPOV */
  116. /*
  117. * joyTestInitDialog - init the testing dialog
  118. */
  119. static BOOL joyTestInitDialog( HWND hwnd, LPARAM lParam)
  120. {
  121. HINSTANCE hinst;
  122. LPJOYREGHWCONFIG pcfg;
  123. LPTESTVARS ptv = NULL;
  124. LPGLOBALVARS pgv = NULL;
  125. UINT i; // ADDED BY CML 2/21/96
  126. assert(hwnd);
  127. hinst = GetResourceInstance();
  128. assert(hinst);
  129. // create test vars
  130. ptv = (test_vars *)DoAlloc( sizeof( test_vars ) );
  131. assert(ptv);
  132. SetWindowLong( hwnd, DWL_USER, (LONG) ptv );
  133. if( ptv == NULL )
  134. return(FALSE);
  135. pgv = gpgv;
  136. assert(pgv);
  137. ptv->pgv = pgv;
  138. ptv->hwnd = hwnd;
  139. // ADDED BY CML 2/21/96
  140. // set default POV icon image
  141. /*
  142. if (fIsSideWinder)
  143. {
  144. HICON hicon; //, holdicon;
  145. hicon = (struct HICON__ *) LoadImage(
  146. GetWindowInstance(hwnd),
  147. (PSTR)IDI_POV_OFF,
  148. IMAGE_ICON,
  149. 48, 48, 0);
  150. assert(hicon);
  151. // if (hicon)
  152. // {
  153. // HWND hCtrl = GetDlgItem(hwnd,IDC_JOYPOV);
  154. // ASSERT (::IsWindow(hCtrl));
  155. //
  156. // holdicon = Static_SetIcon(hCtrl, hicon);
  157. // if (holdicon) DestroyIcon(holdicon);
  158. // }
  159. }
  160. else
  161. {
  162. HICON hicon, holdicon;
  163. hicon = LoadIcon(GetWindowInstance(hwnd), (PSTR)IDI_JOYPOV_NONE);
  164. assert(hicon);
  165. if (hicon)
  166. {
  167. HWND hCtrl = GetDlgItem(hwnd,IDC_JOYPOV);
  168. ASSERT (::IsWindow(hCtrl));
  169. holdicon = Static_SetIcon(hCtrl, hicon);
  170. if (holdicon) DestroyIcon(holdicon);
  171. }
  172. }
  173. */
  174. // END ADD
  175. // set dialog text based on OEM strings
  176. SetOEMText( pgv, hwnd, TRUE );
  177. /*
  178. * customize test dialog's button display
  179. */
  180. pcfg = &pgv->joyHWCurr;
  181. assert(pcfg);
  182. if( pcfg->hws.dwNumButtons <= 2 )
  183. {
  184. ptv->iButtonShift = 1;
  185. // HWND hCtrl = GetDlgItem( hwnd, IDC_JOYB1 );
  186. // ASSERT (::IsWindow(hCtrl));
  187. // ShowWindow( hCtrl, SW_HIDE );
  188. // hCtrl = GetDlgItem( hwnd, IDC_JOYB4 );
  189. // ASSERT (::IsWindow(hCtrl));
  190. // ShowWindow( hCtrl, SW_HIDE );
  191. // hCtrl = GetDlgItem( hwnd, IDC_JOYB1_LABEL );
  192. // ASSERT (::IsWindow(hCtrl));
  193. // ShowWindow( hCtrl, SW_HIDE );
  194. // hCtrl = GetDlgItem( hwnd, IDC_JOYB4_LABEL );
  195. // ASSERT (::IsWindow(hCtrl));
  196. // ShowWindow( hCtrl, SW_HIDE );
  197. } else
  198. {
  199. ptv->iButtonShift = 0;
  200. }
  201. // ADDED BY CML 10/23/96
  202. // size and position the text
  203. /* There is no text on the buttons anymore!
  204. for (i=0; i<8; i++)
  205. {
  206. // HWND hText = GetDlgItem(hwnd, IDC_TEXT_JOYBTN1+i);
  207. // ASSERT (::IsWindow(hText));
  208. HWND hIcon = GetDlgItem(hwnd, IDC_TESTJOYBTNICON1+i);
  209. ASSERT (::IsWindow(hIcon));
  210. RECT rcIcon, rcText;
  211. GetWindowRect(hIcon, &rcIcon);
  212. GetWindowRect(hText, &rcText);
  213. rcText.left = rcIcon.left;
  214. rcText.right = rcIcon.right;
  215. MapWindowPoints(0, hwnd, (POINT*)&rcText, 2);
  216. MoveWindow(
  217. hText,
  218. rcText.left, rcText.top,
  219. rcText.right-rcText.left, rcText.bottom-rcText.top,
  220. FALSE);
  221. }
  222. */
  223. // END ADD
  224. // ADDED BY CML 2/21/96
  225. // display button lights
  226. // ADDED BY JKH 3/29/97
  227. // MORE BUTTONS SUPPORTED
  228. HWND hCtrl;
  229. for( i=pcfg->hws.dwNumButtons; i<32; i++ )
  230. {
  231. hCtrl = GetDlgItem(hwnd, IDC_TESTJOYBTNICON1+i);
  232. ASSERT (::IsWindow(hCtrl));
  233. ShowWindow(hCtrl, SW_HIDE);
  234. }
  235. // END ADD
  236. ShowControls( pcfg, hwnd );
  237. /*
  238. * other misc setup
  239. */
  240. ptv->bHasTimer = SetTimer( hwnd, TIMER_ID, JOYPOLLTIME, NULL );
  241. ptv->bUseTimer = TRUE;
  242. if( !ptv->bHasTimer )
  243. {
  244. DPF( "No timer for joystick test!\r\n" );
  245. return(FALSE);
  246. }
  247. return(TRUE);
  248. } /* joyTestInitDialog */
  249. // TestProc - callback procedure for joystick test dialog
  250. BOOL CALLBACK TestProc( HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam)
  251. {
  252. BOOL rc;
  253. assert(hwnd);
  254. switch( umsg )
  255. {
  256. case WM_HELP:
  257. OnHelp(lParam);
  258. return(1);
  259. case WM_CONTEXTMENU:
  260. OnContextMenu(wParam);
  261. return(1);
  262. case WM_TIMER:
  263. {
  264. LPTESTVARS ptv = (LPTESTVARS) GetWindowLong( hwnd, DWL_USER );
  265. assert(ptv);
  266. if( ptv->bUseTimer )
  267. {
  268. JOYINFOEX ji;
  269. MMRESULT rc;
  270. ptv->bUseTimer = FALSE;
  271. ji.dwSize = sizeof( ji );
  272. ji.dwFlags = JOY_RETURNALL | JOY_RETURNCENTERED | JOY_CAL_READALWAYS;
  273. rc = joyGetPosEx( ptv->pgv->iJoyId, &ji );
  274. // ADDED BY CML 11/13/96
  275. // if this page is for sw3dpro, check for sw3dpro still active
  276. if( fIsSideWinder && rc==JOYERR_NOERROR )
  277. {
  278. char sz[256];
  279. char szValue[64];
  280. DWORD cb = sizeof(szValue);
  281. HKEY hKey;
  282. JOYCAPS jc;
  283. LRESULT lr;
  284. // open reg key for device type // JOYSTICKID1
  285. joyGetDevCaps( ptv->pgv->iJoyId, &jc, sizeof(jc));
  286. wsprintf(
  287. sz, "%s\\%s\\%s",
  288. REGSTR_PATH_JOYCONFIG,
  289. jc.szRegKey,
  290. REGSTR_KEY_JOYCURR);
  291. lr = RegOpenKey(HKEY_LOCAL_MACHINE, sz, &hKey);
  292. wsprintf(sz, REGSTR_VAL_JOYNOEMNAME, 1);
  293. lr = RegQueryValueEx(hKey, sz, 0, 0, (BYTE*)szValue, &cb);
  294. RegCloseKey(hKey);
  295. // is the sw3dpro still connected and not some other device?
  296. if( strcmp(szValue, "Microsoft SideWinder 3D Pro") )
  297. // wrong device
  298. rc = JOYERR_UNPLUGGED;
  299. }
  300. // END ADD
  301. if( rc == JOYERR_NOERROR )
  302. {
  303. DoJoyMove( ptv->pgv, hwnd, &ji, &ptv->ji, JOYMOVE_DRAWALL );
  304. doTestButton( ptv, hwnd, &ji );
  305. doTestPOV( ptv, hwnd, &ji );
  306. ptv->bUseTimer = TRUE;
  307. } else
  308. {
  309. if( JoyError( hwnd ) )
  310. ptv->bUseTimer = TRUE;
  311. }
  312. }
  313. }
  314. break;
  315. case WM_DESTROY:
  316. {
  317. LPTESTVARS ptv;
  318. ptv = (LPTESTVARS) GetWindowLong( hwnd, DWL_USER );
  319. assert(ptv);
  320. DoFree( ptv );
  321. // ADDED BY CML 2/20/96
  322. //RegSaveCurrentJoyHW(gpgv);
  323. RegistryUpdated(gpgv);
  324. // END ADD
  325. break;
  326. }
  327. case WM_INITDIALOG:
  328. {
  329. LRESULT lr=SetJoyInfo( 0, "" );
  330. ASSERT(lr==ERROR_SUCCESS);
  331. // blj: fix #8049, Set ID to ID of device assigned to property sheet.
  332. gpgv->iJoyId = gnID;
  333. // ADDED BY CML 2/20/96
  334. RegSaveCurrentJoyHW(gpgv);
  335. RegistryUpdated(gpgv);
  336. // END ADD
  337. rc = joyTestInitDialog( hwnd, lParam );
  338. if( !rc )
  339. EndDialog( hwnd, 0 );
  340. }
  341. return(FALSE);
  342. // ADDED BY CML 2/21/96
  343. case WM_NOTIFY:
  344. switch( ((NMHDR*)lParam)->code )
  345. {
  346. case PSN_SETACTIVE:
  347. {
  348. LPTESTVARS ptv = (LPTESTVARS)GetWindowLong(hwnd, DWL_USER);
  349. assert(ptv);
  350. ptv->bUseTimer = 1;
  351. joyTestInitDialog(hwnd, 0);
  352. }
  353. break;
  354. // ADDED CML 6/27/96
  355. case PSN_KILLACTIVE:
  356. KillTimer(hwnd, TIMER_ID);
  357. break;
  358. // END ADD 6/27/96
  359. }
  360. return(1);
  361. // END ADD 2/21/96
  362. case WM_PAINT:
  363. {
  364. LPTESTVARS ptv;
  365. ptv = (LPTESTVARS) GetWindowLong( hwnd, DWL_USER );
  366. assert(ptv);
  367. CauseRedraw( &ptv->ji, TRUE );
  368. return(FALSE);
  369. }
  370. case WM_COMMAND:
  371. {
  372. int id;
  373. LPTESTVARS ptv;
  374. ptv = (LPTESTVARS) GetWindowLong( hwnd, DWL_USER );
  375. assert(ptv);
  376. id = GET_WM_COMMAND_ID(wParam, lParam);
  377. switch( id )
  378. {
  379. case IDCANCEL:
  380. case IDOK:
  381. if( ptv->bHasTimer )
  382. {
  383. KillTimer( hwnd, TIMER_ID );
  384. }
  385. EndDialog(hwnd, (id == IDOK));
  386. break;
  387. default:
  388. break;
  389. }
  390. break;
  391. }
  392. default:
  393. break;
  394. }
  395. return(FALSE);
  396. } /* TestProc */
  397. // DoTest - do the test dialog
  398. void DoTest( LPGLOBALVARS pgv, HWND hwnd, LPUPDCFGFN pupdcfgfn, LPVOID pparm )
  399. {
  400. JOYREGHWCONFIG save_joycfg;
  401. int id;
  402. /*
  403. * save the current config, and then update config if required
  404. */
  405. save_joycfg = pgv->joyHWCurr;
  406. if( pupdcfgfn != NULL )
  407. {
  408. pupdcfgfn( pparm );
  409. }
  410. /*
  411. * update the registry with our new joystick info
  412. */
  413. RegSaveCurrentJoyHW( pgv );
  414. RegistryUpdated( pgv );
  415. /*
  416. * process the test dialog
  417. */
  418. if( pgv->joyHWCurr.hws.dwFlags & (JOY_HWS_HASU|JOY_HWS_HASV) )
  419. {
  420. id = IDD_JOYTEST1;
  421. } else
  422. {
  423. id = IDD_JOYTEST;
  424. }
  425. HINSTANCE hResInst = GetResourceInstance();
  426. DialogBoxParam( hResInst,
  427. MAKEINTRESOURCE( id ), hwnd, (int (__stdcall *)(struct HWND__ *,unsigned int,unsigned int,long))TestProc, (LONG) pgv );
  428. /*
  429. * restore the old registry info
  430. */
  431. pgv->joyHWCurr = save_joycfg;
  432. //RegSaveCurrentJoyHW( pgv );
  433. RegistryUpdated( pgv );
  434. } /* DoTest */
  435. ////////////////////////////////////////////////////////////////////////////////////////
  436. // OnContextMenu(WPARAM wParam)
  437. ////////////////////////////////////////////////////////////////////////////////////////
  438. void OnContextMenu(WPARAM wParam)
  439. {
  440. short nSize = STR_LEN_32;
  441. // point to help file
  442. char *pszHelpFileName = new char[nSize];
  443. ASSERT (pszHelpFileName);
  444. // returns help file name and size of string
  445. GetHelpFileName(pszHelpFileName, &nSize);
  446. WinHelp((HWND)wParam, pszHelpFileName, HELP_CONTEXTMENU, (DWORD)gaHelpIDs);
  447. if( pszHelpFileName ) delete[] (pszHelpFileName);
  448. }