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.

1656 lines
42 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: diskinfo.c
  3. *
  4. * Support for the diskinfo dialog box.
  5. *
  6. *
  7. * Created: 18-11-93
  8. * Author: Stephen Estrop [StephenE]
  9. *
  10. * Copyright (c) 1993 Microsoft Corporation
  11. \**************************************************************************/
  12. #pragma warning( once : 4201 4214 )
  13. #define NOOLE
  14. #define NODRAGLIST
  15. #include <windows.h> /* required for all Windows applications */
  16. #include <windowsx.h>
  17. #include <string.h>
  18. #include <malloc.h>
  19. #include <stdarg.h>
  20. #include <stdio.h>
  21. #include <tchar.h>
  22. #include "resource.h"
  23. #include "cdplayer.h"
  24. #include "ledwnd.h"
  25. #include "cdapi.h"
  26. #include "scan.h"
  27. #include "trklst.h"
  28. #include "database.h"
  29. #include "diskinfo.h"
  30. #include "dragdrop.h"
  31. #include "literals.h"
  32. /*
  33. ** This structure is used during the drag/drop copy/move operations.
  34. */
  35. typedef struct {
  36. int index;
  37. DWORD dwData;
  38. TCHAR chName[TRACK_TITLE_LENGTH];
  39. } LIST_INFO;
  40. int dCdrom; /* The ID of the physical cdrom drive being edited */
  41. DWORD dwDiskId; /* The unique ID of the current disk being edited */
  42. HWND hAvailWnd; /* cached hwnd of the available tracks listbox */
  43. HWND hPlayWnd; /* cached hwnd of the play list listbox */
  44. int CurrTocIndex; /* Index into the available tracks listbox of the */
  45. /* track currently being edited. */
  46. BOOL fChanged; /* Has the current track name changed. */
  47. HDC hdcMem; /* Temporary hdc used to draw the track bitmap. */
  48. BOOL fPlaylistChanged; /* Has the playlist been altered ? */
  49. BOOL fTrackNamesChanged; /* Has the playlist been altered ? */
  50. UINT g_DragMessage; /* Message ID of drag drop interface */
  51. HCURSOR g_hCursorDrop; /* Drops allowed cursor */
  52. HCURSOR g_hCursorNoDrop; /* Drops not allowed cursor */
  53. HCURSOR g_hCursorDropDel; /* Drop deletes the selection */
  54. HCURSOR g_hCursorDropCpy; /* Drop copies the selection */
  55. /******************************Public*Routine******************************\
  56. * DiskInfoDlgProc
  57. *
  58. *
  59. *
  60. * History:
  61. * dd-mm-93 - StephenE - Created
  62. *
  63. \**************************************************************************/
  64. BOOL CALLBACK
  65. DiskInfoDlgProc(
  66. HWND hwnd,
  67. UINT message,
  68. WPARAM wParam,
  69. LPARAM lParam
  70. )
  71. {
  72. #if WINVER >= 0x0400
  73. #include "helpids.h"
  74. static const DWORD aIds[] = {
  75. IDC_STATIC_DRIVE, IDH_CD_DRIVE_NAME,
  76. IDC_SJETEXT_DRIVE, IDH_CD_DRIVE_NAME,
  77. IDC_STATIC_ARTIST, IDH_CD_GET_ARTIST,
  78. IDC_EDIT_ARTIST, IDH_CD_GET_ARTIST,
  79. IDC_STATIC_TITLE, IDH_CD_GET_TITLE,
  80. IDC_EDIT_TITLE, IDH_CD_GET_TITLE,
  81. IDC_STATIC_PLAY_LIST, IDH_CD_PLAY_LISTBOX,
  82. IDC_LISTBOX_PLAY_LIST, IDH_CD_PLAY_LISTBOX,
  83. IDC_ADD, IDH_CD_ADD,
  84. IDC_REMOVE, IDH_CD_REMOVE,
  85. IDC_CLEAR, IDH_CD_CLEAR,
  86. IDC_DEFAULT, IDH_CD_DEFAULT,
  87. IDC_STATIC_AVAILABLE_TRACKS, IDH_CD_TRACK_LISTBOX,
  88. IDC_LISTBOX_AVAILABLE_TRACKS, IDH_CD_TRACK_LISTBOX,
  89. IDC_STATIC_TRACK, IDH_CD_TRACK_NAME,
  90. IDC_EDIT_TRACK, IDH_CD_TRACK_NAME,
  91. IDC_SETNAME, IDH_CD_SETNAME,
  92. 0, 0
  93. };
  94. #endif
  95. LPDRAGMULTILISTINFO lpns;
  96. HWND hwndDrop;
  97. /*
  98. ** Process any drag/drop notifications first.
  99. **
  100. ** wParam == The ID of the drag source.
  101. ** lParam == A pointer to a DRAGLISTINFO structure
  102. */
  103. if ( message == g_DragMessage ) {
  104. lpns = (LPDRAGMULTILISTINFO)lParam;
  105. hwndDrop = WindowFromPoint( lpns->ptCursor );
  106. switch ( lpns->uNotification ) {
  107. case DL_BEGINDRAG:
  108. return SetDlgMsgResult( hwnd, WM_COMMAND, TRUE );
  109. case DL_DRAGGING:
  110. return DlgDiskInfo_OnQueryDrop( hwnd, hwndDrop, lpns->hWnd,
  111. lpns->ptCursor, lpns->dwState );
  112. case DL_DROPPED:
  113. return DlgDiskInfo_OnProcessDrop( hwnd, hwndDrop, lpns->hWnd,
  114. lpns->ptCursor, lpns->dwState );
  115. case DL_CANCELDRAG:
  116. InsertIndex( hwnd, lpns->ptCursor, FALSE );
  117. break;
  118. }
  119. return SetDlgMsgResult( hwnd, WM_COMMAND, FALSE );
  120. }
  121. switch ( message ) {
  122. HANDLE_MSG( hwnd, WM_INITDIALOG, DlgDiskInfo_OnInitDialog );
  123. HANDLE_MSG( hwnd, WM_DRAWITEM, DlgDiskInfo_OnDrawItem );
  124. HANDLE_MSG( hwnd, WM_COMMAND, DlgDiskInfo_OnCommand );
  125. HANDLE_MSG( hwnd, WM_DESTROY, DlgDiskInfo_OnDestroy );
  126. HANDLE_MSG( hwnd, WM_CTLCOLORDLG, Common_OnCtlColor );
  127. HANDLE_MSG( hwnd, WM_CTLCOLORSTATIC, Common_OnCtlColor );
  128. HANDLE_MSG( hwnd, WM_MEASUREITEM, Common_OnMeasureItem );
  129. #if WINVER >= 0x0400
  130. case WM_HELP:
  131. WinHelp( ((LPHELPINFO)lParam)->hItemHandle, g_HelpFileName,
  132. HELP_WM_HELP, (DWORD)(LPVOID)aIds );
  133. break;
  134. case WM_CONTEXTMENU:
  135. WinHelp( (HWND)wParam, g_HelpFileName,
  136. HELP_CONTEXTMENU, (DWORD)(LPVOID)aIds );
  137. break;
  138. #endif
  139. default:
  140. return FALSE;
  141. }
  142. }
  143. /*****************************Private*Routine******************************\
  144. * DlgDiskInfo_OnInitDialog
  145. *
  146. *
  147. *
  148. * History:
  149. * 18-11-93 - StephenE - Created
  150. *
  151. \**************************************************************************/
  152. BOOL
  153. DlgDiskInfo_OnInitDialog(
  154. HWND hwnd,
  155. HWND hwndFocus,
  156. LPARAM lParam
  157. )
  158. {
  159. HDC hdc;
  160. UINT num;
  161. #ifdef DAYTONA
  162. if (g_hDlgFont) {
  163. /* Static edit field */
  164. SendDlgItemMessage( hwnd, IDC_SJETEXT_DRIVE,
  165. WM_SETFONT, (WPARAM)(g_hDlgFont), 0L );
  166. /* Dynamic edit fields */
  167. SendDlgItemMessage( hwnd, IDC_EDIT_ARTIST,
  168. WM_SETFONT, (WPARAM)(g_hDlgFont), 0L );
  169. SendDlgItemMessage( hwnd, IDC_EDIT_TITLE,
  170. WM_SETFONT, (WPARAM)(g_hDlgFont), 0L );
  171. SendDlgItemMessage( hwnd, IDC_EDIT_TRACK,
  172. WM_SETFONT, (WPARAM)(g_hDlgFont), 0L );
  173. /* Owner draw listboxes */
  174. SendDlgItemMessage( hwnd, IDC_LISTBOX_PLAY_LIST,
  175. WM_SETFONT, (WPARAM)(g_hDlgFont), 0L );
  176. SendDlgItemMessage( hwnd, IDC_LISTBOX_AVAILABLE_TRACKS,
  177. WM_SETFONT, (WPARAM)(g_hDlgFont), 0L );
  178. }
  179. #endif
  180. dCdrom = (int)lParam;
  181. dwDiskId = g_Devices[ dCdrom ]->CdInfo.Id;
  182. g_DragMessage = InitDragMultiList();
  183. if (g_hCursorNoDrop == NULL) {
  184. g_hCursorNoDrop = LoadCursor(NULL, IDC_NO);
  185. }
  186. if (g_hCursorDrop == NULL) {
  187. g_hCursorDrop = LoadCursor(g_hInst, MAKEINTRESOURCE(IDR_DROP));
  188. }
  189. if (g_hCursorDropDel == NULL) {
  190. g_hCursorDropDel = LoadCursor(g_hInst, MAKEINTRESOURCE(IDR_DROPDEL));
  191. }
  192. if (g_hCursorDropCpy == NULL) {
  193. g_hCursorDropCpy = LoadCursor(g_hInst, MAKEINTRESOURCE(IDR_DROPCPY));
  194. }
  195. /*
  196. ** Cache the two listbox window handles.
  197. */
  198. hPlayWnd = GetDlgItem( hwnd, IDC_LISTBOX_PLAY_LIST );
  199. hAvailWnd = GetDlgItem( hwnd, IDC_LISTBOX_AVAILABLE_TRACKS );
  200. hdc = GetDC( hwnd );
  201. hdcMem = CreateCompatibleDC( hdc );
  202. ReleaseDC( hwnd, hdc );
  203. SelectObject( hdcMem, g_hbmTrack );
  204. InitForNewDrive( hwnd );
  205. /*
  206. ** Set the maximum characters allowed in the edit field to 1 less than
  207. ** the space available in the TRACK_INF and ENTRY structures.
  208. */
  209. SendDlgItemMessage( hwnd, IDC_EDIT_ARTIST, EM_LIMITTEXT, ARTIST_LENGTH - 1, 0 );
  210. SendDlgItemMessage( hwnd, IDC_EDIT_TITLE, EM_LIMITTEXT, TITLE_LENGTH - 1, 0 );
  211. SendDlgItemMessage( hwnd, IDC_EDIT_TRACK, EM_LIMITTEXT, TRACK_TITLE_LENGTH - 1, 0 );
  212. MakeMultiDragList( hPlayWnd );
  213. MakeMultiDragList( hAvailWnd );
  214. num = ListBox_GetCount( hPlayWnd );
  215. if ( num == 0 ) {
  216. EnableWindow( GetDlgItem( hwnd, IDC_CLEAR ), FALSE );
  217. }
  218. EnableWindow( GetDlgItem( hwnd, IDC_ADD ), FALSE );
  219. EnableWindow( GetDlgItem( hwnd, IDC_REMOVE ), FALSE );
  220. fTrackNamesChanged = fPlaylistChanged = FALSE;
  221. return TRUE;
  222. }
  223. /*****************************Private*Routine******************************\
  224. * DlgDiskInfo_OnCommand
  225. *
  226. * This is where most of the UI processing takes place. Basically the dialog
  227. * serves two purposes.
  228. *
  229. * 1. Track name editing
  230. * 2. Play list selection and editing.
  231. *
  232. * History:
  233. * dd-mm-93 - StephenE - Created
  234. *
  235. \**************************************************************************/
  236. void
  237. DlgDiskInfo_OnCommand(
  238. HWND hwnd,
  239. int id,
  240. HWND hwndCtl,
  241. UINT codeNotify
  242. )
  243. {
  244. int items[100];
  245. int i, num, index;
  246. int iCurrTrack;
  247. TCHAR s[TRACK_TITLE_LENGTH];
  248. DWORD dwData;
  249. switch ( id ) {
  250. case IDC_LISTBOX_PLAY_LIST:
  251. if ( codeNotify == LBN_DBLCLK ) {
  252. RemovePlayListSelection( hwnd );
  253. }
  254. EnableWindow( GetDlgItem( hwnd, IDC_REMOVE ),
  255. ListBox_GetSelItems( hwndCtl, 1, items ) == 1 );
  256. break;
  257. case IDC_LISTBOX_AVAILABLE_TRACKS:
  258. /*
  259. ** If the selection in the possible tracks listbox
  260. ** changes, we need to reset which track is being edited
  261. ** down below for the track title editbox.
  262. */
  263. if ( codeNotify == LBN_SELCHANGE ) {
  264. /*
  265. ** Update currently displayed track in track name
  266. ** field - also, enable/diable the add button
  267. ** depending on whether there are any items selected.
  268. */
  269. if ( ListBox_GetSelItems( hwndCtl, 1, items ) == 1 ) {
  270. UpdateTrackName( hwnd, items[0] );
  271. EnableWindow( GetDlgItem( hwnd, IDC_ADD ), TRUE );
  272. }
  273. else {
  274. EnableWindow( GetDlgItem( hwnd, IDC_ADD ), FALSE );
  275. }
  276. }
  277. else if ( codeNotify == LBN_DBLCLK ) {
  278. AddTrackListSelection( hwnd, ListBox_GetCount( hPlayWnd ) );
  279. }
  280. break;
  281. case IDC_EDIT_TRACK:
  282. switch ( codeNotify ) {
  283. case EN_CHANGE:
  284. fChanged = TRUE;
  285. break;
  286. case EN_KILLFOCUS:
  287. SendMessage( hwnd, DM_SETDEFID, IDOK, 0L );
  288. break;
  289. case EN_SETFOCUS:
  290. SendMessage( hwnd, DM_SETDEFID, IDC_SETNAME, 0L );
  291. break;
  292. }
  293. break;
  294. case IDC_SETNAME:
  295. if ( fChanged ) {
  296. fTrackNamesChanged = TRUE;
  297. GrabTrackName( hwnd, CurrTocIndex );
  298. }
  299. CurrTocIndex++;
  300. if ( CurrTocIndex >= NUMTRACKS(dCdrom) ) {
  301. CurrTocIndex = 0;
  302. }
  303. ListBox_SetSel( hPlayWnd, FALSE, -1 );
  304. EnableWindow( GetDlgItem( hwnd, IDC_REMOVE ), FALSE );
  305. ListBox_SetSel( hAvailWnd, FALSE, -1 );
  306. ListBox_SelItemRange( hAvailWnd, TRUE, CurrTocIndex, CurrTocIndex );
  307. /*
  308. ** Display correct track in track field
  309. */
  310. UpdateTrackName( hwnd, CurrTocIndex );
  311. break;
  312. case IDC_ADD:
  313. AddTrackListSelection( hwnd, ListBox_GetCount( hPlayWnd ) );
  314. break;
  315. case IDC_CLEAR:
  316. /*
  317. ** Just wipe out the current play list from the play listbox.
  318. ** Don't forget to grey out the remove and clear buttons.
  319. */
  320. ListBox_ResetContent( hPlayWnd );
  321. SendMessage( hwnd, DM_SETDEFID, IDOK, 0L );
  322. SetFocus( GetDlgItem( hwnd, IDOK ) );
  323. CheckButtons( hwnd );
  324. fPlaylistChanged = TRUE;
  325. break;
  326. case IDC_REMOVE:
  327. RemovePlayListSelection( hwnd );
  328. SetFocus( GetDlgItem( hwnd, IDOK ) );
  329. SendMessage( hwnd, DM_SETDEFID, IDOK, 0L );
  330. EnableWindow( GetDlgItem( hwnd, IDC_REMOVE ),
  331. ListBox_GetSelItems( hPlayWnd, 1, items ) == 1 );
  332. break;
  333. case IDC_DEFAULT:
  334. /*
  335. ** Clear the existing play list and then add the each item from the
  336. ** available tracks listbox maintaing the same order as the available
  337. ** tracks.
  338. */
  339. SetWindowRedraw( hPlayWnd, FALSE );
  340. ListBox_ResetContent( hPlayWnd );
  341. num = ListBox_GetCount( hAvailWnd );
  342. for ( i = 0; i < num; i++ ) {
  343. ListBox_GetText( hAvailWnd, i, s );
  344. dwData = ListBox_GetItemData( hAvailWnd, i );
  345. index = ListBox_AddString( hPlayWnd, s );
  346. ListBox_SetItemData( hPlayWnd, index, dwData );
  347. }
  348. SetWindowRedraw( hPlayWnd, TRUE );
  349. CheckButtons( hwnd );
  350. fPlaylistChanged = TRUE;
  351. break;
  352. case IDOK:
  353. /*
  354. ** Here is where we extract the current play list and
  355. ** available tracks list from the two list boxes.
  356. **
  357. ** If we can't lock the toc for this drive ignore the OK button click
  358. ** the user user will either try again or press cancel.
  359. **
  360. */
  361. if ( LockTableOfContents( dCdrom ) == FALSE ) {
  362. break;
  363. }
  364. /*
  365. ** OK, we've locked the toc for this drive. Now we have to check that
  366. ** it still has the original disk inside it. If the disks match
  367. ** we copy the strings from the available tracks list box straight
  368. ** it the track info structure for this cdrom and update the
  369. ** playlist.
  370. */
  371. if ( g_Devices[ dCdrom ]->CdInfo.Id == dwDiskId ) {
  372. PTRACK_INF pt;
  373. PTRACK_PLAY ppPlay;
  374. PTRACK_PLAY pp;
  375. int m, s, mtemp, stemp;
  376. /*
  377. ** Take care of the track (re)naming function of the dialog
  378. ** box.
  379. */
  380. GetDlgItemText( hwnd, IDC_EDIT_TITLE, TITLE(dCdrom), TITLE_LENGTH );
  381. GetDlgItemText( hwnd, IDC_EDIT_ARTIST, ARTIST(dCdrom), ARTIST_LENGTH );
  382. num = ListBox_GetCount( hAvailWnd );
  383. pt = ALLTRACKS( dCdrom );
  384. for ( i = 0; (pt != NULL) && (i < num); i++ ) {
  385. ListBox_GetText( hAvailWnd, i, pt->name );
  386. pt = pt->next;
  387. }
  388. /*
  389. ** make sure that we read all the tracks from the listbox.
  390. */
  391. ASSERT( i == num );
  392. /*
  393. ** Now take care of the playlist editing function of the
  394. ** dialog box.
  395. */
  396. if (fPlaylistChanged) {
  397. if ( CURRTRACK(dCdrom) != NULL ) {
  398. iCurrTrack = CURRTRACK(dCdrom)->TocIndex;
  399. }
  400. else {
  401. iCurrTrack = -1;
  402. }
  403. /*
  404. ** Get the new play list from the listbox and
  405. ** look for the previous track in the new play list.
  406. */
  407. ppPlay = ConstructPlayListFromListbox();
  408. for ( pp = ppPlay; pp != NULL; pp = pp->nextplay ) {
  409. if ( pp->TocIndex == iCurrTrack ) {
  410. break;
  411. }
  412. }
  413. /*
  414. ** If the track was not found in the new track list and this
  415. ** cd is currently playing then stop it.
  416. */
  417. if ( (pp == NULL) && (STATE(dCdrom) & (CD_PLAYING | CD_PAUSED)) ) {
  418. SendDlgItemMessage( g_hwndApp, IDM_PLAYBAR_STOP,
  419. WM_LBUTTONDOWN, 1, 0 );
  420. SendDlgItemMessage( g_hwndApp, IDM_PLAYBAR_STOP,
  421. WM_LBUTTONUP, 1, 0 );
  422. }
  423. /*
  424. ** Swap over the playlists.
  425. */
  426. ErasePlayList( dCdrom );
  427. EraseSaveList( dCdrom );
  428. PLAYLIST(dCdrom) = ppPlay;
  429. SAVELIST(dCdrom) = CopyPlayList( PLAYLIST(dCdrom) );
  430. /*
  431. ** Set the current track.
  432. */
  433. if ( pp != NULL ) {
  434. CURRTRACK( dCdrom ) = pp;
  435. }
  436. else {
  437. CURRTRACK( dCdrom ) = PLAYLIST( dCdrom );
  438. }
  439. /*
  440. ** If we were previously in "Random" mode shuffle the new
  441. ** playlist.
  442. */
  443. if (!g_fSelectedOrder) {
  444. ComputeSingleShufflePlayList( dCdrom );
  445. }
  446. /*
  447. ** If we were playing, we need to synchronize to make sure
  448. ** we are playing where we should.
  449. */
  450. SyncDisplay();
  451. /*
  452. ** Compute PLAY length
  453. */
  454. m = s = 0;
  455. for( pp = PLAYLIST(dCdrom); pp != NULL; pp = pp->nextplay ) {
  456. FigureTrackTime( dCdrom, pp->TocIndex, &mtemp, &stemp );
  457. m+=mtemp;
  458. s+=stemp;
  459. pp->min = mtemp;
  460. pp->sec = stemp;
  461. }
  462. m += (s / 60);
  463. s = (s % 60);
  464. CDTIME(dCdrom).TotalMin = m;
  465. CDTIME(dCdrom).TotalSec = s;
  466. /*
  467. ** Make sure that the track time displayed in the LED and the
  468. ** status bar is correct. If we have a current track and the
  469. ** CD is playing or paused then everything is OK. Otherwise, we
  470. ** have to reset the track times.
  471. */
  472. if ( CURRTRACK( dCdrom ) != NULL ) {
  473. if ( STATE(dCdrom) & CD_STOPPED ) {
  474. CDTIME(g_CurrCdrom).TrackTotalMin = CURRTRACK( dCdrom )->min;
  475. CDTIME(g_CurrCdrom).TrackRemMin = CURRTRACK( dCdrom )->min;
  476. CDTIME(g_CurrCdrom).TrackTotalSec = CURRTRACK( dCdrom )->sec;
  477. CDTIME(g_CurrCdrom).TrackRemSec = CURRTRACK( dCdrom )->sec;
  478. }
  479. }
  480. else {
  481. CDTIME(g_CurrCdrom).TrackTotalMin = 0;
  482. CDTIME(g_CurrCdrom).TrackRemMin = 0;
  483. CDTIME(g_CurrCdrom).TrackTotalSec = 0;
  484. CDTIME(g_CurrCdrom).TrackRemSec = 0;
  485. }
  486. UpdateDisplay( DISPLAY_UPD_DISC_TIME );
  487. }
  488. /*
  489. ** Now force repaints of the relevant field in the main application
  490. */
  491. InvalidateRect(GetDlgItem(g_hwndApp, IDC_ARTIST_NAME), NULL, FALSE);
  492. SetDlgItemText( g_hwndApp, IDC_TITLE_NAME, TITLE(dCdrom) );
  493. ResetTrackComboBox( dCdrom );
  494. }
  495. /*
  496. ** Now save the tracks to disk.
  497. */
  498. UpdateEntryFromDiskInfoDialog( dwDiskId, hwnd );
  499. SetPlayButtonsEnableState();
  500. case IDCANCEL:
  501. EndDialog( hwnd, id );
  502. break;
  503. }
  504. }
  505. /*****************************Private*Routine******************************\
  506. * DlgDiskInfo_OnDrawItem
  507. *
  508. *
  509. *
  510. * History:
  511. * 18-11-93 - StephenE - Created
  512. *
  513. \**************************************************************************/
  514. BOOL
  515. DlgDiskInfo_OnDrawItem(
  516. HWND hwnd,
  517. const DRAWITEMSTRUCT *lpdis
  518. )
  519. {
  520. if ( (lpdis->itemAction & ODA_DRAWENTIRE) ||
  521. (lpdis->itemAction & ODA_SELECT) ) {
  522. DrawListItem( lpdis->hDC, &lpdis->rcItem,
  523. lpdis->itemData, lpdis->itemState & ODS_SELECTED );
  524. if ( lpdis->itemState & ODS_FOCUS ) {
  525. DrawFocusRect( lpdis->hDC, &lpdis->rcItem );
  526. }
  527. return TRUE;
  528. }
  529. return FALSE;
  530. }
  531. /*****************************Private*Routine******************************\
  532. * DlgDiskInfo_OnDestroy
  533. *
  534. *
  535. *
  536. * History:
  537. * dd-mm-93 - StephenE - Created
  538. *
  539. \**************************************************************************/
  540. void
  541. DlgDiskInfo_OnDestroy(
  542. HWND hwnd
  543. )
  544. {
  545. if ( hdcMem ) {
  546. DeleteDC( hdcMem );
  547. }
  548. }
  549. /*****************************Private*Routine******************************\
  550. * InitForNewDrive
  551. *
  552. *
  553. *
  554. * History:
  555. * dd-mm-93 - StephenE - Created
  556. *
  557. \**************************************************************************/
  558. void
  559. InitForNewDrive(
  560. HWND hwnd
  561. )
  562. {
  563. int index;
  564. PTRACK_INF t;
  565. PTRACK_PLAY t1;
  566. TCHAR s[50];
  567. SetDlgItemText( hwnd, IDC_EDIT_TITLE, TITLE(dCdrom) );
  568. SetDlgItemText( hwnd, IDC_EDIT_ARTIST, ARTIST(dCdrom) );
  569. SetDlgItemText( hwnd, IDC_EDIT_TRACK, ALLTRACKS(dCdrom)->name );
  570. wsprintf( s, TEXT("\\Device\\CdRom%d <%c:>"),
  571. dCdrom, g_Devices[dCdrom]->drive );
  572. SetDlgItemText( hwnd, IDC_SJETEXT_DRIVE, s );
  573. /*
  574. ** Fill in current tracks. This list contains all the available tracks
  575. ** in the correct track order.
  576. */
  577. SetWindowRedraw( hAvailWnd, FALSE );
  578. ListBox_ResetContent( hAvailWnd );
  579. for( t = ALLTRACKS(dCdrom); t != NULL; t = t->next ) {
  580. index = ListBox_AddString( hAvailWnd, t->name );
  581. ListBox_SetItemData( hAvailWnd, index, t->TocIndex );
  582. }
  583. SetWindowRedraw( hAvailWnd, TRUE );
  584. /*
  585. ** Fill in current play list
  586. */
  587. SetWindowRedraw( hPlayWnd, FALSE );
  588. ListBox_ResetContent( hPlayWnd );
  589. for( t1 = SAVELIST(dCdrom); t1 != NULL; t1 = t1->nextplay ) {
  590. t = FindTrackNodeFromTocIndex( t1->TocIndex, ALLTRACKS(dCdrom) );
  591. if ( t != NULL ) {
  592. index = ListBox_AddString( hPlayWnd, t->name );
  593. ListBox_SetItemData( hPlayWnd, index, t->TocIndex );
  594. }
  595. }
  596. SetWindowRedraw( hPlayWnd, TRUE );
  597. /*
  598. ** Display correct track in track field and
  599. ** set CurrTocIndex to first entry in playlist listbox
  600. */
  601. UpdateTrackName( hwnd, 0 );
  602. }
  603. /*****************************Private*Routine******************************\
  604. * DrawListItem
  605. *
  606. * This routine draws items in the PlayList and Available Tracks
  607. * listboxes.
  608. *
  609. * History:
  610. * dd-mm-93 - StephenE - Created
  611. *
  612. \**************************************************************************/
  613. void
  614. DrawListItem(
  615. HDC hdc,
  616. const RECT *rItem,
  617. DWORD itemIndex,
  618. BOOL selected
  619. )
  620. {
  621. DWORD dwROP;
  622. SIZE si;
  623. UINT i;
  624. TCHAR s[TRACK_TITLE_LENGTH];
  625. TCHAR szDotDot[] = TEXT("... ");
  626. int cxDotDot;
  627. /*
  628. ** Check selection status, and set up to draw correctly
  629. */
  630. if ( selected ) {
  631. SetBkColor( hdc, GetSysColor( COLOR_HIGHLIGHT ) );
  632. SetTextColor( hdc, GetSysColor( COLOR_HIGHLIGHTTEXT ) );
  633. dwROP = MERGEPAINT;
  634. }
  635. else {
  636. SetBkColor( hdc, GetSysColor(COLOR_WINDOW));
  637. SetTextColor( hdc, GetSysColor(COLOR_WINDOWTEXT));
  638. dwROP = SRCAND;
  639. }
  640. /*
  641. ** Get track string
  642. */
  643. ListBox_GetText( hAvailWnd, itemIndex, s );
  644. /*
  645. ** Do we need to munge track name (clip to listbox)?
  646. */
  647. GetTextExtentPoint( hdc, szDotDot, _tcslen( szDotDot ), &si );
  648. cxDotDot = si.cx;
  649. i = _tcslen( s ) + 1;
  650. do {
  651. GetTextExtentPoint( hdc, s, --i, &si );
  652. } while( si.cx > (rItem->right - cxDotDot - 20) );
  653. /*
  654. ** Draw track name
  655. */
  656. ExtTextOut( hdc, rItem->left + 20, rItem->top, ETO_OPAQUE | ETO_CLIPPED,
  657. rItem, s, i, NULL );
  658. if ( _tcslen( s ) > i ) {
  659. ExtTextOut( hdc, rItem->left + si.cx + 20, rItem->top, ETO_CLIPPED,
  660. rItem, szDotDot, _tcslen(szDotDot), NULL );
  661. }
  662. /*
  663. ** draw cd icon for each track
  664. */
  665. BitBlt( hdc, rItem->left, rItem->top, 14, 14, hdcMem, 0, 0, dwROP );
  666. }
  667. /*****************************Private*Routine******************************\
  668. * GrabTrackName
  669. *
  670. * This routine reads the track name from the track name edit
  671. * control and updates the screen and internal structures with the
  672. * new track name.
  673. *
  674. * History:
  675. * dd-mm-93 - StephenE - Created
  676. *
  677. \**************************************************************************/
  678. void
  679. GrabTrackName(
  680. HWND hwnd,
  681. int tocindex
  682. )
  683. {
  684. int i, num;
  685. TCHAR s[TRACK_TITLE_LENGTH];
  686. /*
  687. ** Get new title
  688. */
  689. GetDlgItemText( hwnd, IDC_EDIT_TRACK, s, TRACK_TITLE_LENGTH );
  690. /*
  691. ** Update the "track" list.
  692. */
  693. SetWindowRedraw( hAvailWnd, FALSE );
  694. ListBox_DeleteString( hAvailWnd, tocindex );
  695. ListBox_InsertString( hAvailWnd, tocindex, s );
  696. ListBox_SetItemData( hAvailWnd, tocindex, tocindex );
  697. SetWindowRedraw( hAvailWnd, TRUE );
  698. /*
  699. ** Redraw list entries with new title in playlist listbox...there
  700. ** can be more than one
  701. */
  702. SetWindowRedraw( hPlayWnd, FALSE );
  703. num = ListBox_GetCount( hPlayWnd );
  704. for( i = 0; i < num; i++ ) {
  705. if ( ListBox_GetItemData( hPlayWnd, i ) == tocindex ) {
  706. ListBox_DeleteString( hPlayWnd, i );
  707. ListBox_InsertString( hPlayWnd, i, s );
  708. ListBox_SetItemData( hPlayWnd, i, tocindex );
  709. }
  710. }
  711. SetWindowRedraw( hPlayWnd, TRUE );
  712. EnableWindow( GetDlgItem( hwnd, IDC_REMOVE ), FALSE );
  713. }
  714. /*****************************Private*Routine******************************\
  715. * UpdateTrackName
  716. *
  717. *
  718. * History:
  719. * dd-mm-93 - StephenE - Created
  720. *
  721. \**************************************************************************/
  722. void
  723. UpdateTrackName(
  724. HWND hwnd,
  725. int index
  726. )
  727. {
  728. TCHAR s[TRACK_TITLE_LENGTH];
  729. int iFirstTrack;
  730. /*
  731. ** Before using the FIRSTTRACK macro we have to check that we can
  732. ** lock the TOC and that the original disk is still in the drive. If this
  733. ** is not the case "assume" that the first track is track 1.
  734. */
  735. if ( LockTableOfContents(dCdrom)
  736. && g_Devices[dCdrom]->CdInfo.Id == dwDiskId ) {
  737. iFirstTrack = FIRSTTRACK(dCdrom);
  738. }
  739. else {
  740. iFirstTrack = 1;
  741. }
  742. ListBox_GetText( hAvailWnd, index, s );
  743. SetDlgItemText( hwnd, IDC_EDIT_TRACK, s );
  744. wsprintf( s, IdStr( STR_TRACK1 ), index + iFirstTrack);
  745. SetDlgItemText( hwnd, IDC_STATIC_TRACK, s );
  746. SendMessage( GetDlgItem( hwnd, IDC_EDIT_TRACK ),
  747. EM_SETSEL, 0, (LPARAM)-1 );
  748. CurrTocIndex = index;
  749. fChanged = FALSE;
  750. }
  751. /*****************************Private*Routine******************************\
  752. * ConstructPlayListFromListbox
  753. *
  754. *
  755. * History:
  756. * dd-mm-93 - StephenE - Created
  757. *
  758. \**************************************************************************/
  759. PTRACK_PLAY
  760. ConstructPlayListFromListbox(
  761. void
  762. )
  763. {
  764. int num;
  765. int i;
  766. int mtemp, stemp;
  767. DWORD dwData;
  768. PTRACK_PLAY t1, tend, tret;
  769. tret = tend = NULL;
  770. num = ListBox_GetCount( hPlayWnd );
  771. for ( i = 0; i < num; i++ ) {
  772. dwData = ListBox_GetItemData( hPlayWnd, i );
  773. t1 = AllocMemory( sizeof(TRACK_PLAY) );
  774. t1->TocIndex = dwData;
  775. t1->min = 0;
  776. t1->sec = 0;
  777. t1->nextplay = NULL;
  778. t1->prevplay = tend;
  779. if ( tret == NULL ) {
  780. tret = tend = t1;
  781. }
  782. else {
  783. tend->nextplay = t1;
  784. tend = t1;
  785. }
  786. }
  787. /*
  788. ** Compute play length
  789. */
  790. mtemp = stemp = 0;
  791. for( t1 = tret; t1 != NULL; t1 = t1->nextplay ) {
  792. FigureTrackTime( dCdrom, t1->TocIndex, &mtemp, &stemp );
  793. t1->min = mtemp;
  794. t1->sec = stemp;
  795. }
  796. return tret;
  797. }
  798. /*****************************Private*Routine******************************\
  799. * UpdateEntryFromDiskInfoDialog
  800. *
  801. * Here we decide if we need to update the entire track record or just
  802. * a portion of it. This saves a lot of space in the cdplayer.ini file if the
  803. * user only changes the artist name and disk title fields.
  804. *
  805. * History:
  806. * dd-mm-93 - StephenE - Created
  807. *
  808. \**************************************************************************/
  809. void
  810. UpdateEntryFromDiskInfoDialog(
  811. DWORD dwDiskId,
  812. HWND hwnd
  813. )
  814. {
  815. if (fTrackNamesChanged) {
  816. WriteAllEntries( dwDiskId, hwnd );
  817. }
  818. else {
  819. TCHAR Section[10];
  820. TCHAR Buff[512];
  821. TCHAR Name[128];
  822. wsprintf( Section, g_szSectionF, dwDiskId );
  823. /* Write entry type (always 1) */
  824. wsprintf( Buff, TEXT("%d"), 1 );
  825. WritePrivateProfileString(Section, g_szEntryType, Buff, g_IniFileName);
  826. /* Write artist name */
  827. GetDlgItemText( hwnd, IDC_EDIT_ARTIST, Name, ARTIST_LENGTH );
  828. wsprintf( Buff, TEXT("%s"), Name );
  829. WritePrivateProfileString(Section, g_szArtist, Buff, g_IniFileName);
  830. /* Write CD Title */
  831. GetDlgItemText( hwnd, IDC_EDIT_TITLE, Name, TITLE_LENGTH );
  832. wsprintf( Buff, TEXT("%s"), Name );
  833. WritePrivateProfileString(Section, g_szTitle, Buff, g_IniFileName);
  834. /* Write the number of tracks on the disc */
  835. wsprintf( Buff, TEXT("%d"), ListBox_GetCount( hAvailWnd ) );
  836. WritePrivateProfileString(Section, g_szNumTracks, Buff, g_IniFileName);
  837. /* Only write the playlist if it has actually changed */
  838. if (fPlaylistChanged) {
  839. LPTSTR s, sSave;
  840. DWORD dwData;
  841. int i, num;
  842. num = ListBox_GetCount( hPlayWnd );
  843. sSave = s = AllocMemory( num * 4 * sizeof(TCHAR) );
  844. for ( i = 0; i < num; i++ ) {
  845. dwData = ListBox_GetItemData( hPlayWnd, i );
  846. s += wsprintf( s, TEXT("%d "), dwData );
  847. }
  848. WritePrivateProfileString(Section, g_szOrder, sSave, g_IniFileName);
  849. /* Write number of tracks in current playlist */
  850. wsprintf( Buff, TEXT("%d"), num );
  851. WritePrivateProfileString(Section, g_szNumPlay, Buff, g_IniFileName);
  852. LocalFree( (HLOCAL)sSave );
  853. }
  854. }
  855. }
  856. /*****************************Private*Routine******************************\
  857. * WriteAllEntries
  858. *
  859. *
  860. * This monster updates the cdpayer database for the current disk it writes
  861. * all the entries to the database.
  862. *
  863. * History:
  864. * dd-mm-94 - StephenE - Created
  865. *
  866. \**************************************************************************/
  867. void
  868. WriteAllEntries(
  869. DWORD dwDiskId,
  870. HWND hwnd
  871. )
  872. {
  873. TCHAR *Buffer;
  874. TCHAR Section[10];
  875. TCHAR Name[128];
  876. DWORD dwData;
  877. LPTSTR s;
  878. int i;
  879. int num;
  880. //
  881. // Construct ini file buffer, form of:
  882. // EntryType = 1
  883. // artist = artist name
  884. // title = Title of disc
  885. // numtracks = n
  886. // 0 = Title of track 1
  887. // 1 = Title of track 2
  888. // n-1 = Title of track n
  889. // order = 0 4 3 2 6 7 8 ... (n-1)
  890. // numplay = # of entries in order list
  891. //
  892. Buffer = AllocMemory( 64000 * sizeof(TCHAR) );
  893. wsprintf( Section, g_szSectionF, dwDiskId );
  894. s = Buffer;
  895. num = ListBox_GetCount( hAvailWnd );
  896. //
  897. // I assume EntryType=1 means use the new hashing scheme
  898. //
  899. s += 1 + wsprintf( s, g_szEntryTypeF, 1 );
  900. //
  901. // Save the artists name.
  902. //
  903. GetDlgItemText( hwnd, IDC_EDIT_ARTIST, Name, ARTIST_LENGTH );
  904. s += 1 + wsprintf( s, g_szArtistF, Name );
  905. //
  906. // Save the CD Title
  907. //
  908. GetDlgItemText( hwnd, IDC_EDIT_TITLE, Name, TITLE_LENGTH );
  909. s += 1 + wsprintf( s, g_szTitleF, Name );
  910. s += 1 + wsprintf( s, g_szNumTracksF, num );
  911. //
  912. // Save each track name
  913. //
  914. for ( i = 0; i < num; i++ ) {
  915. ListBox_GetText( hAvailWnd, i, Name );
  916. dwData = ListBox_GetItemData( hAvailWnd, i );
  917. s += 1 + wsprintf( s, TEXT("%d=%s"), dwData, Name );
  918. }
  919. //
  920. // Save the play order
  921. //
  922. num = ListBox_GetCount( hPlayWnd );
  923. s += wsprintf( s, g_szOrderF );
  924. for ( i = 0; i < num; i++ ) {
  925. dwData = ListBox_GetItemData( hPlayWnd, i );
  926. s += wsprintf( s, TEXT("%d "), dwData );
  927. }
  928. s += 1;
  929. //
  930. // Save the number of tracks in the play list
  931. //
  932. s += 1 + wsprintf( s, g_szNumPlayF, num );
  933. //
  934. // Just make sure there are NULLs at end of buffer
  935. //
  936. wsprintf( s, g_szThreeNulls );
  937. //
  938. // Try writing buffer into ini file
  939. //
  940. WritePrivateProfileSection( Section, Buffer, g_IniFileName );
  941. LocalFree( (HLOCAL)Buffer );
  942. }
  943. /*****************************Private*Routine******************************\
  944. * Lbox_OnQueryDrop
  945. *
  946. * Is a mouse drop allowed at the current mouse position.
  947. *
  948. * History:
  949. * dd-mm-93 - StephenE - Created
  950. *
  951. \**************************************************************************/
  952. BOOL
  953. DlgDiskInfo_OnQueryDrop(
  954. HWND hwnd,
  955. HWND hwndDrop,
  956. HWND hwndSrc,
  957. POINT ptDrop,
  958. DWORD dwState
  959. )
  960. {
  961. int index;
  962. index = InsertIndex( hwnd, ptDrop, TRUE );
  963. if ( index >= 0 ) {
  964. if ( (hwndSrc == hPlayWnd) && (dwState == DL_COPY) ) {
  965. SetCursor( g_hCursorDropCpy );
  966. }
  967. else {
  968. SetCursor( g_hCursorDrop );
  969. }
  970. }
  971. else if ( IsInListbox( hwnd, hAvailWnd, ptDrop ) ) {
  972. if ( hwndSrc == hPlayWnd ) {
  973. SetCursor( g_hCursorDropDel );
  974. }
  975. else {
  976. SetCursor( g_hCursorDrop );
  977. }
  978. }
  979. else {
  980. SetCursor( g_hCursorNoDrop );
  981. }
  982. SetWindowLong( hwnd, DWL_MSGRESULT, FALSE );
  983. return TRUE;
  984. }
  985. /*****************************Private*Routine******************************\
  986. * Lbox_OnProcessDrop
  987. *
  988. * Process mouse drop(ping)s here.
  989. *
  990. * History:
  991. * dd-mm-93 - StephenE - Created
  992. *
  993. \**************************************************************************/
  994. BOOL
  995. DlgDiskInfo_OnProcessDrop(
  996. HWND hwnd,
  997. HWND hwndDrop,
  998. HWND hwndSrc,
  999. POINT ptDrop,
  1000. DWORD dwState
  1001. )
  1002. {
  1003. int index;
  1004. /*
  1005. ** Are we dropping on the play list window ?
  1006. */
  1007. if ( hwndDrop == hPlayWnd ) {
  1008. index = InsertIndex( hwnd, ptDrop, FALSE );
  1009. /*
  1010. ** Is it OK to drop here ?
  1011. */
  1012. if ( index >= 0 ) {
  1013. /*
  1014. ** Is this an inter or intra window drop
  1015. */
  1016. if ( hwndSrc == hAvailWnd ) {
  1017. AddTrackListSelection( hwnd, index );
  1018. }
  1019. /*
  1020. ** An intra window drop !!
  1021. */
  1022. else if ( hwndSrc == hPlayWnd ) {
  1023. MoveCopySelection( index, dwState );
  1024. }
  1025. }
  1026. }
  1027. /*
  1028. ** Are we dropping on the available tracks list box and the source window
  1029. ** was the play listbox
  1030. */
  1031. else if ( hwndDrop == hAvailWnd && hwndSrc == hPlayWnd ) {
  1032. RemovePlayListSelection( hwnd );
  1033. }
  1034. SetWindowLong( hwnd, DWL_MSGRESULT, FALSE );
  1035. return TRUE;
  1036. }
  1037. /*****************************Private*Routine******************************\
  1038. * InsertIndex
  1039. *
  1040. * If the mouse is over the playlist window return what would be the current
  1041. * insertion position, otherwise return -1.
  1042. *
  1043. * History:
  1044. * dd-mm-93 - StephenE - Created
  1045. *
  1046. \**************************************************************************/
  1047. int
  1048. InsertIndex(
  1049. HWND hDlg,
  1050. POINT pt,
  1051. BOOL bDragging
  1052. )
  1053. {
  1054. int nItem;
  1055. int nCount;
  1056. nCount = ListBox_GetCount( hPlayWnd );
  1057. nItem = LBMultiItemFromPt( hPlayWnd, pt, bDragging );
  1058. /*
  1059. ** If the mouse is not over any particular list item, but it is inside
  1060. ** the client area of the listbox just append to end of the listbox.
  1061. */
  1062. if ( nItem == -1 ) {
  1063. if ( IsInListbox( hDlg, hPlayWnd, pt ) ) {
  1064. nItem = nCount;
  1065. }
  1066. }
  1067. /*
  1068. ** Otherwise, if the mouse is over a list item and there is
  1069. ** at least one item in the listbox determine if the inertion point is
  1070. ** above or below the current item.
  1071. */
  1072. else if ( nItem > 0 && nCount > 0 ) {
  1073. long pt_y;
  1074. RECT rc;
  1075. ListBox_GetItemRect( hPlayWnd, nItem, &rc );
  1076. ScreenToClient( hPlayWnd, &pt );
  1077. pt_y = rc.bottom - ((rc.bottom - rc.top) / 2);
  1078. if ( pt.y > pt_y ) {
  1079. nItem++;
  1080. }
  1081. }
  1082. DrawMultiInsert( hDlg, hPlayWnd, bDragging ? nItem : -1 );
  1083. return nItem;
  1084. }
  1085. /*****************************Private*Routine******************************\
  1086. * IsInListBox
  1087. *
  1088. * Is the mouse over the client area of the specified child listbox.
  1089. *
  1090. * History:
  1091. * dd-mm-93 - StephenE - Created
  1092. *
  1093. \**************************************************************************/
  1094. BOOL
  1095. IsInListbox(
  1096. HWND hDlg,
  1097. HWND hwndListbox,
  1098. POINT pt
  1099. )
  1100. {
  1101. RECT rc;
  1102. ScreenToClient(hDlg, &pt);
  1103. if ( ChildWindowFromPoint( hDlg, pt ) == hwndListbox ) {
  1104. GetClientRect( hwndListbox, &rc );
  1105. MapWindowRect( hwndListbox, hDlg, &rc );
  1106. return PtInRect( &rc, pt );
  1107. }
  1108. return FALSE;
  1109. }
  1110. /*****************************Private*Routine******************************\
  1111. * RemovePlayListSelection
  1112. *
  1113. * Here we remove the slected items from the play list listbox.
  1114. *
  1115. * History:
  1116. * dd-mm-93 - StephenE - Created
  1117. *
  1118. \**************************************************************************/
  1119. void
  1120. RemovePlayListSelection(
  1121. HWND hDlg
  1122. )
  1123. {
  1124. int num;
  1125. int i;
  1126. int *pList;
  1127. /*
  1128. ** Get the number of tracks currently selected. Return if an error
  1129. ** occurrs or zero tracks selected.
  1130. */
  1131. num = ListBox_GetSelCount( hPlayWnd );
  1132. if ( num <= 0 ) {
  1133. return;
  1134. }
  1135. pList = AllocMemory( num * sizeof(int) );
  1136. ListBox_GetSelItems( hPlayWnd, num, pList );
  1137. SetWindowRedraw( hPlayWnd, FALSE );
  1138. for ( i = num - 1; i >= 0; i-- ) {
  1139. ListBox_DeleteString( hPlayWnd, pList[i] );
  1140. }
  1141. /*
  1142. ** Now that we have added the above items we reset this selection
  1143. ** and set the caret to first item in the listbox.
  1144. */
  1145. if ( num != 0 ) {
  1146. ListBox_SetSel( hPlayWnd, FALSE, -1 );
  1147. ListBox_SetCaretIndex( hPlayWnd, 0 );
  1148. }
  1149. SetWindowRedraw( hPlayWnd, TRUE );
  1150. LocalFree( (HLOCAL)pList );
  1151. CheckButtons( hDlg );
  1152. fPlaylistChanged = TRUE;
  1153. }
  1154. /*****************************Private*Routine******************************\
  1155. * AddTrackListSelection
  1156. *
  1157. * Here we add the current selection from the tracks available listbox to
  1158. * the current play list listbox. Try to ensure that the last track
  1159. * added to the playlist is visible in the playlist. This aids continuity.
  1160. *
  1161. * History:
  1162. * dd-mm-93 - StephenE - Created
  1163. *
  1164. \**************************************************************************/
  1165. void
  1166. AddTrackListSelection(
  1167. HWND hDlg,
  1168. int iInsertPos
  1169. )
  1170. {
  1171. int i;
  1172. int num;
  1173. int *pList;
  1174. TCHAR s[TRACK_TITLE_LENGTH];
  1175. /*
  1176. ** Get the number of tracks currently selected. Return if an error
  1177. ** occurrs or zero tracks selected.
  1178. */
  1179. num = ListBox_GetSelCount( hAvailWnd );
  1180. if ( num <= 0 ) {
  1181. return;
  1182. }
  1183. pList = AllocMemory( num * sizeof(int) );
  1184. ListBox_GetSelItems( hAvailWnd, num, pList );
  1185. SetWindowRedraw( hPlayWnd, FALSE );
  1186. for ( i = 0; i < num; i++ ) {
  1187. DWORD dwData;
  1188. ListBox_GetText( hAvailWnd, pList[i], s );
  1189. dwData = ListBox_GetItemData( hAvailWnd, pList[i] );
  1190. ListBox_InsertString( hPlayWnd, iInsertPos + i, s );
  1191. ListBox_SetItemData( hPlayWnd, iInsertPos + i, dwData );
  1192. }
  1193. /*
  1194. ** Here we used to un-hilight the selection in the "available
  1195. ** tracks" listbox. Ant didn't like this and raised a bug. Hence
  1196. ** the next few lines are commented out.
  1197. */
  1198. // if ( num != 0 ) {
  1199. // ListBox_SetSel( hAvailWnd, FALSE, -1 );
  1200. // ListBox_SetCaretIndex( hAvailWnd, 0 );
  1201. // }
  1202. /*
  1203. ** Make sure that the last item added to the "Play List" listbox
  1204. ** is visible.
  1205. */
  1206. ListBox_SetCaretIndex( hPlayWnd, iInsertPos + num - 1 );
  1207. SetWindowRedraw( hPlayWnd, TRUE );
  1208. InvalidateRect( hPlayWnd, NULL, FALSE );
  1209. LocalFree( (HLOCAL)pList );
  1210. CheckButtons( hDlg );
  1211. fPlaylistChanged = TRUE;
  1212. }
  1213. /*****************************Private*Routine******************************\
  1214. * CheckButtons
  1215. *
  1216. * Enables or disables the Remove and Clear buttons depending on the content
  1217. * of the play list listbox.
  1218. *
  1219. * History:
  1220. * dd-mm-93 - StephenE - Created
  1221. *
  1222. \**************************************************************************/
  1223. void
  1224. CheckButtons(
  1225. HWND hDlg
  1226. )
  1227. {
  1228. int num;
  1229. int items[1];
  1230. num = ListBox_GetCount( hPlayWnd );
  1231. EnableWindow( GetDlgItem( hDlg, IDC_CLEAR ), (num != 0) );
  1232. EnableWindow( GetDlgItem( hDlg, IDC_REMOVE ),
  1233. ListBox_GetSelItems( hPlayWnd, 1, items ) == 1 );
  1234. }
  1235. /*****************************Private*Routine******************************\
  1236. * MoveCopySelection
  1237. *
  1238. * Moves or copies the selection within the play list listbox.
  1239. *
  1240. * History:
  1241. * dd-mm-93 - StephenE - Created
  1242. *
  1243. \**************************************************************************/
  1244. void
  1245. MoveCopySelection(
  1246. int iInsertPos,
  1247. DWORD dwState
  1248. )
  1249. {
  1250. int num;
  1251. int i;
  1252. int *pList;
  1253. LIST_INFO *pInfo;
  1254. /*
  1255. ** Get the number of tracks currently selected. Return if an error
  1256. ** occurrs or zero tracks selected.
  1257. */
  1258. num = ListBox_GetSelCount( hPlayWnd );
  1259. if ( num <= 0 ) {
  1260. return;
  1261. }
  1262. pList = AllocMemory( num * sizeof(int) );
  1263. pInfo = AllocMemory( num * sizeof(LIST_INFO) );
  1264. ListBox_GetSelItems( hPlayWnd, num, pList );
  1265. SetWindowRedraw( hPlayWnd, FALSE );
  1266. for ( i = num - 1; i >= 0; i-- ) {
  1267. ListBox_GetText( hPlayWnd, pList[i], pInfo[i].chName );
  1268. pInfo[i].dwData = ListBox_GetItemData( hPlayWnd, pList[i] );
  1269. if ( dwState == DL_MOVE ) {
  1270. pInfo[i].index = pList[i];
  1271. ListBox_DeleteString( hPlayWnd, pList[i] );
  1272. }
  1273. }
  1274. if ( dwState == DL_MOVE ) {
  1275. /*
  1276. ** for each selected item that was above the insertion point
  1277. ** reduce the insertion point by 1.
  1278. */
  1279. int iTempInsertionPt = iInsertPos;
  1280. for ( i = 0; i < num; i++ ) {
  1281. if ( pInfo[i].index < iInsertPos ) {
  1282. iTempInsertionPt--;
  1283. }
  1284. }
  1285. iInsertPos = iTempInsertionPt;
  1286. }
  1287. for ( i = 0; i < num; i++ ) {
  1288. ListBox_InsertString( hPlayWnd, iInsertPos + i, pInfo[i].chName );
  1289. ListBox_SetItemData( hPlayWnd, iInsertPos + i, pInfo[i].dwData );
  1290. }
  1291. /*
  1292. ** Now that we have added the above items we reset this selection
  1293. ** and set the caret to first item in the listbox.
  1294. */
  1295. if ( num != 0 ) {
  1296. ListBox_SetSel( hPlayWnd, FALSE, -1 );
  1297. ListBox_SetCaretIndex( hPlayWnd, 0 );
  1298. }
  1299. SetWindowRedraw( hPlayWnd, TRUE );
  1300. LocalFree( (HLOCAL)pList );
  1301. LocalFree( (HLOCAL)pInfo );
  1302. fPlaylistChanged = TRUE;
  1303. }