|
|
/******************************Module*Header*******************************\
* Module Name: diskinfo.c * * Support for the diskinfo dialog box. * * * Created: 18-11-93 * Author: Stephen Estrop [StephenE] * * Copyright (c) 1993 Microsoft Corporation \**************************************************************************/ #pragma warning( once : 4201 4214 )
#define NOOLE
#define NODRAGLIST
#include <windows.h> /* required for all Windows applications */
#include <windowsx.h>
#include <string.h>
#include <malloc.h>
#include <stdarg.h>
#include <stdio.h>
#include <tchar.h>
#include "resource.h"
#include "cdplayer.h"
#include "ledwnd.h"
#include "cdapi.h"
#include "scan.h"
#include "trklst.h"
#include "database.h"
#include "diskinfo.h"
#include "dragdrop.h"
#include "literals.h"
/*
** This structure is used during the drag/drop copy/move operations. */ typedef struct { int index; DWORD dwData; TCHAR chName[TRACK_TITLE_LENGTH]; } LIST_INFO;
int dCdrom; /* The ID of the physical cdrom drive being edited */ DWORD dwDiskId; /* The unique ID of the current disk being edited */
HWND hAvailWnd; /* cached hwnd of the available tracks listbox */ HWND hPlayWnd; /* cached hwnd of the play list listbox */
int CurrTocIndex; /* Index into the available tracks listbox of the */ /* track currently being edited. */
BOOL fChanged; /* Has the current track name changed. */ HDC hdcMem; /* Temporary hdc used to draw the track bitmap. */ BOOL fPlaylistChanged; /* Has the playlist been altered ? */ BOOL fTrackNamesChanged; /* Has the playlist been altered ? */ UINT g_DragMessage; /* Message ID of drag drop interface */ HCURSOR g_hCursorDrop; /* Drops allowed cursor */ HCURSOR g_hCursorNoDrop; /* Drops not allowed cursor */ HCURSOR g_hCursorDropDel; /* Drop deletes the selection */ HCURSOR g_hCursorDropCpy; /* Drop copies the selection */
/******************************Public*Routine******************************\
* DiskInfoDlgProc * * * * History: * dd-mm-93 - StephenE - Created * \**************************************************************************/ BOOL CALLBACK DiskInfoDlgProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam ) { #if WINVER >= 0x0400
#include "helpids.h"
static const DWORD aIds[] = { IDC_STATIC_DRIVE, IDH_CD_DRIVE_NAME, IDC_SJETEXT_DRIVE, IDH_CD_DRIVE_NAME, IDC_STATIC_ARTIST, IDH_CD_GET_ARTIST, IDC_EDIT_ARTIST, IDH_CD_GET_ARTIST, IDC_STATIC_TITLE, IDH_CD_GET_TITLE, IDC_EDIT_TITLE, IDH_CD_GET_TITLE, IDC_STATIC_PLAY_LIST, IDH_CD_PLAY_LISTBOX, IDC_LISTBOX_PLAY_LIST, IDH_CD_PLAY_LISTBOX, IDC_ADD, IDH_CD_ADD, IDC_REMOVE, IDH_CD_REMOVE, IDC_CLEAR, IDH_CD_CLEAR, IDC_DEFAULT, IDH_CD_DEFAULT, IDC_STATIC_AVAILABLE_TRACKS, IDH_CD_TRACK_LISTBOX, IDC_LISTBOX_AVAILABLE_TRACKS, IDH_CD_TRACK_LISTBOX, IDC_STATIC_TRACK, IDH_CD_TRACK_NAME, IDC_EDIT_TRACK, IDH_CD_TRACK_NAME, IDC_SETNAME, IDH_CD_SETNAME, 0, 0 }; #endif
LPDRAGMULTILISTINFO lpns; HWND hwndDrop;
/*
** Process any drag/drop notifications first. ** ** wParam == The ID of the drag source. ** lParam == A pointer to a DRAGLISTINFO structure */ if ( message == g_DragMessage ) {
lpns = (LPDRAGMULTILISTINFO)lParam; hwndDrop = WindowFromPoint( lpns->ptCursor );
switch ( lpns->uNotification ) {
case DL_BEGINDRAG: return SetDlgMsgResult( hwnd, WM_COMMAND, TRUE );
case DL_DRAGGING: return DlgDiskInfo_OnQueryDrop( hwnd, hwndDrop, lpns->hWnd, lpns->ptCursor, lpns->dwState );
case DL_DROPPED: return DlgDiskInfo_OnProcessDrop( hwnd, hwndDrop, lpns->hWnd, lpns->ptCursor, lpns->dwState );
case DL_CANCELDRAG: InsertIndex( hwnd, lpns->ptCursor, FALSE ); break;
} return SetDlgMsgResult( hwnd, WM_COMMAND, FALSE ); }
switch ( message ) {
HANDLE_MSG( hwnd, WM_INITDIALOG, DlgDiskInfo_OnInitDialog ); HANDLE_MSG( hwnd, WM_DRAWITEM, DlgDiskInfo_OnDrawItem ); HANDLE_MSG( hwnd, WM_COMMAND, DlgDiskInfo_OnCommand ); HANDLE_MSG( hwnd, WM_DESTROY, DlgDiskInfo_OnDestroy ); HANDLE_MSG( hwnd, WM_CTLCOLORDLG, Common_OnCtlColor ); HANDLE_MSG( hwnd, WM_CTLCOLORSTATIC, Common_OnCtlColor ); HANDLE_MSG( hwnd, WM_MEASUREITEM, Common_OnMeasureItem );
#if WINVER >= 0x0400
case WM_HELP: WinHelp( ((LPHELPINFO)lParam)->hItemHandle, g_HelpFileName, HELP_WM_HELP, (DWORD)(LPVOID)aIds ); break;
case WM_CONTEXTMENU: WinHelp( (HWND)wParam, g_HelpFileName, HELP_CONTEXTMENU, (DWORD)(LPVOID)aIds ); break; #endif
default: return FALSE; } }
/*****************************Private*Routine******************************\
* DlgDiskInfo_OnInitDialog * * * * History: * 18-11-93 - StephenE - Created * \**************************************************************************/ BOOL DlgDiskInfo_OnInitDialog( HWND hwnd, HWND hwndFocus, LPARAM lParam ) { HDC hdc; UINT num;
#ifdef DAYTONA
if (g_hDlgFont) {
/* Static edit field */ SendDlgItemMessage( hwnd, IDC_SJETEXT_DRIVE, WM_SETFONT, (WPARAM)(g_hDlgFont), 0L ); /* Dynamic edit fields */ SendDlgItemMessage( hwnd, IDC_EDIT_ARTIST, WM_SETFONT, (WPARAM)(g_hDlgFont), 0L ); SendDlgItemMessage( hwnd, IDC_EDIT_TITLE, WM_SETFONT, (WPARAM)(g_hDlgFont), 0L ); SendDlgItemMessage( hwnd, IDC_EDIT_TRACK, WM_SETFONT, (WPARAM)(g_hDlgFont), 0L );
/* Owner draw listboxes */ SendDlgItemMessage( hwnd, IDC_LISTBOX_PLAY_LIST, WM_SETFONT, (WPARAM)(g_hDlgFont), 0L );
SendDlgItemMessage( hwnd, IDC_LISTBOX_AVAILABLE_TRACKS, WM_SETFONT, (WPARAM)(g_hDlgFont), 0L ); } #endif
dCdrom = (int)lParam; dwDiskId = g_Devices[ dCdrom ]->CdInfo.Id; g_DragMessage = InitDragMultiList();
if (g_hCursorNoDrop == NULL) { g_hCursorNoDrop = LoadCursor(NULL, IDC_NO); }
if (g_hCursorDrop == NULL) { g_hCursorDrop = LoadCursor(g_hInst, MAKEINTRESOURCE(IDR_DROP)); }
if (g_hCursorDropDel == NULL) { g_hCursorDropDel = LoadCursor(g_hInst, MAKEINTRESOURCE(IDR_DROPDEL)); }
if (g_hCursorDropCpy == NULL) { g_hCursorDropCpy = LoadCursor(g_hInst, MAKEINTRESOURCE(IDR_DROPCPY)); }
/*
** Cache the two listbox window handles. */ hPlayWnd = GetDlgItem( hwnd, IDC_LISTBOX_PLAY_LIST ); hAvailWnd = GetDlgItem( hwnd, IDC_LISTBOX_AVAILABLE_TRACKS );
hdc = GetDC( hwnd ); hdcMem = CreateCompatibleDC( hdc ); ReleaseDC( hwnd, hdc );
SelectObject( hdcMem, g_hbmTrack ); InitForNewDrive( hwnd );
/*
** Set the maximum characters allowed in the edit field to 1 less than ** the space available in the TRACK_INF and ENTRY structures. */ SendDlgItemMessage( hwnd, IDC_EDIT_ARTIST, EM_LIMITTEXT, ARTIST_LENGTH - 1, 0 ); SendDlgItemMessage( hwnd, IDC_EDIT_TITLE, EM_LIMITTEXT, TITLE_LENGTH - 1, 0 ); SendDlgItemMessage( hwnd, IDC_EDIT_TRACK, EM_LIMITTEXT, TRACK_TITLE_LENGTH - 1, 0 );
MakeMultiDragList( hPlayWnd ); MakeMultiDragList( hAvailWnd );
num = ListBox_GetCount( hPlayWnd );
if ( num == 0 ) {
EnableWindow( GetDlgItem( hwnd, IDC_CLEAR ), FALSE ); }
EnableWindow( GetDlgItem( hwnd, IDC_ADD ), FALSE ); EnableWindow( GetDlgItem( hwnd, IDC_REMOVE ), FALSE );
fTrackNamesChanged = fPlaylistChanged = FALSE; return TRUE; }
/*****************************Private*Routine******************************\
* DlgDiskInfo_OnCommand * * This is where most of the UI processing takes place. Basically the dialog * serves two purposes. * * 1. Track name editing * 2. Play list selection and editing. * * History: * dd-mm-93 - StephenE - Created * \**************************************************************************/ void DlgDiskInfo_OnCommand( HWND hwnd, int id, HWND hwndCtl, UINT codeNotify ) { int items[100]; int i, num, index; int iCurrTrack; TCHAR s[TRACK_TITLE_LENGTH]; DWORD dwData;
switch ( id ) {
case IDC_LISTBOX_PLAY_LIST: if ( codeNotify == LBN_DBLCLK ) {
RemovePlayListSelection( hwnd ); }
EnableWindow( GetDlgItem( hwnd, IDC_REMOVE ), ListBox_GetSelItems( hwndCtl, 1, items ) == 1 ); break;
case IDC_LISTBOX_AVAILABLE_TRACKS: /*
** If the selection in the possible tracks listbox ** changes, we need to reset which track is being edited ** down below for the track title editbox. */ if ( codeNotify == LBN_SELCHANGE ) {
/*
** Update currently displayed track in track name ** field - also, enable/diable the add button ** depending on whether there are any items selected. */ if ( ListBox_GetSelItems( hwndCtl, 1, items ) == 1 ) { UpdateTrackName( hwnd, items[0] ); EnableWindow( GetDlgItem( hwnd, IDC_ADD ), TRUE ); } else { EnableWindow( GetDlgItem( hwnd, IDC_ADD ), FALSE ); } } else if ( codeNotify == LBN_DBLCLK ) {
AddTrackListSelection( hwnd, ListBox_GetCount( hPlayWnd ) ); } break;
case IDC_EDIT_TRACK: switch ( codeNotify ) {
case EN_CHANGE: fChanged = TRUE; break;
case EN_KILLFOCUS: SendMessage( hwnd, DM_SETDEFID, IDOK, 0L ); break;
case EN_SETFOCUS: SendMessage( hwnd, DM_SETDEFID, IDC_SETNAME, 0L ); break; } break;
case IDC_SETNAME: if ( fChanged ) { fTrackNamesChanged = TRUE; GrabTrackName( hwnd, CurrTocIndex ); }
CurrTocIndex++; if ( CurrTocIndex >= NUMTRACKS(dCdrom) ) { CurrTocIndex = 0; }
ListBox_SetSel( hPlayWnd, FALSE, -1 ); EnableWindow( GetDlgItem( hwnd, IDC_REMOVE ), FALSE );
ListBox_SetSel( hAvailWnd, FALSE, -1 ); ListBox_SelItemRange( hAvailWnd, TRUE, CurrTocIndex, CurrTocIndex );
/*
** Display correct track in track field */ UpdateTrackName( hwnd, CurrTocIndex ); break;
case IDC_ADD: AddTrackListSelection( hwnd, ListBox_GetCount( hPlayWnd ) ); break;
case IDC_CLEAR: /*
** Just wipe out the current play list from the play listbox. ** Don't forget to grey out the remove and clear buttons. */ ListBox_ResetContent( hPlayWnd ); SendMessage( hwnd, DM_SETDEFID, IDOK, 0L ); SetFocus( GetDlgItem( hwnd, IDOK ) ); CheckButtons( hwnd ); fPlaylistChanged = TRUE; break;
case IDC_REMOVE: RemovePlayListSelection( hwnd ); SetFocus( GetDlgItem( hwnd, IDOK ) ); SendMessage( hwnd, DM_SETDEFID, IDOK, 0L ); EnableWindow( GetDlgItem( hwnd, IDC_REMOVE ), ListBox_GetSelItems( hPlayWnd, 1, items ) == 1 ); break;
case IDC_DEFAULT: /*
** Clear the existing play list and then add the each item from the ** available tracks listbox maintaing the same order as the available ** tracks. */ SetWindowRedraw( hPlayWnd, FALSE );
ListBox_ResetContent( hPlayWnd ); num = ListBox_GetCount( hAvailWnd );
for ( i = 0; i < num; i++ ) {
ListBox_GetText( hAvailWnd, i, s ); dwData = ListBox_GetItemData( hAvailWnd, i );
index = ListBox_AddString( hPlayWnd, s ); ListBox_SetItemData( hPlayWnd, index, dwData ); }
SetWindowRedraw( hPlayWnd, TRUE ); CheckButtons( hwnd ); fPlaylistChanged = TRUE; break;
case IDOK: /*
** Here is where we extract the current play list and ** available tracks list from the two list boxes. ** ** If we can't lock the toc for this drive ignore the OK button click ** the user user will either try again or press cancel. ** */ if ( LockTableOfContents( dCdrom ) == FALSE ) { break; }
/*
** OK, we've locked the toc for this drive. Now we have to check that ** it still has the original disk inside it. If the disks match ** we copy the strings from the available tracks list box straight ** it the track info structure for this cdrom and update the ** playlist. */ if ( g_Devices[ dCdrom ]->CdInfo.Id == dwDiskId ) {
PTRACK_INF pt; PTRACK_PLAY ppPlay; PTRACK_PLAY pp; int m, s, mtemp, stemp;
/*
** Take care of the track (re)naming function of the dialog ** box. */
GetDlgItemText( hwnd, IDC_EDIT_TITLE, TITLE(dCdrom), TITLE_LENGTH ); GetDlgItemText( hwnd, IDC_EDIT_ARTIST, ARTIST(dCdrom), ARTIST_LENGTH );
num = ListBox_GetCount( hAvailWnd ); pt = ALLTRACKS( dCdrom );
for ( i = 0; (pt != NULL) && (i < num); i++ ) {
ListBox_GetText( hAvailWnd, i, pt->name ); pt = pt->next; }
/*
** make sure that we read all the tracks from the listbox. */ ASSERT( i == num );
/*
** Now take care of the playlist editing function of the ** dialog box. */ if (fPlaylistChanged) {
if ( CURRTRACK(dCdrom) != NULL ) { iCurrTrack = CURRTRACK(dCdrom)->TocIndex; } else { iCurrTrack = -1; }
/*
** Get the new play list from the listbox and ** look for the previous track in the new play list. */ ppPlay = ConstructPlayListFromListbox(); for ( pp = ppPlay; pp != NULL; pp = pp->nextplay ) {
if ( pp->TocIndex == iCurrTrack ) { break; } }
/*
** If the track was not found in the new track list and this ** cd is currently playing then stop it. */ if ( (pp == NULL) && (STATE(dCdrom) & (CD_PLAYING | CD_PAUSED)) ) {
SendDlgItemMessage( g_hwndApp, IDM_PLAYBAR_STOP, WM_LBUTTONDOWN, 1, 0 );
SendDlgItemMessage( g_hwndApp, IDM_PLAYBAR_STOP, WM_LBUTTONUP, 1, 0 ); }
/*
** Swap over the playlists. */ ErasePlayList( dCdrom ); EraseSaveList( dCdrom ); PLAYLIST(dCdrom) = ppPlay; SAVELIST(dCdrom) = CopyPlayList( PLAYLIST(dCdrom) );
/*
** Set the current track. */ if ( pp != NULL ) {
CURRTRACK( dCdrom ) = pp; } else {
CURRTRACK( dCdrom ) = PLAYLIST( dCdrom ); }
/*
** If we were previously in "Random" mode shuffle the new ** playlist. */ if (!g_fSelectedOrder) { ComputeSingleShufflePlayList( dCdrom ); }
/*
** If we were playing, we need to synchronize to make sure ** we are playing where we should. */ SyncDisplay();
/*
** Compute PLAY length */ m = s = 0; for( pp = PLAYLIST(dCdrom); pp != NULL; pp = pp->nextplay ) {
FigureTrackTime( dCdrom, pp->TocIndex, &mtemp, &stemp );
m+=mtemp; s+=stemp;
pp->min = mtemp; pp->sec = stemp; }
m += (s / 60); s = (s % 60);
CDTIME(dCdrom).TotalMin = m; CDTIME(dCdrom).TotalSec = s;
/*
** Make sure that the track time displayed in the LED and the ** status bar is correct. If we have a current track and the ** CD is playing or paused then everything is OK. Otherwise, we ** have to reset the track times. */ if ( CURRTRACK( dCdrom ) != NULL ) {
if ( STATE(dCdrom) & CD_STOPPED ) {
CDTIME(g_CurrCdrom).TrackTotalMin = CURRTRACK( dCdrom )->min; CDTIME(g_CurrCdrom).TrackRemMin = CURRTRACK( dCdrom )->min;
CDTIME(g_CurrCdrom).TrackTotalSec = CURRTRACK( dCdrom )->sec; CDTIME(g_CurrCdrom).TrackRemSec = CURRTRACK( dCdrom )->sec; }
} else {
CDTIME(g_CurrCdrom).TrackTotalMin = 0; CDTIME(g_CurrCdrom).TrackRemMin = 0; CDTIME(g_CurrCdrom).TrackTotalSec = 0; CDTIME(g_CurrCdrom).TrackRemSec = 0; }
UpdateDisplay( DISPLAY_UPD_DISC_TIME ); }
/*
** Now force repaints of the relevant field in the main application */ InvalidateRect(GetDlgItem(g_hwndApp, IDC_ARTIST_NAME), NULL, FALSE); SetDlgItemText( g_hwndApp, IDC_TITLE_NAME, TITLE(dCdrom) ); ResetTrackComboBox( dCdrom ); }
/*
** Now save the tracks to disk. */ UpdateEntryFromDiskInfoDialog( dwDiskId, hwnd ); SetPlayButtonsEnableState();
case IDCANCEL: EndDialog( hwnd, id ); break; } }
/*****************************Private*Routine******************************\
* DlgDiskInfo_OnDrawItem * * * * History: * 18-11-93 - StephenE - Created * \**************************************************************************/ BOOL DlgDiskInfo_OnDrawItem( HWND hwnd, const DRAWITEMSTRUCT *lpdis ) { if ( (lpdis->itemAction & ODA_DRAWENTIRE) || (lpdis->itemAction & ODA_SELECT) ) {
DrawListItem( lpdis->hDC, &lpdis->rcItem, lpdis->itemData, lpdis->itemState & ODS_SELECTED );
if ( lpdis->itemState & ODS_FOCUS ) { DrawFocusRect( lpdis->hDC, &lpdis->rcItem ); } return TRUE; } return FALSE; }
/*****************************Private*Routine******************************\
* DlgDiskInfo_OnDestroy * * * * History: * dd-mm-93 - StephenE - Created * \**************************************************************************/ void DlgDiskInfo_OnDestroy( HWND hwnd ) { if ( hdcMem ) { DeleteDC( hdcMem ); }
}
/*****************************Private*Routine******************************\
* InitForNewDrive * * * * History: * dd-mm-93 - StephenE - Created * \**************************************************************************/ void InitForNewDrive( HWND hwnd ) {
int index; PTRACK_INF t; PTRACK_PLAY t1; TCHAR s[50];
SetDlgItemText( hwnd, IDC_EDIT_TITLE, TITLE(dCdrom) ); SetDlgItemText( hwnd, IDC_EDIT_ARTIST, ARTIST(dCdrom) ); SetDlgItemText( hwnd, IDC_EDIT_TRACK, ALLTRACKS(dCdrom)->name );
wsprintf( s, TEXT("\\Device\\CdRom%d <%c:>"), dCdrom, g_Devices[dCdrom]->drive ); SetDlgItemText( hwnd, IDC_SJETEXT_DRIVE, s );
/*
** Fill in current tracks. This list contains all the available tracks ** in the correct track order. */ SetWindowRedraw( hAvailWnd, FALSE ); ListBox_ResetContent( hAvailWnd );
for( t = ALLTRACKS(dCdrom); t != NULL; t = t->next ) {
index = ListBox_AddString( hAvailWnd, t->name ); ListBox_SetItemData( hAvailWnd, index, t->TocIndex ); } SetWindowRedraw( hAvailWnd, TRUE );
/*
** Fill in current play list */ SetWindowRedraw( hPlayWnd, FALSE ); ListBox_ResetContent( hPlayWnd );
for( t1 = SAVELIST(dCdrom); t1 != NULL; t1 = t1->nextplay ) {
t = FindTrackNodeFromTocIndex( t1->TocIndex, ALLTRACKS(dCdrom) );
if ( t != NULL ) { index = ListBox_AddString( hPlayWnd, t->name ); ListBox_SetItemData( hPlayWnd, index, t->TocIndex ); } } SetWindowRedraw( hPlayWnd, TRUE );
/*
** Display correct track in track field and ** set CurrTocIndex to first entry in playlist listbox */ UpdateTrackName( hwnd, 0 ); }
/*****************************Private*Routine******************************\
* DrawListItem * * This routine draws items in the PlayList and Available Tracks * listboxes. * * History: * dd-mm-93 - StephenE - Created * \**************************************************************************/ void DrawListItem( HDC hdc, const RECT *rItem, DWORD itemIndex, BOOL selected ) { DWORD dwROP; SIZE si; UINT i; TCHAR s[TRACK_TITLE_LENGTH]; TCHAR szDotDot[] = TEXT("... "); int cxDotDot;
/*
** Check selection status, and set up to draw correctly */ if ( selected ) {
SetBkColor( hdc, GetSysColor( COLOR_HIGHLIGHT ) ); SetTextColor( hdc, GetSysColor( COLOR_HIGHLIGHTTEXT ) ); dwROP = MERGEPAINT;
} else {
SetBkColor( hdc, GetSysColor(COLOR_WINDOW)); SetTextColor( hdc, GetSysColor(COLOR_WINDOWTEXT)); dwROP = SRCAND; }
/*
** Get track string */ ListBox_GetText( hAvailWnd, itemIndex, s );
/*
** Do we need to munge track name (clip to listbox)? */ GetTextExtentPoint( hdc, szDotDot, _tcslen( szDotDot ), &si ); cxDotDot = si.cx;
i = _tcslen( s ) + 1; do { GetTextExtentPoint( hdc, s, --i, &si ); } while( si.cx > (rItem->right - cxDotDot - 20) );
/*
** Draw track name */ ExtTextOut( hdc, rItem->left + 20, rItem->top, ETO_OPAQUE | ETO_CLIPPED, rItem, s, i, NULL );
if ( _tcslen( s ) > i ) {
ExtTextOut( hdc, rItem->left + si.cx + 20, rItem->top, ETO_CLIPPED, rItem, szDotDot, _tcslen(szDotDot), NULL ); }
/*
** draw cd icon for each track */ BitBlt( hdc, rItem->left, rItem->top, 14, 14, hdcMem, 0, 0, dwROP ); }
/*****************************Private*Routine******************************\
* GrabTrackName * * This routine reads the track name from the track name edit * control and updates the screen and internal structures with the * new track name. * * History: * dd-mm-93 - StephenE - Created * \**************************************************************************/ void GrabTrackName( HWND hwnd, int tocindex ) { int i, num; TCHAR s[TRACK_TITLE_LENGTH];
/*
** Get new title */ GetDlgItemText( hwnd, IDC_EDIT_TRACK, s, TRACK_TITLE_LENGTH );
/*
** Update the "track" list. */ SetWindowRedraw( hAvailWnd, FALSE ); ListBox_DeleteString( hAvailWnd, tocindex ); ListBox_InsertString( hAvailWnd, tocindex, s ); ListBox_SetItemData( hAvailWnd, tocindex, tocindex ); SetWindowRedraw( hAvailWnd, TRUE );
/*
** Redraw list entries with new title in playlist listbox...there ** can be more than one */ SetWindowRedraw( hPlayWnd, FALSE );
num = ListBox_GetCount( hPlayWnd ); for( i = 0; i < num; i++ ) {
if ( ListBox_GetItemData( hPlayWnd, i ) == tocindex ) {
ListBox_DeleteString( hPlayWnd, i ); ListBox_InsertString( hPlayWnd, i, s ); ListBox_SetItemData( hPlayWnd, i, tocindex ); } } SetWindowRedraw( hPlayWnd, TRUE ); EnableWindow( GetDlgItem( hwnd, IDC_REMOVE ), FALSE ); }
/*****************************Private*Routine******************************\
* UpdateTrackName * * * History: * dd-mm-93 - StephenE - Created * \**************************************************************************/ void UpdateTrackName( HWND hwnd, int index ) { TCHAR s[TRACK_TITLE_LENGTH]; int iFirstTrack;
/*
** Before using the FIRSTTRACK macro we have to check that we can ** lock the TOC and that the original disk is still in the drive. If this ** is not the case "assume" that the first track is track 1. */ if ( LockTableOfContents(dCdrom) && g_Devices[dCdrom]->CdInfo.Id == dwDiskId ) {
iFirstTrack = FIRSTTRACK(dCdrom); } else { iFirstTrack = 1; }
ListBox_GetText( hAvailWnd, index, s );
SetDlgItemText( hwnd, IDC_EDIT_TRACK, s ); wsprintf( s, IdStr( STR_TRACK1 ), index + iFirstTrack);
SetDlgItemText( hwnd, IDC_STATIC_TRACK, s ); SendMessage( GetDlgItem( hwnd, IDC_EDIT_TRACK ), EM_SETSEL, 0, (LPARAM)-1 );
CurrTocIndex = index; fChanged = FALSE; }
/*****************************Private*Routine******************************\
* ConstructPlayListFromListbox * * * History: * dd-mm-93 - StephenE - Created * \**************************************************************************/ PTRACK_PLAY ConstructPlayListFromListbox( void ) { int num; int i; int mtemp, stemp; DWORD dwData; PTRACK_PLAY t1, tend, tret;
tret = tend = NULL;
num = ListBox_GetCount( hPlayWnd );
for ( i = 0; i < num; i++ ) {
dwData = ListBox_GetItemData( hPlayWnd, i );
t1 = AllocMemory( sizeof(TRACK_PLAY) ); t1->TocIndex = dwData; t1->min = 0; t1->sec = 0; t1->nextplay = NULL; t1->prevplay = tend;
if ( tret == NULL ) {
tret = tend = t1; } else {
tend->nextplay = t1; tend = t1; } }
/*
** Compute play length */
mtemp = stemp = 0;
for( t1 = tret; t1 != NULL; t1 = t1->nextplay ) {
FigureTrackTime( dCdrom, t1->TocIndex, &mtemp, &stemp );
t1->min = mtemp; t1->sec = stemp; }
return tret; }
/*****************************Private*Routine******************************\
* UpdateEntryFromDiskInfoDialog * * Here we decide if we need to update the entire track record or just * a portion of it. This saves a lot of space in the cdplayer.ini file if the * user only changes the artist name and disk title fields. * * History: * dd-mm-93 - StephenE - Created * \**************************************************************************/ void UpdateEntryFromDiskInfoDialog( DWORD dwDiskId, HWND hwnd ) { if (fTrackNamesChanged) { WriteAllEntries( dwDiskId, hwnd ); } else {
TCHAR Section[10]; TCHAR Buff[512]; TCHAR Name[128];
wsprintf( Section, g_szSectionF, dwDiskId );
/* Write entry type (always 1) */ wsprintf( Buff, TEXT("%d"), 1 ); WritePrivateProfileString(Section, g_szEntryType, Buff, g_IniFileName);
/* Write artist name */ GetDlgItemText( hwnd, IDC_EDIT_ARTIST, Name, ARTIST_LENGTH ); wsprintf( Buff, TEXT("%s"), Name ); WritePrivateProfileString(Section, g_szArtist, Buff, g_IniFileName);
/* Write CD Title */ GetDlgItemText( hwnd, IDC_EDIT_TITLE, Name, TITLE_LENGTH ); wsprintf( Buff, TEXT("%s"), Name ); WritePrivateProfileString(Section, g_szTitle, Buff, g_IniFileName);
/* Write the number of tracks on the disc */ wsprintf( Buff, TEXT("%d"), ListBox_GetCount( hAvailWnd ) ); WritePrivateProfileString(Section, g_szNumTracks, Buff, g_IniFileName);
/* Only write the playlist if it has actually changed */ if (fPlaylistChanged) {
LPTSTR s, sSave; DWORD dwData; int i, num;
num = ListBox_GetCount( hPlayWnd ); sSave = s = AllocMemory( num * 4 * sizeof(TCHAR) ); for ( i = 0; i < num; i++ ) {
dwData = ListBox_GetItemData( hPlayWnd, i ); s += wsprintf( s, TEXT("%d "), dwData );
} WritePrivateProfileString(Section, g_szOrder, sSave, g_IniFileName);
/* Write number of tracks in current playlist */ wsprintf( Buff, TEXT("%d"), num ); WritePrivateProfileString(Section, g_szNumPlay, Buff, g_IniFileName); LocalFree( (HLOCAL)sSave ); } } }
/*****************************Private*Routine******************************\
* WriteAllEntries * * * This monster updates the cdpayer database for the current disk it writes * all the entries to the database. * * History: * dd-mm-94 - StephenE - Created * \**************************************************************************/ void WriteAllEntries( DWORD dwDiskId, HWND hwnd ) { TCHAR *Buffer; TCHAR Section[10]; TCHAR Name[128]; DWORD dwData; LPTSTR s; int i; int num;
//
// Construct ini file buffer, form of:
// EntryType = 1
// artist = artist name
// title = Title of disc
// numtracks = n
// 0 = Title of track 1
// 1 = Title of track 2
// n-1 = Title of track n
// order = 0 4 3 2 6 7 8 ... (n-1)
// numplay = # of entries in order list
//
Buffer = AllocMemory( 64000 * sizeof(TCHAR) );
wsprintf( Section, g_szSectionF, dwDiskId );
s = Buffer; num = ListBox_GetCount( hAvailWnd );
//
// I assume EntryType=1 means use the new hashing scheme
//
s += 1 + wsprintf( s, g_szEntryTypeF, 1 );
//
// Save the artists name.
//
GetDlgItemText( hwnd, IDC_EDIT_ARTIST, Name, ARTIST_LENGTH ); s += 1 + wsprintf( s, g_szArtistF, Name );
//
// Save the CD Title
//
GetDlgItemText( hwnd, IDC_EDIT_TITLE, Name, TITLE_LENGTH ); s += 1 + wsprintf( s, g_szTitleF, Name );
s += 1 + wsprintf( s, g_szNumTracksF, num );
//
// Save each track name
//
for ( i = 0; i < num; i++ ) {
ListBox_GetText( hAvailWnd, i, Name ); dwData = ListBox_GetItemData( hAvailWnd, i );
s += 1 + wsprintf( s, TEXT("%d=%s"), dwData, Name ); }
//
// Save the play order
//
num = ListBox_GetCount( hPlayWnd ); s += wsprintf( s, g_szOrderF ); for ( i = 0; i < num; i++ ) {
dwData = ListBox_GetItemData( hPlayWnd, i ); s += wsprintf( s, TEXT("%d "), dwData );
} s += 1;
//
// Save the number of tracks in the play list
//
s += 1 + wsprintf( s, g_szNumPlayF, num );
//
// Just make sure there are NULLs at end of buffer
//
wsprintf( s, g_szThreeNulls );
//
// Try writing buffer into ini file
//
WritePrivateProfileSection( Section, Buffer, g_IniFileName );
LocalFree( (HLOCAL)Buffer ); }
/*****************************Private*Routine******************************\
* Lbox_OnQueryDrop * * Is a mouse drop allowed at the current mouse position. * * History: * dd-mm-93 - StephenE - Created * \**************************************************************************/ BOOL DlgDiskInfo_OnQueryDrop( HWND hwnd, HWND hwndDrop, HWND hwndSrc, POINT ptDrop, DWORD dwState ) { int index;
index = InsertIndex( hwnd, ptDrop, TRUE );
if ( index >= 0 ) {
if ( (hwndSrc == hPlayWnd) && (dwState == DL_COPY) ) {
SetCursor( g_hCursorDropCpy ); } else {
SetCursor( g_hCursorDrop ); } } else if ( IsInListbox( hwnd, hAvailWnd, ptDrop ) ) {
if ( hwndSrc == hPlayWnd ) {
SetCursor( g_hCursorDropDel ); } else {
SetCursor( g_hCursorDrop ); } } else {
SetCursor( g_hCursorNoDrop ); }
SetWindowLong( hwnd, DWL_MSGRESULT, FALSE ); return TRUE; }
/*****************************Private*Routine******************************\
* Lbox_OnProcessDrop * * Process mouse drop(ping)s here. * * History: * dd-mm-93 - StephenE - Created * \**************************************************************************/ BOOL DlgDiskInfo_OnProcessDrop( HWND hwnd, HWND hwndDrop, HWND hwndSrc, POINT ptDrop, DWORD dwState ) {
int index;
/*
** Are we dropping on the play list window ? */ if ( hwndDrop == hPlayWnd ) {
index = InsertIndex( hwnd, ptDrop, FALSE );
/*
** Is it OK to drop here ? */ if ( index >= 0 ) {
/*
** Is this an inter or intra window drop */ if ( hwndSrc == hAvailWnd ) {
AddTrackListSelection( hwnd, index ); }
/*
** An intra window drop !! */ else if ( hwndSrc == hPlayWnd ) {
MoveCopySelection( index, dwState ); } } }
/*
** Are we dropping on the available tracks list box and the source window ** was the play listbox */
else if ( hwndDrop == hAvailWnd && hwndSrc == hPlayWnd ) {
RemovePlayListSelection( hwnd ); }
SetWindowLong( hwnd, DWL_MSGRESULT, FALSE ); return TRUE; }
/*****************************Private*Routine******************************\
* InsertIndex * * If the mouse is over the playlist window return what would be the current * insertion position, otherwise return -1. * * History: * dd-mm-93 - StephenE - Created * \**************************************************************************/ int InsertIndex( HWND hDlg, POINT pt, BOOL bDragging ) { int nItem; int nCount;
nCount = ListBox_GetCount( hPlayWnd ); nItem = LBMultiItemFromPt( hPlayWnd, pt, bDragging );
/*
** If the mouse is not over any particular list item, but it is inside ** the client area of the listbox just append to end of the listbox. */
if ( nItem == -1 ) {
if ( IsInListbox( hDlg, hPlayWnd, pt ) ) { nItem = nCount; } }
/*
** Otherwise, if the mouse is over a list item and there is ** at least one item in the listbox determine if the inertion point is ** above or below the current item. */
else if ( nItem > 0 && nCount > 0 ) {
long pt_y; RECT rc;
ListBox_GetItemRect( hPlayWnd, nItem, &rc ); ScreenToClient( hPlayWnd, &pt );
pt_y = rc.bottom - ((rc.bottom - rc.top) / 2);
if ( pt.y > pt_y ) { nItem++; } }
DrawMultiInsert( hDlg, hPlayWnd, bDragging ? nItem : -1 );
return nItem; }
/*****************************Private*Routine******************************\
* IsInListBox * * Is the mouse over the client area of the specified child listbox. * * History: * dd-mm-93 - StephenE - Created * \**************************************************************************/ BOOL IsInListbox( HWND hDlg, HWND hwndListbox, POINT pt ) { RECT rc;
ScreenToClient(hDlg, &pt);
if ( ChildWindowFromPoint( hDlg, pt ) == hwndListbox ) {
GetClientRect( hwndListbox, &rc ); MapWindowRect( hwndListbox, hDlg, &rc );
return PtInRect( &rc, pt ); }
return FALSE; }
/*****************************Private*Routine******************************\
* RemovePlayListSelection * * Here we remove the slected items from the play list listbox. * * History: * dd-mm-93 - StephenE - Created * \**************************************************************************/ void RemovePlayListSelection( HWND hDlg ) { int num; int i; int *pList;
/*
** Get the number of tracks currently selected. Return if an error ** occurrs or zero tracks selected. */ num = ListBox_GetSelCount( hPlayWnd ); if ( num <= 0 ) { return; }
pList = AllocMemory( num * sizeof(int) ); ListBox_GetSelItems( hPlayWnd, num, pList );
SetWindowRedraw( hPlayWnd, FALSE ); for ( i = num - 1; i >= 0; i-- ) {
ListBox_DeleteString( hPlayWnd, pList[i] );
}
/*
** Now that we have added the above items we reset this selection ** and set the caret to first item in the listbox. */ if ( num != 0 ) {
ListBox_SetSel( hPlayWnd, FALSE, -1 ); ListBox_SetCaretIndex( hPlayWnd, 0 ); } SetWindowRedraw( hPlayWnd, TRUE );
LocalFree( (HLOCAL)pList ); CheckButtons( hDlg ); fPlaylistChanged = TRUE; }
/*****************************Private*Routine******************************\
* AddTrackListSelection * * Here we add the current selection from the tracks available listbox to * the current play list listbox. Try to ensure that the last track * added to the playlist is visible in the playlist. This aids continuity. * * History: * dd-mm-93 - StephenE - Created * \**************************************************************************/ void AddTrackListSelection( HWND hDlg, int iInsertPos ) { int i; int num; int *pList; TCHAR s[TRACK_TITLE_LENGTH];
/*
** Get the number of tracks currently selected. Return if an error ** occurrs or zero tracks selected. */ num = ListBox_GetSelCount( hAvailWnd ); if ( num <= 0 ) { return; }
pList = AllocMemory( num * sizeof(int) ); ListBox_GetSelItems( hAvailWnd, num, pList );
SetWindowRedraw( hPlayWnd, FALSE ); for ( i = 0; i < num; i++ ) {
DWORD dwData;
ListBox_GetText( hAvailWnd, pList[i], s ); dwData = ListBox_GetItemData( hAvailWnd, pList[i] );
ListBox_InsertString( hPlayWnd, iInsertPos + i, s ); ListBox_SetItemData( hPlayWnd, iInsertPos + i, dwData );
}
/*
** Here we used to un-hilight the selection in the "available ** tracks" listbox. Ant didn't like this and raised a bug. Hence ** the next few lines are commented out. */
// if ( num != 0 ) {
// ListBox_SetSel( hAvailWnd, FALSE, -1 );
// ListBox_SetCaretIndex( hAvailWnd, 0 );
// }
/*
** Make sure that the last item added to the "Play List" listbox ** is visible. */ ListBox_SetCaretIndex( hPlayWnd, iInsertPos + num - 1 );
SetWindowRedraw( hPlayWnd, TRUE ); InvalidateRect( hPlayWnd, NULL, FALSE );
LocalFree( (HLOCAL)pList ); CheckButtons( hDlg ); fPlaylistChanged = TRUE; }
/*****************************Private*Routine******************************\
* CheckButtons * * Enables or disables the Remove and Clear buttons depending on the content * of the play list listbox. * * History: * dd-mm-93 - StephenE - Created * \**************************************************************************/ void CheckButtons( HWND hDlg ) { int num; int items[1];
num = ListBox_GetCount( hPlayWnd ); EnableWindow( GetDlgItem( hDlg, IDC_CLEAR ), (num != 0) );
EnableWindow( GetDlgItem( hDlg, IDC_REMOVE ), ListBox_GetSelItems( hPlayWnd, 1, items ) == 1 ); }
/*****************************Private*Routine******************************\
* MoveCopySelection * * Moves or copies the selection within the play list listbox. * * History: * dd-mm-93 - StephenE - Created * \**************************************************************************/ void MoveCopySelection( int iInsertPos, DWORD dwState ) { int num; int i; int *pList; LIST_INFO *pInfo;
/*
** Get the number of tracks currently selected. Return if an error ** occurrs or zero tracks selected. */ num = ListBox_GetSelCount( hPlayWnd ); if ( num <= 0 ) { return; }
pList = AllocMemory( num * sizeof(int) ); pInfo = AllocMemory( num * sizeof(LIST_INFO) ); ListBox_GetSelItems( hPlayWnd, num, pList );
SetWindowRedraw( hPlayWnd, FALSE );
for ( i = num - 1; i >= 0; i-- ) {
ListBox_GetText( hPlayWnd, pList[i], pInfo[i].chName ); pInfo[i].dwData = ListBox_GetItemData( hPlayWnd, pList[i] );
if ( dwState == DL_MOVE ) { pInfo[i].index = pList[i]; ListBox_DeleteString( hPlayWnd, pList[i] ); } }
if ( dwState == DL_MOVE ) {
/*
** for each selected item that was above the insertion point ** reduce the insertion point by 1. */ int iTempInsertionPt = iInsertPos;
for ( i = 0; i < num; i++ ) { if ( pInfo[i].index < iInsertPos ) { iTempInsertionPt--; } } iInsertPos = iTempInsertionPt; }
for ( i = 0; i < num; i++ ) {
ListBox_InsertString( hPlayWnd, iInsertPos + i, pInfo[i].chName ); ListBox_SetItemData( hPlayWnd, iInsertPos + i, pInfo[i].dwData ); }
/*
** Now that we have added the above items we reset this selection ** and set the caret to first item in the listbox. */ if ( num != 0 ) {
ListBox_SetSel( hPlayWnd, FALSE, -1 ); ListBox_SetCaretIndex( hPlayWnd, 0 ); }
SetWindowRedraw( hPlayWnd, TRUE );
LocalFree( (HLOCAL)pList ); LocalFree( (HLOCAL)pInfo ); fPlaylistChanged = TRUE; }
|