mirror of https://github.com/lianthony/NT4.0
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.
2547 lines
55 KiB
2547 lines
55 KiB
/*++
|
|
|
|
Copyright (c) 1992 Microsoft Corporation
|
|
|
|
|
|
Module Name:
|
|
|
|
|
|
discinfo.c
|
|
|
|
|
|
Abstract:
|
|
|
|
|
|
This module implements the wndproc and support routines for
|
|
the disc settings/info dialog window.
|
|
|
|
Author:
|
|
|
|
|
|
Rick Turner (ricktu) 30-Nov-1992
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
|
|
--*/
|
|
|
|
#include <windows.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include "cdplayer.h"
|
|
#include "cdwindef.h"
|
|
#include "trkinfo.h"
|
|
#include "discinfo.h"
|
|
|
|
//
|
|
// module globals
|
|
//
|
|
|
|
static CHAR szDiscInfoClassName[] = "DiscInfoClass";
|
|
HWND gDiscInfoWnd;
|
|
INT dCdrom;
|
|
PTRACK_INF gAllList = NULL;
|
|
PTRACK_PLAY gPlayList = NULL;
|
|
HCURSOR hNormal, hDrag, hNoDrop, hDropDel;
|
|
HBITMAP hTrackIcon, hInsertPoint, hbmEditBtns;
|
|
HHOOK MyListBoxHook;
|
|
HWND hAvailWnd, hPlayWnd, hTheDlg, hStartDrag;
|
|
INT CurrTocIndex;
|
|
BOOL fDrag, fDragCur, fChanged;
|
|
|
|
//
|
|
// from sbutton.c
|
|
//
|
|
|
|
extern BOOL fAdd;
|
|
extern BOOL fClear;
|
|
extern BOOL fRemove;
|
|
|
|
|
|
VOID
|
|
EraseSaveList(
|
|
IN INT cdrom
|
|
);
|
|
|
|
|
|
|
|
VOID
|
|
KillTempTrackList(
|
|
IN VOID
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
This routine deletes temporary track list pointed
|
|
to by gAllPlayList.
|
|
|
|
Arguments:
|
|
|
|
|
|
none.
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
none.
|
|
|
|
--*/
|
|
|
|
|
|
{
|
|
|
|
PTRACK_INF t, t1;
|
|
|
|
//
|
|
// Kill off list pointed to by gAllList
|
|
//
|
|
|
|
DBGPRINT(( 1, "KillTempTrackList: freeing gAllList track list...\n" ));
|
|
|
|
t = gAllList;
|
|
|
|
while( t!=NULL ) {
|
|
|
|
DBGPRINT(( 1, " (0x%lx) TocIndex = %d, next = 0x%lx\n",
|
|
(PVOID)t, (INT)t->TocIndex, (PVOID)t->next ));
|
|
t1 = t->next;
|
|
LocalFree( (HLOCAL)t );
|
|
t = t1;
|
|
|
|
}
|
|
|
|
gAllList = NULL;
|
|
|
|
}
|
|
|
|
|
|
VOID
|
|
KillTempPlayList(
|
|
IN VOID
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
This routine deletes temporary play list pointed
|
|
to by gPlayList.
|
|
|
|
Arguments:
|
|
|
|
|
|
none.
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
none.
|
|
|
|
--*/
|
|
|
|
|
|
{
|
|
|
|
PTRACK_PLAY temp,temp1;
|
|
|
|
|
|
//
|
|
// Kill off list pointed to by gPlayList
|
|
//
|
|
|
|
temp = gPlayList;
|
|
DBGPRINT(( 1, "KillTempPlayList: freeing gPlayList track list...\n" ));
|
|
while( temp!=NULL ) {
|
|
|
|
temp1 = temp->nextplay;
|
|
DBGPRINT(( 1, " (0x%lx) TocIndex = %d, prev = 0x%lx, next = 0x%lx\n",
|
|
temp, temp->TocIndex, temp->prevplay, temp->nextplay ));
|
|
LocalFree( (HLOCAL)temp );
|
|
temp = temp1;
|
|
|
|
}
|
|
|
|
gPlayList = NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
VOID
|
|
GrabNewTrackLists(
|
|
IN INT cdrom
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
This routine deletes the current track and play lists and
|
|
points AllTracks and PlayList to temporary lists.
|
|
|
|
Arguments:
|
|
|
|
|
|
cdrom - index into gDevices structure.
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
none.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
INT tocindex, i;
|
|
PTRACK_PLAY tr;
|
|
|
|
//
|
|
// Save off current track
|
|
//
|
|
|
|
if (CURRTRACK(cdrom)!=NULL) {
|
|
|
|
tocindex = CURRTRACK( cdrom )->TocIndex;
|
|
|
|
} else {
|
|
|
|
tocindex = 0;
|
|
|
|
}
|
|
|
|
//
|
|
// erase current lists
|
|
//
|
|
|
|
ErasePlayList( cdrom );
|
|
EraseSaveList( cdrom );
|
|
EraseTrackList( cdrom );
|
|
|
|
//
|
|
// Point to temporary lists
|
|
//
|
|
|
|
ALLTRACKS( cdrom ) = gAllList;
|
|
PLAYLIST( cdrom ) = gPlayList;
|
|
SAVELIST( cdrom ) = CopyPlayList( PLAYLIST( cdrom ) );
|
|
|
|
for( tr=PLAYLIST( cdrom ), i=0;
|
|
((tr!=NULL) && (tr->TocIndex!=tocindex));
|
|
tr=tr->nextplay, i++
|
|
);
|
|
|
|
if (tr) {
|
|
|
|
CURRTRACK( cdrom ) = tr;
|
|
if (gTrackNameWnd)
|
|
SendMessage( gTrackNameWnd,
|
|
CB_SETCURSEL,
|
|
(WPARAM)i,
|
|
0
|
|
);
|
|
|
|
|
|
} else {
|
|
|
|
CURRTRACK( cdrom ) = PLAYLIST( cdrom );
|
|
if (gTrackNameWnd)
|
|
SendMessage( gTrackNameWnd,
|
|
CB_SETCURSEL,
|
|
0,
|
|
0
|
|
);
|
|
|
|
//
|
|
// FIXFIX -- if playing need to stop and restart at beginning
|
|
//
|
|
|
|
}
|
|
|
|
ResetTrackComboBox( cdrom );
|
|
gAllList = NULL;
|
|
gPlayList = NULL;
|
|
|
|
DBGPRINT(( 1, "GrabNewTrackLists: ALLTRACKS( cdrom ) is 0x%lx...\n",
|
|
ALLTRACKS( cdrom ) ));
|
|
DUMPTRACKLIST(( ALLTRACKS( cdrom ) ));
|
|
DBGPRINT(( 1, "GrabNewTrackLists: PLAYLIST( cdrom ) is 0x%lx...\n",
|
|
PLAYLIST( cdrom ) ));
|
|
DUMPPLAYLIST(( PLAYLIST( cdrom ) ));
|
|
|
|
}
|
|
|
|
VOID
|
|
DuplicateTrackList(
|
|
IN INT cdrom
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
This routine makes a copy of the linked list pointed to
|
|
by gDevices[cdrom]->CdInfo.AllTracks and sets gAllList
|
|
pointing to the copy.
|
|
|
|
Arguments:
|
|
|
|
|
|
cdrom - index into gDevices structure.
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
none.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
PTRACK_INF t,t1,tend;
|
|
|
|
//
|
|
// Kill old list if it exists
|
|
//
|
|
|
|
KillTempTrackList();
|
|
|
|
gAllList = tend = NULL;
|
|
|
|
//
|
|
// Duplicate list pointed to by gDevices[ cdrom ]->CdInfo.AllTracks
|
|
//
|
|
|
|
DBGPRINT(( 1, "DuplicateTrackList: building duplicate track list...\n" ));
|
|
t = ALLTRACKS( cdrom );
|
|
while( t!=NULL ) {
|
|
|
|
t1 = (PTRACK_INF)LocalAlloc( LPTR, sizeof( TRACK_INF ) );
|
|
t1->TocIndex = t->TocIndex;
|
|
strcpy( (LPSTR)t1->name, (LPSTR)t->name );
|
|
t1->next = NULL;
|
|
if (gAllList==NULL) {
|
|
|
|
gAllList = tend = t1;
|
|
|
|
} else {
|
|
|
|
tend->next = t1;
|
|
tend = tend->next;
|
|
|
|
}
|
|
|
|
t = t->next;
|
|
|
|
}
|
|
|
|
|
|
DUMPTRACKLIST(( gAllList ));
|
|
|
|
}
|
|
|
|
|
|
VOID
|
|
DuplicatePlayList(
|
|
IN INT cdrom
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
This routine makes a copy of the linked list pointed to
|
|
by gDevices[cdrom]->CdInfo.PlayList and sets gPlayList
|
|
pointing to the copy.
|
|
|
|
Arguments:
|
|
|
|
|
|
cdrom - index into gDevices structure.
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
none.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
PTRACK_PLAY t,t1,tend;
|
|
|
|
//
|
|
// Kill old list if it exists
|
|
//
|
|
|
|
KillTempPlayList();
|
|
|
|
gPlayList = tend = NULL;
|
|
|
|
//
|
|
// Duplicate list pointed to by gDevices[ cdrom ]->CdInfo.SaveList
|
|
//
|
|
|
|
DBGPRINT(( 1, "DuplicatePlayList: building duplicate play list...\n" ));
|
|
t = SAVELIST( cdrom );
|
|
while( t!=NULL ) {
|
|
|
|
t1 = (PTRACK_PLAY)LocalAlloc( LPTR, sizeof( TRACK_PLAY ) );
|
|
t1->TocIndex = t->TocIndex;
|
|
t1->min = t->min;
|
|
t1->sec = t->sec;
|
|
t1->nextplay = NULL;
|
|
t1->prevplay = tend;
|
|
if (gPlayList==NULL) {
|
|
|
|
gPlayList = tend = t1;
|
|
|
|
} else {
|
|
|
|
tend->nextplay = t1;
|
|
tend = t1;
|
|
|
|
}
|
|
|
|
t = t->nextplay;
|
|
|
|
}
|
|
|
|
|
|
DUMPPLAYLIST(( gPlayList ));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PTRACK_PLAY
|
|
CopyPlayList(
|
|
PTRACK_PLAY p
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Returns a copy of the playlist pointed to by p.
|
|
|
|
Arguments:
|
|
|
|
|
|
p - playlist to return a copy of
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
a copy of the playlist.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
PTRACK_PLAY t,t1,tend,tret;
|
|
|
|
tret = tend = NULL;
|
|
|
|
//
|
|
// Duplicate list pointed to by p.
|
|
//
|
|
|
|
DBGPRINT(( 1, "CopyPlayList: building duplicate play list...\n" ));
|
|
t = p;
|
|
while( t!=NULL ) {
|
|
|
|
t1 = (PTRACK_PLAY)LocalAlloc( LPTR, sizeof( TRACK_PLAY ) );
|
|
t1->TocIndex = t->TocIndex;
|
|
t1->min = t->min;
|
|
t1->sec = t->sec;
|
|
t1->nextplay = NULL;
|
|
t1->prevplay = tend;
|
|
if (tret==NULL) {
|
|
|
|
tret = tend = t1;
|
|
|
|
} else {
|
|
|
|
tend->nextplay = t1;
|
|
tend = t1;
|
|
|
|
}
|
|
|
|
t = t->nextplay;
|
|
|
|
}
|
|
|
|
|
|
DUMPPLAYLIST(( tret ));
|
|
|
|
return(tret);
|
|
|
|
}
|
|
|
|
|
|
VOID
|
|
DrawListItem(
|
|
IN HDC hdc,
|
|
IN LPRECT rItem,
|
|
IN INT itemData,
|
|
IN BOOL selected
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
This routine draws items in the PlayList and Available Tracks
|
|
listboxes.
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
hdc - handle to drawing context to use
|
|
|
|
rItem - pointer to RECT for item (item should be drawn within rect)
|
|
|
|
itemData - tocindex of item to draw
|
|
|
|
selected - flag: TRUE == item drawn selected, FALSE == item drawn normal
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
none.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
HDC hdcMem;
|
|
DWORD dwROP;
|
|
HPEN hPen;
|
|
PTRACK_INF t;
|
|
SIZE si;
|
|
INT i;
|
|
TCHAR s[TRACK_TITLE_LENGTH];
|
|
|
|
//
|
|
// Check selection status, and set up to draw correctly
|
|
//
|
|
|
|
if (selected) {
|
|
|
|
SetBkColor( hdc, GetSysColor( COLOR_HIGHLIGHT ) );
|
|
SetTextColor( hdc, GetSysColor( COLOR_HIGHLIGHTTEXT ) );
|
|
hPen = CreatePen( PS_SOLID, 1, GetSysColor( COLOR_HIGHLIGHTTEXT ) );
|
|
dwROP = MERGEPAINT;
|
|
|
|
} else {
|
|
|
|
// SetBkColor( hdc, cdWHITE );
|
|
// SetTextColor( hdc, cdBLACK );
|
|
SetBkColor( hdc, GetSysColor(COLOR_WINDOW));
|
|
SetTextColor( hdc, GetSysColor(COLOR_WINDOWTEXT));
|
|
hPen = CreatePen( PS_SOLID, 1, cdBLACK );
|
|
dwROP = SRCAND;
|
|
|
|
}
|
|
|
|
SelectObject( hdc, hFont );
|
|
|
|
//
|
|
// Get track info
|
|
//
|
|
|
|
t = FindTrackNodeFromTocIndex( itemData, gAllList );
|
|
|
|
//
|
|
// Do we need to munge track name (clip to listbox)?
|
|
//
|
|
|
|
i = strlen( (LPCSTR)t->name ) + 1;
|
|
do {
|
|
|
|
GetTextExtentPoint( hdc, (LPCSTR)t->name, --i, &si );
|
|
|
|
} while( si.cx > 120 );
|
|
ZeroMemory( s, TRACK_TITLE_LENGTH * sizeof( TCHAR ) );
|
|
strncpy( s, (LPCSTR)t->name, i );
|
|
|
|
//
|
|
// Draw track name
|
|
//
|
|
|
|
ExtTextOut( hdc,
|
|
rItem->left + 20,
|
|
rItem->top,
|
|
ETO_OPAQUE | ETO_CLIPPED,
|
|
(CONST RECT *)rItem,
|
|
s,
|
|
strlen( s ),
|
|
NULL
|
|
);
|
|
|
|
if (strlen( (LPCSTR)t->name ) > LIST_CHAR_WIDTH ) {
|
|
|
|
ExtTextOut( hdc,
|
|
rItem->left + 140,
|
|
rItem->top,
|
|
ETO_CLIPPED,
|
|
(CONST RECT *)rItem,
|
|
"...",
|
|
3,
|
|
NULL
|
|
);
|
|
|
|
}
|
|
|
|
//
|
|
// draw cd icon for each track
|
|
//
|
|
|
|
hdcMem = CreateCompatibleDC( hdc );
|
|
SelectObject( hdcMem, (HGDIOBJ)hTrackIcon );
|
|
BitBlt( hdc, rItem->left, rItem->top, 14, 14, hdcMem, 0, 0, dwROP );
|
|
DeleteDC( hdcMem );
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
GrabDiscAndArtistNames(
|
|
IN INT cdrom
|
|
)
|
|
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
This routine reads the disc and artists names from the corresponding
|
|
edit controls and track updates the screen and internal structures with
|
|
the new information.
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
cdrom - index into gDevices structure.
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
none.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
GetDlgItemText( hTheDlg,
|
|
IDT_GET_ARTIST,
|
|
(LPSTR)ARTIST(cdrom),
|
|
ARTIST_LENGTH
|
|
);
|
|
|
|
GetDlgItemText( hTheDlg,
|
|
IDT_GET_TITLE,
|
|
(LPSTR)TITLE(cdrom),
|
|
TITLE_LENGTH
|
|
);
|
|
|
|
}
|
|
|
|
VOID
|
|
GrabTrackName(
|
|
IN INT tocindex
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
This routine reads the track name from the track name edit
|
|
control and updates the screen and internal structures with the
|
|
new track name.
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
tocindex - index into toc of track to change.
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
none.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
PTRACK_INF t;
|
|
HDC hdc;
|
|
RECT r,r1;
|
|
BOOL fSel;
|
|
INT i, num;
|
|
|
|
//
|
|
// Get new title
|
|
//
|
|
|
|
t = FindTrackNodeFromTocIndex( tocindex, gAllList );
|
|
GetDlgItemText( hTheDlg,
|
|
IDT_GET_TRACK,
|
|
(LPSTR)t->name,
|
|
TRACK_TITLE_LENGTH
|
|
);
|
|
|
|
//
|
|
// Redraw list entries with new title in available tracks listbox
|
|
//
|
|
|
|
hdc = GetDC( hAvailWnd );
|
|
GetClientRect( hAvailWnd, &r1 );
|
|
SendMessage( hAvailWnd, LB_GETITEMRECT, (WPARAM)tocindex, (LPARAM)&r );
|
|
if ((r.bottom > r1.top) && (r.top < r1.bottom)) {
|
|
|
|
DrawListItem( hdc, &r, tocindex, FALSE );
|
|
|
|
}
|
|
ReleaseDC( hAvailWnd, hdc );
|
|
|
|
//
|
|
// Redraw list entries with new title in playlist listbox...there
|
|
// can be more than one
|
|
//
|
|
|
|
hdc = GetDC( hPlayWnd );
|
|
GetClientRect( hPlayWnd, &r1 );
|
|
num = SendMessage( hPlayWnd, LB_GETCOUNT, 0, 0 );
|
|
for( i=0; i<num; i++ ) {
|
|
|
|
if (SendMessage( hPlayWnd, LB_GETITEMDATA, (WPARAM)i, 0 )==tocindex) {
|
|
|
|
SendMessage( hPlayWnd, LB_GETITEMRECT, (WPARAM)i, (LPARAM)&r );
|
|
if ((r.bottom > r1.top) && (r.top < r1.bottom)) {
|
|
|
|
DrawListItem( hdc, &r, tocindex, FALSE );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
ReleaseDC( hPlayWnd, hdc );
|
|
|
|
}
|
|
|
|
INT
|
|
GetTocIndexFromPt(
|
|
HWND hwnd,
|
|
POINT p
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
This routine searches through a listbox pointed to by "hwnd,"
|
|
looking for the entry whose rectangle contains point "p." The
|
|
itemdata for this entry is returned.
|
|
|
|
|
|
Arguments:
|
|
|
|
hwnd -- handle to listbox to search
|
|
|
|
p -- point to check against
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
itemdata for this entry which the point is in.
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
INT items, i;
|
|
RECT r;
|
|
|
|
items = SendMessage( hwnd, LB_GETCOUNT, 0, 0 );
|
|
|
|
for( i=0; i<items; i++ ) {
|
|
|
|
SendMessage( hwnd, LB_GETITEMRECT, (WPARAM)i, (LPARAM)&r );
|
|
if (PtInRect( (CONST RECT *)&r, p )) {
|
|
|
|
return( SendMessage( hwnd, LB_GETITEMDATA, (WPARAM)i, 0 ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
VOID
|
|
DrawInsertPointer(
|
|
IN INT y,
|
|
IN BOOL fErase
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
This routine draw or erases the "insert arrow" for the play list
|
|
listbox that is drawn to show where tracks will be dropped.
|
|
|
|
Arguments:
|
|
|
|
|
|
y - y coordinate of where arrow should point. This is in
|
|
hTheDlg coordinates.
|
|
|
|
fErase - TRUE == erase pointer, FALSE == draw pointer
|
|
|
|
Return Value:
|
|
|
|
|
|
none.
|
|
|
|
--*/
|
|
|
|
|
|
{
|
|
HDC hdc,hdcMem;
|
|
RECT r;
|
|
|
|
hdc = GetDC( hTheDlg );
|
|
|
|
//
|
|
// Check how to draw
|
|
//
|
|
|
|
if (!fErase) {
|
|
|
|
//
|
|
// draw arrow. Arrow is 15x11 bitmap, with point of arrow
|
|
// in the middle, so draw accordingly (shifting up so point
|
|
// is 'even' with "y"
|
|
//
|
|
|
|
hdcMem = CreateCompatibleDC( hdc );
|
|
SelectObject( hdcMem, (HGDIOBJ)hInsertPoint );
|
|
BitBlt( hdc, 1, y-6, 15, 11, hdcMem, 0, 0, SRCCOPY );
|
|
DeleteDC( hdcMem );
|
|
|
|
} else {
|
|
|
|
//
|
|
// Erase the area where pointer would be
|
|
//
|
|
|
|
SetBkColor( hdc, cdLTGRAY );
|
|
r.top = y-6;
|
|
r.bottom = r.top + 11;
|
|
r.left = 1;
|
|
r.right = r.left + 15;
|
|
ExtTextOut( hdc, 0, 0, ETO_OPAQUE, (CONST RECT *)&r, NULL, 0, NULL );
|
|
|
|
}
|
|
|
|
ReleaseDC( hTheDlg, hdc );
|
|
|
|
}
|
|
|
|
INT
|
|
FigureInsertY(
|
|
IN HWND hwnd,
|
|
IN INT CurY
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
This routine computes where the y value of where the "insert pointer"
|
|
should point. The value returned is in the coordinate system of
|
|
"hwnd."
|
|
|
|
Arguments:
|
|
|
|
|
|
hwnd - used for coordinate system translation.
|
|
|
|
CurY - current Y value of mouse pointer, in "hwnd" coordinates.
|
|
|
|
Return Value:
|
|
|
|
|
|
INT -- "y" value of pointer, in "hwnd" coordinates.
|
|
|
|
--*/
|
|
|
|
|
|
{
|
|
|
|
RECT r;
|
|
|
|
GetClientRect( hwnd, &r );
|
|
if (CurY < r.top) return( r.top );
|
|
if (CurY > r.bottom) return( r.bottom );
|
|
|
|
return( (CurY / LIST_ITEM_H) * LIST_ITEM_H );
|
|
|
|
}
|
|
|
|
|
|
VOID
|
|
RecomputePlayListBox(
|
|
IN VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
This routine recomputes (clear, then re-adds all entries) the
|
|
playlist listbox. The list is recreated from the playlist pointed
|
|
to gPlayList, and will be blank is gPlayList is NULL.
|
|
|
|
|
|
Arguments:
|
|
|
|
none.
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
none.
|
|
|
|
--*/
|
|
|
|
{
|
|
PTRACK_PLAY t1;
|
|
|
|
|
|
//
|
|
// Reset play list listbox
|
|
//
|
|
|
|
|
|
SendMessage( GetDlgItem( hTheDlg, IDL_PLAY_LISTBOX ),
|
|
WM_SETREDRAW,
|
|
(WPARAM)FALSE,
|
|
0
|
|
);
|
|
|
|
SendMessage( GetDlgItem( hTheDlg, IDL_PLAY_LISTBOX ),
|
|
LB_RESETCONTENT,
|
|
0,
|
|
0
|
|
);
|
|
|
|
for( t1=gPlayList; t1!=NULL; t1=t1->nextplay ) {
|
|
|
|
SendMessage( GetDlgItem( hTheDlg, IDL_PLAY_LISTBOX ),
|
|
LB_ADDSTRING,
|
|
0,
|
|
(LPARAM)t1->TocIndex
|
|
);
|
|
|
|
}
|
|
|
|
SendMessage( GetDlgItem( hTheDlg, IDL_PLAY_LISTBOX ),
|
|
WM_SETREDRAW,
|
|
(WPARAM)TRUE,
|
|
0
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
LRESULT CALLBACK ListMessHookProc(
|
|
IN INT nCode,
|
|
IN WPARAM wParam,
|
|
IN LPARAM lParam
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
This routine is a MsgFilterProc for the listboxes in this
|
|
dialog. It implements the selection and drag and drop code
|
|
for this dialog box.
|
|
|
|
|
|
Arguments:
|
|
|
|
Standard MsgFilter hook proc arguments
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
TRUE if message was handled, FALSE if not.
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
static BOOL fDrag;
|
|
static BOOL fInsert;
|
|
static INT InsY;
|
|
// POINT p;
|
|
// RECT r,r1;
|
|
LPMSG lpm = (LPMSG)lParam;
|
|
INT i;
|
|
PTRACK_INF t;
|
|
DWORD dwStart,dwEnd;
|
|
TCHAR s[ 15 ];
|
|
|
|
switch( (INT)(lpm->message) ) {
|
|
|
|
case WM_KEYDOWN:
|
|
switch( (INT)(lpm->wParam) ) {
|
|
case VK_RETURN:
|
|
|
|
//
|
|
// Find out which control we were in.
|
|
//
|
|
i = GetDlgCtrlID(GetFocus());
|
|
|
|
//
|
|
// If we're in an edit control, save that control's info.
|
|
//
|
|
switch (i) {
|
|
|
|
case IDT_GET_ARTIST:
|
|
|
|
fChanged =TRUE;
|
|
GetDlgItemText(hTheDlg,
|
|
i,
|
|
(LPSTR)ARTIST(dCdrom),
|
|
ARTIST_LENGTH
|
|
);
|
|
SendDlgItemMessage(hTheDlg,i,EM_GETSEL,(WPARAM)&dwStart,(LPARAM)&dwEnd);
|
|
SendDlgItemMessage(hTheDlg,i,EM_SETSEL,dwEnd,dwEnd);
|
|
|
|
return(1);
|
|
break;
|
|
|
|
case IDT_GET_TITLE:
|
|
|
|
fChanged =TRUE;
|
|
GetDlgItemText(hTheDlg,
|
|
i,
|
|
(LPSTR)TITLE(dCdrom),
|
|
TITLE_LENGTH
|
|
);
|
|
SendDlgItemMessage(hTheDlg,i,EM_GETSEL,(WPARAM)&dwStart,(LPARAM)&dwEnd);
|
|
SendDlgItemMessage(hTheDlg,i,EM_SETSEL,dwEnd,dwEnd);
|
|
return(1);
|
|
break;
|
|
|
|
case IDT_GET_TRACK:
|
|
|
|
fChanged =TRUE;
|
|
GrabTrackName( CurrTocIndex );
|
|
CurrTocIndex++;
|
|
if (CurrTocIndex >= NUMTRACKS( dCdrom )) {
|
|
|
|
CurrTocIndex = 0;
|
|
|
|
}
|
|
|
|
SendMessage( hPlayWnd,
|
|
LB_SETSEL,
|
|
(WPARAM)(BOOL)FALSE,
|
|
MAKELPARAM( -1, -1 )
|
|
);
|
|
|
|
SendMessage( hAvailWnd,
|
|
LB_SETSEL,
|
|
(WPARAM)(BOOL)FALSE,
|
|
MAKELPARAM( -1, -1 )
|
|
);
|
|
|
|
|
|
SendMessage( hAvailWnd,
|
|
LB_SELITEMRANGE,
|
|
(WPARAM)(BOOL)TRUE,
|
|
MAKELPARAM( CurrTocIndex, CurrTocIndex )
|
|
);
|
|
|
|
//
|
|
// Display correct track in track field
|
|
//
|
|
|
|
t = FindTrackNodeFromTocIndex( CurrTocIndex, gAllList );
|
|
SetDlgItemText( hTheDlg, IDT_GET_TRACK, (LPCSTR)t->name );
|
|
sprintf( s, IdStr( STR_TRACK1 ), CurrTocIndex + FIRSTTRACK( dCdrom ) );
|
|
SetDlgItemText( hTheDlg, IDT_DTRACK_NAME, s );
|
|
SendMessage( GetDlgItem( hTheDlg, IDT_GET_TRACK ),
|
|
EM_SETSEL,
|
|
(WPARAM)0,
|
|
(LPARAM)-1
|
|
);
|
|
return(1);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case VK_DOWN:
|
|
break;
|
|
case VK_UP:
|
|
break;
|
|
|
|
}
|
|
break;
|
|
/*******************
|
|
case WM_LBUTTONDOWN:
|
|
|
|
//
|
|
// The left mouse button was pressed. Is it in one of the
|
|
// list boxes?
|
|
//
|
|
|
|
p.x = lpm->pt.x;
|
|
p.y = lpm->pt.y;
|
|
ScreenToClient( hAvailWnd, &p );
|
|
GetClientRect( hAvailWnd, &r );
|
|
|
|
//
|
|
// Did user click in the Available tracks listbox?
|
|
//
|
|
|
|
if (PtInRect( (CONST RECT *)&r, p )) {
|
|
|
|
//
|
|
// Need to turn off any selection in the PlayList
|
|
// list box, enable "add" button and disable "remove"
|
|
// button
|
|
//
|
|
|
|
GrabTrackName( CurrTocIndex );
|
|
SendMessage( hPlayWnd,
|
|
LB_SETSEL,
|
|
(WPARAM)(BOOL)FALSE,
|
|
MAKELPARAM( -1, -1 )
|
|
);
|
|
fAdd = TRUE;
|
|
SetWindowText( GetDlgItem( hTheDlg, IDB_ADD ), "U" );
|
|
SendMessage( GetDlgItem( hTheDlg, IDB_REMOVE ),
|
|
WM_KILLFOCUS,
|
|
0,
|
|
(LPARAM)NULL
|
|
);
|
|
fRemove = FALSE;
|
|
SetWindowText( GetDlgItem( hTheDlg, IDB_REMOVE ), "X" );
|
|
//
|
|
// Update currently displayed track in track name
|
|
// field
|
|
//
|
|
|
|
i = GetTocIndexFromPt( hAvailWnd, p );
|
|
t = FindTrackNodeFromTocIndex( i, gAllList );
|
|
SetDlgItemText( hTheDlg, IDT_GET_TRACK, (LPSTR)t->name );
|
|
sprintf( s, IdStr( STR_TRACK1 ), i + FIRSTTRACK( dCdrom ) );
|
|
SetDlgItemText( hTheDlg, IDT_DTRACK_NAME, s );
|
|
CurrTocIndex = i;
|
|
//
|
|
// Where in available tracks listbox was click?
|
|
//
|
|
|
|
if (p.x < 14) {
|
|
|
|
//
|
|
// This is a potential drag and drop
|
|
//
|
|
|
|
fDrag = TRUE;
|
|
fDragCur = TRUE;
|
|
fInsert = FALSE;
|
|
hStartDrag = hAvailWnd;
|
|
SetCursor( hDrag );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
|
|
p.x = lpm->pt.x;
|
|
p.y = lpm->pt.y;
|
|
ScreenToClient( hPlayWnd, &p );
|
|
GetClientRect( hPlayWnd, &r );
|
|
|
|
//
|
|
// Did user click in the PlayList listbox?
|
|
//
|
|
|
|
if (PtInRect( (CONST RECT *)&r, p )) {
|
|
|
|
//
|
|
// Need to turn off any selection in the PlayList
|
|
// list box, disable "add" button and enable "remove"
|
|
// button
|
|
//
|
|
|
|
GrabTrackName( CurrTocIndex );
|
|
SendMessage( hAvailWnd,
|
|
LB_SETSEL,
|
|
(WPARAM)(BOOL)FALSE,
|
|
MAKELPARAM( -1, -1 )
|
|
);
|
|
fAdd = FALSE;
|
|
SendMessage( GetDlgItem( hTheDlg, IDB_ADD ),
|
|
WM_KILLFOCUS,
|
|
0,
|
|
(LPARAM)NULL
|
|
);
|
|
SetWindowText( GetDlgItem( hTheDlg, IDB_ADD ), "#X" );
|
|
fRemove = TRUE;
|
|
SetWindowText( GetDlgItem( hTheDlg, IDB_REMOVE ), "U" );
|
|
|
|
//
|
|
// Update currently displayed track in track name
|
|
// field
|
|
//
|
|
|
|
i = GetTocIndexFromPt( hPlayWnd, p );
|
|
t = FindTrackNodeFromTocIndex( i, gAllList );
|
|
SetDlgItemText( hTheDlg, IDT_GET_TRACK, (LPCSTR)t->name );
|
|
sprintf( s, IdStr( STR_TRACK1 ), i + FIRSTTRACK( dCdrom ) );
|
|
SetDlgItemText( hTheDlg, IDT_DTRACK_NAME, s );
|
|
CurrTocIndex = i;
|
|
|
|
//
|
|
// Where in PlayList listbox was click?
|
|
//
|
|
|
|
if (p.x < 14) {
|
|
|
|
//
|
|
// This is a potential drag and drop
|
|
//
|
|
|
|
fDrag = TRUE;
|
|
fDragCur = TRUE;
|
|
fInsert = TRUE;
|
|
p.y = FigureInsertY( hPlayWnd, p.y );
|
|
ClientToScreen( hPlayWnd, &p );
|
|
ScreenToClient( hTheDlg, &p );
|
|
InsY = p.y;
|
|
DrawInsertPointer( p.y, FALSE );
|
|
hStartDrag = hPlayWnd;
|
|
SetCursor( hDrag );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case WM_MOUSEMOVE:
|
|
|
|
if (fDrag) {
|
|
|
|
GetWindowRect( hPlayWnd, &r );
|
|
GetWindowRect( hAvailWnd, &r1 );
|
|
|
|
p.x = lpm->pt.x;
|
|
p.y = lpm->pt.y;
|
|
|
|
if (PtInRect((CONST RECT *)&r,p)) {
|
|
|
|
//
|
|
// Cursor is in Play List listbox
|
|
//
|
|
|
|
if (!fDragCur) {
|
|
|
|
SetCursor( hDrag );
|
|
fDragCur = TRUE;
|
|
|
|
}
|
|
|
|
//
|
|
// Adjust insert pointer if necessary
|
|
//
|
|
|
|
fInsert = TRUE;
|
|
ScreenToClient( hPlayWnd, &p );
|
|
p.y = FigureInsertY( hPlayWnd, p.y );
|
|
ClientToScreen( hPlayWnd, &p );
|
|
ScreenToClient( hTheDlg, &p );
|
|
if (p.y!=InsY) {
|
|
|
|
DrawInsertPointer( InsY, TRUE );
|
|
DrawInsertPointer( p.y, FALSE );
|
|
InsY = p.y;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (fInsert) {
|
|
|
|
DrawInsertPointer( InsY, TRUE );
|
|
fInsert = FALSE;
|
|
|
|
}
|
|
|
|
if (PtInRect((CONST RECT *)&r1,p)) {
|
|
|
|
//
|
|
// Cursor is in Available Tracks list box
|
|
//
|
|
|
|
if ((!fDragCur) && (hStartDrag==hAvailWnd)) {
|
|
|
|
SetCursor( hDrag );
|
|
fDragCur = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
//
|
|
// Cursor is outside of both listboxes
|
|
//
|
|
|
|
if (fDragCur) {
|
|
|
|
if (hStartDrag==hPlayWnd) {
|
|
|
|
SetCursor( hDropDel );
|
|
|
|
} else {
|
|
|
|
SetCursor( hNoDrop );
|
|
|
|
}
|
|
fDragCur = FALSE;
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return( 1 );
|
|
|
|
}
|
|
break;
|
|
|
|
case WM_LBUTTONUP:
|
|
SetCursor( hNormal );
|
|
if (fInsert) DrawInsertPointer( InsY, TRUE );
|
|
fInsert = FALSE;
|
|
fDrag = FALSE;
|
|
fDragCur = FALSE;
|
|
break;
|
|
**************/
|
|
}
|
|
|
|
if (nCode<0) {
|
|
|
|
return( CallNextHookEx( MyListBoxHook, nCode, wParam, lParam ) );
|
|
|
|
}
|
|
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
|
|
LRESULT CALLBACK DlgTextWndProc(
|
|
HWND hwnd,
|
|
UINT message,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
This routine handles messages for the "header" text in the disc
|
|
info dialog.
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
hwnd - supplies a handle to the window to draw into
|
|
|
|
message - supplies the window message to the window pointed to be "hwnd"
|
|
|
|
wParam - supplies the word parameter for the message in "message"
|
|
|
|
lParam - supplies the long parameter for the message in "message"
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
Whatever our call to DefWindowProc returns for this window,
|
|
or 0 if we handle the message.
|
|
|
|
--*/
|
|
|
|
|
|
{
|
|
PAINTSTRUCT ps;
|
|
RECT r;
|
|
HDC hdc;
|
|
TCHAR s[ 128 ];
|
|
|
|
|
|
switch( message ) {
|
|
case WM_PAINT:
|
|
hdc = BeginPaint( hwnd, &ps );
|
|
GetClientRect( hwnd, &r );
|
|
SetBkColor( hdc, cdLTGRAY );
|
|
SetTextColor( hdc, cdBLACK );
|
|
SelectObject( hdc, (HGDIOBJ)hFont );
|
|
GetWindowText( hwnd, (LPSTR)s, 128 );
|
|
ExtTextOut( hdc,
|
|
0,
|
|
0,
|
|
ETO_OPAQUE | ETO_CLIPPED,
|
|
(CONST RECT *)&r,
|
|
s,
|
|
strlen(s),
|
|
NULL
|
|
);
|
|
EndPaint( hwnd, (CONST PAINTSTRUCT *)&ps );
|
|
return( 0 );
|
|
|
|
case WM_SETTEXT:
|
|
hdc = GetDC( hwnd );
|
|
SetTextColor( hdc, cdBLACK );
|
|
GetClientRect( hwnd, &r );
|
|
SetBkColor( hdc, cdLTGRAY );
|
|
SelectObject( hdc, (HGDIOBJ)hFont );
|
|
ExtTextOut( hdc,
|
|
0,
|
|
0,
|
|
ETO_OPAQUE | ETO_CLIPPED,
|
|
(CONST RECT *)&r,
|
|
(LPSTR)lParam,
|
|
strlen((LPSTR)lParam),
|
|
NULL
|
|
);
|
|
ReleaseDC( hwnd, hdc );
|
|
break;
|
|
}
|
|
|
|
return( DefWindowProc( hwnd, message, wParam, lParam ) );
|
|
|
|
}
|
|
|
|
VOID
|
|
InitForNewDrive(
|
|
IN VOID
|
|
)
|
|
|
|
{
|
|
|
|
HWND hwnd;
|
|
PTRACK_INF t;
|
|
PTRACK_PLAY t1,prev;
|
|
TCHAR s[50];
|
|
|
|
SetDlgItemText( hTheDlg, IDT_GET_TITLE, (LPCSTR)TITLE(dCdrom) );
|
|
SetDlgItemText( hTheDlg, IDT_GET_ARTIST, (LPCSTR)ARTIST(dCdrom) );
|
|
SetDlgItemText( hTheDlg, IDT_GET_TRACK, (LPCSTR)ALLTRACKS(dCdrom)->name );
|
|
|
|
//
|
|
// Fill in current tracks
|
|
//
|
|
|
|
hwnd = GetDlgItem( hTheDlg, IDL_TRACK_LISTBOX );
|
|
SendMessage( hwnd, LB_RESETCONTENT, 0, 0 );
|
|
for( t=gAllList; t!=NULL; t=t->next ) {
|
|
|
|
SendMessage( hwnd, LB_ADDSTRING, 0, t->TocIndex );
|
|
|
|
}
|
|
|
|
//
|
|
// Is current play list empty? If so, fill in default
|
|
// play list which is all tracks in order.
|
|
//
|
|
|
|
if ((gPlayList==NULL)&&(gDevices[ dCdrom ]->CdInfo.IsVirginCd)) {
|
|
|
|
DBGPRINT(( 1, "InitForNewDrive: Creating default playlist for %d\n", dCdrom ));
|
|
//
|
|
// Fill in default play list
|
|
//
|
|
|
|
prev = NULL;
|
|
for( t=gAllList; t!=NULL; t=t->next ) {
|
|
|
|
t1 = (PTRACK_PLAY)LocalAlloc( LPTR, sizeof( TRACK_PLAY ) );
|
|
t1->min = 0;
|
|
t1->sec = 0;
|
|
t1->nextplay = NULL;
|
|
t1->prevplay = prev;
|
|
t1->TocIndex = t->TocIndex;
|
|
|
|
if (gPlayList==NULL) {
|
|
|
|
gPlayList = t1;
|
|
prev = t1;
|
|
|
|
} else {
|
|
|
|
prev->nextplay = t1;
|
|
prev = t1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
DUMPPLAYLIST(( gPlayList ));
|
|
|
|
}
|
|
|
|
//
|
|
// Fill in current play list
|
|
//
|
|
|
|
hwnd = GetDlgItem( hTheDlg, IDL_PLAY_LISTBOX );
|
|
SendMessage( hwnd, LB_RESETCONTENT, 0, 0 );
|
|
for( t1=gPlayList; t1!=NULL; t1=t1->nextplay ) {
|
|
|
|
SendMessage( hwnd, LB_ADDSTRING, 0, t1->TocIndex );
|
|
|
|
}
|
|
|
|
//
|
|
// Set CurrTocIndex to first entry in playlist listbox
|
|
//
|
|
|
|
if (gPlayList!=NULL) {
|
|
|
|
CurrTocIndex = gPlayList->TocIndex;
|
|
|
|
} else {
|
|
|
|
CurrTocIndex = 0;
|
|
|
|
}
|
|
|
|
//
|
|
// Display correct track in track field
|
|
//
|
|
|
|
t = FindTrackNodeFromTocIndex( CurrTocIndex, gAllList );
|
|
SetDlgItemText( hTheDlg, IDT_GET_TRACK, (LPCSTR)t->name );
|
|
sprintf( s, IdStr( STR_TRACK1 ), CurrTocIndex + FIRSTTRACK( dCdrom ) );
|
|
SetDlgItemText( hTheDlg, IDT_DTRACK_NAME, s );
|
|
|
|
//
|
|
// Mark this as "virgin" territory
|
|
//
|
|
|
|
fChanged = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL FAR PASCAL
|
|
GetDiscInfoDlgProc(
|
|
IN HWND hDlg,
|
|
IN UINT message,
|
|
IN WPARAM wParam,
|
|
IN LPARAM lParam
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
This routine handles messages from the child windows for this
|
|
routine.
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
hwnd - supplies a handle to the window to draw into
|
|
|
|
message - supplies the window message to the window pointed to be "hwnd"
|
|
|
|
wParam - supplies the word parameter for the message in "message"
|
|
|
|
lParam - supplies the long parameter for the message in "message"
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
Whatever our call to DefWindowProc returns for this window,
|
|
or 0 if we handle the message.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
HDC hdc;
|
|
HWND hwnd,hDlgItem;
|
|
RECT r;
|
|
UINT i,num,y;
|
|
static HBRUSH hbrWhite;
|
|
static HBRUSH hbrLtGray;
|
|
static int iCurCtl;
|
|
PTRACK_INF t;
|
|
PTRACK_PLAY t1,t2,prev;
|
|
TCHAR s[50];
|
|
INT items[100];
|
|
BOOL save;
|
|
|
|
switch( message ) {
|
|
|
|
case WM_INITDIALOG:
|
|
|
|
//
|
|
// Set global handle
|
|
//
|
|
|
|
hTheDlg = hDlg;
|
|
fClear = TRUE;
|
|
fAdd = FALSE;
|
|
fRemove = FALSE;
|
|
fChanged = FALSE;
|
|
iCurCtl = 0;
|
|
|
|
//
|
|
// Get handles to cursors we will need
|
|
//
|
|
|
|
hNormal = LoadCursor( (HINSTANCE)gInstance, IDC_ARROW );
|
|
hDrag = LoadCursor( (HINSTANCE)gInstance, "DropCur" );
|
|
hDropDel = LoadCursor( (HINSTANCE)gInstance, "DropDel" );
|
|
hNoDrop = LoadCursor( (HINSTANCE)gInstance, "NoDropCur" );
|
|
|
|
//
|
|
// Load track icon bitmap for listboxes
|
|
//
|
|
|
|
hTrackIcon = LoadBitmap( (HINSTANCE)gInstance, "trackdrag" );
|
|
hInsertPoint = LoadBitmap( (HINSTANCE)gInstance, "insert" );
|
|
|
|
//
|
|
// Get handles to windows for the two listboxes
|
|
//
|
|
|
|
hAvailWnd = GetDlgItem( hDlg, IDL_TRACK_LISTBOX );
|
|
hPlayWnd = GetDlgItem( hDlg, IDL_PLAY_LISTBOX );
|
|
|
|
//
|
|
// Install hook procedures for listboxes
|
|
//
|
|
|
|
MyListBoxHook = SetWindowsHookEx( WH_MSGFILTER,
|
|
ListMessHookProc,
|
|
(HINSTANCE)gInstance,
|
|
GetCurrentThreadId()
|
|
);
|
|
|
|
|
|
sprintf( s,
|
|
"\\Device\\CdRom%d <%c:>",
|
|
dCdrom,
|
|
gDevices[dCdrom]->drive
|
|
);
|
|
|
|
SetDlgItemText(hDlg,IDT_DRIVE_FIELD,s);
|
|
|
|
|
|
//
|
|
// Initialize disc info fields
|
|
//
|
|
|
|
hbrWhite = CreateSolidBrush( cdWHITE );
|
|
hbrLtGray = CreateSolidBrush( cdLTGRAY );
|
|
for( i=IDT_ARTIST_NAME; i<IDL_TRACK_LISTBOX; i++ ) {
|
|
hwnd = GetDlgItem( hDlg, i );
|
|
SetWindowLong( hwnd, GWL_WNDPROC, (LONG)DlgTextWndProc );
|
|
}
|
|
|
|
InitForNewDrive();
|
|
SendDlgItemMessage(hDlg,IDT_GET_ARTIST,EM_LIMITTEXT,ARTIST_LENGTH,0);
|
|
SendDlgItemMessage(hDlg,IDT_GET_TITLE, EM_LIMITTEXT,TITLE_LENGTH,0);
|
|
SendDlgItemMessage(hDlg,IDT_GET_TRACK, EM_LIMITTEXT,TRACK_TITLE_LENGTH,0);
|
|
|
|
SendDlgItemMessage(hDlg,IDL_TRACK_LISTBOX,LB_SETSEL, TRUE, 0);
|
|
SendDlgItemMessage(hDlg,IDL_PLAY_LISTBOX,LB_SETSEL, TRUE, 0);
|
|
|
|
num = SendDlgItemMessage(hDlg,IDL_PLAY_LISTBOX,LB_GETCOUNT, 0, 0);
|
|
|
|
if (num == 0) {
|
|
|
|
EnableWindow(GetDlgItem(hDlg,IDB_REMOVE), FALSE);
|
|
EnableWindow(GetDlgItem(hDlg,IDB_CLEAR), FALSE);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case WM_CTLCOLORSTATIC:
|
|
// SetBkColor( (HDC)wParam, cdLTGRAY );
|
|
// SetTextColor( (HDC)wParam, cdBLACK );
|
|
SetBkColor( (HDC)wParam, GetSysColor(COLOR_WINDOW));
|
|
SetTextColor((HDC)wParam, GetSysColor(COLOR_WINDOWTEXT));
|
|
// return( (BOOL)hbrLtGray );
|
|
return( (BOOL) CreateSolidBrush(GetSysColor(COLOR_WINDOW)) );
|
|
break;
|
|
|
|
case WM_CTLCOLOREDIT:
|
|
case WM_CTLCOLORLISTBOX:
|
|
// SetBkColor( (HDC)wParam, cdWHITE );
|
|
// SetTextColor( (HDC)wParam, cdBLACK );
|
|
SetBkColor( (HDC)wParam, GetSysColor(COLOR_WINDOW));
|
|
SetTextColor((HDC)wParam, GetSysColor(COLOR_WINDOWTEXT));
|
|
return( (BOOL) CreateSolidBrush(GetSysColor(COLOR_WINDOW)));
|
|
break;
|
|
|
|
case WM_ERASEBKGND:
|
|
hdc = (HDC)wParam;
|
|
GetClientRect( hDlg, &r );
|
|
SetBkColor( hdc, GetSysColor(COLOR_WINDOW));
|
|
SetTextColor( hdc, GetSysColor(COLOR_WINDOWTEXT));
|
|
SetBkColor( hdc, cdLTGRAY );
|
|
ExtTextOut( hdc, 0, 0, ETO_OPAQUE, (CONST RECT *)&r, NULL, 0, NULL );
|
|
|
|
y = (LINE_1_Y * HIWORD(GetDialogBaseUnits())) / 8;
|
|
SelectObject( hdc, (HGDIOBJ)hpBlack );
|
|
MoveToEx( hdc, r.left, y, NULL );
|
|
LineTo( hdc, r.right, y );
|
|
SelectObject( hdc, (HGDIOBJ)hpWhite );
|
|
MoveToEx( hdc, r.left, y+1, NULL );
|
|
LineTo( hdc, r.right, y+1 );
|
|
|
|
y = (LINE_2_Y * HIWORD(GetDialogBaseUnits())) / 8;
|
|
SelectObject( hdc, (HGDIOBJ)hpBlack );
|
|
MoveToEx( hdc, r.left, y, NULL );
|
|
LineTo( hdc, r.right, y );
|
|
SelectObject( hdc, (HGDIOBJ)hpWhite );
|
|
MoveToEx( hdc, r.left, y+1, NULL );
|
|
LineTo( hdc, r.right, y+1 );
|
|
|
|
return( TRUE );
|
|
|
|
case WM_SYSCOMMAND:
|
|
switch( wParam ) {
|
|
case SC_CLOSE:
|
|
DeleteObject( (HGDIOBJ)hbrWhite );
|
|
DeleteObject( (HGDIOBJ)hbrLtGray );
|
|
UnhookWindowsHookEx( MyListBoxHook );
|
|
EndDialog( hDlg, TRUE );
|
|
return( 0 );
|
|
}
|
|
break;
|
|
|
|
|
|
case WM_COMMAND:
|
|
switch ( LOWORD(wParam)) {
|
|
|
|
case IDL_TRACK_LISTBOX:
|
|
case IDL_PLAY_LISTBOX:
|
|
switch (HIWORD(wParam)) {
|
|
case LBN_SELCHANGE:
|
|
//
|
|
// 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 (LOWORD(wParam) == IDL_TRACK_LISTBOX) {
|
|
|
|
|
|
GrabTrackName( CurrTocIndex );
|
|
//
|
|
// Update currently displayed track in track name
|
|
// field
|
|
//
|
|
hDlgItem = (HWND) lParam;
|
|
SendMessage(hDlgItem,LB_GETSELITEMS,1,(LPARAM) items);
|
|
i = SendMessage( hDlgItem, LB_GETITEMDATA, items[0], 0 );
|
|
|
|
t = FindTrackNodeFromTocIndex( i, gAllList );
|
|
SetDlgItemText( hTheDlg, IDT_GET_TRACK, (LPSTR)t->name );
|
|
sprintf( s, IdStr( STR_TRACK1 ), i + FIRSTTRACK( dCdrom ) );
|
|
SetDlgItemText( hTheDlg, IDT_DTRACK_NAME, s );
|
|
CurrTocIndex = i;
|
|
|
|
}
|
|
break;
|
|
case LBN_KILLFOCUS:
|
|
//
|
|
// The listbox is losing focus. Un-highlight all the entries.
|
|
//
|
|
hDlgItem = GetDlgItem(hDlg,(int) LOWORD(wParam));
|
|
iCurCtl = 0;
|
|
RedrawWindow(hDlgItem,NULL,NULL,RDW_INVALIDATE);
|
|
//UpdateWindow(hDlgItem);
|
|
break;
|
|
case LBN_SETFOCUS:
|
|
//
|
|
// The listbox is gaining focus. Highlight selected entries.
|
|
//
|
|
hDlgItem = GetDlgItem(hDlg,(int) LOWORD(wParam));
|
|
|
|
i = SendMessage(hDlgItem,LB_GETTOPINDEX,0,0);
|
|
|
|
if (!SendMessage(hDlgItem,LB_GETSELCOUNT,0,0)) {
|
|
|
|
SendMessage(hDlgItem,LB_SETSEL,TRUE,0);
|
|
|
|
}
|
|
|
|
iCurCtl = (int) LOWORD(wParam);
|
|
RedrawWindow(hDlgItem,NULL,NULL,RDW_INVALIDATE);
|
|
//UpdateWindow(hDlgItem);
|
|
SendMessage(hDlgItem,LB_SETTOPINDEX,(WPARAM)i,0);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
//
|
|
// Everything that ISN'T one of the two listboxes is a default.
|
|
//
|
|
default:
|
|
|
|
|
|
switch( HIWORD(wParam) ) {
|
|
|
|
case EN_CHANGE:
|
|
if ( (LOWORD(wParam)==IDT_GET_ARTIST) ||
|
|
(LOWORD(wParam)==IDT_GET_TITLE)
|
|
) {
|
|
|
|
fChanged = TRUE;
|
|
|
|
}
|
|
break;
|
|
/************************************************
|
|
case CBN_SELCHANGE:
|
|
if (LOWORD(wParam)==IDC_DRIVE_FIELD) {
|
|
i = SendMessage( GetDlgItem( hTheDlg, IDC_DRIVE_FIELD ),
|
|
CB_GETCURSEL,
|
|
0,
|
|
0
|
|
);
|
|
|
|
if (i != (UINT)dCdrom) {
|
|
|
|
if (fChanged) {
|
|
|
|
if ( MessageBox( hTheDlg,
|
|
IdStr( STR_SAVE_CHANGES ), //"Do you wish to save your changes?",
|
|
IdStr( STR_SAVE_INFO ), // "CD Player: Save Play Information",
|
|
MB_ICONQUESTION | MB_YESNO)==IDYES
|
|
) {
|
|
|
|
//
|
|
// Point to new information (OK was pressed)
|
|
//
|
|
|
|
GrabNewTrackLists( dCdrom );
|
|
GrabDiscAndArtistNames( dCdrom );
|
|
|
|
} else {
|
|
|
|
//
|
|
// Need to free up temp nodes
|
|
//
|
|
|
|
KillTempTrackList();
|
|
KillTempPlayList();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
KillTempTrackList();
|
|
KillTempPlayList();
|
|
|
|
}
|
|
|
|
dCdrom = i;
|
|
|
|
//
|
|
// Make copies of play list and track list
|
|
//
|
|
|
|
DuplicateTrackList( dCdrom );
|
|
DuplicatePlayList( dCdrom );
|
|
|
|
//
|
|
// Update everything
|
|
//
|
|
|
|
InitForNewDrive();
|
|
|
|
}
|
|
}
|
|
break;
|
|
|
|
************************************************/
|
|
|
|
|
|
case BN_CLICKED:
|
|
case BN_DOUBLECLICKED:
|
|
switch( LOWORD(wParam) ) {
|
|
case IDOK:
|
|
if (fChanged) {
|
|
|
|
save = TRUE;
|
|
|
|
} else {
|
|
|
|
save = FALSE;
|
|
|
|
}
|
|
|
|
if (save) {
|
|
|
|
GrabDiscAndArtistNames( dCdrom );
|
|
|
|
}
|
|
|
|
DeleteObject( (HGDIOBJ)hbrWhite );
|
|
UnhookWindowsHookEx( MyListBoxHook );
|
|
EndDialog( hDlg, save );
|
|
return( TRUE );
|
|
|
|
case IDCANCEL:
|
|
|
|
save = FALSE;
|
|
DeleteObject( (HGDIOBJ)hbrWhite );
|
|
UnhookWindowsHookEx( MyListBoxHook );
|
|
EndDialog( hDlg, save );
|
|
return( TRUE );
|
|
|
|
|
|
case IDB_ADD:
|
|
|
|
//
|
|
// Get selection(s)
|
|
//
|
|
|
|
num = SendMessage( GetDlgItem( hTheDlg, IDL_TRACK_LISTBOX ),
|
|
LB_GETSELITEMS,
|
|
(WPARAM)100,
|
|
(LPARAM)items
|
|
);
|
|
|
|
|
|
//
|
|
// Find end of list, or if this is the first
|
|
// entry in the list, then point PlayList to
|
|
// first node
|
|
//
|
|
|
|
for( prev = gPlayList;
|
|
((prev!=NULL) && (prev->nextplay!=NULL));
|
|
prev = prev->nextplay
|
|
);
|
|
|
|
//
|
|
// Tack each selection onto end of play list
|
|
//
|
|
|
|
DBGPRINT(( 1, "IDB_ADD: Adding track(s) to end of play list\n" ));
|
|
for( i=0; i<num; i++) {
|
|
|
|
t1 = (PTRACK_PLAY)LocalAlloc( LPTR, sizeof( TRACK_PLAY ) );
|
|
t1->sec = 0;
|
|
t1->min = 0;
|
|
t1->prevplay = prev;
|
|
t1->nextplay = NULL;
|
|
t1->TocIndex = SendMessage( GetDlgItem( hTheDlg, IDL_TRACK_LISTBOX ),
|
|
LB_GETITEMDATA,
|
|
(WPARAM)items[i],
|
|
0
|
|
);
|
|
if (prev!=NULL) {
|
|
|
|
prev->nextplay = t1;
|
|
prev = t1;
|
|
|
|
} else {
|
|
|
|
gPlayList = t1;
|
|
prev = t1;
|
|
|
|
}
|
|
|
|
SendMessage( GetDlgItem( hTheDlg, IDL_PLAY_LISTBOX ),
|
|
LB_ADDSTRING,
|
|
(WPARAM)-1,
|
|
(LPARAM)t1->TocIndex
|
|
);
|
|
|
|
}
|
|
|
|
num = SendDlgItemMessage(hDlg,IDL_PLAY_LISTBOX,LB_GETCOUNT, 0, 0);
|
|
|
|
EnableWindow(GetDlgItem(hDlg,IDB_REMOVE), (num != 0));
|
|
EnableWindow(GetDlgItem(hDlg,IDB_CLEAR), (num != 0));
|
|
|
|
num = SendDlgItemMessage(hDlg,IDL_PLAY_LISTBOX,LB_GETSELCOUNT, 0, 0);
|
|
|
|
if (num == 0) {
|
|
|
|
SendDlgItemMessage( hDlg,IDL_PLAY_LISTBOX,
|
|
LB_SETSEL, TRUE, 0);
|
|
|
|
}
|
|
|
|
DUMPPLAYLIST(( gPlayList ));
|
|
|
|
fChanged = TRUE;
|
|
|
|
break;
|
|
|
|
case IDB_REMOVE:
|
|
|
|
if (gPlayList!=NULL) {
|
|
|
|
DBGPRINT(( 1, "IDB_REMOVE: removing track(s) from play list...\n" ));
|
|
|
|
//
|
|
// Get selection(s)
|
|
//
|
|
|
|
num = SendMessage( GetDlgItem( hTheDlg,
|
|
IDL_PLAY_LISTBOX ),
|
|
LB_GETSELITEMS,
|
|
(WPARAM)100,
|
|
(LPARAM)items
|
|
);
|
|
|
|
//
|
|
// find first to delete...
|
|
//
|
|
|
|
if (num == 0) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
for( i=0, t1 = gPlayList;
|
|
i != (UINT)items[0];
|
|
t1 = t1->nextplay, i++
|
|
);
|
|
|
|
//
|
|
// mark previous node
|
|
//
|
|
|
|
prev = t1->prevplay;
|
|
|
|
//
|
|
// Delete selection(s)
|
|
//
|
|
|
|
for( i=0; i < num ; i++ ) {
|
|
|
|
t2 = t1->nextplay;
|
|
LocalFree( (HLOCAL)t1 );
|
|
if ((i+1)==num) {
|
|
|
|
//
|
|
// last node was deleted, so patch
|
|
// up list
|
|
//
|
|
|
|
if (prev!=NULL) {
|
|
|
|
prev->nextplay = t2;
|
|
|
|
} else {
|
|
|
|
gPlayList = t2;
|
|
|
|
|
|
}
|
|
|
|
if (t2!=NULL)
|
|
t2->prevplay = prev;
|
|
|
|
} else {
|
|
|
|
//
|
|
// still mode nodes to delete
|
|
//
|
|
|
|
t1 = t2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// Rebuild listbox w/items deleted
|
|
//
|
|
|
|
|
|
RecomputePlayListBox();
|
|
|
|
if (gPlayList==NULL) {
|
|
|
|
//
|
|
// Make sure remove button is disabled now
|
|
// that there are no tracks
|
|
//
|
|
|
|
fRemove = FALSE;
|
|
SendMessage( GetDlgItem( hTheDlg, IDB_REMOVE ),
|
|
WM_KILLFOCUS,
|
|
0,
|
|
(LPARAM)NULL
|
|
);
|
|
|
|
EnableWindow(GetDlgItem(hDlg,IDB_REMOVE), FALSE);
|
|
EnableWindow(GetDlgItem(hDlg,IDB_CLEAR), FALSE);
|
|
|
|
} else {
|
|
|
|
SendDlgItemMessage( hDlg,IDL_PLAY_LISTBOX,
|
|
LB_SETSEL, TRUE, 0);
|
|
}
|
|
|
|
DUMPPLAYLIST(( gPlayList ));
|
|
|
|
}
|
|
|
|
fChanged = TRUE;
|
|
break;
|
|
|
|
case IDB_CLEAR:
|
|
if (gPlayList!=NULL) {
|
|
|
|
//
|
|
// Erase all nodes in gPlayList
|
|
//
|
|
|
|
KillTempPlayList();
|
|
|
|
gPlayList = NULL;
|
|
|
|
//
|
|
// Reset play list listbox
|
|
//
|
|
|
|
RecomputePlayListBox();
|
|
EnableWindow(GetDlgItem(hDlg,IDB_REMOVE), FALSE);
|
|
EnableWindow(GetDlgItem(hDlg,IDB_CLEAR), FALSE);
|
|
|
|
//
|
|
// Reset remove button if necessary
|
|
//
|
|
|
|
if (fRemove) {
|
|
|
|
fRemove = FALSE;
|
|
SetFocus( GetDlgItem( hTheDlg, IDB_SET ) );
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
fChanged = TRUE;
|
|
|
|
break;
|
|
|
|
case IDB_DEFAULT:
|
|
|
|
if (gPlayList!=NULL) {
|
|
|
|
//
|
|
// Erase all nodes in gPlayList
|
|
//
|
|
|
|
KillTempPlayList();
|
|
gPlayList = NULL;
|
|
|
|
}
|
|
|
|
//
|
|
// Reconstruct play list from available tracks
|
|
//
|
|
|
|
DBGPRINT(( 1, "IDB_DEFAULT: building default play list...\n"));
|
|
prev = NULL;
|
|
for( t=gAllList; t!=NULL; t=t->next ) {
|
|
|
|
t1 = (PTRACK_PLAY)LocalAlloc( LPTR, sizeof( TRACK_PLAY ) );
|
|
t1->nextplay = NULL;
|
|
t1->prevplay = prev;
|
|
t1->TocIndex = t->TocIndex;
|
|
|
|
if (gPlayList==NULL) {
|
|
|
|
gPlayList = t1;
|
|
prev = t1;
|
|
|
|
} else {
|
|
|
|
prev->nextplay = t1;
|
|
prev = t1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// Reset play list listbox
|
|
//
|
|
|
|
RecomputePlayListBox();
|
|
|
|
//
|
|
// Reset remove button if necessary
|
|
//
|
|
num = SendDlgItemMessage(hDlg,IDL_PLAY_LISTBOX,LB_GETCOUNT, 0, 0);
|
|
|
|
EnableWindow(GetDlgItem(hDlg,IDB_REMOVE), (num != 0));
|
|
EnableWindow(GetDlgItem(hDlg,IDB_CLEAR), (num != 0));
|
|
|
|
if (fRemove) {
|
|
|
|
fRemove = FALSE;
|
|
SetFocus( GetDlgItem( hTheDlg, IDB_SET ) );
|
|
|
|
}
|
|
|
|
fChanged = TRUE;
|
|
|
|
SendDlgItemMessage( hDlg,IDL_PLAY_LISTBOX,
|
|
LB_SETSEL, TRUE, 0);
|
|
|
|
|
|
DUMPPLAYLIST(( gPlayList ));
|
|
|
|
break;
|
|
|
|
}
|
|
break;
|
|
|
|
}
|
|
break;
|
|
|
|
|
|
}
|
|
break;
|
|
|
|
|
|
case WM_CLOSE:
|
|
DeleteObject( (HGDIOBJ)hbrWhite );
|
|
DeleteObject( (HGDIOBJ)hTrackIcon );
|
|
DeleteObject( (HGDIOBJ)hInsertPoint );
|
|
// DeleteObject( (HGDIOBJ)hbmEditBtns );
|
|
UnhookWindowsHookEx( MyListBoxHook );
|
|
break;
|
|
|
|
// ---------------------------------
|
|
//
|
|
// Listbox messages
|
|
//
|
|
// ---------------------------------
|
|
|
|
|
|
#define MIS (*((MEASUREITEMSTRUCT *)lParam))
|
|
case WM_MEASUREITEM:
|
|
|
|
//
|
|
// All items are the same height and width
|
|
//
|
|
|
|
MIS.itemWidth = LIST_WIDTH;
|
|
MIS.itemHeight = LIST_ITEM_H;
|
|
return( 0 );
|
|
|
|
#define DIS (*((DRAWITEMSTRUCT *)lParam))
|
|
case WM_DRAWITEM:
|
|
|
|
switch( DIS.CtlType ) {
|
|
|
|
case ODT_LISTBOX:
|
|
|
|
if ((DIS.itemAction & ODA_DRAWENTIRE) ||
|
|
(DIS.itemAction & ODA_SELECT)) {
|
|
|
|
if ((DIS.itemState & ODS_SELECTED)&&(wParam == (UINT)iCurCtl)) {
|
|
|
|
DrawListItem( DIS.hDC,
|
|
&(DIS.rcItem),
|
|
DIS.itemData,
|
|
TRUE
|
|
);
|
|
|
|
} else {
|
|
|
|
DrawListItem( DIS.hDC,
|
|
&(DIS.rcItem),
|
|
DIS.itemData,
|
|
FALSE
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
break;
|
|
|
|
}
|
|
return( TRUE );
|
|
|
|
}
|
|
|
|
return( FALSE );
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL
|
|
GetDiscInfoFromUser(
|
|
INT cdrom
|
|
)
|
|
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Launches dialog box for user to enter information
|
|
about selected disc.
|
|
|
|
Arguments:
|
|
|
|
|
|
cdrom - supplies index into gDevices array
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
TRUE if user wants to add this disc
|
|
FALSE if user pressed cancel
|
|
|
|
|
|
--*/
|
|
|
|
|
|
{
|
|
|
|
INT result, TocIndex,iOldStart,iOldEnd,iNewEnd;
|
|
PTRACK_PLAY trNew,trOld, trHold;
|
|
BOOL bNewSeek = FALSE;
|
|
|
|
if (gDevices[cdrom]->State & DATA_CD_LOADED)
|
|
return( FALSE );
|
|
|
|
if (gDevices[cdrom]->State & NO_CD)
|
|
return( FALSE );
|
|
|
|
//
|
|
// Set current disc for the dialog (dCdrom)
|
|
//
|
|
|
|
dCdrom = cdrom;
|
|
|
|
//
|
|
// Make copies of play list and track list
|
|
//
|
|
|
|
DuplicateTrackList( cdrom );
|
|
DuplicatePlayList( cdrom );
|
|
|
|
//
|
|
// put up dialog box
|
|
//
|
|
|
|
result = DialogBox( (HINSTANCE)gInstance,
|
|
(LPCTSTR)"DiscInfoDlg",
|
|
(HWND)gMainWnd,
|
|
(DLGPROC)GetDiscInfoDlgProc
|
|
);
|
|
|
|
|
|
if (result) {
|
|
|
|
//
|
|
// If 'OK' was pressed, we need to sync to the new playlist.
|
|
//
|
|
|
|
//
|
|
// Find the playing track in the OLD playlist.
|
|
//
|
|
|
|
if (CURRTRACK(cdrom) != NULL) {
|
|
|
|
iOldStart = CURRTRACK(cdrom)->TocIndex;
|
|
|
|
} else {
|
|
|
|
iOldStart = -1;
|
|
|
|
}
|
|
|
|
trOld = CURRTRACK(cdrom);
|
|
|
|
if (trOld != NULL) {
|
|
|
|
iOldEnd = trOld->TocIndex + 1;
|
|
|
|
while ((trOld->nextplay != NULL)&&(trOld->nextplay->TocIndex == iOldEnd)) {
|
|
|
|
trOld = trOld->nextplay;
|
|
iOldEnd++;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
for( trNew=gPlayList;
|
|
((trNew!=NULL) && (trNew->TocIndex != iOldStart));
|
|
trNew=trNew->nextplay
|
|
);
|
|
|
|
|
|
trHold = trNew;
|
|
|
|
//
|
|
// If the current track isn't in the new playlist, we need to
|
|
// stop playback.
|
|
//
|
|
if (trNew == NULL) {
|
|
|
|
SendMessage(ghwndStop,WM_LBUTTONDOWN,1,0);
|
|
SendMessage(ghwndStop,WM_LBUTTONUP,1,0);
|
|
|
|
//
|
|
// Wait for other threads to stop playback
|
|
//
|
|
|
|
while (!(gState & STOPPED)) {
|
|
|
|
Sleep(50);
|
|
|
|
}
|
|
|
|
|
|
if (gPlayList != NULL) {
|
|
|
|
TocIndex = gPlayList->TocIndex;
|
|
|
|
} else {
|
|
|
|
TocIndex = FIRSTTRACK(cdrom);
|
|
|
|
}
|
|
|
|
SeekToTrackAndHold(cdrom,TocIndex);
|
|
|
|
} else {
|
|
|
|
//
|
|
// The currently playing track was found in the new playlist.
|
|
// We need to see if the old contiguous end <= the new. If
|
|
// so, we don't need to anything. If not, we need to reset
|
|
// the play.
|
|
//
|
|
|
|
|
|
iNewEnd = trNew->TocIndex + 1;
|
|
|
|
while ((trNew->nextplay != NULL)&&(trNew->nextplay->TocIndex == iNewEnd)) {
|
|
|
|
trNew = trNew->nextplay;
|
|
iNewEnd++;
|
|
|
|
}
|
|
|
|
//
|
|
// New is less than the old. We need to redo the play operation.
|
|
//
|
|
if (iNewEnd < iOldEnd) {
|
|
|
|
bNewSeek = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
GrabNewTrackLists( dCdrom );
|
|
|
|
if (bNewSeek) {
|
|
|
|
SeekToCurrSecond(cdrom);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
//
|
|
// Need to free up temp nodes
|
|
//
|
|
|
|
KillTempTrackList();
|
|
KillTempPlayList();
|
|
|
|
}
|
|
|
|
return( result );
|
|
|
|
}
|
|
|
|
|
|
|