#pragma comment (lib, "comctl32.lib") #pragma comment (lib, "dxguid.lib") #pragma comment (lib, "strmiids.lib") #ifndef UNICODE #define UNICODE #endif #define daviddr 090430 #include <windows.h> #include <commctrl.h> #include <dshow.h> #include <cstdio> extern"C" WINBASEAPI HWND WINAPI GetConsoleWindow(); #define MsgBox(s) MessageBox (0,s,0,MB_OK) WCHAR e_str[256]; void cdecl MsgBox_ (wchar_t* fmt, ...) {swprintf_s (e_str, 256, fmt, (char*)(&fmt+1)); MsgBox(e_str);} namespace FileDlg { WCHAR title[256] = L"*.*"; WCHAR filter[256] = L"AVI File (*.avi)\0*.avi\0" L"MPEG File (*.mpg)\0*.mpg\0" L"Mp3 File (*.mp3)\0*.mp3\0" L"Wave File (*.wav)\0*.wav\0" L"All Files (*.*)\0*.*\0\0"; WCHAR file_name[512], init_dir[512], exe_path[512]={0}, *fname; OPENFILENAME ofn = { sizeof(OPENFILENAME), 0, 0, (LPCWSTR)filter,0,0,1, title, 512, file_name, 512, init_dir, 0, 6, 0,1, L"", 0,0,0 }; LPWSTR open (HWND hwnd) { ofn.hwndOwner = hwnd; ofn.lpstrTitle = L"開檔"; ofn.lpstrFilter = filter; ofn.Flags = 6; ofn.lpstrFile[0] = 0; //若開檔後仍為0表示按了[Cancel] if (!GetOpenFileName (&ofn)) { if(*ofn.lpstrFile) MsgBox_ (L"Fail to open: %d", CommDlgExtendedError()); return 0; } return fname = ofn.lpstrFile; //取個短名字 } } #define DO(b) if (FAILED(b)) \ {MsgBox_(L"fail in %s line %d",__FILE__,__LINE__);} struct Player { bool bPlaying; long evCode; LONGLONG pos, duration; IMediaEvent* pEvent; IGraphBuilder* pGraph; IMediaControl* pCtrl; IVideoWindow* pVideo; IMediaSeeking* pSeek; void init() { bPlaying = false; DO (CoCreateInstance (CLSID_FilterGraph, 0, CLSCTX_INPROC, IID_IGraphBuilder, (void**) &pGraph)); DO (pGraph->QueryInterface (IID_IMediaControl, (void**) &pCtrl)); DO (pGraph->QueryInterface (IID_IVideoWindow, (void**) &pVideo)); DO (pGraph->QueryInterface (IID_IMediaEvent, (void**) &pEvent)); DO (pGraph->QueryInterface (IID_IMediaSeeking, (void**) &pSeek)); } void free() { if (bPlaying) { setTimeInfo (0); pCtrl->Stop(); } pVideo->put_Visible (OAFALSE); pVideo->put_Owner (0); pSeek->Release(); pCtrl->Release(); pGraph->Release(); } void run (WCHAR* path, HWND hwnd) { bPlaying = true; DO (pGraph->RenderFile (path, 0)); DO (pVideo->put_Owner ((OAHWND)hwnd)); resize (hwnd); DO (pCtrl->Run()); } void resize (HWND hwnd) { if (!bPlaying) return; RECT rc; GetClientRect (hwnd, &rc); DO (pVideo->put_WindowStyle (WS_CHILD| WS_CLIPSIBLINGS)); DO (pVideo->SetWindowPosition (0, 0, rc.right, rc.bottom-20)); } void getTimeInfo() { pSeek->GetCurrentPosition (&pos); pSeek->GetDuration (&duration); } void setTimeInfo (double pos_) { LONGLONG duration = 1; pSeek->GetDuration (&duration); duration *= pos_; pSeek->SetPositions (&duration, AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning); } void pause (bool b) {b?pCtrl->Pause():pCtrl->Run();} }; //-------------------------- 主程式 ------------------------------- HINSTANCE e_hInst; LRESULT CALLBACK WndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { static enum {ID_TIMER, ID_OPEN, ID_PAUSE, ID_SLIDER}; static bool bPause; static int w,h; static Player player; static HMENU hMenu; static HWND hSlider; //scroll handle switch (msg) { case WM_CREATE: hMenu = (HMENU) CreateMenu(); AppendMenu (hMenu, MF_STRING, ID_OPEN, L"開檔"); AppendMenu (hMenu, MF_STRING, ID_PAUSE, L"暫停"); SetMenu (hwnd, hMenu); hSlider = CreateWindow (TRACKBAR_CLASS, L"", WS_CHILD| WS_VISIBLE| TBS_AUTOTICKS, 216,4,256,16, hwnd, (HMENU)ID_SLIDER, e_hInst, 0); SendMessage (hSlider, TBM_SETRANGE, TRUE, MAKELONG(1,1000)); SendMessage (hSlider, TBM_SETPOS, TRUE, 1); return 0; case WM_CLOSE: if (player.bPlaying) { player.free(); KillTimer (hwnd, ID_TIMER); } PostQuitMessage(0); return 0; case WM_SIZE: player.resize (hwnd); w = LOWORD (lParam); h = HIWORD (lParam); MoveWindow (hSlider, 2, h-20, w-4, 20, TRUE); return 0; case WM_KEYDOWN: switch (wParam) { case VK_ESCAPE: SendMessage (hwnd, WM_CLOSE, 0, 0); break; case VK_RETURN: player.pause (bPause = !bPause); break; } return 0; case WM_HSCROLL: player.setTimeInfo ( double(SendMessage (hSlider, TBM_GETPOS, 0, 0))/1000); return 0; case WM_TIMER: player.getTimeInfo(); SendMessage (hSlider, TBM_SETPOS, TRUE, player.pos * 1000 / player.duration); return 0; case WM_COMMAND: if (ID_OPEN == LOWORD(wParam)) { if (FileDlg::open (hwnd)) { //若開檔成功 if (player.bPlaying) { //關閉計時器 player.free(); KillTimer (hwnd, ID_TIMER); } bPause = false; swprintf_s (e_str, L"%s", FileDlg::fname); SetWindowText (hwnd, e_str); player.init(); player.run (FileDlg::fname, hwnd); SetTimer (hwnd, ID_TIMER, 20, 0); //啟動計時器 } }else if (ID_PAUSE == LOWORD(wParam)) player.pause (bPause = !bPause); return 0; default: return DefWindowProc (hwnd, msg, wParam, lParam); } return 0; } int WINAPI WinMain (HINSTANCE hInst, HINSTANCE, PSTR, int nShow) { CoInitialize (0); WNDCLASSEX wc = {0x30,3,WndProc,0,0,hInst,0,0,(HBRUSH)1,0,L"DS",0}; if (!RegisterClassEx(&wc)) return 0; HWND hwnd = CreateWindow (L"DS",L"Player", 13565952,100,50,560,500,0,0,hInst,0); if (!hwnd) return 0; e_hInst = hInst; MSG msg; ShowWindow (hwnd, nShow); while (GetMessage (&msg, 0,0,0)) { TranslateMessage (&msg); DispatchMessage (&msg); } CoUninitialize(); return msg.wParam; }
2009年10月30日 星期五
影片播放器
訂閱:
張貼留言 (Atom)
沒有留言:
張貼留言