Leaked source code of windows server 2003
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.

704 lines
18 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: property.cpp
  3. *
  4. * Support for the mpeg video and audio decoder property pages.
  5. *
  6. *
  7. * Created: 24-01-96
  8. * Author: Stephen Estrop [StephenE]
  9. *
  10. * Copyright (c) 1996 - 1998 Microsoft Corporation. All Rights Reserved.
  11. \**************************************************************************/
  12. #include <streams.h>
  13. #include <mmreg.h>
  14. #include <commctrl.h>
  15. #include "project.h"
  16. #include "mpgcodec.h"
  17. #include <stdarg.h>
  18. #include <stdio.h>
  19. extern HINSTANCE hInst;
  20. extern HWND hwndApp;
  21. extern CMpegMovie *pMpegMovie;
  22. extern "C" {
  23. INT_PTR CALLBACK
  24. VideoStatsDialogProc(
  25. HWND hwnd,
  26. UINT uMsg,
  27. WPARAM wParam,
  28. LPARAM lParam
  29. );
  30. INT_PTR CALLBACK
  31. VideoDialogProc(
  32. HWND hwnd,
  33. UINT uMsg,
  34. WPARAM wParam,
  35. LPARAM lParam
  36. );
  37. INT_PTR CALLBACK
  38. AudioDialogProc(
  39. HWND hwnd,
  40. UINT uMsg,
  41. WPARAM wParam,
  42. LPARAM lParam
  43. );
  44. }
  45. void
  46. UpdateStats(
  47. HWND hwnd
  48. );
  49. TCHAR *
  50. StringFromId(
  51. int idResource
  52. );
  53. void
  54. SetDecoderOption(
  55. HWND m_hwnd,
  56. DWORD dwOptions
  57. );
  58. DWORD
  59. GetDecoderOption(
  60. HWND m_hwnd
  61. );
  62. void
  63. GetButtonValues(
  64. HWND m_hwnd,
  65. LPDWORD iChannels,
  66. LPDWORD iSkip,
  67. LPDWORD iQuality,
  68. LPDWORD iInteger,
  69. LPDWORD iOutputWordSize
  70. );
  71. void
  72. SetButtonValues(
  73. HWND m_hwnd,
  74. DWORD iChannels,
  75. DWORD iSkip,
  76. DWORD iQuality,
  77. DWORD iInteger,
  78. DWORD iOutputWordSize
  79. );
  80. void
  81. PutDecoderInteger(
  82. const TCHAR *pKey,
  83. int iValue
  84. );
  85. /* -------------------------------------------------------------------------
  86. ** Decoder strings
  87. ** -------------------------------------------------------------------------
  88. */
  89. const TCHAR chVideoFramesDecoded[] = TEXT("VideoFramesDecoded");
  90. const TCHAR chVideoQuality[] = TEXT("VideoQuality");
  91. const TCHAR chGreyScale[] = TEXT("GreyScale");
  92. const TCHAR chIgnoreQMessages[] = TEXT("IgnoreQMessages");
  93. const TCHAR chAudioChannels[] = TEXT("AudioChannels");
  94. const TCHAR chAudioFreqDivider[] = TEXT("AudioFreqDivider");
  95. const TCHAR chAudioQuality[] = TEXT("AudioQuality");
  96. const TCHAR chAudioQuarterInt[] = TEXT("AudioQuarterInt");
  97. const TCHAR chAudioBits[] = TEXT("AudioBits");
  98. const TCHAR chRegistryKey[] = TEXT("Software\\Microsoft\\Multimedia\\ActiveMovie Filters\\MPEG Decoder");
  99. /******************************Public*Routine******************************\
  100. * DoMpegVideoPropertyPage
  101. *
  102. *
  103. *
  104. * History:
  105. * 24-01-96 - StephenE - Created
  106. *
  107. \**************************************************************************/
  108. void
  109. DoMpegVideoPropertyPage()
  110. {
  111. DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_VIDEOPROP),
  112. hwndApp, VideoDialogProc, (LPARAM)NULL);
  113. }
  114. /******************************Public*Routine******************************\
  115. * DoMpegAudioPropertyPage
  116. *
  117. *
  118. *
  119. * History:
  120. * 24-01-96 - StephenE - Created
  121. *
  122. \**************************************************************************/
  123. void
  124. DoMpegAudioPropertyPage()
  125. {
  126. DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_AUDIOPROP),
  127. hwndApp, AudioDialogProc, (LPARAM)NULL);
  128. }
  129. /******************************Public*Routine******************************\
  130. * VideoDialogProc
  131. *
  132. * Handles the messages for our property window
  133. *
  134. * History:
  135. * 27-09-95 - StephenE - Created
  136. *
  137. \**************************************************************************/
  138. INT_PTR CALLBACK
  139. VideoDialogProc(
  140. HWND hwnd,
  141. UINT uMsg,
  142. WPARAM wParam,
  143. LPARAM lParam
  144. )
  145. {
  146. DWORD m_dwDecoderOptions;
  147. BOOL m_fQualityOption;
  148. BOOL m_fGreyScaleOption;
  149. switch (uMsg) {
  150. case WM_INITDIALOG:
  151. pMpegMovie->pMpegDecoder->get_DefaultDecoderOption(&m_dwDecoderOptions);
  152. pMpegMovie->pMpegDecoder->get_QualityMsgProcessing(&m_fQualityOption);
  153. pMpegMovie->pMpegDecoder->get_GreyScaleOutput(&m_fGreyScaleOption);
  154. SetDecoderOption(hwnd, m_dwDecoderOptions);
  155. Button_SetCheck(GetDlgItem(hwnd, B_GREY), m_fGreyScaleOption);
  156. Button_SetCheck(GetDlgItem(hwnd, IGNORE_QUALITY), m_fQualityOption);
  157. return TRUE;
  158. case WM_COMMAND:
  159. switch (LOWORD(wParam)) {
  160. case IDCANCEL:
  161. EndDialog(hwnd, wParam);
  162. break;
  163. case IDOK:
  164. m_dwDecoderOptions = GetDecoderOption(hwnd);
  165. m_fQualityOption = Button_GetCheck(GetDlgItem(hwnd, IGNORE_QUALITY));
  166. m_fGreyScaleOption = Button_GetCheck(GetDlgItem(hwnd, B_GREY));
  167. pMpegMovie->pMpegDecoder->set_DefaultDecoderOption(m_dwDecoderOptions);
  168. pMpegMovie->pMpegDecoder->set_QualityMsgProcessing(m_fQualityOption);
  169. pMpegMovie->pMpegDecoder->set_GreyScaleOutput(m_fGreyScaleOption);
  170. EndDialog(hwnd, wParam);
  171. break;
  172. case STATS_BUTTON:
  173. DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_VIDEOSTATS),
  174. hwnd, VideoStatsDialogProc, (LPARAM)NULL);
  175. break;
  176. case ID_DEFAULT:
  177. m_dwDecoderOptions = GetDecoderOption(hwnd);
  178. PutDecoderInteger(chVideoFramesDecoded, m_dwDecoderOptions & 0x3F);
  179. PutDecoderInteger(chVideoQuality, m_dwDecoderOptions & 0x30000000);
  180. PutDecoderInteger(chGreyScale,
  181. Button_GetCheck(GetDlgItem(hwnd, B_GREY)));
  182. PutDecoderInteger(chIgnoreQMessages,
  183. Button_GetCheck(GetDlgItem(hwnd, IGNORE_QUALITY)));
  184. break;
  185. }
  186. return TRUE;
  187. default:
  188. return FALSE;
  189. }
  190. }
  191. /*****************************Private*Routine******************************\
  192. * SetDecoderOption
  193. *
  194. * This function puts the buttons on the property page into the state that
  195. * corresponds to the passed in dwOptions parameter.
  196. *
  197. * History:
  198. * 27-09-95 - StephenE - Created
  199. *
  200. \**************************************************************************/
  201. void
  202. SetDecoderOption(
  203. HWND m_hwnd,
  204. DWORD dwOptions
  205. )
  206. {
  207. switch (dwOptions & 0x0FFFFFFF) {
  208. case DECODE_I:
  209. Button_SetCheck(GetDlgItem(m_hwnd, I_ONLY), TRUE );
  210. break;
  211. case DECODE_IP:
  212. Button_SetCheck(GetDlgItem(m_hwnd, IP_ONLY), TRUE );
  213. break;
  214. case DECODE_IPB:
  215. Button_SetCheck(GetDlgItem(m_hwnd, IP_ALL_B), TRUE );
  216. break;
  217. case DECODE_IPB1:
  218. Button_SetCheck(GetDlgItem(m_hwnd, IP_1_IN_4_B), TRUE );
  219. break;
  220. case DECODE_IPB2:
  221. Button_SetCheck(GetDlgItem(m_hwnd, IP_2_IN_4_B), TRUE );
  222. break;
  223. case DECODE_IPB3:
  224. Button_SetCheck(GetDlgItem(m_hwnd, IP_3_IN_4_B), TRUE );
  225. break;
  226. }
  227. switch (dwOptions & 0xF0000000) {
  228. case DECODE_BQUAL_HIGH:
  229. Button_SetCheck(GetDlgItem(m_hwnd, B_HIGH), TRUE );
  230. break;
  231. case DECODE_BQUAL_MEDIUM:
  232. Button_SetCheck(GetDlgItem(m_hwnd, B_MEDIUM), TRUE );
  233. break;
  234. case DECODE_BQUAL_LOW:
  235. Button_SetCheck(GetDlgItem(m_hwnd, B_LOW), TRUE );
  236. break;
  237. }
  238. }
  239. /*****************************Private*Routine******************************\
  240. * GetDecoderOption
  241. *
  242. * Returns the decoder options from the property page dialog.
  243. *
  244. * History:
  245. * 27-09-95 - StephenE - Created
  246. *
  247. \**************************************************************************/
  248. DWORD
  249. GetDecoderOption(
  250. HWND m_hwnd
  251. )
  252. {
  253. DWORD dwOption = 0L;
  254. if (Button_GetCheck(GetDlgItem(m_hwnd, I_ONLY))) {
  255. dwOption = DECODE_I;
  256. }
  257. else if (Button_GetCheck(GetDlgItem(m_hwnd, I_ONLY))) {
  258. dwOption = DECODE_I;
  259. }
  260. else if (Button_GetCheck(GetDlgItem(m_hwnd, IP_ONLY))) {
  261. dwOption = DECODE_IP;
  262. }
  263. else if (Button_GetCheck(GetDlgItem(m_hwnd, IP_ALL_B))) {
  264. dwOption = DECODE_IPB;
  265. }
  266. else if (Button_GetCheck(GetDlgItem(m_hwnd, IP_1_IN_4_B))) {
  267. dwOption = DECODE_IPB1;
  268. }
  269. else if (Button_GetCheck(GetDlgItem(m_hwnd, IP_2_IN_4_B))) {
  270. dwOption = DECODE_IPB2;
  271. }
  272. else if (Button_GetCheck(GetDlgItem(m_hwnd, IP_3_IN_4_B))) {
  273. dwOption = DECODE_IPB3;
  274. }
  275. if (Button_GetCheck(GetDlgItem(m_hwnd, B_HIGH))) {
  276. dwOption |= DECODE_BQUAL_HIGH;
  277. }
  278. else if (Button_GetCheck(GetDlgItem(m_hwnd, B_MEDIUM))) {
  279. dwOption |= DECODE_BQUAL_MEDIUM;
  280. }
  281. else if (Button_GetCheck(GetDlgItem(m_hwnd, B_LOW))) {
  282. dwOption |= DECODE_BQUAL_LOW;
  283. }
  284. return dwOption;
  285. }
  286. /******************************Public*Routine******************************\
  287. * VideoStatsDialogProc
  288. *
  289. * Handles the messages for our property window
  290. *
  291. * History:
  292. * 27-09-95 - StephenE - Created
  293. *
  294. \**************************************************************************/
  295. INT_PTR CALLBACK
  296. VideoStatsDialogProc(
  297. HWND hwnd,
  298. UINT uMsg,
  299. WPARAM wParam,
  300. LPARAM lParam
  301. )
  302. {
  303. switch (uMsg) {
  304. case WM_INITDIALOG:
  305. SetWindowFont(GetDlgItem(hwnd,ID_STATSBOX),
  306. GetStockObject(ANSI_FIXED_FONT), FALSE);
  307. UpdateStats(hwnd);
  308. return TRUE;
  309. case WM_COMMAND:
  310. switch (LOWORD(wParam)) {
  311. case IDCANCEL:
  312. case IDOK:
  313. EndDialog(hwnd, wParam);
  314. break;
  315. case ID_REFRESH:
  316. UpdateStats(hwnd);
  317. break;
  318. }
  319. return TRUE;
  320. default:
  321. return FALSE;
  322. }
  323. }
  324. /*****************************Private*Routine******************************\
  325. * UpdateStats
  326. *
  327. * Gets the video decoder statics and then formats and displays then in the
  328. * read only edit field.
  329. *
  330. * History:
  331. * 27-09-95 - StephenE - Created
  332. *
  333. \**************************************************************************/
  334. void
  335. UpdateStats(
  336. HWND hwnd
  337. )
  338. {
  339. DWORD dwIFramesDecoded;
  340. DWORD dwPFramesDecoded;
  341. DWORD dwBFramesDecoded;
  342. DWORD dwIFramesSkipped;
  343. DWORD dwPFramesSkipped;
  344. DWORD dwBFramesSkipped;
  345. DWORD dwTotalFrames;
  346. DWORD dwTotalIFrames;
  347. DWORD dwTotalPFrames;
  348. DWORD dwTotalBFrames;
  349. DWORD dwTotalDecoded;
  350. TCHAR Text[1024];
  351. SEQHDR_INFO SeqHdr;
  352. pMpegMovie->pMpegDecoder->get_SequenceHeader(&SeqHdr);
  353. pMpegMovie->pMpegDecoder->get_FrameStatistics(
  354. &dwIFramesDecoded, &dwPFramesDecoded, &dwBFramesDecoded,
  355. &dwIFramesSkipped, &dwPFramesSkipped, &dwBFramesSkipped);
  356. dwTotalIFrames = dwIFramesDecoded + dwIFramesSkipped;
  357. dwTotalPFrames = dwPFramesDecoded + dwPFramesSkipped;
  358. dwTotalBFrames = dwBFramesDecoded + dwBFramesSkipped;
  359. dwTotalFrames = dwTotalIFrames + dwTotalPFrames + dwTotalBFrames;
  360. dwTotalDecoded = dwIFramesDecoded + dwPFramesDecoded + dwBFramesDecoded;
  361. wsprintf(Text, StringFromId(IDS_IMAGE_SIZE), SeqHdr.lWidth, SeqHdr.lHeight);
  362. wsprintf(Text + lstrlen(Text), StringFromId(IDS_BUFFER_VBV), SeqHdr.lvbv);
  363. wsprintf(Text + lstrlen(Text), StringFromId(IDS_BITRATE), SeqHdr.dwBitRate);
  364. if (dwTotalFrames != 0) {
  365. lstrcat(Text, StringFromId(IDS_NEWLINE));
  366. wsprintf(Text + lstrlen(Text), StringFromId(IDS_FRAMES_DEC),
  367. dwTotalDecoded, dwTotalFrames);
  368. wsprintf(Text + lstrlen(Text), StringFromId(IDS_PROPORTION),
  369. (100 * dwTotalDecoded) / dwTotalFrames);
  370. lstrcat(Text, StringFromId(IDS_NEWLINE));
  371. wsprintf(Text + lstrlen(Text), StringFromId(IDS_SKIP_I),
  372. dwIFramesDecoded, dwIFramesSkipped);
  373. wsprintf(Text + lstrlen(Text), StringFromId(IDS_SKIP_P),
  374. dwPFramesDecoded, dwPFramesSkipped);
  375. wsprintf(Text + lstrlen(Text), StringFromId(IDS_SKIP_B),
  376. dwBFramesDecoded, dwBFramesSkipped);
  377. }
  378. SetWindowText(GetDlgItem(hwnd, ID_STATSBOX), Text);
  379. }
  380. /******************************Public*Routine******************************\
  381. * AudioDialogProc
  382. *
  383. * Handles the messages for our property window
  384. *
  385. * History:
  386. * dd-mm-95 - StephenE - Created
  387. *
  388. \**************************************************************************/
  389. INT_PTR CALLBACK
  390. AudioDialogProc(
  391. HWND hwnd,
  392. UINT uMsg,
  393. WPARAM wParam,
  394. LPARAM lParam
  395. )
  396. {
  397. DWORD m_iChannels;
  398. DWORD m_iSkip;
  399. DWORD m_iQuality;
  400. DWORD m_iInteger;
  401. DWORD m_iWordSize;
  402. switch (uMsg) {
  403. case WM_INITDIALOG:
  404. pMpegMovie->pMpegAudioDecoder->get_Stereo(&m_iChannels);
  405. pMpegMovie->pMpegAudioDecoder->get_IntegerDecode(&m_iInteger );
  406. pMpegMovie->pMpegAudioDecoder->get_FrequencyDivider(&m_iSkip);
  407. pMpegMovie->pMpegAudioDecoder->get_DecoderAccuracy(&m_iQuality);
  408. pMpegMovie->pMpegAudioDecoder->get_DecoderWordSize(&m_iWordSize);
  409. SetButtonValues(hwnd, m_iChannels, m_iSkip,
  410. m_iQuality, m_iInteger, m_iWordSize);
  411. return TRUE;
  412. case WM_COMMAND:
  413. switch (LOWORD(wParam)) {
  414. case IDCANCEL:
  415. EndDialog(hwnd, wParam);
  416. break;
  417. case IDOK:
  418. GetButtonValues(hwnd, &m_iChannels, &m_iSkip, &m_iQuality,
  419. &m_iInteger, &m_iWordSize);
  420. pMpegMovie->pMpegAudioDecoder->put_Stereo(m_iChannels);
  421. pMpegMovie->pMpegAudioDecoder->put_IntegerDecode(m_iInteger );
  422. pMpegMovie->pMpegAudioDecoder->put_FrequencyDivider(m_iSkip);
  423. pMpegMovie->pMpegAudioDecoder->put_DecoderAccuracy(m_iQuality);
  424. pMpegMovie->pMpegAudioDecoder->put_DecoderWordSize(m_iWordSize);
  425. EndDialog(hwnd, wParam);
  426. break;
  427. case IDC_AINFO:
  428. // DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_VIDEOSTATS),
  429. // hwnd, VideoStatsDialogProc, (LPARAM)pThis);
  430. break;
  431. case IDC_ADEFAULT:
  432. GetButtonValues(hwnd, &m_iChannels, &m_iSkip,
  433. &m_iQuality, &m_iInteger, &m_iWordSize);
  434. PutDecoderInteger(chAudioChannels, m_iChannels);
  435. PutDecoderInteger(chAudioFreqDivider, m_iSkip);
  436. PutDecoderInteger(chAudioQuality, m_iQuality);
  437. PutDecoderInteger(chAudioQuarterInt, m_iInteger);
  438. PutDecoderInteger(chAudioBits, m_iWordSize);
  439. break;
  440. }
  441. return TRUE;
  442. default:
  443. return FALSE;
  444. }
  445. }
  446. /*****************************Private*Routine******************************\
  447. *
  448. * SetButtonValues
  449. *
  450. * Sets the buttons in the dialog
  451. *
  452. * History:
  453. * dd-mm-96 - StephenE - Created
  454. *
  455. \**************************************************************************/
  456. void
  457. SetButtonValues(
  458. HWND m_hwnd,
  459. DWORD iChannels,
  460. DWORD iSkip,
  461. DWORD iQuality,
  462. DWORD iInteger,
  463. DWORD iWordSize
  464. )
  465. {
  466. Button_SetCheck(GetDlgItem(m_hwnd, STEREO_OUTPUT), iChannels == 2);
  467. int iButton;
  468. if (iInteger) {
  469. iButton = IDC_INTEGER;
  470. }
  471. else {
  472. switch (iSkip) {
  473. case 1:
  474. iButton = FULL_FREQ;
  475. break;
  476. case 2:
  477. iButton = HALF_FREQ;
  478. break;
  479. case 4:
  480. iButton = QUARTER_FREQ;
  481. break;
  482. default:
  483. DbgBreak("Illegal case");
  484. }
  485. }
  486. Button_SetCheck(GetDlgItem(m_hwnd, iButton), TRUE);
  487. switch (iQuality) {
  488. case DECODE_HALF_FULLQ:
  489. iButton = D_MEDIUM;
  490. break;
  491. case DECODE_HALF_HIQ:
  492. iButton = D_LOW;
  493. break;
  494. default:
  495. iButton = D_HIGH;
  496. break;
  497. }
  498. Button_SetCheck(GetDlgItem(m_hwnd, iButton), TRUE);
  499. switch(iWordSize) {
  500. case 16:
  501. iButton = IDC_16_BIT;
  502. break;
  503. default:
  504. iButton = IDC_8_BIT;
  505. break;
  506. }
  507. Button_SetCheck(GetDlgItem(m_hwnd, iButton), TRUE);
  508. }
  509. /*****************************Private*Routine******************************\
  510. * GetButtonValues
  511. *
  512. * Gets the values of the button settings
  513. *
  514. * History:
  515. * dd-mm-96 - StephenE - Created
  516. *
  517. \**************************************************************************/
  518. void
  519. GetButtonValues(
  520. HWND m_hwnd,
  521. LPDWORD iChannels,
  522. LPDWORD iSkip,
  523. LPDWORD iQuality,
  524. LPDWORD iInteger,
  525. LPDWORD iOutputWordSize
  526. )
  527. {
  528. *iChannels = Button_GetCheck(GetDlgItem(m_hwnd, STEREO_OUTPUT)) ? 2 : 1;
  529. *iInteger = 0;
  530. if (Button_GetCheck(GetDlgItem(m_hwnd, FULL_FREQ))) {
  531. *iSkip = 1;
  532. }
  533. else if (Button_GetCheck(GetDlgItem(m_hwnd, HALF_FREQ))) {
  534. *iSkip = 2;
  535. }
  536. else if (Button_GetCheck(GetDlgItem(m_hwnd, QUARTER_FREQ))) {
  537. *iSkip = 4;
  538. }
  539. else if (Button_GetCheck(GetDlgItem(m_hwnd, IDC_INTEGER))) {
  540. *iSkip = 4;
  541. *iInteger = 1;
  542. }
  543. else {
  544. DbgBreak("One button should be set");
  545. }
  546. if (Button_GetCheck(GetDlgItem(m_hwnd, D_MEDIUM))) {
  547. *iQuality = DECODE_HALF_FULLQ;
  548. }
  549. else if (Button_GetCheck(GetDlgItem(m_hwnd, D_LOW))) {
  550. *iQuality = DECODE_HALF_HIQ;
  551. }
  552. else if (Button_GetCheck(GetDlgItem(m_hwnd, D_HIGH))) {
  553. *iQuality = 0L;
  554. }
  555. else {
  556. DbgBreak("One button should be set");
  557. }
  558. if (Button_GetCheck(GetDlgItem(m_hwnd, IDC_8_BIT))) {
  559. *iOutputWordSize = 8;
  560. }
  561. else if (Button_GetCheck(GetDlgItem(m_hwnd, IDC_16_BIT))) {
  562. *iOutputWordSize = 16;
  563. }
  564. else {
  565. DbgBreak("One button should be set");
  566. }
  567. }
  568. /******************************Public*Routine******************************\
  569. * StringFromId
  570. *
  571. *
  572. *
  573. * History:
  574. * dd-mm-96 - StephenE - Created
  575. *
  576. \**************************************************************************/
  577. TCHAR *
  578. StringFromId(
  579. int idResource
  580. )
  581. {
  582. static TCHAR chBuffer[ STR_MAX_STRING_LEN ];
  583. static TCHAR chEmpty[] = TEXT("");
  584. if (LoadString(hInst, idResource, chBuffer, STR_MAX_STRING_LEN) == 0) {
  585. return chEmpty;
  586. }
  587. return chBuffer;
  588. }
  589. /******************************Public*Routine******************************\
  590. * PutDecoderDword
  591. *
  592. *
  593. *
  594. * History:
  595. * dd-mm-96 - StephenE - Created
  596. *
  597. \**************************************************************************/
  598. void
  599. PutDecoderInteger(
  600. const TCHAR *pKey,
  601. int iValue
  602. )
  603. {
  604. HKEY hKey;
  605. if (ERROR_SUCCESS == RegCreateKey(HKEY_CURRENT_USER,
  606. chRegistryKey, &hKey)) {
  607. DWORD dwTmp = (DWORD)iValue;
  608. RegSetValueEx(hKey, pKey, 0L, REG_DWORD, (LPBYTE)&dwTmp, sizeof(dwTmp));
  609. RegCloseKey(hKey);
  610. }
  611. }