/****************************************************************************** * CAVI: Creates AVI video from static bitmap images * * >>VERY<< as-is program by Mark Gamber * * Portions from Microsoft Corp. * ******************************************************************************/ #include "windows.h" #include "vfw.h" #include "commctrl.h" // === Function Prototypes ==================================================== BOOL WINAPI MainDlgProc( HWND, UINT, WPARAM, LPARAM ); BOOL WINAPI AboutDlgProc( HWND, UINT, WPARAM, LPARAM ); BOOL WINAPI PlayDlgProc( HWND, UINT, WPARAM, LPARAM ); BOOL AddFile( HWND, BOOL ); BOOL RemoveFile( HWND ); BOOL SaveAVI( HWND ); HANDLE MakeDib( HBITMAP, UINT ); BOOL ResizeControls( HWND, LPARAM ); // === Global Variables ======================================================= HINSTANCE hInst; HWND hMainWnd; // === Application Entry Point ================================================ int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrev, LPSTR lpCmd, int nShow ) { WNDCLASS wc; hInst = hInstance; if( ! GetClassInfo( NULL, WC_DIALOG, &wc ) ) return( FALSE ); wc.lpszClassName = "CAVI32"; wc.hInstance = hInstance; wc.hIcon = LoadIcon( NULL, IDI_APPLICATION ); wc.cbWndExtra = DLGWINDOWEXTRA; wc.lpfnWndProc = DefDlgProc; if( ! RegisterClass( &wc ) ) return( FALSE ); DialogBox( hInstance, MAKEINTRESOURCE( 10000 ), NULL, MainDlgProc ); return( FALSE ); } // === Main Window (Dialog Box) =============================================== BOOL WINAPI MainDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam ) { switch( msg ) { case WM_INITDIALOG: { HWND hAni; POINT pt; RECT Rect; InitCommonControls(); // Initialize control DLL GetWindowRect( GetDlgItem( hDlg, 1000 ), &Rect ); DestroyWindow( GetDlgItem( hDlg, 1000 ) ); pt.x = Rect.left; pt.y = Rect.top; ScreenToClient( hDlg, &pt ); hAni = Animate_Create( hDlg, 1000, WS_CHILD | WS_VISIBLE | ACS_CENTER | ACS_TRANSPARENT, hInst ); if( hAni ) { // Give it the AVI in this app's resources Animate_Open( hAni, "CUSTAVI" ); Animate_Play( hAni, 0, -1, -1 ); SetWindowPos( hAni, NULL, pt.x, pt.y, 32, 32, SWP_NOZORDER ); } SetDlgItemText( hDlg, 105, "2" ); // Init to 2 frames per second return( TRUE ); } case WM_SIZE: return( ResizeControls( hDlg, lParam ) ); case WM_COMMAND: if( wParam == IDCANCEL ) // Exit dialog box { EndDialog( hDlg, TRUE ); return( TRUE ); } if( wParam == 100 ) return( AddFile( hDlg, FALSE ) ); // Add a bitmap if( wParam == 101 ) return( AddFile( hDlg, TRUE ) ); // Insert a bitmap if( wParam == 102 ) return( RemoveFile( hDlg ) ); // Remove a bitmap if( wParam == 103 ) return( SaveAVI( hDlg ) ); // Save to AVI file if( wParam == 104 ) // Display About box return( DialogBox( hInst, MAKEINTRESOURCE( 10001 ), hDlg, AboutDlgProc ) ); if( wParam == 107 ) // Play an AVI file return( DialogBox( hInst, MAKEINTRESOURCE( 10002 ), hDlg, PlayDlgProc ) ); break; } return( FALSE ); } // End of MainDlgProc() // ============================================================================ BOOL ResizeControls( HWND hDlg, LPARAM lParam ) { RECT Rect; HDWP hDwp; int iSize; POINT pt; hDwp = BeginDeferWindowPos( 7 ); GetWindowRect( GetDlgItem( hDlg, 100 ), &Rect ); iSize = LOWORD( lParam ) / 6; DeferWindowPos( hDwp, GetDlgItem( hDlg, 100 ), NULL, 0, 0, iSize, Rect.bottom - Rect.top, SWP_NOZORDER ); DeferWindowPos( hDwp, GetDlgItem( hDlg, 101 ), NULL, iSize, 0, iSize, Rect.bottom - Rect.top, SWP_NOZORDER ); DeferWindowPos( hDwp, GetDlgItem( hDlg, 102 ), NULL, iSize * 2, 0, iSize, Rect.bottom - Rect.top, SWP_NOZORDER ); DeferWindowPos( hDwp, GetDlgItem( hDlg, 107 ), NULL, iSize * 3, 0, iSize, Rect.bottom - Rect.top, SWP_NOZORDER ); DeferWindowPos( hDwp, GetDlgItem( hDlg, 103 ), NULL, iSize * 4, 0, iSize, Rect.bottom - Rect.top, SWP_NOZORDER ); DeferWindowPos( hDwp, GetDlgItem( hDlg, 104 ), NULL, iSize * 5, 0, iSize, Rect.bottom - Rect.top, SWP_NOZORDER ); GetWindowRect( GetDlgItem( hDlg, 106 ), &Rect ); pt.x = Rect.left; pt.y = Rect.top; ScreenToClient( hDlg, &pt ); DeferWindowPos( hDwp, GetDlgItem( hDlg, 106 ), NULL, 0, 0, LOWORD( lParam ) - ( pt.x * 2 ), HIWORD( lParam ) - pt.y - pt.x, SWP_NOZORDER | SWP_NOMOVE ); EndDeferWindowPos( hDwp ); return( TRUE ); } // === Add Bitmap File to Listing ============================================= BOOL AddFile( HWND hDlg, BOOL bInsert ) { OPENFILENAME ofn; char szFile[ 300 ]; int iItem; if( bInsert ) // If inserting, we need a current selection { iItem = SendDlgItemMessage( hDlg, 106, LB_GETCURSEL, 0, 0 ); if( iItem == LB_ERR ) // Exit if no selection available return( FALSE ); } lstrcpy( szFile, "*.bmp" ); // Look for bitmaps memset( &ofn, 0, sizeof(OPENFILENAME) ); ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = hDlg; ofn.lpstrFilter = "Bitmaps\0*.bmp\0All Files\0*.*\0\0"; ofn.lpstrFile = szFile; ofn.nMaxFile = 300; ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; if( ! GetOpenFileName( &ofn ) ) // Get a filename from the user return( FALSE ); if( ! bInsert ) // Add or insert into the listbox iItem = SendDlgItemMessage( hDlg, 106, LB_ADDSTRING, 0, (LPARAM)szFile ); else iItem = SendDlgItemMessage( hDlg, 106, LB_INSERTSTRING, iItem, (LPARAM)szFile ); if( iItem != LB_ERR ) // Make new bitmap current selection { SendDlgItemMessage( hDlg, 106, LB_SETCURSEL, iItem, 0 ); return( TRUE ); } return( FALSE ); } // End of AddFile() // === Remove Listed Bitmap File ============================================== BOOL RemoveFile( HWND hDlg ) { int iItem; // Get current selection to remove iItem = SendDlgItemMessage( hDlg, 106, LB_GETCURSEL, 0, 0 ); if( iItem == LB_ERR ) return( FALSE ); // Quit if no selection // Otherwise, remove it SendDlgItemMessage( hDlg, 106, LB_DELETESTRING, iItem, 0 ); return( TRUE ); } // End of RemoveFile() // === Save Bitmaps to AVI File =============================================== BOOL SaveAVI( HWND hDlg ) { LPBITMAPINFOHEADER lpBih[ 64 ]; int iCount, i, iRate, junk; HANDLE hBmp, hDib; char szFile[ 300 ], szOutput[ 300 ]; HRESULT hResult; PAVIFILE pfile; AVISTREAMINFO asi; PAVISTREAM ps; OPENFILENAME ofn; // How many bitmaps are there? iCount = SendDlgItemMessage( hDlg, 106, LB_GETCOUNT, 0, 0 ); if( ! iCount ) return( FALSE ); // None? What are we doing here then? // Get playback rates iRate = GetDlgItemInt( hDlg, 105, &junk, TRUE ); if( ! iRate ) // Zero sure looks invalid return( FALSE ); memset( &ofn, 0, sizeof(OPENFILENAME) ); lstrcpy( szOutput, "*.avi" ); // Prepare to get output filename ofn.lStructSize = sizeof(OPENFILENAME); ofn.lpstrFile = szOutput; ofn.nMaxFile = 300; ofn.lpstrFilter = "AVI Video\0*.avi\0All Files\0*.*\0\0"; ofn.hwndOwner = hDlg; ofn.Flags = OFN_HIDEREADONLY; if( ! GetSaveFileName( &ofn ) ) return( FALSE ); // If cancelled, exit // Max of 64 bitmaps memset( lpBih, 0, sizeof(LPBITMAPINFOHEADER) * 64 ); for( i = 0; i < iCount; i++ ) { // Load each image listed in listbox SendDlgItemMessage( hDlg, 106, LB_GETTEXT, i, (LPARAM)szFile ); hBmp = LoadImage( NULL, szFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_DEFAULTCOLOR | LR_LOADTRANSPARENT ); if( hBmp ) { hDib = MakeDib( hBmp, 8 ); // Turn image into 8 bit DIB if( hDib ) // Save DIB info in array lpBih[ i ] = (LPBITMAPINFOHEADER)GlobalLock( hDib ); } } AVIFileInit(); // Initialize AVI pfile = NULL; ps = NULL; // Open the output file hResult = AVIFileOpen( &pfile, szOutput, OF_WRITE | OF_CREATE, NULL ); if( hResult == AVIERR_OK ) { memset( &asi, 0, sizeof(AVISTREAMINFO) ); // Hey, it opened! asi.fccType = streamtypeVIDEO; // Now prepare the stream asi.fccHandler = 0; asi.dwScale = 1; asi.dwRate = iRate; asi.dwSuggestedBufferSize = lpBih[ 0 ]->biSizeImage; SetRect( &asi.rcFrame, 0, 0, (int)lpBih[ 0 ]->biWidth, (int)lpBih[ 0 ]->biHeight ); hResult = AVIFileCreateStream( pfile, &ps, &asi ); if( hResult == AVIERR_OK ) { hResult = AVIStreamSetFormat( ps, 0, lpBih[ 0 ], lpBih[ 0 ]->biSize + ( lpBih[ 0 ]->biClrUsed * sizeof(RGBQUAD) ) ); if( hResult == AVIERR_OK ) { for( i = 0; i < iCount; i++ ) { // Now write out all the bitmaps hResult = AVIStreamWrite( ps, i, 1, (LPBYTE)lpBih[ i ] + lpBih[ i ]->biSize + ( lpBih[ i ]->biClrUsed * sizeof(RGBQUAD) ), lpBih[ i ]->biSizeImage, AVIIF_KEYFRAME, NULL, NULL ); if( hResult != AVIERR_OK ) break; } } } } if( ps ) AVIStreamClose( ps ); if( pfile ) AVIFileClose( pfile ); AVIFileExit(); // Close down AVI from here for( i = 0; i < iCount; i++ ) { if( lpBih[ i ] ) // Loop through and clean out all bitmaps { hDib = GlobalHandle( lpBih[ i ] ); GlobalUnlock( hDib ); GlobalFree( hDib ); } else break; } return( TRUE ); } // === Turn Bitmap into DIB for AVI Output ==================================== HANDLE MakeDib( HBITMAP hbitmap, UINT bits ) { HANDLE hdib; HDC hdc; BITMAP bitmap; UINT wLineLen; DWORD dwSize; DWORD wColSize; LPBITMAPINFOHEADER lpbi; LPBYTE lpBits; GetObject( hbitmap, sizeof( BITMAP ), &bitmap ); wLineLen = ( bitmap.bmWidth * bits + 31 ) / 32 * 4; wColSize = sizeof(RGBQUAD) * ( ( bits <= 8 ) ? 1 << bits : 0 ); dwSize = sizeof( BITMAPINFOHEADER ) + wColSize + (DWORD)(UINT)wLineLen * (DWORD)(UINT)bitmap.bmHeight; hdib = GlobalAlloc( GHND, dwSize ); if( ! hdib ) return( hdib ); lpbi = (LPBITMAPINFOHEADER)GlobalLock( hdib ); lpbi->biSize = sizeof(BITMAPINFOHEADER); lpbi->biWidth = bitmap.bmWidth; lpbi->biHeight = bitmap.bmHeight; lpbi->biPlanes = 1; lpbi->biBitCount = (WORD)bits; lpbi->biCompression = BI_RGB; lpbi->biSizeImage = dwSize - sizeof(BITMAPINFOHEADER) - wColSize; lpbi->biXPelsPerMeter = 0; lpbi->biYPelsPerMeter = 0; lpbi->biClrUsed = ( bits <= 8 ) ? 1 << bits : 0; lpbi->biClrImportant = 0; lpBits = (LPBYTE)( lpbi + 1 )+ wColSize; hdc = CreateCompatibleDC( NULL ); GetDIBits( hdc, hbitmap, 0, bitmap.bmHeight, lpBits, (LPBITMAPINFO)lpbi, DIB_RGB_COLORS ); lpbi->biClrUsed = ( bits <= 8 ) ? 1 << bits : 0; DeleteDC( hdc ); return( hdib ); } // ============================================================================ BOOL WINAPI AboutDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam ) { switch( msg ) { case WM_INITDIALOG: return( TRUE ); case WM_COMMAND: if( wParam == IDCANCEL ) EndDialog( hDlg, TRUE ); break; } return( FALSE ); } // ============================================================================ BOOL WINAPI PlayDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam ) { switch( msg ) { case WM_INITDIALOG: { char szFile[ 300 ]; OPENFILENAME ofn; HWND hCtrl; RECT Rect; lstrcpy( szFile, "*.avi" ); memset( &ofn, 0, sizeof(OPENFILENAME) ); ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = hDlg; ofn.lpstrFilter = "AVI Files\0*.avi\0All Files\0*.*\0\0"; ofn.lpstrFile = szFile; ofn.nMaxFile = 300; ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; if( ! GetOpenFileName( &ofn ) ) { EndDialog( hDlg, TRUE ); return( TRUE ); } hCtrl = MCIWndCreate( hDlg, hInst, MCIWNDF_NOPLAYBAR, szFile ); if( ! hCtrl ) { EndDialog( hDlg, TRUE ); return( TRUE ); } GetClientRect( hDlg, &Rect ); SetWindowPos( hCtrl, NULL, 0, 0, Rect.right, Rect.bottom - 30, SWP_NOMOVE | SWP_NOZORDER ); SetProp( hDlg, "AVIWND", hCtrl ); MCIWndHome( hCtrl ); return( TRUE ); } case WM_SIZE: SetWindowPos( GetProp( hDlg, "AVIWND" ), NULL, 0, 0, LOWORD( lParam ) - 2, HIWORD( lParam ) - 30, SWP_NOMOVE | SWP_NOZORDER ); break; case WM_COMMAND: if( wParam == IDCANCEL ) { MCIWndDestroy( GetProp( hDlg, "AVIWND" ) ); RemoveProp( hDlg, "AVIWND" ); EndDialog( hDlg, TRUE ); } if( wParam == IDOK ) { MCIWndHome( GetProp( hDlg, "AVIWND" ) ); MCIWndPlay( GetProp( hDlg, "AVIWND" ) ); MCIWndSetRepeat( GetProp( hDlg, "AVIWND" ), -1 ); break; } break; } return( FALSE ); } // ============================================================================