/***********************************************************************/ /* Simple CD Player --- 24 October 1992 */ /* */ /* Written by John A. Junod using code ideas presented in the SDK */ /* documentation and uses the basic code form from Quick Case. */ /* */ /* This program opens "CDAUDIO" when the program starts, keeps it open */ /* while the program is running and closes it on exit. This does make */ /* some actions take less time. Error recovery is basically non- */ /* existant beyond giving the user a basically useless error message. */ /* */ /* Modify this as much as you wish and redistribute however you wish, */ /* but I do ask that you give me some of the credit and that you let */ /* other people use the final product for FREE and don't charge some */ /* silly shareware fee of $25. */ /***********************************************************************/ #include "CD.h" HWND hInst; HWND hMainWnd; char szAppName[80]; char szBuffer[4096]; /* general purpose large buffer */ char szBuf[256]; /* general purpose small buffer */ char szTitle[100]; /* window title */ UINT wDeviceID; /* open cd device id */ int iCDstatus; /* cd status */ #define CD_STOPPED 0 #define CD_PLAYING 1 #define CD_PAUSED 2 #define CD_NOTRDY 3 #define CD_OPEN 4 char *szStatus[5]={"stopped","playing","paused","notready","open"}; HBITMAP bm_maincabinet; HBITMAP bm_status[5]; HCURSOR hHourGlass; HCURSOR hSaveCursor; HICON hIcon; BOOL bCanEject; BOOL bPauseFlag=FALSE; int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) { /***********************************************************************/ /* HANDLE hInstance; handle for this instance */ /* HANDLE hPrevInstance; handle for possible previous instances */ /* LPSTR lpszCmdLine; long pointer to exec command line */ /* int nCmdShow; Show code for main window display */ /***********************************************************************/ MSG msg; /* MSG structure to store your messages */ int nRc; /* return value from Register Classes */ MCI_OPEN_PARMS mciOpenParms; FARPROC lpMainDlg; DWORD dwMCIerr; hInst = hInstance; strcpy(szAppName, "CD"); if(hPrevInstance) return(0); else { /* register window classes if first instance of application */ if ((nRc = nCwRegisterClasses()) == -1) { /* registering one of the windows failed */ MessageBox(NULL, "Failed to register window", NULL, MB_ICONEXCLAMATION); return nRc; } } /* create application's Main window */ hMainWnd = CreateWindow( szAppName, /* Window class name */ "CD Player", /* Window's title */ WS_POPUP, CW_USEDEFAULT, 0, /* Use default X, Y */ 263,90, /* Use default X, Y */ NULL, /* Parent window's handle */ NULL, /* Default to Class Menu */ hInst, /* Instance of window */ NULL); /* Create struct for WM_CREATE */ if(hMainWnd == NULL) { MessageBox(NULL,"Failed to create window.", NULL, MB_ICONEXCLAMATION); return 1; } hHourGlass=LoadCursor(NULL,IDC_WAIT); hIcon=LoadIcon(hInst,"CDICON"); bm_maincabinet=LoadBitmap(hInst,"CDCAB"); bm_status[CD_STOPPED]=LoadBitmap(hInst,"CDSTOP"); bm_status[CD_PLAYING]=LoadBitmap(hInst,"CDPLAY"); bm_status[CD_PAUSED]=LoadBitmap(hInst,"CDPAUSE"); bm_status[CD_NOTRDY]=LoadBitmap(hInst,"CDNOTRDY"); bm_status[CD_OPEN]=LoadBitmap(hInst,"CDOPEN"); // open the compact disc device mciOpenParms.lpstrDeviceType="cdaudio"; if(dwMCIerr=mciSendCommand(NULL,MCI_OPEN,MCI_OPEN_TYPE, (DWORD)(LPVOID)&mciOpenParms)) { // failed to open, show the error and end this program. showMCIError(dwMCIerr); return(FALSE); } // opened successfully wDeviceID=mciOpenParms.wDeviceID; if(dwMCIerr=CD_GetDeviceInfo(wDeviceID)) showMCIError(dwMCIerr); iCDstatus=CD_GetCurrentStatus(wDeviceID); ShowWindow(hMainWnd, nCmdShow); while(GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } // close the CD device and exit program if(dwMCIerr=mciSendCommand(wDeviceID,MCI_CLOSE,0,NULL)) showMCIError(dwMCIerr); CwUnRegisterClasses(); return msg.wParam; } /* End of WinMain */ LONG FAR PASCAL WndProc(HWND hWnd, WORD Message, WORD wParam, LONG lParam) { MCI_OPEN_PARMS mciOpenParms; FARPROC lpMainDlg; HMENU hMenu=0; /* handle for the menu */ HBITMAP hBitmap=0; /* handle for bitmaps */ HDC hDC,hBM; /* handle for the display device */ PAINTSTRUCT ps; /* holds PAINT information */ int nRc=0; /* return code */ DWORD dwMCIerr; LPSTR *s,*d; int x,y,rx; UINT uAUXerr; DWORD volume; RECT rect; switch (Message) { case WM_COMMAND: switch (wParam) { // start play at track 1 case IDM_PLAY: if(iCDstatus==CD_PAUSED) SendMessage(hWnd,WM_COMMAND,IDM_RESUME,0L); else { if((dwMCIerr=CD_PlayTrack(wDeviceID,1,0))!=0L) showMCIError(dwMCIerr); else { iCDstatus=CD_PLAYING; } bPauseFlag=FALSE; } break; // if the CD is paused, resume play (play at current location) case IDM_RESUME: if(iCDstatus==CD_PAUSED || iCDstatus==CD_STOPPED) { if((dwMCIerr=CD_ResumePlay(wDeviceID))!=0L) showMCIError(dwMCIerr); else { iCDstatus=CD_PLAYING; bPauseFlag=FALSE; } } break; // if the CD is playing, pause it, else resume play case IDM_PAUSE: if(iCDstatus==CD_PLAYING) { if((dwMCIerr=CD_Pause(wDeviceID))!=0L) showMCIError(dwMCIerr); else { iCDstatus=CD_PAUSED; bPauseFlag=TRUE; } } else if(bPauseFlag) SendMessage(hWnd,WM_COMMAND,IDM_RESUME,0L); break; // if the CD is playing, backup one track, else play case IDM_BACK: if(iCDstatus==CD_PLAYING) { if((dwMCIerr=CD_ChangeTrack(wDeviceID,-1))!=0L) showMCIError(dwMCIerr); } else SendMessage(hWnd,WM_COMMAND,IDM_PLAY,0L); bPauseFlag=FALSE; break; // if the CD is playing, forward one track, else play case IDM_FORWARD: if(iCDstatus==CD_PLAYING) { if((dwMCIerr=CD_ChangeTrack(wDeviceID,1))!=0L) showMCIError(dwMCIerr); } else SendMessage(hWnd,WM_COMMAND,IDM_PLAY,0L); bPauseFlag=FALSE; break; // if the CD is playing or pause, stop it case IDM_STOP: if(iCDstatus==CD_PLAYING || iCDstatus==CD_PAUSED) { if((dwMCIerr=CD_Stop(wDeviceID))!=0L) showMCIError(dwMCIerr); else iCDstatus=CD_STOPPED; } bPauseFlag=FALSE; break; // untested (mine doesn't support) toggle door open/closed case IDM_EJECT: if(iCDstatus!=CD_OPEN) { if((dwMCIerr=CD_Open(wDeviceID))!=0L) showMCIError(dwMCIerr); else iCDstatus=CD_OPEN; } else if((dwMCIerr=CD_Close(wDeviceID))!=0L) showMCIError(dwMCIerr); else iCDstatus=CD_STOPPED; bPauseFlag=FALSE; break; // this is a test routine (activated by non-visible button) case IDM_SHVOL: uAUXerr=auxGetVolume(wDeviceID,(LPDWORD)&volume); wsprintf(szBuf,"E:%u VL:%d VH:%d",uAUXerr, LOWORD(volume),HIWORD(volume)); MessageBox(hWnd,szBuf,"CD Volume",MB_OK); break; case IDM_STATUS: case IDM_SHAUTH: MessageBox(hWnd, "(C) 1994 John A. Junod\n\ 267 Hillwood Street\n\ Martinez GA, 30907\n\ internet: junodj@gordon-css583.army.mil\n\ compuserve: 72321,366\n\ \n\ version 94.01.02\n\ Released for FREE use.", "CD Player Author",MB_OK); break; case IDM_EXIT: GetWindowRect(hWnd,&rect); sprintf(szBuf,"%u",rect.left); WriteProfileString("CD_AUDIO","X_COORD",szBuf); sprintf(szBuf,"%u",rect.top); WriteProfileString("CD_AUDIO","Y_COORD",szBuf); SendMessage(hWnd,WM_CLOSE,0,0L); break; default: return DefWindowProc(hWnd, Message, wParam, lParam); } break; /* End of WM_COMMAND */ case WM_LBUTTONUP: rx=LOWORD(lParam); y=HIWORD(lParam); if(rx>11 && rx<253 && y>50 && y<80) { x=(rx-11)/30; switch(x) { case 0: SendMessage(hWnd,WM_COMMAND,IDM_EXIT,0L); break; case 1: SendMessage(hWnd,WM_COMMAND,IDM_EJECT,0L); break; case 2: SendMessage(hWnd,WM_COMMAND,IDM_STOP,0L); break; case 3: SendMessage(hWnd,WM_COMMAND,IDM_PAUSE,0L); break; case 4: SendMessage(hWnd,WM_COMMAND,IDM_PLAY,0L); break; case 5: SendMessage(hWnd,WM_COMMAND,IDM_BACK,0L); break; case 6: SendMessage(hWnd,WM_COMMAND,IDM_FORWARD,0L); break; case 7: SendMessage(hWnd,WM_COMMAND,IDM_STATUS,0L); break; } } else if(rx<11 || rx>252 || y<11 || y>80) { GetWindowRect(GetDesktopWindow(),&rect); if(y<21) y=10; else if(y>68) y=rect.bottom-100; else y=(rect.bottom-100)/2; if(rx<21) x=11; else if(rx>242) x=rect.right-273; else x=(rect.right-263)/2; MoveWindow(hWnd,x,y,263,90,TRUE); } break; case WM_TIMER: case MM_MCINOTIFY: iCDstatus=CD_GetCurrentStatus(wDeviceID); // format the window title line wsprintf(szBuffer,"CD (%s) %d", (LPSTR)szStatus[iCDstatus], CD_GetCurrentTrack(wDeviceID)); // only update it if it changes as we don't like flashing if(lstrcmp(szBuffer,szTitle)!=0) { lstrcpy(szTitle,szBuffer); SetWindowText(hWnd,szTitle); rect.left=11; rect.top=11; rect.right=126+11+30; rect.bottom=30+11; InvalidateRect(hWnd,&rect,FALSE); } break; case WM_CREATE: x=GetProfileInt("CD_AUDIO","X_COORD",10); y=GetProfileInt("CD_AUDIO","Y_COORD",10); GetWindowRect(GetDesktopWindow(),&rect); if(x>(rect.right-263)) x=rect.right-273; else if(x<10) x=10; if(y>(rect.bottom-100)) y=rect.bottom-100; else if(y<10) y=10; MoveWindow(hWnd,x,y,263,90,TRUE); // format the window title line wsprintf(szTitle,"CD (%s) %d", (LPSTR)szStatus[CD_GetCurrentStatus(wDeviceID)], CD_GetCurrentTrack(wDeviceID)); // display new title SetWindowText(hWnd,szTitle); // set a timer ~2 seconds to update title SetTimer(hWnd,1,2000,NULL); break; /* End of WM_CREATE */ case WM_MOVE: /* code for moving the window */ break; case WM_SIZE: /* code for sizing client area */ break; /* End of WM_SIZE */ case WM_PAINT: /* code for the window's client area */ /* Obtain a handle to the device context */ /* BeginPaint will sends WM_ERASEBKGND if appropriate */ memset(&ps, 0x00, sizeof(PAINTSTRUCT)); hDC = BeginPaint(hWnd, &ps); /* Included in case the background is not a pure color */ SetBkMode(hDC, TRANSPARENT); hBM=CreateCompatibleDC(hDC); SelectObject(hBM,bm_maincabinet); BitBlt(hDC,0,0,263,90,hBM,0,0,SRCCOPY); SelectObject(hBM,bm_status[iCDstatus]); BitBlt(hDC,11,11,126,30,hBM,0,0,SRCCOPY); wsprintf(szBuf,"%2d",CD_GetCurrentTrack(wDeviceID)); TextOut(hDC,140,17,szBuf,lstrlen(szBuf)); DeleteDC(hBM); /* Inform Windows painting is complete */ EndPaint(hWnd, &ps); break; /* End of WM_PAINT */ case WM_CLOSE: /* close the window */ KillTimer(hWnd,1); DestroyWindow(hWnd); if (hWnd == hMainWnd) PostQuitMessage(0); /* Quit the application */ break; default: /* For any message for which you don't specifically provide a */ /* service routine, you should return the message to Windows */ /* for default message processing. */ return DefWindowProc(hWnd, Message, wParam, lParam); } return 0L; } /* End of WndProc */ /************************************************************************/ /* */ /* nCwRegisterClasses Function */ /* */ /* The following function registers all the classes of all the windows */ /* associated with this application. The function returns an error code */ /* if unsuccessful, otherwise it returns 0. */ /* */ /************************************************************************/ int nCwRegisterClasses(void) { WNDCLASS wndclass; /* struct to define a window class */ memset(&wndclass, 0x00, sizeof(WNDCLASS)); /* load WNDCLASS with window's characteristics */ wndclass.style = CS_BYTEALIGNWINDOW; wndclass.lpfnWndProc = WndProc; /* Extra storage for Class and Window objects */ wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInst; wndclass.hIcon = LoadIcon(hInst,"CDICON"); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); /* Create brush for erasing background */ wndclass.hbrBackground = (HBRUSH)(COLOR_SCROLLBAR+1); wndclass.lpszMenuName = szAppName; /* Menu Name is App Name */ wndclass.lpszClassName = szAppName; /* Class Name is App Name */ if(!RegisterClass(&wndclass)) return -1; return(0); } /* End of nCwRegisterClasses */ /************************************************************************/ /* CwUnRegisterClasses Function */ /* */ /* Deletes any refrences to windows resources created for this */ /* application, frees memory, deletes instance, handles and does */ /* clean up prior to exiting the window */ /* */ /************************************************************************/ void CwUnRegisterClasses(void) { WNDCLASS wndclass; /* struct to define a window class */ memset(&wndclass, 0x00, sizeof(WNDCLASS)); UnregisterClass(szAppName, hInst); } /* End of CwUnRegisterClasses */ // use mciGetErrorString to display error void showMCIError(DWORD dwError) { char szErrorBuf[MAXERRORLENGTH]; MessageBeep(MB_ICONEXCLAMATION); if(mciGetErrorString(dwError,(LPSTR)szErrorBuf,MAXERRORLENGTH)) MessageBox(hMainWnd,szErrorBuf,"MCI Error",MB_ICONEXCLAMATION); else MessageBox(hMainWnd,"Unknown Error","MCI Error",MB_ICONEXCLAMATION); }