관리 메뉴

ㄴrㅎnㅂrㄹrㄱi

[강좌 16] 멀티미디어4 본문

API 관련/API 강좌모음

[강좌 16] 멀티미디어4

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

[API]강좌(16)<--멀티미디어4




우리가 앞에서 알아본 웨이브 파일, 미디 파일은 파일명을 지정해서 플레이 해주면
됐지만 CD 플레이어는 파일이 없습니다. 그렇죠? 그러기 때문에 MCI 장치 여는 과
정이 조금 다릅니다. 우리는 장치를 열때 lpstrDeviceType에 장치 이름을 지정해
주었는데 CD 플레이어는 장치 이름으로 cdaudio를 지정해 주면 됩니다. 그리고 한
가지 작업을 더 했죠? 그것은 lpstrElementName에 파일 이름을 지정해 주었다는 것
입니다. 그러나 CD 플레이어에서는 파일 이름을 지정하는 과정을 하지 않아도 됩
니다. 당연한 얘기죠. 그리고 우리는 장치를 열기 위해서 mciSendCommand() 함수를
사용했을 겁니다. 그리고 이 함수의 세번째 파라미터로 MCI_OPEN_TYPE|MCI_OPEN_
ELEMENT를 지정했는데 이 부분에서 MCI_OPEN_ELEMENT를 빼주고 MCI_OPEN_TYPE만
지정해 주면 됩니다. 왜냐하면 파일 이름이 없기 때문입니다. 그리고 해주어야
할 작업은 길이 단위를 세팅하는 작업입니다. 우리가 앞에서 알아본 웨이브 파일
이나 미디 파일은 그 단위가 그렇게 중요한 문제가 되지 않았으나 CD 플레이어 같
은 경우에는 중요합니다. 왜냐하면 다음곡을 플레이하거나 이전 곡을 플레이할때
이 단위로 이동해야 되기 때문이죠. 물론 이 단위는 트랙단위입니다. 역시 세팅
할때 사용하는 함수는 mciSendCommand() 함수입니다. 그리고 마지막 파라미터에
MCI_SET_PARMS라는 구조체 변수의 주소를 지정해 주어야 합니다.
typedef struct {
DWORD dwCallback;
DWORD dwTimeFormat;
DWORD dwAudio;
} MCI_SET_PARMS;
위 구조체 변수의 멤버중 dwTimeFormat에 MCI_FORMAT_TNSF라는 예약어를 지정해 주
고 mciSendCommand() 함수를 사용하면 됩니다. 바로 아래 처럼 사용하면 되죠.
mciSetParms.dwTimeFormat = MCI_FORMAT_TMSF;
mciError = mciSendCommand(dwID, MCI_SET, MCI_SET_TIME_FORMAT,
(DWORD)&mciSetParms);
이 부분까지 됐으면 그 다음부터는 미디 파일을 플레이할때와 같습니다. 즉 잠시
중단했다가 다시 재생하는 부분의 처리 방식이 미디 파일 할때와 같습니다. 즉
Resume() 기능을 Play()함수로 구현한다는 것입니다. 그러면 우리가 여기서 추가
해서 알아 볼것은 바로 다음 곡의 플레이와 이전 곡의 플레이인데 구현의 원리
는 간단합니다. 다음곡 같은 경우는 먼저 Pause를 시키고 현재 트랙 번호를 얻어서
그 값을 증가시켜 위치를 옮기면 됩니다. 그리고 Play하면 되죠. 이전 곡 같은 경
우는 감소시키면 되죠. 그런데 만약에 CD 음악이 총 10개의 음악으로 되어 있는데
하나를 증가시켜 트랙위치가 11이 된다면 어떤일이 발생할까요? 위치를 세팅할때
에러가 발생합니다. 그러면 간단하죠. 에러 체크하는 루틴에 현재 트랙위치로
고정하는 구문이 있으면 됩니다. 그러면 10번째 음악다음에 다음곡을 선택해도 계
속 10번째 음악이 나오는거죠. 물론 이 부분은 여러분들이 나름대로 수정해서
구현하면 됩니다. 자 그러면 구체적인 구현의 방법을 봅시다. 현재 트랙번호를 얻
는 과정을 할때에 사용하는 구조체 변수는 앞에서 알아 본 MCI_STATUS_PARMS입니
다. 이 구조체 멤버중 dwItem에 MCI_STAUS_CURRENT_TRACK을 지정하고
mciSendCommand() 함수를 사용하면 됩니다. 아래 처럼 하면 되죠.
mciStatusParms.dwItem = MCI_STATUS_CURRENT_TRACK;
mciError = mciSendCommand(dwID, MCI_STATUS, MCI_STATUS_ITEM,
(DWORD)&mciStatusParms);
에러가 발생하지 않고 성공적으로 되었다면 mciStatusParms.dwReturn에 현재 트랙
이 저장됩니다. 우리는 이값을 증가시키거나 감소시켜서 다음곡으로 이동할수도 있
고 이전 곡으로 이동할수도 있습니다.
이동이 됐으면 이 부분으로 플레이 위치를 세팅해 주어야 할겁니다. 이 부분은 이
미 앞에서 다 한 부분입니다. 그러면 실제로 간단하게 CD 음악을 연주하는 프로그
램을 만들어 봅시다.
MyMenu MENU
BEGIN
POPUP "&CD"
BEGIN
MENUITEM "&Play", 100
MENUITEM "&Next", 200
MENUITEM "&Prev", 300
MENUITEM "P&ause", 400
MENUITEM "&Resume", 500
MENUITEM "&Stop", 600
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);
void SetFormat(HWND hWnd, DWORD dwID);
DWORD MoveNextTrack(HWND hWnd, DWORD dwID);
DWORD MovePrevTrack(HWND hWnd, DWORD dwID);
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, bNext, bPrev;
switch(message)
{
case WM_CREATE :
dwID = Open(hWnd);
SetFormat(hWnd, dwID);
return 0;
case MM_MCINOTIFY :
if(bPause)
{
SetCurrentPosition(hWnd, dwID,
MoveStartCurrentPosition(hWnd, dwID));
bPause = FALSE;
}
else if(bNext)
{
SetCurrentPosition(hWnd, dwID,
MoveNextTrack(hWnd, dwID));
bNext = FALSE;
Play(hWnd, dwID);
}
else if(bPrev)
{
SetCurrentPosition(hWnd, dwID,
MovePrevTrack(hWnd, dwID));
bPrev = FALSE;
Play(hWnd, dwID);
}
else
MoveStartPosition(hWnd, dwID);
return 0;
case WM_COMMAND :
switch(LOWORD(wParam))
{
case 100 :
Play(hWnd, dwID);
break;
case 200 :
Pause(hWnd, dwID);
bNext = TRUE;
break;
case 300 :
Pause(hWnd, dwID);
bPrev = TRUE;
break;
case 400 :
Pause(hWnd, dwID);
bPause = TRUE;
break;
case 500 :
Play(hWnd, dwID);
break;
case 600 :
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 = "cdaudio";
mciError = mciSendCommand(NULL, MCI_OPEN, MCI_OPEN_TYPE,
(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 SetFormat(HWND hWnd, DWORD dwID)
{
MCI_SET_PARMS mciSetParms;
MCIERROR mciError;
mciSetParms.dwTimeFormat = MCI_FORMAT_TMSF;
mciError = mciSendCommand(dwID, MCI_SET, MCI_SET_TIME_FORMAT,
(DWORD)&mciSetParms);
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_STATUS_PARMS mciStatusParms;
MCI_SEEK_PARMS mciSeekParms;
MCIERROR mciError;
mciSeekParms.dwTo = dwPos;
mciError = mciSendCommand(dwID, MCI_SEEK, MCI_TO, (DWORD)&mciSeekParms);
if(mciError)
{
mciStatusParms.dwItem = MCI_STATUS_CURRENT_TRACK;
mciError = mciSendCommand(dwID, MCI_STATUS, MCI_STATUS_ITEM,
(DWORD)&mciStatusParms);
if(mciError)
MessageBox(hWnd, "Status Position Error!!", "Error", MB_OK);
}
}
DWORD MoveNextTrack(HWND hWnd, DWORD dwID)
{
MCI_STATUS_PARMS mciStatusParms;
MCIERROR mciError;
mciStatusParms.dwItem = MCI_STATUS_CURRENT_TRACK;
mciError = mciSendCommand(dwID, MCI_STATUS, MCI_STATUS_ITEM,
(DWORD)&mciStatusParms);
if(mciError)
MessageBox(hWnd, "Status Position Error!!", "Error", MB_OK);
return ++mciStatusParms.dwReturn;
}
DWORD MovePrevTrack(HWND hWnd, DWORD dwID)
{
MCI_STATUS_PARMS mciStatusParms;
MCIERROR mciError;
mciStatusParms.dwItem = MCI_STATUS_CURRENT_TRACK;
mciError = mciSendCommand(dwID, MCI_STATUS, MCI_STATUS_ITEM,
(DWORD)&mciStatusParms);
if(mciError)
MessageBox(hWnd, "Status Position Error!!", "Error", MB_OK);
return --mciStatusParms.dwReturn;
}

CD 플레이어 프로그램을 분석해 보겠습니다.
case WM_CREATE :
dwID = Open(hWnd);
SetFormat(hWnd, dwID);
return 0;
윈도우가 생성될 때 MCI 장치를 열고 그 포맷을 트랙단위로 하겠다는 것을 명시해
주는 구문입니다.
case MM_MCINOTIFY :
if(bPause)
{
SetCurrentPosition(hWnd, dwID,
MoveStartCurrentPosition(hWnd, dwID));
bPause = FALSE;
이 부분은 이미 미디 파일을 플레이할때 다루었을 겁니다.
}
else if(bNext)
{
SetCurrentPosition(hWnd, dwID,
MoveNextTrack(hWnd, dwID));
bNext = FALSE;
Play(hWnd, dwID);
다음곡 플레이가 선택되었을때 현재 플레이 위치를 다음 트랙으로 옮긴후에 다시
플레이하는 것을 보여주고 있습니다.
}
else if(bPrev)
{
SetCurrentPosition(hWnd, dwID,
MovePrevTrack(hWnd, dwID));
bPrev = FALSE;
Play(hWnd, dwID);
이전곡 플레이가 선택되었을때 현재 플레이 위치를 이전 트랙으로 옮긴후에 다시
플레이하는 것을 보여주고 있습니다.
}
else
MoveStartPosition(hWnd, dwID);
return 0;
case WM_COMMAND :
switch(LOWORD(wParam))
{
case 100 :
Play(hWnd, dwID);
break;
case 200 :
Pause(hWnd, dwID);
bNext = TRUE;
break;
다음곡 플레이가 선택되었을때도 역시 Pause()함수를 이용해서 중단한뒤 다음곡플
레이때문에 중단되었다는 것을 bNext변수를 이용해서 알려주고 있습니다.
case 300 :
Pause(hWnd, dwID);
bPrev = TRUE;
break;
이전곡 플레이가 선택되었을때도 역시 Pause()함수를 이용해서 중단한뒤 이전곡 플
레이때문에 중단되었다는 것을 bPrev변수를 이용해서 알려주고 있습니다.
case 400 :
Pause(hWnd, dwID);
bPause = TRUE;
break;
case 500 :
Play(hWnd, dwID);
break;
case 600 :
Stop(hWnd, dwID);
break;
}
return 0;
case WM_DESTROY :
Close(hWnd, dwID);
PostQuitMessage(0);
return 0;
나머지 부분은 크게 달라진 점이 없을 겁니다. 그러면 MCI 장치를 여는 Open() 함
수를 보도록 합시다.
DWORD Open(HWND hWnd)
{
MCI_OPEN_PARMS mciOpenParms;
MCIERROR mciError;
mciOpenParms.lpstrDeviceType = "cdaudio";
mciError = mciSendCommand(NULL, MCI_OPEN, MCI_OPEN_TYPE,
(DWORD)&mciOpenParms);
세번째 파라미터에 MCI_OPEN_ELEMENT라는 예약어가 없죠? 파일을 읽어서 플레이하
는 것이 아니기 때문입니다.
if(mciError)
MessageBox(hWnd, "Open Error!!", "Error", MB_OK);
return mciOpenParms.wDeviceID;
}
void SetFormat(HWND hWnd, DWORD dwID)
{
MCI_SET_PARMS mciSetParms;
MCIERROR mciError;
mciSetParms.dwTimeFormat = MCI_FORMAT_TMSF;
mciError = mciSendCommand(dwID, MCI_SET, MCI_SET_TIME_FORMAT,
(DWORD)&mciSetParms);
트랙단위로 길이 단위를 사용하겠다는 것을 지정해주고 있습니다. 이미 앞에서 설
명드렸습니다.
if(mciError)
MessageBox(hWnd, "Resume Error!!", "Error", MB_OK);
}
void SetCurrentPosition(HWND hWnd, DWORD dwID, DWORD dwPos)
{
MCI_STATUS_PARMS mciStatusParms;
MCI_SEEK_PARMS mciSeekParms;
MCIERROR mciError;
mciSeekParms.dwTo = dwPos;
mciError = mciSendCommand(dwID, MCI_SEEK, MCI_TO, (DWORD)&mciSeekParms);
if(mciError)
{
mciStatusParms.dwItem = MCI_STATUS_CURRENT_TRACK;
mciError = mciSendCommand(dwID, MCI_STATUS, MCI_STATUS_ITEM,
(DWORD)&mciStatusParms);
if(mciError)
MessageBox(hWnd, "Status Position Error!!", "Error", MB_OK);
}
에러가 발생된다는 것은 그 트랙의 범위에 벗어난다는 의미이므로 이럴때 그냥 현재
트랙의 노래를 플레이하기 위해서 위와같이 구현했습니다.
}
DWORD MoveNextTrack(HWND hWnd, DWORD dwID)
{
이 함수는 다음 트랙번호를 얻는 역할을 합니다.
MCI_STATUS_PARMS mciStatusParms;
MCIERROR mciError;
mciStatusParms.dwItem = MCI_STATUS_CURRENT_TRACK;
mciError = mciSendCommand(dwID, MCI_STATUS, MCI_STATUS_ITEM,
(DWORD)&mciStatusParms);
현재 트랙번호를 얻는 구문입니다.
if(mciError)
MessageBox(hWnd, "Status Position Error!!", "Error", MB_OK);
return ++mciStatusParms.dwReturn;
트랙번호를 증가해서 값을 리턴하고 있습니다.
}
DWORD MovePrevTrack(HWND hWnd, DWORD dwID)
{

이 함수는 다음 트랙번호를 얻는 역할을 합니다.
MCI_STATUS_PARMS mciStatusParms;
MCIERROR mciError;
mciStatusParms.dwItem = MCI_STATUS_CURRENT_TRACK;
mciError = mciSendCommand(dwID, MCI_STATUS, MCI_STATUS_ITEM,
(DWORD)&mciStatusParms);
현재 트랙번호를 얻는 구문입니다.
if(mciError)
MessageBox(hWnd, "Status Position Error!!", "Error", MB_OK);
return --mciStatusParms.dwReturn;
트랙번호를 감소해서 값을 리턴하고 있습니다.
}
자 그렇게 크게 어려운 점은 없죠? 그러면 이번에는 멀티미디어 관련 마지막인
확장자가 avi인 파일을 어떻게 플레이하는지 알아 보겠습니다. 여러분들이 앞에
서 알아본것들중에서 이 부분이 가장 어려울거라고 생각들수도 있으나 사실 이
부분이 제일 쉽습니다. 간단하게 함수 하나로 모든 기능을 가진 avi 플레이어
를 구현할수 있거든요. 우리가 앞에서 알아본 프로그램은 전부 mmsystem.h라는
헤더파일을 포함시켰고 또 컴파일할때도 winmm.lib 파일을 같이 묶어서 컴파일 했을
겁니다. 그러나 우리가 이제 알아볼 avi 파일을 플레이할때에는 이 헤더 파일과
라이브러리 파일이 필요 없습니다. 대신 다른 헤더 파일과 라이브러리 파일이 필요
합니다. 필요한 헤더 파일은 vfw.h라는 헤더 파일이고 필요한 라이브러리 파일은
vfw32.lib입니다. vfw가 뭐의 약자인지 아십니까? 바로 Video For Windows의 약자
입니다. 이게 뭔지는 굳이 제가 설명 드리지 않더라도 알겠죠?
함수 하나로 플레이할수 있다고 했는데 과연 그 함수가 뭘까요?
HWND VFWAPIV MCIWndCreate(HWND hwndParent, HINSTANCE hInstance,
DWORD dwStyle,LPCSTR szFile);
바로 위 함수 하나로 avi를 플레이할수 있는 조그만 윈도우를 만들수 있습니다. 첫
번째 파라미터에 현재 윈도우의 핸들을 지정해야 하고 두번째 파라미터에는 인스턴
스 핸들, 세번째 파라미터는 이 윈도우의 속성을 지정해 줄수 있는데 보통 NULL
을 지정하면 기본 속성을 사용하겠다는 것을 의미합니다. 마지막 파라미터는 플레
이 할 avi 파일이름을 지정하면 됩니다. 만약에 NULL로 지정하면 파일을 직접 찾아
서 플레이할수 있게 됩니다.
위 함수를 이용해서 윈도우를 생성하고 나면 나중에 프로그램 종료시 윈도우를 제
거해 주어야 합니다. 이때에는 아래 함수를 이용해서 하면 됩니다.
void MCIWndDestroy(HWND hwnd);
그러면 이 두함수를 이용해서 구현한 간단하고 뛰어난 avi 플레이어를 만들어 봅시
다.
#include <windows.h>
#include <string.h>
#include <vfw.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HINSTANCE hInst;
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
);
hInst = hInstance;
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)
{
HWND hAviWnd;
switch(message)
{
case WM_CREATE :
hAviWnd = MCIWndCreate(
hWnd,
hInst,
NULL,
"d:\\test.avi"
);
return 0;
case WM_DESTROY :
MCIWndDestroy(hAviWnd);
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
정말로 간단하죠? 이 소스를 보신분은 정말 이 프로그램이 avi 파일을 플레이할수
있는지 의문이 생길수도 있을 겁니다. 직접 코딩해서 컴파일 해보시기 바랍니다.
간단하게 만들었지만정말 대단하다는 것을 느낄겁니다. 그러면 구체적으로 소스
를 보도록 하겠습니다.
#include <vfw.h>
프로그램 상단에 위 헤더 파일을 포함시켜 줘야 합니다. 물론 컴파일할때에는
vfw32.lib 파일을 묶어서 해줘야 하구요.
HWND hAviWnd;
조그마하게 생성되는 avi 플레이어 윈도우의 핸들을 얻기 위해서 위 변수를 선언
했습니다.
switch(message)
{
case WM_CREATE :
hAviWnd = MCIWndCreate(
hWnd,
hInst,
NULL,
"d:\\test.avi"
);
return 0;
윈도우가 생성될때 avi 플레이어 윈도우를 생성하는 구문입니다.
case WM_DESTROY :
MCIWndDestroy(hAviWnd);
윈도우가 종료될때 avi 플레이어 윈도우를 없애는 구문입니다.
PostQuitMessage(0);
return 0;
}
반응형

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

[강좌 18] 파일과 디렉토리  (0) 2007.10.26
[강좌 17] 폰트  (0) 2007.10.26
[강좌 15] 멀티미디어3  (0) 2007.10.26
[강좌 14] 멀티미디어2  (0) 2007.10.26
[강좌 13] 멀티미디어1  (0) 2007.10.26
Comments