/* *************************************************************** * video.c * * Copyright (C) Microsoft, 1990, All Rights Reserved. * * Displays the Simple media properties * * History: * * July 1994 -by- VijR (Created) * *************************************************************** */ #include "mmcpl.h" #include #ifdef DEBUG #undef DEBUG #include #define DEBUG #else #include #endif #include #include #include "utils.h" #include "medhelp.h" #include "..\..\..\media\avi\inc\profile.key" // For ROOTKEY and KEYNAME etc /* *************************************************************** * Defines *************************************************************** */ // // !!! These actually live in mciavi\graphic.h // !!! If MCIAVI changes these, we're hosed! // #define MCIAVIO_ZOOMBY2 0x00000100 #define MCIAVIO_USEVGABYDEFAULT 0x00000200 #define MCIAVIO_1QSCREENSIZE 0x00010000 #define MCIAVIO_2QSCREENSIZE 0x00020000 #define MCIAVIO_3QSCREENSIZE 0x00040000 #define MCIAVIO_MAXWINDOWSIZE 0x00080000 #define MCIAVIO_DEFWINDOWSIZE 0x00000000 #define MCIAVIO_WINDOWSIZEMASK 0x000f0000 // This bit is set in dwOptions if f16BitCompat, but doesn't get written back // directly into the registry's version of that DWORD. // #define MCIAVIO_F16BITCOMPAT 0x00000001 /* *************************************************************** * File Globals *************************************************************** */ static SZCODE aszMCIAVIOpt[] = "Software\\Microsoft\\Multimedia\\Video For Windows\\MCIAVI"; static SZCODE aszDefVideoOpt[] = "DefaultOptions"; static SZCODE aszReject[] = "RejectWOWOpenCalls"; static SZCODE aszRejectSection[] = "MCIAVI"; HBITMAP g_hbmMonitor = NULL; // monitor bitmap (original) HBITMAP g_hbmScrSample = NULL; // bitmap used for IDC_SCREENSAMPLE HBITMAP g_hbmDefault = NULL; HDC g_hdcMem = NULL; /* *************************************************************** * Prototypes *************************************************************** */ BOOL PASCAL DoVideoCommand(HWND hDlg, int id, HWND hwndCtl, UINT codeNotify); /* *************************************************************** *************************************************************** */ // mmGetProfileInt/mmWriteProfileInt snitched from MCIAVI32 UINT mmGetProfileInt(LPCTSTR appname, LPCTSTR valuename, INT uDefault) { TCHAR achName[MAX_PATH]; HKEY hkey; DWORD dwType; INT value = uDefault; DWORD dwData; int cbData; lstrcpy(achName, KEYNAME); lstrcat(achName, appname); if (RegOpenKey(ROOTKEY, achName, &hkey) == ERROR_SUCCESS) { cbData = sizeof(dwData); if (RegQueryValueEx( hkey, (LPTSTR)valuename, NULL, &dwType, (PBYTE) &dwData, &cbData) == ERROR_SUCCESS) { if (dwType == REG_DWORD) { value = (INT)dwData; } } RegCloseKey(hkey); } return((UINT)value); } /* * write a UINT to the profile, if it is not the * same as the default or the value already there */ VOID mmWriteProfileInt(LPCTSTR appname, LPCTSTR valuename, INT Value) { // If we would write the same as already there... return. if (mmGetProfileInt(appname, valuename, !Value) == (UINT)Value) { return; } { TCHAR achName[MAX_PATH]; HKEY hkey; lstrcpy(achName, KEYNAME); lstrcat(achName, appname); if (RegCreateKey(ROOTKEY, achName, &hkey) == ERROR_SUCCESS) { RegSetValueEx( hkey, valuename, 0, REG_DWORD, (PBYTE) &Value, sizeof(Value) ); RegCloseKey(hkey); } } } /* *************************************************************** *************************************************************** */ STATIC void WriteVideoOptions(DWORD dwOpt) { HKEY hkVideoOpt; BOOL f16BitCompat; f16BitCompat = (dwOpt & MCIAVIO_F16BITCOMPAT) ? TRUE : FALSE; dwOpt &= ~MCIAVIO_F16BITCOMPAT; if(RegCreateKeyEx( HKEY_CURRENT_USER, (LPSTR)aszMCIAVIOpt, 0, NULL, 0,KEY_WRITE | KEY_READ, NULL, &hkVideoOpt, NULL )) return; RegSetValueEx( hkVideoOpt, (LPSTR)aszDefVideoOpt, 0, REG_DWORD,(LPBYTE)&dwOpt, sizeof(DWORD) ); mmWriteProfileInt (aszRejectSection, aszReject, (int)f16BitCompat); } STATIC DWORD ReadVideoOptions(void) { HKEY hkVideoOpt; DWORD dwType; DWORD dwOpt; DWORD cbSize; if(RegCreateKeyEx( HKEY_CURRENT_USER, (LPSTR)aszMCIAVIOpt, 0, NULL, 0,KEY_WRITE | KEY_READ, NULL, &hkVideoOpt, NULL )) return 0 ; cbSize = sizeof(DWORD); if (RegQueryValueEx( hkVideoOpt,(LPSTR)aszDefVideoOpt,NULL,&dwType,(LPBYTE)&dwOpt,&cbSize )) { dwOpt = 0; RegSetValueEx( hkVideoOpt, (LPSTR)aszDefVideoOpt, 0, REG_DWORD,(LPBYTE)&dwOpt, sizeof(DWORD) ); } if (mmGetProfileInt (aszRejectSection, aszReject, 0)) { dwOpt |= MCIAVIO_F16BITCOMPAT; } return dwOpt; } STATIC void FillWindowSizeCB(DWORD dwOptions, HWND hCBWinSize) { char sz1QScreenSize[64]; char sz2QScreenSize[64]; char sz3QScreenSize[64]; char szMaxSize[64]; char szOriginalSize[64]; char szZoomedSize[64]; int iIndex; LPSTR lpszCurDefSize; LoadString(ghInstance, IDS_NORMALSIZE, szOriginalSize, sizeof(szOriginalSize)); LoadString(ghInstance, IDS_ZOOMEDSIZE, szZoomedSize, sizeof(szZoomedSize)); LoadString(ghInstance, IDS_1QSCREENSIZE, sz1QScreenSize, sizeof(sz1QScreenSize)); LoadString(ghInstance, IDS_2QSCREENSIZE, sz2QScreenSize, sizeof(sz2QScreenSize)); LoadString(ghInstance, IDS_3QSCREENSIZE, sz3QScreenSize, sizeof(sz3QScreenSize)); LoadString(ghInstance, IDS_VIDEOMAXIMIZED, szMaxSize, sizeof(szMaxSize)); iIndex = ComboBox_AddString(hCBWinSize, szOriginalSize); ComboBox_SetItemData(hCBWinSize, iIndex, (LPARAM)MCIAVIO_DEFWINDOWSIZE); iIndex = ComboBox_AddString(hCBWinSize, szZoomedSize); ComboBox_SetItemData(hCBWinSize, iIndex, (LPARAM)MCIAVIO_ZOOMBY2); iIndex = ComboBox_AddString(hCBWinSize, sz1QScreenSize); ComboBox_SetItemData(hCBWinSize, iIndex, (LPARAM)MCIAVIO_1QSCREENSIZE); iIndex = ComboBox_AddString(hCBWinSize, sz2QScreenSize); ComboBox_SetItemData(hCBWinSize, iIndex, (LPARAM)MCIAVIO_2QSCREENSIZE); iIndex = ComboBox_AddString(hCBWinSize, sz3QScreenSize); ComboBox_SetItemData(hCBWinSize, iIndex, (LPARAM)MCIAVIO_3QSCREENSIZE); iIndex = ComboBox_AddString(hCBWinSize, szMaxSize); ComboBox_SetItemData(hCBWinSize, iIndex, (LPARAM)MCIAVIO_MAXWINDOWSIZE); switch(dwOptions & MCIAVIO_WINDOWSIZEMASK) { case MCIAVIO_DEFWINDOWSIZE: if (dwOptions & MCIAVIO_ZOOMBY2) lpszCurDefSize = szZoomedSize; else lpszCurDefSize = szOriginalSize; break; case MCIAVIO_1QSCREENSIZE: lpszCurDefSize = sz1QScreenSize; break; case MCIAVIO_2QSCREENSIZE: lpszCurDefSize = sz2QScreenSize; break; case MCIAVIO_3QSCREENSIZE: lpszCurDefSize = sz3QScreenSize; break; case MCIAVIO_MAXWINDOWSIZE: lpszCurDefSize = szMaxSize; break; } ComboBox_SelectString(hCBWinSize, 0, lpszCurDefSize); } /*--------------------------------------------------------- ** **---------------------------------------------------------*/ // information about the monitor bitmap // x, y, dx, dy define the size of the "screen" part of the bitmap // the RGB is the color of the screen's desktop // these numbers are VERY hard-coded to a monitor bitmap #define MON_X 16 #define MON_Y 17 #define MON_DX 152 #define MON_DY 112 #define MON_IMAGE_X (MON_X + 46) #define MON_IMAGE_Y (MON_Y + 33) #define MON_IMAGE_DX 59 #define MON_IMAGE_DY 44 #define MON_TITLE 10 #define MON_BORDER 2 #define MON_TRAY 8 STATIC HBITMAP FAR LoadMonitorBitmap( BOOL bFillDesktop ) { HBITMAP hbm,hbmT; BITMAP bm; HBRUSH hbrT; HDC hdc; COLORREF c3df = GetSysColor( COLOR_3DFACE ); hbm = LoadBitmap(ghInstance, MAKEINTRESOURCE(IDB_MONITOR)); if (hbm == NULL) { Assert(0); return NULL; } // // convert the "base" of the monitor to the right color. // // the lower left of the bitmap has a transparent color // we fixup using FloodFill // hdc = CreateCompatibleDC(NULL); hbmT = SelectObject(hdc, hbm); hbrT = SelectObject(hdc, GetSysColorBrush(COLOR_3DFACE)); GetObject(hbm, sizeof(bm), &bm); ExtFloodFill(hdc, 0, bm.bmHeight-1, GetPixel(hdc, 0, bm.bmHeight-1), FLOODFILLSURFACE); // round off the corners // the bottom two were done by the floodfill above // the top left is important since SS_CENTERIMAGE uses it to fill gaps // the top right should be rounded because the other three are SetPixel( hdc, 0, 0, c3df ); SetPixel( hdc, bm.bmWidth-1, 0, c3df ); // unless the caller would like to do it, we fill in the desktop here if( bFillDesktop ) { SelectObject(hdc, GetSysColorBrush(COLOR_DESKTOP)); ExtFloodFill(hdc, MON_X+1, MON_Y+1, GetPixel(hdc, MON_X+1, MON_Y+1), FLOODFILLSURFACE); } // clean up after ourselves SelectObject(hdc, hbrT); SelectObject(hdc, hbmT); DeleteDC(hdc); return hbm; } /*------------------------pixel resolution--------------------------- ** ** show the sample screen with proper sizing */ STATIC void NEAR PASCAL ShowSampleScreen(HWND hDlg, int iMCIWindowSize) { HBITMAP hbmOld; HBRUSH hbr; HDC hdcMem2; SIZE dSrc = {MON_IMAGE_DX, MON_IMAGE_DY}; POINT ptSrc = {MON_IMAGE_X, MON_IMAGE_Y}; SIZE dDst; POINT ptDst; RECT rcImage = {MON_IMAGE_X, MON_IMAGE_Y, MON_IMAGE_X + MON_IMAGE_DX, MON_IMAGE_Y + MON_IMAGE_DY}; if (!g_hbmMonitor || !g_hbmScrSample) return; switch(iMCIWindowSize) { case MCIAVIO_DEFWINDOWSIZE: dDst = dSrc; ptDst = ptSrc; break; case MCIAVIO_ZOOMBY2: dDst.cx = 2 * dSrc.cx; dDst.cy = 2 * dSrc.cy; ptDst.x = ptSrc.x - (int)(dSrc.cx/2); ptDst.y = ptSrc.y - (int)(dSrc.cy/2); break; case MCIAVIO_MAXWINDOWSIZE: ptDst.x = MON_X; ptDst.y = MON_Y; dDst.cx = MON_DX; dDst.cy = MON_DY - MON_TRAY; break; case MCIAVIO_1QSCREENSIZE: dDst.cx = MulDiv(MON_DX, 1, 4); dDst.cy = MulDiv(MON_DY, 1, 4); ptDst.x = MON_X + MulDiv((MON_DX - dDst.cx), 1 , 2); ptDst.y = MON_Y + MulDiv((MON_DY - dDst.cy - MON_TRAY), 1 , 2); break; case MCIAVIO_2QSCREENSIZE: dDst.cx = MulDiv(MON_DX, 1, 2); dDst.cy = MulDiv(MON_DY, 1, 2); ptDst.x = MON_X + MulDiv((MON_DX - dDst.cx), 1 , 2); ptDst.y = MON_Y + MulDiv((MON_DY - dDst.cy - MON_TRAY), 1 , 2); break; case MCIAVIO_3QSCREENSIZE: dDst.cx = MulDiv(MON_DX, 3, 4); dDst.cy = MulDiv(MON_DY, 3, 4); ptDst.x = MON_X + MulDiv((MON_DX - dDst.cx), 1 , 2); ptDst.y = MON_Y + MulDiv((MON_DY - dDst.cy - MON_TRAY), 1 , 2); break; case MCIAVIO_USEVGABYDEFAULT: dDst.cx = MON_DX; dDst.cy = MON_DY; ptDst.x = MON_X; ptDst.y = MON_Y; dSrc.cx = MON_IMAGE_DX - (2 * MON_BORDER); dSrc.cy = MON_IMAGE_DY - MON_TITLE - MON_BORDER; ptSrc.x = MON_IMAGE_X + MON_BORDER; ptSrc.y = MON_IMAGE_Y + MON_TITLE + MON_BORDER; break; } // set up a work area to play in hdcMem2 = CreateCompatibleDC(g_hdcMem); if (!hdcMem2) return; SelectObject(hdcMem2, g_hbmScrSample); hbmOld = SelectObject(g_hdcMem, g_hbmMonitor); //copy the whole bmp first and then start stretching BitBlt(hdcMem2, MON_X, MON_Y, MON_DX, MON_DY, g_hdcMem, MON_X, MON_Y, SRCCOPY); //Wipe out the existing Image hbr = CreateSolidBrush( GetPixel( g_hdcMem, MON_X + 1, MON_Y + 1 ) ); FillRect(hdcMem2, &rcImage, hbr); DeleteObject( hbr ); // stretch the image to reflect the new size SetStretchBltMode( hdcMem2, COLORONCOLOR ); StretchBlt( hdcMem2, ptDst.x, ptDst.y, dDst.cx, dDst.cy, g_hdcMem, ptSrc.x, ptSrc.y, dSrc.cx, dSrc.cy, SRCCOPY ); SelectObject( hdcMem2, g_hbmDefault ); DeleteObject( hdcMem2 ); SelectObject( g_hdcMem, hbmOld ); InvalidateRect(GetDlgItem(hDlg, IDC_SCREENSAMPLE), NULL, FALSE); } STATIC void DoMonitorBmp(HWND hDlg) { HDC hdc = GetDC(NULL); HBITMAP hbm; g_hdcMem = CreateCompatibleDC(hdc); ReleaseDC(NULL, hdc); if (!g_hdcMem) return; hbm = CreateBitmap(1,1,1,1,NULL); g_hbmDefault = SelectObject(g_hdcMem, hbm); SelectObject(g_hdcMem, g_hbmDefault); DeleteObject(hbm); // set up bitmaps for sample screen g_hbmScrSample = LoadMonitorBitmap( TRUE ); // let them do the desktop SendDlgItemMessage(hDlg, IDC_SCREENSAMPLE, STM_SETIMAGE, IMAGE_BITMAP, (DWORD)g_hbmScrSample); // get a base copy of the bitmap for when the "internals" change g_hbmMonitor = LoadMonitorBitmap( FALSE ); // we'll do the desktop } const static DWORD aAdvVideoDlgHelpIds[] = { // Context Help IDs (DWORD)IDC_STATIC, IDH_VIDEO_ADVANCED_COMPAT, ID_ADVVIDEO_COMPAT, IDH_VIDEO_ADVANCED_COMPAT, 0, 0 }; BOOL AdvancedVideoDlgProc (HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam) { static BOOL *pfCompat = NULL; switch (wMsg) { case WM_INITDIALOG: { if ((pfCompat = (BOOL *)lParam) == NULL) return -1; CheckDlgButton (hDlg, ID_ADVVIDEO_COMPAT, (*pfCompat)); break; } case WM_COMMAND: { switch (GET_WM_COMMAND_ID(wParam, lParam)) { case IDOK: *pfCompat = IsDlgButtonChecked (hDlg, ID_ADVVIDEO_COMPAT); // fall through case IDCANCEL: EndDialog (hDlg, GET_WM_COMMAND_ID(wParam, lParam)); break; } break; } case WM_CONTEXTMENU: { WinHelp ((HWND)wParam, NULL, HELP_CONTEXTMENU, (DWORD)aAdvVideoDlgHelpIds); return TRUE; } case WM_HELP: { WinHelp (((LPHELPINFO)lParam)->hItemHandle, NULL, HELP_WM_HELP, (DWORD)aAdvVideoDlgHelpIds); return TRUE; } } return FALSE; } const static DWORD aVideoDlgHelpIds[] = { // Context Help IDs IDC_GROUPBOX, IDH_MMSE_GROUPBOX, IDC_SCREENSAMPLE, IDH_VIDEO_GRAPHIC, IDC_VIDEO_FULLSCREEN, IDH_VIDEO_FULL_SCREEN, IDC_VIDEO_INWINDOW, IDH_VIDEO_FIXED_WINDOW, IDC_VIDEO_CB_SIZE, IDH_VIDEO_FIXED_WINDOW, ID_VIDEO_ADVANCED, IDH_VIDEO_ADVANCED_BUTTON, 0, 0 }; BOOL CALLBACK VideoDlg(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { NMHDR FAR *lpnm; switch (uMsg) { case WM_NOTIFY: lpnm = (NMHDR FAR *)lParam; switch(lpnm->code) { case PSN_KILLACTIVE: FORWARD_WM_COMMAND(hDlg, IDOK, 0, 0, SendMessage); break; case PSN_APPLY: FORWARD_WM_COMMAND(hDlg, ID_APPLY, 0, 0, SendMessage); break; case PSN_SETACTIVE: FORWARD_WM_COMMAND(hDlg, ID_INIT, 0, 0, SendMessage); break; case PSN_RESET: FORWARD_WM_COMMAND(hDlg, IDCANCEL, 0, 0, SendMessage); break; } break; case WM_INITDIALOG: { DWORD dwOptions; dwOptions = ReadVideoOptions(); FillWindowSizeCB(dwOptions, GetDlgItem(hDlg, IDC_VIDEO_CB_SIZE)); SetWindowLong(hDlg, DWL_USER, (LPARAM)dwOptions); DoMonitorBmp(hDlg); if (IsFlagSet(dwOptions, MCIAVIO_USEVGABYDEFAULT)) { CheckRadioButton(hDlg, IDC_VIDEO_INWINDOW, IDC_VIDEO_FULLSCREEN, IDC_VIDEO_FULLSCREEN); EnableWindow(GetDlgItem(hDlg, IDC_VIDEO_CB_SIZE), FALSE); ShowSampleScreen(hDlg, MCIAVIO_USEVGABYDEFAULT); break; } else { CheckRadioButton(hDlg, IDC_VIDEO_INWINDOW, IDC_VIDEO_FULLSCREEN, IDC_VIDEO_INWINDOW); EnableWindow(GetDlgItem(hDlg, IDC_VIDEO_CB_SIZE), TRUE); } ShowSampleScreen(hDlg, dwOptions & (MCIAVIO_WINDOWSIZEMASK|MCIAVIO_ZOOMBY2)); break; } case WM_DESTROY: if (g_hbmScrSample) { DeleteObject(g_hbmScrSample); g_hbmScrSample = NULL; } if (g_hbmMonitor) { DeleteObject(g_hbmMonitor); g_hbmMonitor = NULL; } if (g_hbmDefault) { DeleteObject(g_hbmDefault); g_hbmDefault = NULL; } if (g_hdcMem) { DeleteDC(g_hdcMem); g_hdcMem = NULL; } break; case WM_DROPFILES: break; case WM_CONTEXTMENU: WinHelp ((HWND) wParam, NULL, HELP_CONTEXTMENU, (DWORD) (LPSTR) aVideoDlgHelpIds); return TRUE; case WM_HELP: { LPHELPINFO lphi = (LPVOID) lParam; WinHelp (lphi->hItemHandle, NULL, HELP_WM_HELP, (DWORD) (LPSTR) aVideoDlgHelpIds); return TRUE; } case WM_COMMAND: HANDLE_WM_COMMAND(hDlg, wParam, lParam, DoVideoCommand); break; } return FALSE; } BOOL PASCAL DoVideoCommand(HWND hDlg, int id, HWND hwndCtl, UINT codeNotify) { switch (id) { case ID_APPLY: { int iIndex; HWND hCBWinSize = GetDlgItem(hDlg,IDC_VIDEO_CB_SIZE); DWORD dwOldOpt; DWORD dwNewOpt; dwOldOpt = (DWORD)GetWindowLong(hDlg, DWL_USER); if(Button_GetCheck(GetDlgItem(hDlg, IDC_VIDEO_FULLSCREEN))) { dwNewOpt = MCIAVIO_USEVGABYDEFAULT; } else { iIndex = ComboBox_GetCurSel(hCBWinSize); dwNewOpt = (DWORD)ComboBox_GetItemData(hCBWinSize, iIndex); } ClearFlag(dwOldOpt,MCIAVIO_WINDOWSIZEMASK|MCIAVIO_USEVGABYDEFAULT|MCIAVIO_ZOOMBY2); SetFlag(dwOldOpt, dwNewOpt); WriteVideoOptions(dwOldOpt); SetWindowLong(hDlg, DWL_USER, (LPARAM)dwOldOpt); return TRUE; } case IDOK: break; case IDCANCEL: break; case IDC_VIDEO_FULLSCREEN: EnableWindow(GetDlgItem(hDlg, IDC_VIDEO_CB_SIZE), FALSE); PropSheet_Changed(GetParent(hDlg),hDlg); ShowSampleScreen(hDlg, MCIAVIO_USEVGABYDEFAULT); break; case IDC_VIDEO_INWINDOW: { HWND hwndCB = GetDlgItem(hDlg,IDC_VIDEO_CB_SIZE); int iIndex = ComboBox_GetCurSel(hwndCB); int iOpt = (int)ComboBox_GetItemData(hwndCB, iIndex); EnableWindow(GetDlgItem(hDlg, IDC_VIDEO_CB_SIZE), TRUE); PropSheet_Changed(GetParent(hDlg),hDlg); ShowSampleScreen(hDlg, iOpt); break; } case IDC_VIDEO_CB_SIZE: switch (codeNotify) { case CBN_SELCHANGE: { int iIndex = ComboBox_GetCurSel(hwndCtl); int iOpt = (int)ComboBox_GetItemData(hwndCtl, iIndex); PropSheet_Changed(GetParent(hDlg),hDlg); ShowSampleScreen(hDlg, iOpt); break; } default: break; } break; case ID_VIDEO_ADVANCED: { BOOL f16BitCompat; f16BitCompat = (GetWindowLong(hDlg, DWL_USER) & MCIAVIO_F16BITCOMPAT); if (DialogBoxParam (ghInstance, MAKEINTRESOURCE(ADVVIDEODLG), hDlg, AdvancedVideoDlgProc, (LPARAM)&f16BitCompat) == IDOK) { SetWindowLong (hDlg, DWL_USER, GetWindowLong (hDlg, DWL_USER) & (~MCIAVIO_F16BITCOMPAT) | ((f16BitCompat) ? (MCIAVIO_F16BITCOMPAT) : 0)); PropSheet_Changed(GetParent(hDlg),hDlg); } break; } case ID_INIT: break; } return FALSE; }