⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ripseg.c

📁 读取音乐光盘磁道为磁盘文件的DLL源码
💻 C
字号:
/*
 * ripseg.c - Copyright (C) 2000 Jay A. Key
 *
 * Code to handle ripping absolute segments.
 *
 **********************************************************************
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 */

#include <windows.h>
#include <commctrl.h>
#include "trackwnd.h"
#include "resources.h"
#include "globals.h"
#include "rangeslider.h"


typedef struct {
  TOC toc;
  LPADDTRACK addTrack;
} RSDWINDOW, FAR *LPRSDWINDOW;

BOOL RipTrackSegmentDlgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );

BOOL CALLBACK RipSegmentDlgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
void InitializeSliders( HWND hWnd );
void MSB2DWORD( DWORD *d, BYTE *b );
char *scrollString( int nCode );
int InitRangeSliderClass( void );
BOOL ripsegHandleSliderNotify( HWND hWnd, LPARAM lParam );
char *ripsegGenAddressString( HWND hWnd, DWORD addr, char *buf, int len );
char *ripsegGenLenString( HWND hWnd, DWORD addr, char *buf, int len );
BOOL ripsegSaveValues( HWND hWnd );
void ripsegSetAddressText( HWND hWnd, DWORD addr, BOOL bStart );


static BOOL bInitClass = FALSE;
static int segno = 0;


BOOL RipTrackSegment( HWND hParent, HWND hTrckWnd )
{
  ADDTRACK addTrack;

  if ( !bInitClass && !InitRangeSliderClass( ) )
    return FALSE;
  bInitClass = TRUE;

  if ( DialogBoxParam( ghInstance, "RipSegmentDialog", hParent, (DLGPROC)RipSegmentDlgProc, (LPARAM)&addTrack ) )
    {
      DialogBoxParam( ghInstance, "RipTrackDialog", hParent, (DLGPROC)RipTrackSegmentDlgProc, (LPARAM)&addTrack );
    }

  return TRUE;
}


BOOL CALLBACK RipSegmentDlgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
  NMHDR *l;
  LPRSDWINDOW lpw;

  switch( uMsg )
    {
    case WM_INITDIALOG:
      lpw = (LPRSDWINDOW)GlobalAlloc( GPTR, sizeof(RSDWINDOW) );
      lpw->addTrack = (LPADDTRACK)lParam;
      SetWindowLong( hWnd, GWL_USERDATA, (LONG)lpw );
      // set values for ID_STARTSLIDER and ID_ENDSLIDER
      InitializeSliders( hWnd );
      break;

    case WM_DESTROY:
      l = (NMHDR *)GetWindowLong( hWnd, GWL_USERDATA );
      if ( l )
	GlobalFree( (HGLOBAL)l );
      break;

    case WM_COMMAND:
      switch( LOWORD(wParam) )
	{
	case IDE_START:
	  if ( HIWORD(wParam) == EN_KILLFOCUS )
	    {
	      DWORD d;
	      d = GetDlgItemInt( hWnd, IDE_START, NULL, FALSE );
	      SendDlgItemMessage( hWnd, ID_SLIDER, RSB_SETSTART, TRUE, d );
	      ripsegSetAddressText( hWnd, d, TRUE );
	    }
	  break;

	case IDE_FINISH:
	  if ( HIWORD(wParam) == EN_KILLFOCUS )
	    {
	      DWORD d;
	      d = GetDlgItemInt( hWnd, IDE_FINISH, NULL, FALSE );
	      SendDlgItemMessage( hWnd, ID_SLIDER, RSB_SETFINISH, TRUE, d );
	      ripsegSetAddressText( hWnd, d, FALSE );
	    }
	  break;

	case IDCANCEL:
	case IDBN_RIPSEGCANCEL:
	  EndDialog( hWnd, 0 );
	  break;
	case IDBN_RIPSEGOK:
	  if ( ripsegSaveValues( hWnd ) )
	    EndDialog( hWnd, 1 );
	  break;
	}
      break;

    case WM_NOTIFY:
      l = (NMHDR *)lParam;
      if ( l->idFrom == ID_SLIDER )
	return ripsegHandleSliderNotify( hWnd, lParam );

    default:
      return FALSE;
    }

  return TRUE;
}



/*
 * Sets the initial range and positions of the sliders based on the CD which
 * is in the drive
 */
void InitializeSliders( HWND hWnd )
{
  LPTOC toc;
  LPRSDWINDOW lpw;
  BOOL bMSF;
  DWORD dwAddr, dwLen;
  BYTE i;
  char buf[128];

  lpw = (LPRSDWINDOW)GetWindowLong( hWnd, GWL_USERDATA );
  toc = &lpw->toc;

  bMSF = QueryCDParms( hCD, CDP_MSF, NULL );
  ModifyCDParms( hCD, CDP_MSF, (DWORD)FALSE );

  ReadTOC( hCD, toc );
  ModifyCDParms( hCD, CDP_MSF, (DWORD)bMSF );

  if ( toc->firstTrack == toc->lastTrack )
    return;

  MSB2DWORD( &dwAddr, toc->tracks[0].addr );
  SendDlgItemMessage( hWnd, ID_SLIDER, RSB_SETMIN, 0, dwAddr );
  SendDlgItemMessage( hWnd, ID_SLIDER, RSB_SETTIC, 0, dwAddr );

  MSB2DWORD( &dwAddr, toc->tracks[toc->lastTrack - toc->firstTrack+1].addr );
  SendDlgItemMessage( hWnd, ID_SLIDER, RSB_SETMAX, 0, dwAddr );
  SendDlgItemMessage( hWnd, ID_SLIDER, RSB_SETTIC, 0, dwAddr );

  for( i = toc->firstTrack + 1; i < toc->lastTrack; i++ )
    {
      MSB2DWORD( &dwAddr, toc->tracks[i-toc->firstTrack].addr );
      SendDlgItemMessage( hWnd, ID_SLIDER, RSB_SETTIC, FALSE,
			  dwAddr );
    }

  dwLen = dwAddr = SendDlgItemMessage( hWnd, ID_SLIDER, RSB_GETMIN, 0, 0L );
  SendDlgItemMessage( hWnd, ID_SLIDER, RSB_SETSTART, 0, dwAddr );
  dwAddr = SendDlgItemMessage( hWnd, ID_SLIDER, RSB_GETMAX, 0, 0L );
  SendDlgItemMessage( hWnd, ID_SLIDER, RSB_SETFINISH, 0, dwAddr );
  dwLen = dwAddr - dwLen;

  ripsegGenLenString( hWnd, dwLen, buf, 128 );
  SetDlgItemText( hWnd, IDT_TRACKLEN, buf );

  dwAddr = SendDlgItemMessage( hWnd, ID_SLIDER, RSB_GETSTART, 0, 0L );
  ripsegSetAddressText( hWnd, dwAddr, TRUE );
  SetDlgItemInt( hWnd, IDE_START, dwAddr, FALSE );

  dwAddr = SendDlgItemMessage( hWnd, ID_SLIDER, RSB_GETFINISH, 0, 0L );
  ripsegSetAddressText( hWnd, dwAddr, FALSE );
  SetDlgItemInt( hWnd, IDE_FINISH, dwAddr, FALSE );

  wsprintf( buf, "Custom Segment %d", ++segno );
  SetDlgItemText( hWnd, IDE_SEGMENTFNAME, buf );
  SetFocus( GetDlgItem( hWnd, ID_SLIDER ) );
}


void ripsegSetAddressText( HWND hWnd, DWORD addr, BOOL bStart )
{
  char buf[128];
  DWORD dwStart, dwFinish;

  ripsegGenAddressString( hWnd, addr, buf, 128 );
  if ( bStart )
    SetDlgItemText( hWnd, IDT_STARTTEXT, buf );
  else
    SetDlgItemText( hWnd, IDT_FINISHTEXT, buf );

  dwStart = GetDlgItemInt( hWnd, IDE_START, NULL, FALSE );
  dwFinish = GetDlgItemInt( hWnd, IDE_FINISH, NULL, FALSE );

  ripsegGenLenString( hWnd, dwFinish - dwStart, buf, 128 );
  SetDlgItemText( hWnd, IDT_TRACKLEN, buf );
}



BOOL ripsegHandleSliderNotify( HWND hWnd, LPARAM lParam )
{
  LPRSBNOTIFY l = (LPRSBNOTIFY)lParam;
  char buf[128];

  switch( l->hdr.code )
    {
    case RSBN_STARTCHANGING:
      // sent whenever the top slider is moving, but before updated
      if ( l->newStart < l->finish )
	{
	  ripsegGenAddressString( hWnd, l->newStart, buf, 128 );
	  SetDlgItemText( hWnd, IDT_STARTTEXT, buf );
	  ripsegGenLenString( hWnd, l->finish - l->newStart, buf, 128 );
	  SetDlgItemText( hWnd, IDT_TRACKLEN, buf );
	  SetWindowLong( hWnd, DWL_MSGRESULT, TRUE ); // allow the change
	}
      else
	{
	  ripsegGenAddressString( hWnd, l->start, buf, 128 );
	  SetDlgItemText( hWnd, IDT_STARTTEXT, buf );
	  ripsegGenLenString( hWnd, l->finish - l->start, buf, 128 );
	  SetDlgItemText( hWnd, IDT_TRACKLEN, buf );
	  SetWindowLong( hWnd, DWL_MSGRESULT, FALSE ); // disallow the change
	}
      break;

    case RSBN_STARTCHANGED:
      // sent after the top slider has moved and been updated
      ripsegGenAddressString( hWnd, l->start, buf, 128 );
      SetDlgItemText( hWnd, IDT_STARTTEXT, buf );
      SetDlgItemInt( hWnd, IDE_START, l->start, FALSE );
      ripsegGenLenString( hWnd, l->finish - l->start, buf, 128 );
      SetDlgItemText( hWnd, IDT_TRACKLEN, buf );
      break;

    case RSBN_FINISHCHANGING:
      // sent whenever the bottom slider is moving, but before updated
      if ( l->newFinish > l->start )
	{
	  ripsegGenAddressString( hWnd, l->newFinish, buf, 128 );
	  SetDlgItemText( hWnd, IDT_FINISHTEXT, buf );
	  ripsegGenLenString( hWnd, l->newFinish - l->start, buf, 128 );
	  SetDlgItemText( hWnd, IDT_TRACKLEN, buf );
	  SetWindowLong( hWnd, DWL_MSGRESULT, TRUE ); // allow the change
	}
      else
	{
	  ripsegGenAddressString( hWnd, l->finish, buf, 128 );
	  SetDlgItemText( hWnd, IDT_FINISHTEXT, buf );
	  ripsegGenLenString( hWnd, l->finish - l->start, buf, 128 );
	  SetDlgItemText( hWnd, IDT_TRACKLEN, buf );
	  SetWindowLong( hWnd, DWL_MSGRESULT, FALSE ); // disallow the change
	}
      break;

    case RSBN_FINISHCHANGED:
      // sent after the bottom slider has moved and been updated
      ripsegGenAddressString( hWnd, l->finish, buf, 128 );
      SetDlgItemText( hWnd, IDT_FINISHTEXT, buf );
      SetDlgItemInt( hWnd, IDE_FINISH, l->finish, FALSE );
      ripsegGenLenString( hWnd, l->finish - l->start, buf, 128 );
      SetDlgItemText( hWnd, IDT_TRACKLEN, buf );
      break;

    default:
      return FALSE;
    }

  return TRUE;
}


char *ripsegGenAddressString( HWND hWnd, DWORD addr, char *buf, int len )
{
  BYTE i, num;
  LPTOC t;
  LPRSDWINDOW lpw;
  DWORD ofs, addr1, addr2;
  DWORD m, s, f;
  char tmp[128];

  if ( !buf )
    return NULL;

  ZeroMemory( buf, len );

  lpw = (LPRSDWINDOW)GetWindowLong( hWnd, GWL_USERDATA );

  t = &lpw->toc;
  num = t->lastTrack - t->firstTrack + 1;
  for( i = 0; i < num; i++ )
    {
      MSB2DWORD( &addr1, t->tracks[i].addr );;
      MSB2DWORD( &addr2, t->tracks[i+1].addr );;
      if ( (addr >= addr1) && (addr < addr2) )
	{
	  ofs = addr - addr1;
	  f = ofs % 75;
	  ofs /= 75;
	  s = ofs % 60;
	  m = ofs / 60;
	  wsprintf( tmp, "Track %d: %02d:%02d:%02d (%d)",
		    i+1, m, s, f, addr );
	  lstrcpyn( buf, tmp, len-1 );
	  return buf;
	}
    }

  return buf;
}


char *ripsegGenLenString( HWND hWnd, DWORD addr, char *buf, int len )
{
  DWORD m, s, f, dwLen;
  char tmp[128];

  if ( !buf )
    return NULL;

  ZeroMemory( buf, len );

  dwLen = addr;

  if ( (int)addr < 0 )
    addr = 0;

  f = addr % 75;
  addr /= 75;
  s = addr % 60;
  m = addr / 60;
  wsprintf( tmp, "%d frames (%02d:%02d:%02d)", dwLen, m, s, f );
  lstrcpyn( buf, tmp, len-1 );

  return buf;
}



BOOL ripsegSaveValues( HWND hWnd )
{
  DWORD dwStart, dwEnd;
  char buf[MAX_PATH+1];
  LPRSDWINDOW lpw;
  BOOL bOK;

  lpw = (LPRSDWINDOW)GetWindowLong( hWnd, GWL_USERDATA );

  dwStart = GetDlgItemInt( hWnd, IDE_START, &bOK, FALSE );
  dwEnd = GetDlgItemInt( hWnd, IDE_FINISH, &bOK, FALSE );
  GetDlgItemText( hWnd, IDE_SEGMENTFNAME, buf, MAX_PATH );

  if ( dwStart >= dwEnd )
    {
      MessageBox( hWnd, "The start frame must be less than the end frame.  Please correct and try again.", "Huh?!?", MB_APPLMODAL | MB_ICONERROR | MB_OK );      return FALSE;
    }

  if ( buf[0] == '\0' )
    {
      MessageBox( hWnd, "Please enter the output filename for the segment to be ripped.", "Huh?!?", MB_APPLMODAL | MB_ICONERROR | MB_OK );      return FALSE;
      return FALSE;
    }

  lpw->addTrack->start = dwStart;
  lpw->addTrack->len = dwEnd - dwStart;
  lpw->addTrack->bComplete = FALSE;
  if ( !lstrlen( buf ) )
    wsprintf( buf, "Custom Segment %d", ++segno );
  lstrcpy( lpw->addTrack->name, buf );

  return TRUE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -