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.

187 lines
5.1 KiB

  1. /******************************************************************************
  2. Copyright (C) Microsoft Corporation 1985-1990. All rights reserved.
  3. Title: mmwnd.c - contains the window procedure for the MMSYSTEM 'global'
  4. window
  5. the global window is used by sndPlaySound and MCI for
  6. reciving notification messages.
  7. Version: 1.00
  8. Date: 04-Sep-1990
  9. Author: ToddLa
  10. *****************************************************************************/
  11. #include <windows.h>
  12. #include "mmsystem.h"
  13. #include "mmddk.h"
  14. #include "mmsysi.h"
  15. #include "mmsysver.h"
  16. #define CLASS_NAME MAKEINTATOM(42)
  17. /*
  18. SOUND_DELAY is the number of ms to delay before closing the wave device
  19. after the buffer is done.
  20. */
  21. #define SOUND_DELAY 300
  22. typedef LRESULT (CALLBACK *LPWNDPROC)(HWND, UINT, WPARAM, LPARAM);
  23. // Place the normal code in the _TEXT segment
  24. static LRESULT CALLBACK mmWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
  25. #pragma alloc_text(_TEXT, mmWndProc)
  26. HWND hwndNotify;
  27. /****************************************************************************
  28. strings
  29. ****************************************************************************/
  30. SZCODE szStartupSound[] = "SystemStart";
  31. /***************************************************************************/
  32. static BOOL PASCAL FAR CreateMMClass(void)
  33. {
  34. WNDCLASS cls;
  35. cls.hCursor = NULL;
  36. cls.hIcon = NULL;
  37. cls.lpszMenuName = NULL;
  38. cls.lpszClassName = CLASS_NAME;
  39. cls.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  40. cls.hInstance = ghInst;
  41. cls.style = CS_GLOBALCLASS;
  42. cls.lpfnWndProc = (WNDPROC)mmWndProc;
  43. cls.cbWndExtra = 0;
  44. cls.cbClsExtra = 0;
  45. return RegisterClass(&cls);
  46. }
  47. /***************************************************************************
  48. *
  49. * @doc INTERNAL MMSYSTEM
  50. *
  51. * @api BOOL | WndInit | called to create the MMSYSTEM global window.
  52. *
  53. * @comm we need to create this window on be-half of the SHELL task
  54. * so it will be around all the time.
  55. *
  56. ***************************************************************************/
  57. BOOL NEAR PASCAL WndInit(void)
  58. {
  59. if (hwndNotify) // if we are init'ed already, just get out
  60. return TRUE;
  61. if (!CreateMMClass())
  62. return FALSE;
  63. if (!(hwndNotify = CreateWindowEx(0, CLASS_NAME, NULL, WS_OVERLAPPED,
  64. 0, 0, 0, 0, NULL, NULL, ghInst, NULL))) {
  65. UnregisterClass(CLASS_NAME, ghInst);
  66. return FALSE;
  67. }
  68. #ifdef DEBUGX
  69. {
  70. DPRINTF(("MMSYSTEM: Creating Notify Window: htask=%04X hwnd=%04X\r\n", GetCurrentTask(),hwndNotify));
  71. }
  72. #endif // DEBUGX
  73. return TRUE;
  74. }
  75. /***************************************************************************
  76. *
  77. * @doc INTERNAL MMSYSTEM
  78. *
  79. * @api void | WndTerminate | called when MMSYSTEM is terminating
  80. *
  81. ***************************************************************************/
  82. void NEAR PASCAL WndTerminate(void)
  83. {
  84. if (hwndNotify)
  85. {
  86. SendMessage(hwndNotify, WM_CLOSE, 0, 0L);
  87. UnregisterClass(CLASS_NAME, ghInst);
  88. }
  89. }
  90. /***************************************************************************
  91. *
  92. * @doc INTERNAL MMSYSTEM
  93. *
  94. * @api LRESULT | mmWndProc | The Window procedure for the MMSYSTEM window
  95. *
  96. * @comm mmWndProc calls DefWindowProc for all messages except:
  97. *
  98. * MM_MCINOTIFY: calls MciNotify() in MCI.C
  99. * MM_WOM_DONE: calls WaveOutNotify() in PLAYWAV.C
  100. *
  101. * @xref sndPlaySound
  102. *
  103. ***************************************************************************/
  104. static LRESULT CALLBACK mmWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  105. {
  106. switch (msg)
  107. {
  108. case WM_CREATE:
  109. hwndNotify = hwnd;
  110. // sndPlaySound(szStartupSound, SND_ASYNC | SND_NODEFAULT);
  111. break;
  112. case WM_TIMER:
  113. KillTimer(hwnd, (UINT)wParam);
  114. WaveOutNotify(0,0);
  115. break;
  116. case MM_MCINOTIFY:
  117. MciNotify(wParam, lParam);
  118. break;
  119. case MM_WOM_DONE:
  120. /*
  121. The sound started with sndPlaySound has completed
  122. so we should call the cleanup routine. We delay
  123. this call for several hundred milliseconds because
  124. some sound drivers have a nasty characteristic - they
  125. will notify before the final DMA transfer is complete
  126. because the app. supplied buffer is no longer required.
  127. This means that they may have to spin inside a close
  128. request until the dma transfer completes. This hangs
  129. the system for hundreds of milliseconds.
  130. */
  131. SetTimer(hwndNotify, 1, SOUND_DELAY, NULL);
  132. break;
  133. case MM_SND_PLAY:
  134. return (LRESULT)(LONG)sndMessage((LPSTR)lParam, (UINT)wParam);
  135. case MM_MCISYSTEM_STRING:
  136. return (LRESULT)mciRelaySystemString ((LPMCI_SYSTEM_MESSAGE)lParam);
  137. default:
  138. return DefWindowProc(hwnd, msg, wParam,lParam);
  139. }
  140. return (LRESULT)0L;
  141. }