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.

298 lines
7.6 KiB

  1. /****************************************************************************
  2. *
  3. * File : multimed.c
  4. *
  5. * Description :
  6. * Top level control panel applet code for multimedia for
  7. * Windows NT
  8. *
  9. * Copyright (c) 1993 Microsoft Corporation
  10. *
  11. *****************************************************************************/
  12. /*****************************************************************************
  13. Design
  14. This module contains the code and data (apart from the icons for
  15. the 3 applets) to support 3 control panel applets for multi-media :
  16. sound - Setting system sounds
  17. midimap - Midi mapper
  18. drivers - Installation and configuration of installable drivers through
  19. installable drivers interface
  20. The interface in is as for all control panel applets. This (super)
  21. applet returns a number of internal applets to the CPL_GETCOUNT
  22. message depending on :
  23. waveOutGetNumDevs returns non-zero - then sound is supported.
  24. midiOutGetNumDevs returns non-zero or midiInGetNumDevs returns
  25. non-zero - then midimap is supported.
  26. Interface to sub-applets. For packaging and historical reasons the
  27. other applets are separate files :
  28. sound - sound.dll
  29. midimap - midimap.dll - is also a midi driver
  30. drivers - drivers.dll
  31. When an applet (which is supported for the current configuration of
  32. the system as determined above) is run (and ONLY THEN) via the
  33. CPL_DBLCLK message we call LoadLibrary for the (sub) applet and
  34. call its entry point (usually a 'cut-down' CplApplet).
  35. To do this each sub-applet's icon and string have fixed ids defined in
  36. multimed.h.
  37. *****************************************************************************/
  38. #include <windows.h>
  39. #include <mmsystem.h>
  40. #include <cpl.h>
  41. #include <cphelp.h>
  42. #include "multimed.h"
  43. // This applet has been neutered to provide only MIDIMAP.DLL's CPL
  44. // interface; the others are now supported by MMSYS.CPL.
  45. //
  46. // #define EXTRA_APPLETS
  47. #ifdef EXTRA_APPLETS
  48. enum {
  49. SoundsApplet = 0,
  50. DriversApplet,
  51. MidiMapApplet,
  52. ACMApplet,
  53. NumberOfApplets
  54. };
  55. struct {
  56. LPCTSTR AppletFileName;
  57. DWORD dwHelpContext;
  58. HINSTANCE ActiveHandle;
  59. APPLET_PROC AppletEntryPoint;
  60. BOOL AppInUse;
  61. NEWCPLINFO CplInfo;
  62. }
  63. AppletInfo[] = { { TEXT("sound.dll"), IDH_CHILD_SND },
  64. { TEXT("drivers.dll"), IDH_CHILD_DRIVERS },
  65. { TEXT("midimap.dll"), IDH_CHILD_MIDI },
  66. { TEXT("msacm32.drv"), 0 } }; // No context for ACM
  67. #else
  68. enum {
  69. MidiMapApplet = 0,
  70. NumberOfApplets
  71. };
  72. struct {
  73. LPCTSTR AppletFileName;
  74. DWORD dwHelpContext;
  75. HINSTANCE ActiveHandle;
  76. APPLET_PROC AppletEntryPoint;
  77. BOOL AppInUse;
  78. NEWCPLINFO CplInfo;
  79. }
  80. AppletInfo[] = { { TEXT("midimap.dll"), IDH_CHILD_MIDI } };
  81. #endif
  82. int IdMapping[NumberOfApplets];
  83. int TotalApplets;
  84. BOOL LoadDataPart(int AppletIndex)
  85. {
  86. UINT OldErrorMode;
  87. LPNEWCPLINFO lpCplInfo;
  88. HINSTANCE DataOnlyHandle;
  89. OldErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
  90. DataOnlyHandle =
  91. LoadLibraryEx(AppletInfo[AppletIndex].AppletFileName,
  92. NULL,
  93. DONT_RESOLVE_DLL_REFERENCES);
  94. SetErrorMode(OldErrorMode);
  95. if (DataOnlyHandle == NULL) {
  96. return FALSE;
  97. }
  98. /*
  99. * Cache all Cpl data now so we're not embarrassed by errors later
  100. */
  101. lpCplInfo = &AppletInfo[AppletIndex].CplInfo;
  102. lpCplInfo->dwSize = sizeof(NEWCPLINFO);
  103. lpCplInfo->lData = 0; // Applets we use expect this
  104. lpCplInfo->dwHelpContext = AppletInfo[AppletIndex].dwHelpContext;
  105. lpCplInfo->hIcon =
  106. LoadIcon(DataOnlyHandle,
  107. MAKEINTRESOURCE(ID_ICON));
  108. if (lpCplInfo->hIcon == NULL ||
  109. !LoadString(DataOnlyHandle,
  110. IDS_NAME,
  111. lpCplInfo->szName,
  112. sizeof(lpCplInfo->szName)) ||
  113. !LoadString(DataOnlyHandle,
  114. IDS_INFO,
  115. lpCplInfo->szInfo,
  116. sizeof(lpCplInfo->szInfo)) ||
  117. !LoadString(DataOnlyHandle,
  118. IDS_CONTROL_HLP,
  119. lpCplInfo->szHelpFile,
  120. sizeof(lpCplInfo->szHelpFile))) {
  121. FreeLibrary(DataOnlyHandle);
  122. return FALSE;
  123. }
  124. FreeLibrary(DataOnlyHandle);
  125. return TRUE;
  126. }
  127. LONG CPlApplet(HWND hCplWnd, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
  128. {
  129. LONG ReturnCode = 0L; // The default apparently
  130. int i;
  131. switch (uMsg) {
  132. case CPL_INIT:
  133. /*
  134. * I've no idea why this is a better place to initialize than
  135. * CPL_GETCOUNT but why not?
  136. *
  137. */
  138. /*
  139. * Check there's somebody home
  140. */
  141. for (i = 0; i < NumberOfApplets; i++) {
  142. /*
  143. ** Don't put up useless junk!
  144. */
  145. if (i == MidiMapApplet && midiOutGetNumDevs() == 0
  146. #ifdef EXTRA_APPLETS
  147. || i == ACMApplet && waveOutGetNumDevs() == 0
  148. #endif
  149. )
  150. {
  151. continue;
  152. }
  153. if (LoadDataPart(i)) {
  154. IdMapping[TotalApplets++] = i;
  155. }
  156. }
  157. /*
  158. * Only succeed if we support something
  159. */
  160. ReturnCode = TotalApplets != 0;
  161. break;
  162. case CPL_GETCOUNT:
  163. return TotalApplets;
  164. break;
  165. case CPL_NEWINQUIRE:
  166. {
  167. LPNEWCPLINFO lpCplInfo;
  168. int iApplet;
  169. iApplet = IdMapping[lParam1];
  170. lpCplInfo = (LPNEWCPLINFO)lParam2;
  171. *lpCplInfo = AppletInfo[iApplet].CplInfo;
  172. }
  173. break;
  174. case CPL_DBLCLK:
  175. /*
  176. * The job here is to
  177. * 1. If the applet is not already loaded
  178. * -- load it
  179. * -- Pass it a cpl_init message - this will do for our applets(!)
  180. *
  181. * 2. Pass it a CPL_DBLCLK message with the parameters we got
  182. *
  183. */
  184. {
  185. int iApplet;
  186. iApplet = IdMapping[lParam1];
  187. if (AppletInfo[iApplet].ActiveHandle == NULL) {
  188. UINT OldErrorMode;
  189. OldErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
  190. AppletInfo[iApplet].ActiveHandle =
  191. LoadLibrary(AppletInfo[iApplet].AppletFileName);
  192. SetErrorMode(OldErrorMode);
  193. if (AppletInfo[iApplet].ActiveHandle != NULL) {
  194. AppletInfo[iApplet].AppletEntryPoint =
  195. (APPLET_PROC)GetProcAddress(
  196. AppletInfo[iApplet].ActiveHandle,
  197. "CPlApplet");
  198. }
  199. if (AppletInfo[iApplet].AppletEntryPoint != NULL) {
  200. (*AppletInfo[iApplet].AppletEntryPoint)
  201. (hCplWnd, CPL_INIT, 0, 0);
  202. }
  203. }
  204. if (AppletInfo[iApplet].AppletEntryPoint != NULL) {
  205. (*AppletInfo[iApplet].AppletEntryPoint)
  206. (hCplWnd, uMsg, lParam1, lParam2);
  207. }
  208. }
  209. break;
  210. case CPL_EXIT:
  211. /*
  212. * Unload all our friends
  213. */
  214. {
  215. int i;
  216. for (i = 0; i < NumberOfApplets; i++) {
  217. if (AppletInfo[i].ActiveHandle != NULL) {
  218. if (AppletInfo[i].AppletEntryPoint != NULL) {
  219. (*AppletInfo[i].AppletEntryPoint)
  220. (hCplWnd, CPL_EXIT, 0, 0);
  221. }
  222. FreeLibrary(AppletInfo[i].ActiveHandle);
  223. }
  224. }
  225. }
  226. break;
  227. }
  228. return ReturnCode;
  229. }