// Avi PostEdit - Camstudio Annotation Re-capture // Initial drafted code developed by giulio8 // http://camstudio.org/forum/comments.php?DiscussionID=145&page=1#Item_0 // https://sourceforge.net/forum/forum.php?thread_id=3287208&forum_id=447910 // Play an AVI using the MSvfw32.lib // in the case of Dev-C++ link with libmsvfw32.a via // Project>>Project Options>>Parameters>>Add Lib>>libmsvfw32.a // created via BCX generated C code then modified for Dev-C++ // (actually-Dev C++ is the IDE for the GNU GCC/G++ compiler) // a Dev-C++ tested Windows Application by vegaseat 21nov2004 #include #include using namespace std; #include #include #define ID_MCIFrame 0 #define ID_MENU1 9001 #define ID_MENU2 9002 #define ID_MENU3 9003 #define ID_MENU4 9004 #define ID_MENU5 9005 static HINSTANCE BCX_hInstance; static int BCX_ScaleX; static int BCX_ScaleY; static char BCX_ClassName[2048]; static HANDLE ghInst; static HWND Form1; static HWND MCIFrame; static HMENU MainMenu; static HMENU FileMenu; static OPENFILENAME OpenFileName; static char szFile[2048]; static char szFileTitle[2048]; static char szFileBmp[2048]; static char szFileTitleBmp[2048]; static char szFileBmpC[2048]; static char szFileTitleBmpC[2048]; #define Show(Window) RedrawWindow(Window,0,0,0);ShowWindow(Window,SW_SHOW); HWND BCX_Form(char*,int=0,int=0,int=250,int=150,int=0,int=0); void BCX_Set_Form_Color (HWND,COLORREF); void Center (HWND,HWND=0,HWND=0); char* BCX_TmpStr(size_t); char* str (double); char* curdir (void); void FormLoad (void); LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); int InitOpenFileName (void); int PopFileOpenDlg (HWND, char *, char *); BOOL AddMenu (HWND); // standard Windows Graphical User Interface main int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrev,LPSTR CmdLine,int CmdShow) { WNDCLASS Wc; MSG Msg; // ***************************** strcpy(BCX_ClassName,"MCI_demo1"); // ************************************ // Scale Dialog Units To Screen Units // ************************************ RECT rc = {0,0,4,8}; MapDialogRect (NULL,&rc); BCX_ScaleX = rc.right/2; BCX_ScaleY = rc.bottom/4; BCX_hInstance = hInst; // ****************************************************** Wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; Wc.lpfnWndProc = WndProc; Wc.cbClsExtra = 0; Wc.cbWndExtra = 0; Wc.hInstance = hInst; Wc.hIcon = LoadIcon(NULL,IDI_WINLOGO); Wc.hCursor = LoadCursor(NULL,IDC_ARROW); Wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1); Wc.lpszMenuName = NULL; Wc.lpszClassName = BCX_ClassName; RegisterClass(&Wc); FormLoad(); // event message loop while(GetMessage(&Msg,NULL,0,0)) { HWND hActiveWindow = GetActiveWindow(); if (!IsWindow(hActiveWindow) || !IsDialogMessage(hActiveWindow,&Msg)) { TranslateMessage(&Msg); DispatchMessage(&Msg); } } return Msg.wParam; } // circular storage, hold the memory leaks to a minimum char *BCX_TmpStr (size_t Bites) { static int StrCnt; static char *StrFunc[2048]; StrCnt=(StrCnt + 1) & 2047; if(StrFunc[StrCnt]) free (StrFunc[StrCnt]); return StrFunc[StrCnt]=(char*)calloc(Bites+128,sizeof(char)); } char *str (double d) { register char *strtmp = BCX_TmpStr(16); sprintf(strtmp,"% .15G",d); return strtmp; } char *curdir (void) { register char *strtmp = BCX_TmpStr(2048); GetCurrentDirectory (1024,strtmp); return strtmp; } // center the window form on the screen, optional, for looks void Center (HWND hwnd, HWND Xhwnd, HWND Yhwnd) { RECT rect, rectP; int x, y, width, height; int screenwidth, screenheight; if(Xhwnd==0) { RECT DesktopArea; RECT rc; SystemParametersInfo(SPI_GETWORKAREA,0,&DesktopArea,0); GetWindowRect(hwnd,&rc); SetWindowPos(hwnd,HWND_TOP, ((DesktopArea.right-DesktopArea.left)-(rc.right-rc.left))/2+ DesktopArea.left,((DesktopArea.bottom-DesktopArea.top)- (rc.bottom-rc.top))/2 + DesktopArea.top,0,0,SWP_NOSIZE); return; } GetWindowRect (hwnd,&rect); GetWindowRect (Xhwnd,&rectP); width = rect.right-rect.left; x = ((rectP.right-rectP.left)-width)/2 + rectP.left; if (Yhwnd==NULL) { height = rect.bottom-rect.top; y = ((rectP.bottom-rectP.top)-height)/2 + rectP.top; } else { GetWindowRect(Yhwnd,&rectP); height = rect.bottom-rect.top; y = ((rectP.bottom-rectP.top)-height)/2+rectP.top; } screenwidth = GetSystemMetrics(SM_CXSCREEN); screenheight = GetSystemMetrics(SM_CYSCREEN); if ((x<0)) x=0; if ((y<0)) y=0; if ((x+width>screenwidth)) x = screenwidth-width; if ((y+height>screenheight)) y = screenheight-height; MoveWindow (hwnd, x, y, width, height, FALSE); } // create the windows form HWND BCX_Form(char *Caption, int X, int Y, int W, int H, int Style, int Exstyle) { HWND A; // assigne default style if none given if (!Style) { Style= WS_MINIMIZEBOX | WS_SIZEBOX | WS_CAPTION | WS_MAXIMIZEBOX | WS_POPUP | WS_SYSMENU; } A = CreateWindowEx(Exstyle,BCX_ClassName,Caption, Style, X*BCX_ScaleX, Y*BCX_ScaleY, (4+W)*BCX_ScaleX, (12+H)*BCX_ScaleY, NULL,(HMENU)NULL,BCX_hInstance,NULL); SendMessage(A,(UINT)WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT), (LPARAM)MAKELPARAM(FALSE,0)); return A; } // color, why not void BCX_Set_Form_Color (HWND hWnd, COLORREF Kolor) { HBRUSH hbr=CreateSolidBrush(Kolor); DeleteObject((HBRUSH)SetClassLong(hWnd,GCL_HBRBACKGROUND,(DWORD)hbr)); InvalidateRect (hWnd,NULL,TRUE); } // the details - corner coordinates,width,height,title void FormLoad (void) { Form1=BCX_Form("PostEdit Capture",0,0,197,170); SetClassLong(Form1,GCL_STYLE,GetClassLong(Form1,GCL_STYLE)|CS_DBLCLKS); BCX_Set_Form_Color(Form1,RGB(0,0,0)); // Now create the MCIWnd MCIFrame=MCIWndCreate(Form1,(HINSTANCE)ghInst,WS_CHILD|WS_VISIBLE|MCIWNDF_NOPLAYBAR|MCIWNDF_NOTIFYALL,""); AddMenu(Form1); Center(Form1); Show(Form1); //MessageBox (NULL , "Edit", "Avviso", MB_ICONEXCLAMATION | MB_OK); } int InitSaveFileName (void) { *szFile=0; *szFileTitle=0; OpenFileName.lStructSize=sizeof(OPENFILENAME); OpenFileName.hwndOwner=MCIFrame; OpenFileName.hInstance=(HINSTANCE)ghInst; OpenFileName.lpstrFilter = "Avi Files (*.BMP)\0*.bmp\0All Files(*.*)\0*.*\0\0"; OpenFileName.lpstrCustomFilter=NULL; OpenFileName.nMaxCustFilter=0; OpenFileName.nFilterIndex=0; OpenFileName.lpstrFile=szFile; OpenFileName.nMaxFile=MAX_PATH; OpenFileName.lpstrFileTitle=szFileTitle; OpenFileName.nMaxFileTitle=MAX_PATH; OpenFileName.lpstrInitialDir=curdir(); OpenFileName.lpstrTitle=NULL; OpenFileName.nFileOffset=0; OpenFileName.nFileExtension=0; OpenFileName.lpstrDefExt="*.bmp"; OpenFileName.lCustData=0L; OpenFileName.Flags=OFN_SHOWHELP|OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST|OFN_HIDEREADONLY; OpenFileName.lpfnHook=NULL; OpenFileName.lpTemplateName=NULL; return 0; } int PopFileSaveDlg (HWND Form1, char *szFileBmp, char *szFileTitleBmp) { OpenFileName.lpstrTitle="Save bitmap"; OpenFileName.hwndOwner=MCIFrame; OpenFileName.lpstrFile=szFileBmp; OpenFileName.lpstrFileTitle=szFileTitleBmp; OpenFileName.Flags=OFN_EXPLORER|OFN_CREATEPROMPT; return GetOpenFileNamePreview(&OpenFileName); } /* Funzione per scrivere l'handle di una bitmap su file Thanks to http://www.geocities.com/krishnapg/bitmap.html#SaveBitmap */ void SaveBitmap(char *szFilename,HBITMAP hBitmap){ HDC hdc=NULL; FILE* fp=NULL; LPVOID pBuf=NULL; BITMAPINFO bmpInfo; BITMAPFILEHEADER bmpFileHeader; do{ hdc=GetDC(NULL); ZeroMemory(&bmpInfo,sizeof(BITMAPINFO)); bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); GetDIBits(hdc,hBitmap,0,0,NULL,&bmpInfo,DIB_RGB_COLORS); if(bmpInfo.bmiHeader.biSizeImage<=0) bmpInfo.bmiHeader.biSizeImage=bmpInfo.bmiHeader.biWidth*abs(bmpInfo.bmiHeader.biHeight)*(bmpInfo.bmiHeader.biBitCount+7)/8; if((pBuf = malloc(bmpInfo.bmiHeader.biSizeImage))==NULL) { //MessageBox( NULL, "Unable to Allocate Bitmap Memory", "Error", MB_OK|MB_ICONERROR); break; } bmpInfo.bmiHeader.biCompression=BI_RGB; GetDIBits(hdc,hBitmap,0,bmpInfo.bmiHeader.biHeight,pBuf, &bmpInfo, DIB_RGB_COLORS); if((fp = fopen(szFilename,"wb"))==NULL) { //MessageBox( NULL, "Unable to Create Bitmap File", "Error", MB_OK|MB_ICONERROR); break; } bmpFileHeader.bfReserved1=0; bmpFileHeader.bfReserved2=0; bmpFileHeader.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+bmpInfo.bmiHeader.biSizeImage; bmpFileHeader.bfType='MB'; bmpFileHeader.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER); fwrite(&bmpFileHeader,sizeof(BITMAPFILEHEADER),1,fp); fwrite(&bmpInfo.bmiHeader,sizeof(BITMAPINFOHEADER),1,fp); fwrite(pBuf,bmpInfo.bmiHeader.biSizeImage,1,fp); }while(false); if(hdc) ReleaseDC(NULL,hdc); if(pBuf) free(pBuf); if(fp) fclose(fp); } // event message handler LRESULT CALLBACK WndProc (HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { static char s[2048]; memset(&s,0,sizeof(s)); static char mstr[2048]; memset(&mstr,0,sizeof(mstr)); static char mstr1[2048]; memset(&mstr1,0,sizeof(mstr1)); while(1) { if (Msg==WM_CREATE) { return 0; break; } if (Msg==WM_COMMAND) { if (LOWORD(wParam)==ID_MENU2) { MCIWndClose(MCIFrame); InitOpenFileName(); PopFileOpenDlg(Form1,szFile,szFileTitle); if(strlen(szFile)>0) { MCIWndOpen(MCIFrame,szFile,0); } return 0; } if(LOWORD(wParam)==ID_MENU3) { MCIWndClose(MCIFrame); ExitProcess(0); } //break; if(LOWORD(wParam)==ID_MENU4) { // Some steps: PAVIFILE aviFile; PAVISTREAM aviStream; AVISTREAMINFO aviStreamInfo; AVIFileInit(); AVIFileOpen(&aviFile,szFile,OF_READ,NULL); AVIFileGetStream(aviFile,&aviStream,streamtypeVIDEO,0); AVIFileRelease(aviFile); AVIStreamInfo(aviStream,&aviStreamInfo,sizeof(aviStreamInfo)); // OK! Now we can extract any frame from AVI stream! BITMAPFILEHEADER BMPFileHeader; LPBITMAPINFOHEADER lpbi; PGETFRAME pgf; pgf=AVIStreamGetFrameOpen(aviStream,NULL); LONG lFrame; lFrame = MCIWndGetPosition(MCIFrame); lpbi=(LPBITMAPINFOHEADER)AVIStreamGetFrame(pgf,lFrame); BMPFileHeader.bfType=0x4d42; BMPFileHeader.bfSize=(DWORD)(sizeof(BITMAPFILEHEADER)+lpbi->biSize+ lpbi->biClrUsed*sizeof(RGBQUAD)+lpbi->biSizeImage); BMPFileHeader.bfReserved1=0; BMPFileHeader.bfReserved2=0; BMPFileHeader.bfOffBits=(DWORD)sizeof(BITMAPFILEHEADER)+lpbi->biSize+ lpbi->biClrUsed*sizeof(RGBQUAD); // Than create file to save frame and write BMP sections into it! // WriteFile(hFile,(LPVOID)&BMPFileHeader,sizeof(BITMAPFILEHEADER), // (LPDWORD)&lpNumberOfBytesWritten,NULL); // WriteFile(hFile,(LPVOID)lpbi,sizeof(BITMAPFILEHEADER)+lpbi->biSize+ // lpbi->biClrUsed*sizeof(RGBQUAD)+lpbi->biSizeImage, // (LPDWORD)&lpNumberOfBytesWritten,NULL); InitSaveFileName(); PopFileSaveDlg(Form1,szFileBmp,szFileTitleBmp); ofstream fout(szFileBmp, ios::binary); BITMAPFILEHEADER bfh; fout.write((const char *)&BMPFileHeader,sizeof(BITMAPFILEHEADER)); fout.write((const char *)lpbi,sizeof(BITMAPFILEHEADER)+lpbi->biSize+ lpbi->biClrUsed*sizeof(RGBQUAD)+lpbi->biSizeImage); //fout.write((char *)lpbuff,len); fout.close(); // And in the end make some clean! AVIStreamGetFrameClose(pgf); // We can save one more frame or finish or work. AVIFileExit(); } if(LOWORD(wParam)==ID_MENU5) { HDC hDc = CreateCompatibleDC(0); RECT rcWind; GetClientRect(MCIFrame, &rcWind); int width = rcWind.right - rcWind.left; int height = rcWind.bottom - rcWind.top; HBITMAP hBmp = CreateCompatibleBitmap(GetDC(MCIFrame), width, height); // join em up SelectObject(hDc, hBmp); // copy from the screen to my bitmap BitBlt(hDc, 0, 0, width, height, GetDC(MCIFrame), 0, 0, SRCCOPY); // save my bitmap InitSaveFileName(); PopFileSaveDlg(Form1,szFileBmpC,szFileTitleBmpC); SaveBitmap(szFileBmpC,hBmp); DeleteObject(hBmp); } break; } if (Msg==MCIWNDM_NOTIFYMODE) { while(1) { if ((long)lParam==MCI_MODE_NOT_READY) { SetWindowText(Form1,"Not Ready"); break; } if ((long)lParam==MCI_MODE_PAUSE) { SetWindowText(Form1,"Paused"); break; } if ((long)lParam==MCI_MODE_PLAY) { SetWindowText(Form1,"Playing"); break; } if ((long)lParam==MCI_MODE_STOP) { SetWindowText(Form1,"Stopped"); break; } if ((long)lParam==MCI_MODE_OPEN) { SetWindowText(Form1,"Opening"); break; } if ((long)lParam==MCI_MODE_RECORD) { SetWindowText(Form1,"Recording"); break; } if ((long)lParam==MCI_MODE_SEEK) { SetWindowText(Form1,"Seeking"); } break; } break; } if (Msg==MCIWNDM_NOTIFYMEDIA) { SetWindowText(Form1,(LPSTR)lParam); break; } if (Msg==MCIWNDM_NOTIFYPOS) { SetWindowText(Form1,str(MCIWndGetPosition(MCIFrame))); break; } if (Msg==MCIWNDM_NOTIFYERROR) { SetWindowText(Form1,"MCI ERROR"); break; } if (Msg==WM_PAINT) { // The VideoWindow is restricted to a ratio of 4:3 here break; } if (Msg==WM_SIZE) { static WORD Basedsp; memset(&Basedsp,0,sizeof(Basedsp)); static WORD Cntr; memset(&Cntr,0,sizeof(Cntr)); Basedsp=(HIWORD(lParam)-20)/3; Cntr=(LOWORD(lParam)-(Basedsp*4))/2; // MoveWindow(MCIFrame,Cntr,0,(Basedsp*4),HIWORD(lParam),TRUE); // Don't forget to close opened Files break; } if (Msg==WM_CLOSE) { MCIWndClose(MCIFrame); DestroyWindow(Form1); return 0; break; } if (Msg==WM_DESTROY) { MCIWndClose(MCIFrame); PostQuitMessage(0); return 0; } break; } // tidy up and exit program if (Msg==WM_DESTROY) { UnregisterClass(BCX_ClassName,BCX_hInstance); PostQuitMessage(0); } return DefWindowProc(hWnd,Msg,wParam,lParam); } // tons of options for the neat file dialog box int InitOpenFileName (void) { *szFile=0; *szFileTitle=0; OpenFileName.lStructSize=sizeof(OPENFILENAME); OpenFileName.hwndOwner=MCIFrame; OpenFileName.hInstance=(HINSTANCE)ghInst; OpenFileName.lpstrFilter = "Avi Files (*.AVI)\0*.avi\0All Files(*.*)\0*.*\0\0"; OpenFileName.lpstrCustomFilter=NULL; OpenFileName.nMaxCustFilter=0; OpenFileName.nFilterIndex=0; OpenFileName.lpstrFile=szFile; OpenFileName.nMaxFile=MAX_PATH; OpenFileName.lpstrFileTitle=szFileTitle; OpenFileName.nMaxFileTitle=MAX_PATH; OpenFileName.lpstrInitialDir=curdir(); OpenFileName.lpstrTitle=NULL; OpenFileName.nFileOffset=0; OpenFileName.nFileExtension=0; OpenFileName.lpstrDefExt="*.avi"; OpenFileName.lCustData=0L; OpenFileName.Flags=OFN_SHOWHELP|OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST|OFN_HIDEREADONLY; OpenFileName.lpfnHook=NULL; OpenFileName.lpTemplateName=NULL; return 0; } int PopFileOpenDlg (HWND Form1, char *szFile, char *szFileTitle) { OpenFileName.lpstrTitle="Open File"; OpenFileName.hwndOwner=MCIFrame; OpenFileName.lpstrFile=szFile; OpenFileName.lpstrFileTitle=szFileTitle; OpenFileName.Flags=OFN_EXPLORER|OFN_CREATEPROMPT; return GetOpenFileNamePreview(&OpenFileName); } BOOL AddMenu (HWND hwndOwner) { MainMenu=CreateMenu(); FileMenu=CreateMenu(); InsertMenu(MainMenu,0,MF_POPUP,(UINT)FileMenu,"&File"); AppendMenu(FileMenu,MF_STRING,ID_MENU2,"&Open"); AppendMenu(FileMenu,MF_STRING,ID_MENU3,"&Exit"); AppendMenu(FileMenu,MF_STRING,ID_MENU4,"&Save bmp"); AppendMenu(FileMenu,MF_STRING,ID_MENU5,"&Save capture"); // activate the menu if (!SetMenu(hwndOwner,MainMenu)) { return FALSE; } return TRUE; } // ************* credit to a true genius Kevin ***************** // Created with BCX -- The BASIC To C Translator (ver 5.02) // BCX (c) 1999, 2000, 2001, 2002, 2003, 2004 by Kevin Diggins // *************************************************************