관리 메뉴

ㄴrㅎnㅂrㄹrㄱi

[강좌 15] 멀티미디어3 본문

API 관련/API 강좌모음

[강좌 15] 멀티미디어3

님투 2007. 10. 26. 03:41
반응형

[API]강좌(15)<--멀티미디어3





그러면 이번에는 플레이될 위치를 세팅하는 방법을 알아 봅시다. 그런데 이것은 이
미 낯이 익을지도 모르겠습니다. 이미 앞에서 비슷한것을 알아 보았거든요. 바로
플레이될 위치를 처음으로 옮길때 사용했던 MCI_SEEK을 이용해서 합니다. 이것을
이용해서 mciSendCommand()함수를 사용할때에 MCI_SEEK_PARMS이라는 구조체 변수의
주소가 필요했던것이 기억날겁니다.
이 구조체 멤버중 dwTo에 옮길 곳을 지정해 주고 mciSendCommand()함수의 세번째
파라미터에 MCI_TO를 지정해서 사용해주면 지정해준 곳을 옮길수 있습니다.
그러면 이것을 이용한 실제적인 프로그램을 보도록 합시다.
#include <windows.h>
MyMenu MENU
BEGIN
POPUP "&Midi"
BEGIN
MENUITEM "&Play", 100
MENUITEM "P&ause", 200
MENUITEM "&Resume", 300
MENUITEM "&Stop", 400
END
END
#include <windows.h>
#include <string.h>
#include <mmsystem.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
DWORD Open(HWND hWnd);
void Play(HWND hWnd, DWORD dwID);
void Stop(HWND hWnd, DWORD dwID);
void Pause(HWND hWnd, DWORD dwID);
void Close(HWND hWnd, DWORD dwID);
void MoveStartPosition(HWND hWnd, DWORD dwID);
DWORD MoveStartCurrentPosition(HWND hWnd, DWORD dwID);
void SetCurrentPosition(HWND hWnd, DWORD dwID, DWORD dwPos);
int WINAPI WinMain
(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszArg, int nCmdShow)
{
static char szAppName[] = "Multimedia Example";
HWND hWnd;
MSG msg;
WNDCLASS WndClass;
WndClass.style = CS_HREDRAW|CS_VREDRAW;
WndClass.lpfnWndProc = WndProc;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hInstance = hInstance;
WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClass.hbrBackground = GetStockObject(WHITE_BRUSH);
WndClass.lpszMenuName = "MyMenu";
WndClass.lpszClassName = szAppName;
if(!RegisterClass(&WndClass))
return FALSE;
hWnd = CreateWindow(
szAppName,
szAppName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL
);
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK
WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static DWORD dwID;
static BOOL bPause;
switch(message)
{
case WM_CREATE :
dwID = Open(hWnd);
return 0;
case MM_MCINOTIFY :
if(bPause)
{
SetCurrentPosition(hWnd, dwID,
MoveStartCurrentPosition(hWnd, dwID));
bPause = FALSE;
}
else
MoveStartPosition(hWnd, dwID);
return 0;
case WM_COMMAND :
switch(LOWORD(wParam))
{
case 100 :
Play(hWnd, dwID);
break;
case 200 :
Pause(hWnd, dwID);
bPause = TRUE;
break;
case 300 :
Play(hWnd, dwID);
break;
case 400 :
Stop(hWnd, dwID);
break;
}
return 0;
case WM_DESTROY :
Close(hWnd, dwID);
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
DWORD Open(HWND hWnd)
{
MCI_OPEN_PARMS mciOpenParms;
MCIERROR mciError;
mciOpenParms.lpstrDeviceType = "sequencer";
mciOpenParms.lpstrElementName = "d:\\test.mid";
mciError = mciSendCommand(NULL, MCI_OPEN, MCI_OPEN_TYPE|MCI_OPEN_ELEMENT,
(DWORD)&mciOpenParms);
if(mciError)
MessageBox(hWnd, "Open Error!!", "Error", MB_OK);
return mciOpenParms.wDeviceID;
}
void Play(HWND hWnd, DWORD dwID)
{
MCI_PLAY_PARMS mciPlayParms;
MCIERROR mciError;
mciPlayParms.dwCallback = (DWORD)hWnd;
mciError = mciSendCommand(dwID, MCI_PLAY, MCI_NOTIFY,
(DWORD)&mciPlayParms);
if(mciError)
MessageBox(hWnd, "Play Error!!", "Error", MB_OK);
}
void Stop(HWND hWnd, DWORD dwID)
{
MCI_GENERIC_PARMS mciGenericParms;
MCIERROR mciError;
mciError = mciSendCommand(dwID, MCI_STOP, MCI_WAIT,
(DWORD)&mciGenericParms);
if(mciError)
MessageBox(hWnd, "Stop Error!!", "Error", MB_OK);
}
void Pause(HWND hWnd, DWORD dwID)
{
MCI_GENERIC_PARMS mciGenericParms;
MCIERROR mciError;
mciError = mciSendCommand(dwID, MCI_PAUSE, MCI_WAIT,
(DWORD)&mciGenericParms);
if(mciError)
MessageBox(hWnd, "Pause Error!!", "Error", MB_OK);
}
void Close(HWND hWnd, DWORD dwID)
{
MCI_GENERIC_PARMS mciGenericParms;
MCIERROR mciError;
mciError = mciSendCommand(dwID, MCI_CLOSE, MCI_WAIT,
(DWORD)&mciGenericParms);
if(mciError)
MessageBox(hWnd, "Resume Error!!", "Error", MB_OK);
}
void MoveStartPosition(HWND hWnd, DWORD dwID)
{
MCI_SEEK_PARMS mciSeekParms;
MCIERROR mciError;
mciError = mciSendCommand(dwID, MCI_SEEK, MCI_SEEK_TO_START,
(DWORD)&mciSeekParms);
if(mciError)
MessageBox(hWnd, "Set Length Format Error!!", "Error", MB_OK);
}
DWORD MoveStartCurrentPosition(HWND hWnd, DWORD dwID)
{
MCI_STATUS_PARMS mciStatusParms;
MCIERROR mciError;
mciStatusParms.dwItem = MCI_STATUS_POSITION;
mciError = mciSendCommand(dwID, MCI_STATUS, MCI_STATUS_ITEM,
(DWORD)&mciStatusParms);
if(mciError)
MessageBox(hWnd, "Status Position Error!!", "Error", MB_OK);
return mciStatusParms.dwReturn;
}
void SetCurrentPosition(HWND hWnd, DWORD dwID, DWORD dwPos)
{
MCI_SEEK_PARMS mciSeekParms;
MCIERROR mciError;
mciSeekParms.dwTo = dwPos;
mciError = mciSendCommand(dwID, MCI_SEEK, MCI_TO, (DWORD)&mciSeekParms);
if(mciError)
MessageBox(hWnd, "Set Length Format Error!!", "Error", MB_OK);
}

프로그램을 분석해 보겠습니다. 뭐 별로 그렇게
어려운 부분은 없을 겁니다.
case WM_CREATE :
dwID = Open(hWnd);
return 0;
MCI 장치를 여는 방법에는 차이가 없습니다.
case MM_MCINOTIFY :
이 메시지 처리하는 부분이 바꾸었군요. 이미 앞에서 원리는 설명 드렸을 겁니다.
메뉴 아이템중 Pause가 선택되었다면 플레이된 현재 위치를 얻어서 그 위치로 플
레이 위치를 세팅하는 과정이 바로 아래 부분입니다.
if(bPause)
{
SetCurrentPosition(hWnd, dwID,
MoveStartCurrentPosition(hWnd, dwID));
bPause = FALSE;
각 함수에 대한것은 아래 부분에서 설명 드리겠습니다.
}
else
MoveStartPosition(hWnd, dwID);
이 함수는 이미 웨이브 파일을 플레이할때 설명 드렸던 함수입니다. 기억 납니까?
return 0;
case WM_COMMAND :
switch(LOWORD(wParam))
{
case 100 :
Play(hWnd, dwID);
break;
case 200 :
Pause(hWnd, dwID);
bPause = TRUE;
break;
case 300 :
Play(hWnd, dwID);
break;
Resume이 선택되었을때 그냥 플레이하는 함수를 사용했습니다. 플레이될 위치를 지
정했기 때문에 그 부분부터 플레이가 되죠.
case 400 :
Stop(hWnd, dwID);
break;
}
return 0;
case WM_DESTROY :
Close(hWnd, dwID);
PostQuitMessage(0);
return 0;
나머지 부분은 크게 다른점이 없습니다. 그러면 새롭게 나온 두 함수에 대해 알아
봅시다.
DWORD MoveStartCurrentPosition(HWND hWnd, DWORD dwID)
{
이 함수는 현재 플레이된 위치를 반환하는 역할을 합니다.
MCI_STATUS_PARMS mciStatusParms;
MCIERROR mciError;
mciStatusParms.dwItem = MCI_STATUS_POSITION;
mciError = mciSendCommand(dwID, MCI_STATUS, MCI_STATUS_ITEM,
(DWORD)&mciStatusParms);
위 구문은 이미 앞에서 예로 알아본 구문과 같죠?
if(mciError)
MessageBox(hWnd, "Status Position Error!!", "Error", MB_OK);
return mciStatusParms.dwReturn;
현재 위치를 반환하고 있습니다.
}
void SetCurrentPosition(HWND hWnd, DWORD dwID, DWORD dwPos)
{
MCI_SEEK_PARMS mciSeekParms;
MCIERROR mciError;
mciSeekParms.dwTo = dwPos;
파라미터로 지정되는 값을 dwTo에 저장하고 있습니다. 플레이될 위치를 지정하기
위한 과정입니다.
mciError = mciSendCommand(dwID, MCI_SEEK, MCI_TO, (DWORD)&mciSeekParms);
이것도 이미 설명드렸을 겁니다.
if(mciError)
MessageBox(hWnd, "Set Length Format Error!!", "Error", MB_OK);
}
크게 어려운 점은 없을 겁니다. 그러면 이번에는 CD 플레이어를 어떻게 구현하는지
알아 보도록 하겠습니다. 비록 간단한 CD 플레이어래도 기본적인것들은 있어야 할
겁니다. 플레이, 중단, 임시중단, 다시 재생, 다음곡, 이전곡등을 구현하면 되겠네
요. 그러면 본격적으로 알아 봅시다.
반응형

'API 관련 > API 강좌모음' 카테고리의 다른 글

[강좌 17] 폰트  (0) 2007.10.26
[강좌 16] 멀티미디어4  (0) 2007.10.26
[강좌 14] 멀티미디어2  (0) 2007.10.26
[강좌 13] 멀티미디어1  (0) 2007.10.26
[강좌 12] 그래픽3  (0) 2007.10.26
Comments