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.

518 lines
16 KiB

  1. /* (C) Copyright Microsoft Corporation 1991-1994. All Rights Reserved */
  2. /* init.c
  3. *
  4. * init (discardable) utility functions.
  5. */
  6. /* Revision History.
  7. * 4/2/91 LaurieGr (AKA LKG) Ported to WIN32 / WIN16 common code
  8. * 22/Feb/94 LaurieGr merged Motown and Daytona versions
  9. */
  10. #include <windows.h>
  11. #include <mmsystem.h>
  12. #include <shellapi.h>
  13. #include <mmreg.h>
  14. #include <winnls.h>
  15. #include <tchar.h>
  16. #define INCLUDE_OLESTUBS
  17. #include "soundrec.h"
  18. #include "srecids.h"
  19. #include "reg.h"
  20. #define NOMENUHELP
  21. #define NODRAGLIST
  22. #ifdef USE_MMCNTRLS
  23. #include "mmcntrls.h"
  24. #else
  25. #include <commctrl.h>
  26. #include "buttons.h"
  27. #endif
  28. /* globals */
  29. TCHAR gachAppName[12]; // 8-character name
  30. TCHAR gachAppTitle[30]; // full name
  31. TCHAR gachHelpFile[20]; // name of help file
  32. TCHAR gachHtmlHelpFile[20]; // name of help file
  33. TCHAR gachDefFileExt[10]; // default file extension
  34. HBRUSH ghbrPanel = NULL; // color of main window
  35. HANDLE ghAccel;
  36. TCHAR aszNull[2];
  37. TCHAR aszUntitled[32]; // Untitled string resource
  38. TCHAR aszFilter[64]; // Common Dialog file list filter
  39. #ifdef FAKEITEMNAMEFORLINK
  40. TCHAR aszFakeItemName[16]; // Wave
  41. #endif
  42. TCHAR aszPositionFormat[32];
  43. TCHAR aszNoZeroPositionFormat[32];
  44. extern UINT guWaveHdrs ; // 1/2 second of buffering?
  45. extern DWORD gdwBufferDeltaMSecs ; // # msecs added to end on record
  46. extern UINT gwMSecsPerBuffer; // 1/8 second. initialised in this file
  47. extern BITMAPBTN tbPlaybar[];
  48. static SZCODE aszDecimal[] = TEXT("sDecimal");
  49. static SZCODE aszLZero[] = TEXT("iLzero");
  50. static SZCODE aszWaveClass[] = TEXT("wavedisplay");
  51. static SZCODE aszNoFlickerClass[] = TEXT("noflickertext");
  52. static SZCODE aszShadowClass[] = TEXT("shadowframe");
  53. static SZCODE aszBufferDeltaSeconds[] = TEXT("BufferDeltaSeconds");
  54. static SZCODE aszNumAsyncWaveHeaders[] = TEXT("NumAsyncWaveHeaders");
  55. static SZCODE aszMSecsPerAsyncBuffer[] = TEXT("MSecsPerAsyncBuffer");
  56. /* FixupNulls(chNull, p)
  57. *
  58. * To facilitate localization, we take a localized string with non-NULL
  59. * NULL substitutes and replacement with a real NULL.
  60. */
  61. void NEAR PASCAL FixupNulls(
  62. TCHAR chNull,
  63. LPTSTR p)
  64. {
  65. while (*p) {
  66. if (*p == chNull)
  67. *p++ = 0;
  68. else
  69. p = CharNext(p);
  70. }
  71. } /* FixupNulls */
  72. /* AppInit(hInst, hPrev)
  73. *
  74. * This is called when the application is first loaded into memory.
  75. * It performs all initialization that doesn't need to be done once
  76. * per instance.
  77. */
  78. BOOL PASCAL AppInit(
  79. HINSTANCE hInst, // instance handle of current instance
  80. HINSTANCE hPrev) // instance handle of previous instance
  81. {
  82. #ifdef OLE1_REGRESS
  83. TCHAR aszClipFormat[32];
  84. #endif
  85. WNDCLASS cls;
  86. UINT i;
  87. /* load strings */
  88. LoadString(hInst, IDS_APPNAME, gachAppName, SIZEOF(gachAppName));
  89. LoadString(hInst, IDS_APPTITLE, gachAppTitle, SIZEOF(gachAppTitle));
  90. LoadString(hInst, IDS_HELPFILE, gachHelpFile, SIZEOF(gachHelpFile));
  91. LoadString(hInst, IDS_HTMLHELPFILE, gachHtmlHelpFile, SIZEOF(gachHtmlHelpFile));
  92. LoadString(hInst, IDS_UNTITLED, aszUntitled, SIZEOF(aszUntitled));
  93. LoadString(hInst, IDS_FILTER, aszFilter, SIZEOF(aszFilter));
  94. LoadString(hInst, IDS_FILTERNULL, aszNull, SIZEOF(aszNull));
  95. LoadString(hInst, IDS_DEFFILEEXT, gachDefFileExt, SIZEOF(gachDefFileExt));
  96. FixupNulls(*aszNull, aszFilter);
  97. #ifdef FAKEITEMNAMEFORLINK
  98. LoadString(hInst, IDS_FAKEITEMNAME, aszFakeItemName, SIZEOF(aszFakeItemName));
  99. #endif
  100. LoadString(hInst, IDS_POSITIONFORMAT, aszPositionFormat, SIZEOF(aszPositionFormat));
  101. LoadString(hInst, IDS_NOZEROPOSITIONFORMAT, aszNoZeroPositionFormat, SIZEOF(aszNoZeroPositionFormat));
  102. ghiconApp = LoadIcon(hInst, MAKEINTRESOURCE(IDI_APP));
  103. #ifdef OLE1_REGRESS
  104. /* Initialize OLE server stuff */
  105. InitVTbls();
  106. // IDS_OBJECTLINK "ObjectLink"
  107. // IDS_OWNERLINK "OwnerLink"
  108. // IDS_NATIVE "Native"
  109. LoadString(hInst, IDS_OBJECTLINK, aszClipFormat, SIZEOF(aszClipFormat));
  110. cfLink = (OLECLIPFORMAT)RegisterClipboardFormat(aszClipFormat);
  111. LoadString(hInst, IDS_OWNERLINK, aszClipFormat, SIZEOF(aszClipFormat));
  112. cfOwnerLink = (OLECLIPFORMAT)RegisterClipboardFormat(aszClipFormat);
  113. LoadString(hInst, IDS_NATIVE, aszClipFormat, SIZEOF(aszClipFormat));
  114. cfNative = (OLECLIPFORMAT)RegisterClipboardFormat(aszClipFormat);
  115. #if 0
  116. cfLink = (OLECLIPFORMAT)RegisterClipboardFormatA("ObjectLink");
  117. cfOwnerLink = (OLECLIPFORMAT)RegisterClipboardFormatA("OwnerLink");
  118. cfNative = (OLECLIPFORMAT)RegisterClipboardFormatA("Native");
  119. #endif
  120. #endif
  121. #ifdef DEBUG
  122. ReadRegistryData(NULL
  123. , TEXT("Debug")
  124. , NULL
  125. , (LPBYTE)&__iDebugLevel
  126. , (DWORD)sizeof(__iDebugLevel));
  127. DPF(TEXT("Debug level = %d\n"),__iDebugLevel);
  128. #endif
  129. ghbrPanel = CreateSolidBrush(RGB_PANEL);
  130. if (hPrev == NULL)
  131. {
  132. /* register the "wavedisplay" window class */
  133. cls.lpszClassName = aszWaveClass;
  134. cls.hCursor = LoadCursor(NULL, IDC_ARROW);
  135. cls.hIcon = NULL;
  136. cls.lpszMenuName = NULL;
  137. cls.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  138. cls.hInstance = hInst;
  139. cls.style = CS_HREDRAW | CS_VREDRAW;
  140. cls.lpfnWndProc = WaveDisplayWndProc;
  141. cls.cbClsExtra = 0;
  142. cls.cbWndExtra = 0;
  143. if (!RegisterClass(&cls))
  144. return FALSE;
  145. /* register the "noflickertext" window class */
  146. cls.lpszClassName = aszNoFlickerClass;
  147. cls.hCursor = LoadCursor(NULL, IDC_ARROW);
  148. cls.hIcon = NULL;
  149. cls.lpszMenuName = NULL;
  150. cls.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  151. cls.hInstance = hInst;
  152. cls.style = CS_HREDRAW | CS_VREDRAW;
  153. cls.lpfnWndProc = NFTextWndProc;
  154. cls.cbClsExtra = 0;
  155. cls.cbWndExtra = 0;
  156. if (!RegisterClass(&cls))
  157. return FALSE;
  158. /* register the "shadowframe" window class */
  159. cls.lpszClassName = aszShadowClass;
  160. cls.hCursor = LoadCursor(NULL, IDC_ARROW);
  161. cls.hIcon = NULL;
  162. cls.lpszMenuName = NULL;
  163. cls.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  164. cls.hInstance = hInst;
  165. cls.style = CS_HREDRAW | CS_VREDRAW;
  166. cls.lpfnWndProc = SFrameWndProc;
  167. cls.cbClsExtra = 0;
  168. cls.cbWndExtra = 0;
  169. if (!RegisterClass(&cls))
  170. return FALSE;
  171. /* register the dialog's window class */
  172. cls.lpszClassName = gachAppName;
  173. cls.hCursor = LoadCursor(NULL, IDC_ARROW);
  174. cls.hIcon = ghiconApp;
  175. cls.lpszMenuName = NULL;
  176. cls.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  177. cls.hInstance = hInst;
  178. cls.style = CS_HREDRAW | CS_VREDRAW;
  179. cls.lpfnWndProc = DefDlgProc;
  180. cls.cbClsExtra = 0;
  181. cls.cbWndExtra = DLGWINDOWEXTRA;
  182. if (!RegisterClass(&cls))
  183. return FALSE;
  184. }
  185. #ifdef USE_MMCNTRLS
  186. if (!InitTrackBar(hPrev))
  187. return FALSE;
  188. #else
  189. InitCommonControls();
  190. #endif
  191. if (!(ghAccel = LoadAccelerators(hInst, gachAppName)))
  192. return FALSE;
  193. i = DEF_BUFFERDELTASECONDS;
  194. ReadRegistryData(NULL
  195. , (LPTSTR)aszBufferDeltaSeconds
  196. , NULL
  197. , (LPBYTE)&i
  198. , (DWORD)sizeof(i));
  199. if (i > MAX_DELTASECONDS)
  200. i = MAX_DELTASECONDS;
  201. else if (i < MIN_DELTASECONDS)
  202. i = MIN_DELTASECONDS;
  203. gdwBufferDeltaMSecs = i * 1000L;
  204. DPF(TEXT("gdwBufferDeltaMSecs=%lu\n"), gdwBufferDeltaMSecs);
  205. //
  206. // because it really doesn't help in standard mode to stream with
  207. // multiple wave headers (we sorta assume we having a paging device
  208. // to make things work...), we just revert to one big buffer in
  209. // standard mode... might want to check if paging is enabled??
  210. //
  211. // in any case, this helps a LOT when running KRNL286-->the thing
  212. // is buggy and GP faults when lots of discarding, etc
  213. // is going on... like when dealing with large sound objects, eh?
  214. //
  215. i = DEF_NUMASYNCWAVEHEADERS;
  216. ReadRegistryData(NULL
  217. , (LPTSTR)aszNumAsyncWaveHeaders
  218. , NULL
  219. , (LPBYTE)&i
  220. , (DWORD)sizeof(i));
  221. if (i > MAX_WAVEHDRS)
  222. i = MAX_WAVEHDRS;
  223. else if (i < MIN_WAVEHDRS)
  224. i = 1;
  225. guWaveHdrs = i;
  226. DPF(TEXT(" guWaveHdrs=%u\n"), guWaveHdrs);
  227. i = DEF_MSECSPERASYNCBUFFER;
  228. ReadRegistryData(NULL
  229. , (LPTSTR)aszMSecsPerAsyncBuffer
  230. , NULL
  231. , (LPBYTE)&i
  232. , (DWORD)sizeof(i));
  233. if (i > MAX_MSECSPERBUFFER)
  234. i = MAX_MSECSPERBUFFER;
  235. else if (i < MIN_MSECSPERBUFFER)
  236. i = MIN_MSECSPERBUFFER;
  237. gwMSecsPerBuffer = i;
  238. DPF(TEXT(" gwMSecsPerBuffer=%u\n"), gwMSecsPerBuffer);
  239. return TRUE;
  240. } /* AppInit */
  241. /*
  242. * */
  243. void DoOpenFile(void)
  244. {
  245. LPTSTR lpCmdLine = GetCommandLine();
  246. /* increment pointer past the argv[0] */
  247. while ( *lpCmdLine && *lpCmdLine != TEXT(' '))
  248. lpCmdLine = CharNext(lpCmdLine);
  249. if( gfLinked )
  250. {
  251. FileOpen(gachLinkFilename);
  252. }
  253. else if (!gfEmbedded)
  254. {
  255. // skip blanks
  256. while (*lpCmdLine == TEXT(' '))
  257. {
  258. lpCmdLine++;
  259. continue;
  260. }
  261. if(*lpCmdLine)
  262. {
  263. ResolveIfLink(lpCmdLine);
  264. FileOpen(lpCmdLine);
  265. }
  266. }
  267. }
  268. /*
  269. * Dialog box initialization
  270. * */
  271. BOOL PASCAL SoundDialogInit(
  272. HWND hwnd,
  273. int iCmdShow)
  274. {
  275. /* make the window handle global */
  276. ghwndApp = hwnd;
  277. DragAcceptFiles(ghwndApp, TRUE); /* Process dragged and dropped file */
  278. GetIntlSpecs();
  279. /* Hide the window unless we want to display it later */
  280. ShowWindow(ghwndApp,SW_HIDE);
  281. /* remember the window handles of the important controls */
  282. ghwndWaveDisplay = GetDlgItem(hwnd, ID_WAVEDISPLAY);
  283. ghwndScroll = GetDlgItem(hwnd, ID_CURPOSSCRL);
  284. ghwndPlay = GetDlgItem(hwnd, ID_PLAYBTN);
  285. ghwndStop = GetDlgItem(hwnd, ID_STOPBTN);
  286. ghwndRecord = GetDlgItem(hwnd, ID_RECORDBTN);
  287. ghwndForward = GetDlgItem(hwnd, ID_FORWARDBTN);
  288. ghwndRewind = GetDlgItem(hwnd, ID_REWINDBTN);
  289. #ifdef THRESHOLD
  290. ghwndSkipStart = GetDlgItem(hwnd, ID_SKIPSTARTBTN);
  291. ghwndSkipEnd = GetDlgItem(hwnd, ID_SKIPENDBTN);
  292. #endif //THRESHOLD
  293. /* set up scroll bar */
  294. // SetScrollRange(ghwndScroll, SB_CTL, 0, SCROLL_RANGE, TRUE);
  295. SendMessage(ghwndScroll,TBM_SETRANGEMIN, 0, 0);
  296. SendMessage(ghwndScroll,TBM_SETRANGEMAX, 0, SCROLL_RANGE);
  297. SendMessage(ghwndScroll,TBM_SETPOS, TRUE, 0);
  298. /* Set up the bitmap buttons */
  299. BtnCreateBitmapButtons( hwnd,
  300. (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE),
  301. IDR_PLAYBAR,
  302. BBS_TOOLTIPS,
  303. tbPlaybar,
  304. NUM_OF_BUTTONS,
  305. 25,
  306. 17);
  307. //
  308. // OLE2 and command line initialization...
  309. //
  310. InitializeSRS(ghInst);
  311. gfRunWithEmbeddingFlag = gfEmbedded;
  312. //
  313. // Try and init ACM
  314. //
  315. LoadACM();
  316. //
  317. // build the File.New menu
  318. //
  319. //
  320. // create a blank document
  321. //
  322. if (!FileNew(FMT_DEFAULT, TRUE, FALSE))
  323. {
  324. PostMessage(hwnd, WM_CLOSE, 0, 0);
  325. return TRUE;
  326. }
  327. //
  328. // Note, FileNew/FileOpen has the side effect of releasing the
  329. // server when called by the user. For now, do it here. In the future
  330. // Wrapping these calls would suffice.
  331. //
  332. FlagEmbeddedObject(gfEmbedded);
  333. //
  334. // open a file if requested on command line
  335. //
  336. //
  337. // Execute command line verbs here.
  338. //
  339. // Would be nicer just to execute methods that are likewise exportable
  340. // through an OLE interface.
  341. if (gStartParams.fNew)
  342. {
  343. //
  344. // Behavior: If there is a filename specified, create it and
  345. // commit it so we have a named, empty document. Otherwise, we
  346. // start in a normal new state.
  347. //
  348. //TODO: Implement checkbox to set-as default format and not bring up
  349. //TODO: the format selection dialog box.
  350. FileNew(FMT_DEFAULT,TRUE,TRUE);
  351. if (gStartParams.achOpenFilename[0] != 0)
  352. {
  353. lstrcpy(gachFileName, gStartParams.achOpenFilename);
  354. FileSave(FALSE);
  355. }
  356. //
  357. // Behaviour: If -close was specified, all we do is exit.
  358. //
  359. if (gStartParams.fClose)
  360. PostMessage(hwnd,WM_CLOSE,0,0);
  361. }
  362. else if (gStartParams.fPlay)
  363. {
  364. /* Behavior: If there is a file, just open it. If not, ask for the
  365. * filename. Then queue up a play request.
  366. * If -close was specified, then when the play is done the application
  367. * will exit. (see wave.c:YieldStop())
  368. */
  369. if (gStartParams.achOpenFilename[0] != 0)
  370. FileOpen(gStartParams.achOpenFilename);
  371. else
  372. FileOpen(NULL);
  373. AppPlay(gStartParams.fPlay && gStartParams.fClose);
  374. }
  375. else
  376. {
  377. /* case: Both linked and standalone "open" cases are handled
  378. * here. The only unusual case is if -open was specified without
  379. * a filename, meaning the user should be asked for a filename
  380. * first upon app start.
  381. *
  382. * Behaviour: -open and -close has no meaning, unless as a
  383. * verification (i.e. is this a valid wave file). So this
  384. * isn't implemented.
  385. */
  386. if (gStartParams.achOpenFilename[0] != 0)
  387. FileOpen(gStartParams.achOpenFilename);
  388. else if (gStartParams.fOpen)
  389. FileOpen(NULL);
  390. }
  391. if (!gfRunWithEmbeddingFlag) {
  392. ShowWindow(ghwndApp,iCmdShow);
  393. /* set focus to "Record" if the file is empty, "Play" if not */
  394. if (glWaveSamplesValid == 0 && IsWindowEnabled(ghwndRecord))
  395. SetDlgFocus(ghwndRecord);
  396. else if (glWaveSamplesValid > 0 && IsWindowEnabled(ghwndPlay))
  397. SetDlgFocus(ghwndPlay);
  398. else
  399. SetDlgFocus(ghwndScroll);
  400. if (!waveInGetNumDevs() && !waveOutGetNumDevs()) {
  401. /* No recording or playback devices */
  402. ErrorResBox(hwnd, ghInst, MB_ICONHAND | MB_OK,
  403. IDS_APPTITLE, IDS_NOWAVEFORMS);
  404. }
  405. return FALSE; // FALSE because we set the focus above
  406. }
  407. //
  408. // return FALSE, so the dialog manager will not activate us, it is
  409. // ok because we are hidden anyway
  410. //
  411. return FALSE;
  412. } /* SoundDialogInit */
  413. /*
  414. * localisation stuff - decimal point delimiter etc
  415. * */
  416. BOOL FAR PASCAL
  417. GetIntlSpecs()
  418. {
  419. TCHAR szTmp[5];
  420. // find decimal seperator
  421. szTmp[0] = chDecimal;
  422. szTmp[1] = 0;
  423. GetLocaleInfo(LOCALE_USER_DEFAULT
  424. , LOCALE_SDECIMAL
  425. , szTmp
  426. , SIZEOF(szTmp));
  427. chDecimal = szTmp[0];
  428. // leading zeros
  429. szTmp[0] = TEXT('1');
  430. szTmp[1] = 0;
  431. GetLocaleInfo(LOCALE_USER_DEFAULT
  432. , LOCALE_ILZERO
  433. , szTmp
  434. , SIZEOF(szTmp));
  435. gfLZero = _ttoi(szTmp);
  436. szTmp[0] = TEXT('0');
  437. LoadString(ghInst, IDS_RTLENABLED, szTmp, SIZEOF(szTmp));
  438. gfIsRTL = (szTmp[0] != TEXT('0'));
  439. return TRUE;
  440. } /* GetIntlSpecs */