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

📄 trackwnd.c

📁 读取音乐光盘磁道为磁盘文件的DLL源码
💻 C
📖 第 1 页 / 共 3 页
字号:
  hDC = BeginPaint( hWnd, &p );

  /*
   * compute the offsets for each header section
   */
  ZeroMemory( hw, sizeof(int[5]) );
  ZeroMemory( hx, sizeof(int[5]) );
  for( i = 0; i < 4; i++ )
    {
      HD_ITEM hi;
      ZeroMemory( &hi, sizeof(hi) );
      hi.mask = HDI_WIDTH;
      SendMessage( lpe->hHeader, HDM_GETITEM, i, (LPARAM)&hi );
      hw[i] = hi.cxy;
      hx[i+1] = hx[i] + hw[i];
    }

  oldBkMode = SetBkMode( hDC, TRANSPARENT );

  for( i = 0; i < lpe->iNum; i++ )
    {
      // compute rectangle for track title
      rc.left = hx[1] + 5 - lpe->dx;
      rc.right = rc.left + hw[1] - 10;
      rc.top = 6 + (lpe->iHeaderHeight + i*(lpe->iTextHeight+4) ) - lpe->dy;
      rc.bottom = rc.top + 16;

      if ( i == lpe->iSelected )
        {
          SetBkMode( hDC, OPAQUE );
          oldBkColor = SetBkColor( hDC, RGB(20,20,140) );
          oldTextColor = SetTextColor( hDC, oldBkColor );
        }
      DrawText( hDC, lpe->tracks[i].name, lstrlen( lpe->tracks[i].name ), &rc, DT_VCENTER );
      if ( i == lpe->iSelected )
        {
          SetBkMode( hDC, TRANSPARENT );
          SetBkColor( hDC, oldBkColor );
          SetTextColor( hDC, oldTextColor );
        }

      // compute rectangle for status text
      rc.left = hx[3] + 5 - lpe->dx;
      rc.right = rc.left + hw[3] - 10;
      DrawText( hDC, lpe->tracks[i].status, lstrlen( lpe->tracks[i].status ),
                &rc, DT_VCENTER );

      rc.left = hx[2] + 5 - lpe->dx;
      rc.right = rc.left + hw[2] - 10;

      len = lpe->tracks[i].len / 75;
      wsprintf( buf, "%02d:%02d", len / 60, len % 60 );
      DrawText( hDC, buf, lstrlen( buf ), &rc, DT_VCENTER );

      // draw check box
      pts[0].x = pts[3].x = pts[4].x = ((hx[1]+1)/2 - 4) - lpe->dx;
      pts[1].x = pts[2].x = pts[0].x + 8;
      pts[0].y = pts[1].y = pts[4].y = rc.top + 5;
      pts[2].y = pts[3].y = rc.top + 13;
      hOldPen = SelectObject( hDC, lpe->hBrownPen );
      Polyline( hDC, pts, 5 );

      if ( lpe->tracks[i].bChecked )
        {
          SelectObject( hDC, lpe->hBlackPen );
          pts[0].x += 2;
          pts[0].y += 3;
          pts[1].x = pts[0].x + 2;
          pts[1].y = pts[0].y + 3;
          pts[2].x = pts[1].x + 7;
          pts[2].y = pts[1].y - 7;
          Polyline( hDC, pts, 3 );

          pts[0].x += 1;
          pts[1].x = pts[0].x + 2;
          pts[1].y = pts[0].y + 3;
          pts[2].x = pts[1].x + 7;
          pts[2].y = pts[1].y - 7;
          Polyline( hDC, pts, 3 );
        }
      SelectObject( hDC, hOldPen );
    }

  SetBkMode( hDC, oldBkMode );

  EndPaint( hWnd, &p );
}


HFONT CreateTrackWndFont( HDC hDC )
{
  LOGFONT lf;

  ZeroMemory( &lf, sizeof(lf) );
  lf.lfHeight = -MulDiv( 12, GetDeviceCaps( hDC, LOGPIXELSY), 72 );
  lf.lfCharSet = DEFAULT_CHARSET;
  lf.lfOutPrecision = OUT_TT_PRECIS;
  lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
  lf.lfQuality = DEFAULT_QUALITY;
  lf.lfPitchAndFamily = FF_MODERN | DEFAULT_PITCH;
  strcpy( lf.lfFaceName, "Courier New" );

  return CreateFontIndirect( &lf );
}


void RecalcWindow( HWND hWnd, LPTRACKWNDEXTRA lpe )
{
  RECT rc;
  SCROLLINFO si;
  int i;

  /*
   * compute the offsets for each header section, used for mouse hit testing
   * The paint code will recompute on a per paint basis
   */
  ZeroMemory( lpe->hw, sizeof(int[5]) );
  ZeroMemory( lpe->hx, sizeof(int[5]) );
  for( i = 0; i < 3; i++ )
    {
      HD_ITEM hi;
      ZeroMemory( &hi, sizeof(hi) );
      hi.mask = HDI_WIDTH;
      SendMessage( lpe->hHeader, HDM_GETITEM, i, (LPARAM)&hi );
      lpe->hw[i] = hi.cxy;
      lpe->hx[i+1] = lpe->hx[i] + lpe->hw[i];
    }

  GetClientRect( hWnd, &rc );
  lpe->vh = lpe->iNum * (lpe->iTextHeight + 4) + lpe->iHeaderHeight + 5;

  ZeroMemory( &si, sizeof(si) );
  si.cbSize = sizeof(si);
  si.fMask  = SIF_PAGE | SIF_RANGE;
  si.nMin   = 0;
  si.nMax   = lpe->vh;
  si.nPage  = rc.bottom;
  si.nPos   = lpe->dy;

#if 0
  if ( !lpe->bVScroll )
#endif
    si.fMask |= SIF_POS;

  SetScrollInfo( hWnd, SB_VERT, &si, TRUE );

  if ( lpe->bVScroll && ( lpe->vh < rc.bottom ) )
    lpe->bVScroll = FALSE;
  else if ( !lpe->bVScroll && ( lpe->vh > rc.bottom ) )
    lpe->bVScroll = TRUE;

  if ( lpe->bVScroll == FALSE )
    lpe->dy = 0;

  ZeroMemory( &si, sizeof(si) );
  si.cbSize = sizeof(si);
  si.fMask  = SIF_PAGE | SIF_RANGE;
  si.nMin   = 0;
  si.nMax   = lpe->vw;
  si.nPage  = rc.right;
  si.nPos   = lpe->dx;

  if ( !lpe->bHScroll )
    si.fMask |= SIF_POS;

  SetScrollInfo( hWnd, SB_HORZ, &si, TRUE );

  if ( lpe->bHScroll && ( lpe->vw < rc.right ) )
    lpe->bHScroll = FALSE;
  else if ( !lpe->bHScroll && ( lpe->vw > rc.right ) )
    lpe->bHScroll = TRUE;

  if ( lpe->bHScroll == FALSE )
    lpe->dx = 0;

  ComputeHeaderPos( lpe->hHeader, hWnd );
}


void DeleteTrack( HWND hWnd, int iTrack, LPTRACKWNDEXTRA lpe )
{
  int i;

  hWnd = hWnd;
  if ( iTrack == (int)ALLTRACKS )
    {
      lpe->iSelected = -1;
      lpe->iNum = 0;
      return;
    }

  if ( iTrack > lpe->iNum )
    return;

  lpe->iSelected = -1;
  for( i = iTrack; i < lpe->iNum; i++ )
    {
      lpe->tracks[i] = lpe->tracks[i+1];
    }
  lpe->iNum--;
}


void HandleHScroll( HWND hWnd, int nScrollCode, int nPos, LPTRACKWNDEXTRA lpe )
{
  hWnd = hWnd; nScrollCode = nScrollCode; nPos = nPos; lpe = lpe;
}

void HandleVScroll( HWND hWnd, int nScrollCode, int nPos, LPTRACKWNDEXTRA lpe )
{
  RECT rc;
  SCROLLINFO si;

  GetClientRect( hWnd, &rc );

  si.cbSize   = sizeof(si);
  si.fMask    = SIF_ALL;
  GetScrollInfo( hWnd, SB_VERT, &si );

  // one line of text takes up lpe->iTextHeight + 4 units
  switch( nScrollCode )
    {
    case SB_BOTTOM: break;
    case SB_ENDSCROLL: break;
    case SB_LINEDOWN:
      lpe->dy = min( lpe->dy + lpe->iTextHeight + 4, 
                     lpe->vh - (rc.bottom-1) );
      break;

    case SB_LINEUP:
      lpe->dy = max( 0, lpe->dy - (lpe->iTextHeight+4) );
      break;

    case SB_PAGEDOWN:
      lpe->dy = min( lpe->dy + rc.bottom, lpe->vh - (rc.bottom-1) );
      break;

    case SB_PAGEUP:
      lpe->dy = max( 0, lpe->dy - rc.bottom );
      break;

    case SB_THUMBPOSITION:
      lpe->dy = nPos;
      break;

    case SB_THUMBTRACK:
      lpe->dy = nPos;
      break;

    case SB_TOP: break;
      break;

    default: 
      //OutputDebugString( "Unknown scroll-bar message" );
      break;
    }
}




HWND createHeader( HWND hWnd, HINSTANCE hInst )
{
  HD_ITEM hdi;
  HWND hRet;

  hRet = CreateWindowEx( 0L, WC_HEADER, "",
                         WS_CHILD | WS_BORDER | HDS_HORZ,
                         0, 0, 0, 0,
                         hWnd, (HMENU)IDM_HEADER, hInst, NULL );
  if ( !hRet )
    return NULL;

  ComputeHeaderPos( hRet, hWnd );

  hdi.mask    = HDI_FORMAT | HDI_WIDTH;
  hdi.cxy     = 30;
  hdi.fmt     = HDF_LEFT | HDF_STRING;
  SendMessage( hRet, HDM_INSERTITEM, 9999, (LPARAM)&hdi );

  hdi.mask    = HDI_TEXT | HDI_FORMAT | HDI_WIDTH;
  hdi.pszText = "Title";
  hdi.cxy     = 200;
  hdi.cchTextMax = lstrlen( hdi.pszText );
  hdi.fmt     = HDF_LEFT | HDF_STRING;
  SendMessage( hRet, HDM_INSERTITEM, 9999, (LPARAM)&hdi );

  hdi.mask    = HDI_TEXT | HDI_FORMAT | HDI_WIDTH;
  hdi.pszText = "Time";
  hdi.cxy     = 70;
  hdi.cchTextMax = lstrlen( hdi.pszText );
  hdi.fmt     = HDF_LEFT | HDF_STRING;
  SendMessage( hRet, HDM_INSERTITEM, 9999, (LPARAM)&hdi );

  hdi.mask    = HDI_TEXT | HDI_FORMAT | HDI_WIDTH;
  hdi.pszText = "Status";
  hdi.cxy     = 200;
  hdi.cchTextMax = lstrlen( hdi.pszText );
  hdi.fmt     = HDF_LEFT | HDF_STRING;
  SendMessage( hRet, HDM_INSERTITEM, 9999, (LPARAM)&hdi );

  return hRet;
}



void ComputeHeaderPos( HWND hHdr, HWND hParent )
{
  WINDOWPOS wp;
  HD_LAYOUT hdl;
  RECT rc;

  GetClientRect( hParent, &rc );
  hdl.prc = &rc;
  hdl.pwpos = &wp;
  SendMessage( hHdr, HDM_LAYOUT, 0, (LPARAM)&hdl );
  SetWindowPos( hHdr, wp.hwndInsertAfter, wp.x, wp.y, wp.cx, wp.cy,
                wp.flags | SWP_SHOWWINDOW );
}


BOOL handleHeaderNotify( HWND hWnd, LPARAM lParam, LPTRACKWNDEXTRA lpe )
{
  HD_NOTIFY *lphd = (HD_NOTIFY *)lParam;
  LPNMHDR lpnm = (LPNMHDR)lParam;

#if 0
  if ( lpnm->code <= HDN_FIRST && lpnm->code >= HDN_LAST )
    {
      wsprintf( buf, "Header notify[%04X:%d:%d]: %s", lphd->hdr.hwndFrom, lphd->iItem,lphd->iButton,  notifyString( lphd->hdr.code ) );
    }
  else
    wsprintf( buf, "Header notify[%04X]: %s", lphd->hdr.hwndFrom,  notifyString( lphd->hdr.code ) );

  OutputDebugString( buf );
#endif

  switch( lpnm->code )
    {
    case HDN_ITEMCHANGED:
      RecalcWindow( hWnd, lpe );
      InvalidateRect( hWnd, NULL, TRUE );
      UpdateWindow( hWnd );
      break;

    case HDN_BEGINTRACK:
      SetFocus( hWnd );
      // prevent the first header from changing
      if ( lphd->iItem == 0 )
        return TRUE;
      break;
    }

  return FALSE;
}


#ifndef NM_CUSTOMDRAW
#define NM_CUSTOMDRAW     (NM_FIRST-12)
#endif

#ifndef NM_RELEASEDCAPTURE
#define NM_RELEASEDCAPTURE   (NM_FIRST-16)
#endif

char *notifyString( UINT code )
{
  static char buf[60];
  switch( code )
    {
    case NM_CUSTOMDRAW: return "NM_CUSTOMDRAW";
    case NM_CLICK: return "NM_CLICK";
    case NM_DBLCLK: return "NM_DBLCLK";
    case NM_KILLFOCUS: return "NM_KILLFOCUS";
    case NM_OUTOFMEMORY: return "NM_OUTOFMEMORY";
    case NM_RCLICK: return "NM_RCLICK";
    case NM_RDBLCLK: return "NM_RDBLCLK";
    case NM_RETURN: return "NM_RETURN";
    case NM_SETFOCUS: return "NM_SETFOCUS";
    case NM_RELEASEDCAPTURE: return "NM_RELEASEDCAPTURE";
    case HDN_BEGINTRACK: return "HDN_BEGINTRACK";
    case HDN_DIVIDERDBLCLICK: return "NM_DIVIDERDBLCLICK";
    case HDN_ENDTRACK: return "HDN_ENDTRACK";
    case HDN_ITEMCHANGED: return "HDN_ITEMCHANGED";
    case HDN_ITEMCHANGING: return "HDN_ITEMCHANGING";
    case HDN_ITEMCLICK: return "HDN_ITEMCLICK";
    case HDN_ITEMDBLCLICK: return "HDN_ITEMDBLCLICK";
    case HDN_TRACK: return "HDN_TRACK";
    default: wsprintf( buf, "unknown %04X (%d)", code, code ); return buf;
    }
}

/*
 * determines if a mouse click (in window coordinates) was on a check box.
 * If so, returns the index of the track.  If not, returns -1
 */
int CheckBoxHit( LPTRACKWNDEXTRA lpe, LPARAM lParam )
{
  int i, x, y;
  int mx, my;

  mx = (int)LOWORD(lParam) + lpe->dx;
  my = (int)HIWORD(lParam) + lpe->dy;

  for( i = 0; i < lpe->iNum; i++ )
    {
      x = (lpe->hx[1] + 1) / 2 - 4;   // left side x value
      y = 11 + lpe->iHeaderHeight + i*(lpe->iTextHeight + 4);
      if ( (mx >= x) && (mx <= (x+8)) && (my >= y) && (my <= (y+8)) )
        return i;
    }

  return -1;
}


/*
 * Determines if a mouse click was on a track name on the screen.  lParam
 * is expected to be in client coordinates, as sent with the WM_LBUTTONDOWN,
 * etc. messages.  Returns the index of the track hit, or -1 if not on a
 * track name
 */
int TrackNameHit( LPTRACKWNDEXTRA lpe, LPARAM lParam )
{
  int i, x, y;
  int mx, my;
  RECT rc;

  // if it's within the header, return -1 (no track hit)
  if ( ((int)HIWORD(lParam)) <= lpe->iHeaderHeight )
    return -1;

  mx = (int)LOWORD(lParam) + lpe->dx;
  my = (int)HIWORD(lParam) + lpe->dy;


  for( i = 0; i < lpe->iNum; i++ )

⌨️ 快捷键说明

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