/*     動画ファイルの再生 1999/ 3/18 宍戸 輝光 */ #include LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); void draw(void); LPBYTE lpBuf,lpFrame; LPBITMAPINFO lpDIB; LPRGBQUAD lpRGB; HWND hwMain; DWORD dwTime,dwIndex,dwStart,dwPIndex,dwFFrame; HANDLE fh; BYTE lpStr[64]; HINSTANCE hInst; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){ MSG msg; WNDCLASSEX wndclass ; int i; hInst=hInstance; fh=CreateFile("test.vid",GENERIC_READ,0,NULL, OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if (fh==INVALID_HANDLE_VALUE || GetFileSize(fh,NULL)!=256*256*240) { MessageBox(NULL,"動画ファイルがありません。","失敗",MB_OK); CloseHandle(fh); return 0; } wndclass.cbSize = sizeof(wndclass); wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = NULL; wndclass.hCursor = LoadCursor(NULL,IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = "CWindow"; wndclass.hIconSm = NULL; RegisterClassEx (&wndclass); hwMain=CreateWindow ("CWindow","動画ファイルの再生", WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,320,360, NULL,NULL,hInstance,NULL); lpBuf=(LPBYTE)GlobalAlloc /* 必要なメモリをまとめて確保 */ (GPTR,sizeof(BITMAPINFO)+255*sizeof(RGBQUAD)+256*256); lpDIB=(LPBITMAPINFO)lpBuf; lpRGB=(RGBQUAD*)(lpBuf+sizeof(BITMAPINFOHEADER)); lpFrame=lpBuf+sizeof(BITMAPINFO)+255*sizeof(RGBQUAD); lpDIB->bmiHeader.biSize=sizeof(BITMAPINFOHEADER); /* BITMAPINFO構造体 */ lpDIB->bmiHeader.biWidth=256; lpDIB->bmiHeader.biHeight=256; lpDIB->bmiHeader.biPlanes=1; lpDIB->bmiHeader.biBitCount=8; lpDIB->bmiHeader.biCompression=BI_RGB; lpDIB->bmiColors[0]=lpRGB[0]; /* カラーテーブルの先頭 */ for (i=0;i<256;i++) { /* カラーテーブル作成 */ lpRGB[i].rgbRed=i; lpRGB[i].rgbGreen=i; lpRGB[i].rgbBlue=i; } ShowWindow (hwMain,iCmdShow); /* ウインドウを表示 */ UpdateWindow (hwMain); dwTime=GetTickCount(); dwIndex=240; wsprintf(lpStr,"フレーム %03d/ コマ落ち %03d",0,0); while (1) { /* メインループ */ if (PeekMessage (&msg,NULL,0,0,PM_NOREMOVE)) { if (!GetMessage (&msg,NULL,0,0)) /* メッセージ処理 */ return msg.wParam ; TranslateMessage(&msg); DispatchMessage(&msg); } else draw(); /* 描画処理 */ } } void draw(void) { /* メインループ描画処理 */ DWORD dwDummy; if (dwIndex>239) return; if (GetTickCount()>dwTime+5) dwTime=GetTickCount(); else /* 前回の処理から5ms 以上経ってなければ戻る */ return; if (dwStart==0) /* 最初の時間を記録 */ dwStart=GetTickCount(); dwIndex=(int)((GetTickCount()-dwStart)/50.0); /* 1/20秒毎に1増やす */ if (dwIndex>dwPIndex+1) /* コマ落ち判定 */ dwFFrame+=dwIndex-dwPIndex-1; dwPIndex=dwIndex; /* 今回再生したフレームを記録 */ if (dwIndex>239) return; SetFilePointer(fh,256*256*dwIndex,&dwDummy,FILE_BEGIN); ReadFile(fh,lpFrame,256*256,&dwDummy,NULL); wsprintf(lpStr,"フレーム %03d/ コマ落ち %03d",dwIndex,dwFFrame); InvalidateRect(hwMain,NULL,FALSE); UpdateWindow (hwMain); /* フレーム表示 */ } LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { HDC hdc; HWND hwPlayB; PAINTSTRUCT ps; switch (iMsg) { case WM_CREATE: hwPlayB=CreateWindow("Button","再生", /* ボタン作成 */ WS_CHILD | WS_VISIBLE,240,280,64,32,hwnd, (HMENU)0,hInst,NULL); return 0; case WM_COMMAND: /* ボタンクリック */ dwStart=0; /* 再生開始の設定 */ dwIndex=0; dwPIndex=0; dwFFrame=0; return 0; case WM_PAINT: hdc=BeginPaint(hwnd,&ps); /* フレームを表示 */ StretchDIBits(hdc,8,8,256,256,0,0,256,256, lpFrame,lpDIB,DIB_RGB_COLORS,SRCCOPY); TextOut(hdc,8,280,lpStr,lstrlen(lpStr)); EndPaint(hwnd,&ps); break; case WM_DESTROY : /* 終了処理 */ GlobalFree(lpBuf); CloseHandle(fh); PostQuitMessage(0); return 0; } return DefWindowProc (hwnd, iMsg, wParam, lParam) ; }