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

📄 trackwnd.c

📁 读取音乐光盘磁道为磁盘文件的DLL源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * trackwnd.c - Copyright (C) 1999,2000 Jay A. Key
 *
 * Implementation of the TrackWnd window class.  TrackWnd is intended to
 * be a child window of the main application window, and supports the 
 * displaying, editing and selectind of CD audio tracks.  Includes a header
 * control for changing the width of the items displayed on screen.
 *
 **********************************************************************
 *
 * 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 <string.h>

#include "resources.h"
#include "trackwnd.h"
#include "globals.h"
#include "statusbar.h"

typedef struct
{
  int iNum;
  int iMax;
  int iTextHeight;
  int vw, vh;
  int dx, dy;              // scroll bar offsets into virtual window
  int iHeaderHeight;
  int hx[5];               // header x offsets
  int hw[5];               // header widths
  int iFound;
  HWND hHeader;
  BOOL bVScroll, bHScroll;
  HPEN hBrownPen, hBlackPen;
  int iSelected;
  ADDTRACK *tracks;
} TRACKWNDEXTRA, *LPTRACKWNDEXTRA;


LRESULT CALLBACK TrackWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
void doTrackWndPaint( HWND hWnd, LPTRACKWNDEXTRA lpe );
void RecalcWindow( HWND hWnd, LPTRACKWNDEXTRA lpe );
void DeleteTrack( HWND hWnd, int iTrack, LPTRACKWNDEXTRA lpe );
void HandleVScroll( HWND, int, int, LPTRACKWNDEXTRA );
void HandleHScroll( HWND, int, int, LPTRACKWNDEXTRA );
void ComputeHeaderPos( HWND hHdr, HWND hParent );
HWND createHeader( HWND hWnd, HINSTANCE hInst );
char *notifyString( UINT code );
BOOL handleHeaderNotify( HWND hWnd, LPARAM lParam, LPTRACKWNDEXTRA lpe );
BOOL HandleLMouseDown( HWND hWnd, LPTRACKWNDEXTRA lpe, LPARAM lParam );
BOOL HandleRMouseDown( HWND hWnd, LPTRACKWNDEXTRA lpe, LPARAM lParam );
int CheckBoxHit( LPTRACKWNDEXTRA lpe, LPARAM lParam );
BOOL HandleCheckTrack( HWND hWnd, LPTRACKWNDEXTRA lpe, int trackNo, BOOL bChecked );
BOOL HandleInvertCheck( HWND hWnd, LPTRACKWNDEXTRA lpe, int trackNo );
int doContextMenu( HWND hWnd, LPARAM lParam );
BOOL RenameSelectedTrack( HWND hWnd, LPTRACKWNDEXTRA lpe );
LRESULT processFindFirst( LPTRACKWNDEXTRA lpe, LPADDTRACK lpAddTrack );
LRESULT processFindNext( LPTRACKWNDEXTRA lpe, LPADDTRACK lpAddTrack );
void convertuMsg( UINT uMsg, char * s );
void logWindowsProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
LRESULT CALLBACK EditSubclassWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
LRESULT CALLBACK FooWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
void SetTrackWndText( HWND hWnd );
LRESULT numChecked( LPTRACKWNDEXTRA lpe );
int doTrackContextMenu( HWND hParent, HWND hChild, LPARAM lParam );
BOOL setTrackStatus( LPTRACKWNDEXTRA lpe, int idx, LPCSTR s );


static char szTrackWndClass[] = "akripTrackWnd";
//static char szFooClass[] = "fooclass";
//static ADDTRACK tmpAddTrack;
HWND hHeader;
static int iCtlId = 10000;
static BOOL bInEditTrack = FALSE;
static HWND hEdit = NULL;

int InitTrackWnd( HINSTANCE hInst )
{
  WNDCLASSEX wc;
  LOGBRUSH lb;
  HBRUSH hBrush;

  ZeroMemory( &lb, sizeof(lb) );
  lb.lbStyle = BS_SOLID;
  lb.lbColor = RGB( 240, 255, 220 );
  lb.lbHatch = 0;
  hBrush = CreateBrushIndirect( &lb );

  ZeroMemory( &wc, sizeof(wc) );
  wc.cbSize          = sizeof(wc);
  wc.style           = CS_HREDRAW | CS_VREDRAW;
  wc.lpfnWndProc     = (WNDPROC)TrackWndProc;
  wc.hInstance       = hInst;
  wc.hCursor         = LoadCursor( NULL, IDC_ARROW );
  wc.hbrBackground   = hBrush;
  wc.lpszClassName   = szTrackWndClass;

  if ( !RegisterClassEx( &wc ) )
    return 0;

#if 0
  ZeroMemory( &wc, sizeof(wc) );
  wc.cbSize          = sizeof(wc);
  wc.style           = CS_HREDRAW | CS_VREDRAW;
  wc.lpfnWndProc     = (WNDPROC)FooWndProc;
  wc.hInstance       = hInst;
  wc.hCursor         = LoadCursor( NULL, IDC_ARROW );
  wc.hbrBackground   = hBrush;
  wc.lpszClassName   = szFooClass;

  if ( !RegisterClassEx( &wc ) )
    return 0;
#endif

  return -1;
}


LRESULT CALLBACK TrackWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
  LPTRACKWNDEXTRA lpe;
  RECT rc;

  logWindowsProc( hWnd, uMsg, wParam, lParam );

  lpe = (LPTRACKWNDEXTRA)GetWindowLong( hWnd, GWL_USERDATA);
  if ( !lpe && ( uMsg != WM_CREATE ) )
    return DefWindowProc( hWnd, uMsg, wParam, lParam );

  switch( uMsg )
    {
    case WM_COMMAND:
      switch( HIWORD(wParam) )
        {
        case EN_SETFOCUS: break;
        case EN_KILLFOCUS: break;
        }
      break;

    case WM_CONTEXTMENU:
      doTrackContextMenu( GetParent(hWnd), hWnd, lParam );
      break;

    case WM_SETFOCUS:
      //OutputDebugString( "TrackWnd gaining focus" );
      break;

    case WM_KILLFOCUS:
      //OutputDebugString( "TrackWnd losing focus" );
      break;

    case WM_NOTIFY:
      if ( wParam == IDM_HEADER )
        return handleHeaderNotify( hWnd, lParam, lpe );
      break;

    case WM_DESTROY:
      lpe = (LPTRACKWNDEXTRA)GetWindowLong( hWnd, GWL_USERDATA );
      if ( lpe )
        {
          if ( lpe->tracks )
            GlobalFree( (HGLOBAL)lpe->tracks );
          if ( lpe->hBrownPen )
            DeleteObject( lpe->hBrownPen );
          if ( lpe->hBlackPen )
            DeleteObject( lpe->hBlackPen );
          GlobalFree( lpe );
        }
      return DefWindowProc( hWnd, uMsg, wParam, lParam );

    case WM_CREATE:
      lpe = (LPTRACKWNDEXTRA)GlobalAlloc( GPTR, sizeof(TRACKWNDEXTRA) );
      lpe->tracks = (LPADDTRACK)GlobalAlloc( GPTR, sizeof(ADDTRACK)*100 );
      lpe->iNum = 0;
      lpe->iMax = 100;
      lpe->hBrownPen = CreatePen( PS_SOLID, 1, 0x00003384 );
      lpe->hBlackPen = CreatePen( PS_SOLID, 1, 0x00000000 );
      lpe->iSelected = -1;
      lpe->iFound = -1;
      SetWindowLong( hWnd, GWL_USERDATA, (LONG)lpe );
      UpdateStatusBar();
      break;

    case WM_PAINT:
      doTrackWndPaint( hWnd, lpe );
      break;

    case WM_VSCROLL:
      HandleVScroll( hWnd, (int)LOWORD(wParam), (int)HIWORD(wParam), lpe );
      RecalcWindow( hWnd, lpe );
      GetClientRect( hWnd, &rc );
      rc.top += (lpe->iHeaderHeight+1);
      InvalidateRect( hWnd, &rc, TRUE );
      UpdateWindow( hWnd );
      break;

    case WM_HSCROLL:
      HandleHScroll( hWnd, (int)LOWORD(wParam), (int)HIWORD(wParam), lpe );
      RecalcWindow( hWnd, lpe );
      GetClientRect( hWnd, &rc );
      rc.top += (lpe->iHeaderHeight+1);
      InvalidateRect( hWnd, &rc, TRUE );
      UpdateWindow( hWnd );
      break;

    case WM_SIZE:
      RecalcWindow( hWnd, lpe );
      break;

    case WM_ADDTRACK:
      if ( lpe->iNum >= lpe->iMax )
        break;
      memcpy( &(lpe->tracks[lpe->iNum]), (void *)lParam, sizeof(ADDTRACK) );
      lpe->iNum++;
      RecalcWindow( hWnd, lpe );
      GetClientRect( hWnd, &rc );
      rc.top += (lpe->iHeaderHeight+1);
      InvalidateRect( hWnd, &rc, TRUE );
      UpdateWindow( hWnd );
      UpdateStatusBar();
      break;

    case WM_CHECKTRACK:
      if ( HandleCheckTrack( hWnd, lpe, (int)wParam, (BOOL)lParam ) )
        {
          GetClientRect( hWnd, &rc );
          rc.top += (lpe->iHeaderHeight+1);
          InvalidateRect( hWnd, &rc, TRUE );
          UpdateWindow( hWnd );
        }
      UpdateStatusBar();
      break;

    case WM_INVERTCHECK:
      if ( HandleInvertCheck( hWnd, lpe, (int)wParam ) )
        {
          GetClientRect( hWnd, &rc );
          rc.top += (lpe->iHeaderHeight+1);
          InvalidateRect( hWnd, &rc, TRUE );
          UpdateWindow( hWnd );
        }
      UpdateStatusBar();
      break;

    case WM_DELTRACK:
      DeleteTrack( hWnd, (int)wParam, lpe );
      RecalcWindow( hWnd, lpe );
      GetClientRect( hWnd, &rc );
      rc.top += (lpe->iHeaderHeight+1);
      InvalidateRect( hWnd, &rc, TRUE );
      UpdateWindow( hWnd );
      UpdateStatusBar();
      break;

    case WM_SELTRACK:
      if ( lpe->iSelected != (int)wParam )
        {
          lpe->iSelected = (int)wParam;
          GetClientRect( hWnd, &rc );
          rc.top += (lpe->iHeaderHeight+1);
          InvalidateRect( hWnd, &rc, TRUE );
          UpdateWindow( hWnd );
        }
      break;

    case WM_MOUSEMOVE:
      // grrr... it's an evil hack, but I need for the MouseCapture to 
      // remain with the edit control.  When the user selects text with the
      // mouse, the edit control automatically captures the mouse (even if
      // it already has the mouse captured.  Then it releases it, but not
      // until after the WM_*BUTTONUP message.  Until I write a custom
      // edit control, I'll have to use this workaround.
      if ( bInEditTrack && hEdit )
        SetCapture( hEdit );
      break;

    case WM_LBUTTONDOWN:
      if ( HandleLMouseDown( hWnd, lpe, lParam ) )
        {
          GetClientRect( hWnd, &rc );
          rc.top += (lpe->iHeaderHeight+1);
          InvalidateRect( hWnd, &rc, TRUE );
          UpdateWindow( hWnd );
        }
      break;

    case WM_RBUTTONDOWN:
      if ( HandleRMouseDown( hWnd, lpe, lParam ) )
        {
          GetClientRect( hWnd, &rc );
          rc.top += (lpe->iHeaderHeight+1);
          InvalidateRect( hWnd, &rc, TRUE );
          UpdateWindow( hWnd );
        }
      break;

    case WM_RENSELTRACK:
      if ( RenameSelectedTrack( hWnd, lpe ) )
        {
          GetClientRect( hWnd, &rc );
          rc.top += (lpe->iHeaderHeight+1);
          InvalidateRect( hWnd, &rc, TRUE );
          UpdateWindow( hWnd );
        }
      break;

    // copies the first checked track found into (LPADDTRACK)lParam .
    // Returns index of the track, or -1 if no track found
    case WM_FINDFIRSTTRACK:
      return processFindFirst( lpe, (LPADDTRACK)lParam );
      break;

    // returns NULL if no more tracks are selected, otherwise LPADDTRACK
    case WM_FINDNEXTTRACK:
      return processFindNext( lpe, (LPADDTRACK)lParam );
      break;

    case WM_SETSELTEXT:
      lstrcpy( lpe->tracks[lpe->iSelected].name, (char *)lParam );
      GetClientRect( hWnd, &rc );
      rc.top += (lpe->iHeaderHeight+1);
      InvalidateRect( hWnd, &rc, TRUE );
      UpdateWindow( hWnd );
      break;

    case WM_SETTRACKTEXT:
      if ( (int)wParam < lpe->iNum )
        {
          lstrcpyn( lpe->tracks[wParam].name, (char *)lParam, MAX_PATH );
          lpe->tracks[wParam].name[MAX_PATH] = '\0';
          GetClientRect( hWnd, &rc );
          rc.top += (lpe->iHeaderHeight+1);
          InvalidateRect( hWnd, &rc, TRUE );
          UpdateWindow( hWnd );
        }
      break;

    case WM_SETTRACKSTATUS:
      if ( setTrackStatus( lpe, (int)wParam, (LPCSTR)lParam ) )
        {
          GetClientRect( hWnd, &rc );
          rc.top += (lpe->iHeaderHeight+1);
          InvalidateRect( hWnd, &rc, TRUE );
          UpdateWindow( hWnd );
        }
      break;

    case WM_NUMCHECKED:
      return numChecked( lpe );

    case WM_NUMTRACKS:
      return (LRESULT)lpe->iNum;

    case WM_GETTRACK:
      if ( lParam )
        {
          memcpy( (BYTE *)lParam, (BYTE *)&lpe->tracks[wParam], sizeof(ADDTRACK) );
          return (LRESULT)lParam;
        }
      break;

    case WM_CAPTURECHANGED:
      //OutputDebugString( "TrackWndProc: WM_CAPTURECHANGED" );
      break;

    default:
      return DefWindowProc( hWnd, uMsg, wParam, lParam );
    }

  return 0L;
}


HWND createTrackWnd( HWND hParent, HINSTANCE hInst, int idCtrl, LPRECT lprc )
{
  LPTRACKWNDEXTRA lpe;
  HWND hRet;
  HDC hDC;
  SIZE s;
  RECT rc;

  hRet = CreateWindowEx( 0, szTrackWndClass, "A Bogus Name",
                         WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL,
                         lprc->left, lprc->top,
                         lprc->right - lprc->left, lprc->bottom - lprc->top,
                         hParent, (HMENU)idCtrl, hInst, NULL );


  /*
   * compute text height
   */
  lpe = (LPTRACKWNDEXTRA)GetWindowLong( hRet, GWL_USERDATA );
  hDC = GetWindowDC( hRet );
  GetTextExtentPoint32( hDC, "ABCDEFGHIJKLMNOPQRSTUVWYXZabcdefghijklmnopqrstuvwxyz", 52, &s );
  lpe->iTextHeight = s.cy;
  ReleaseDC( hRet, hDC );

  lpe->hHeader = createHeader( hRet, hInst );
  GetClientRect( lpe->hHeader, &rc );
  lpe->iHeaderHeight = rc.bottom - rc.top + 1;

  return hRet;
}



void doTrackWndPaint( HWND hWnd, LPTRACKWNDEXTRA lpe )
{
  PAINTSTRUCT p;
  HDC hDC;
  RECT rc;
  int i;
  int oldBkMode;
  int hw[5];            // width of header items
  int hx[5];            // x offset of header items
  DWORD len;
  //char buf[32];
  POINT pts[5];
  HPEN hOldPen;
  COLORREF oldBkColor, oldTextColor;
  char buf[81];

  GetClientRect( hWnd, &rc );

⌨️ 快捷键说明

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