www.pudn.com > mediator15src.zip > mediator.cpp
/* * mediator.cpp * Copyright (C) 2001-2002 Arno Hornberger* * This file is part of MPEG Mediator, a free MPEG stream converter. * * MPEG Mediator is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * MPEG Mediator is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include "resource.h" #include "mpegstream.h" #include "except.h" #include "output.h" #include "progress.h" #define WM_DONE (WM_USER + 0) #define IDC_TRACKBAR 50000 #define IDM_AC3_0 50100 #define IDM_AC3_7 50107 #define IDM_MPA_0 50108 #define IDM_MPA_1F 50139 #define IDM_LPCM_0 50140 #define IDM_LPCM_7 50147 #define IDM_NOAUDIO 50150 #define IDM_PLUGIN_0 50156 #define IDM_PLUGIN_F 50171 #define TRACKBAR_HEIGHT 27 #define INIT_WIDTH 600 #define INIT_HEIGHT 400 extern bool mmx_available(); extern VOID ConverterThread(PVOID pvoid); extern VOID AudioExtractionThread(PVOID pvoid); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK PropertiesDlgProc(HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK AboutDlgProc(HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK FramesDlgProc(HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK OpenDlgProc(HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK ProgressDlgProc(HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK AudioProgressDlgProc(HWND, UINT, WPARAM, LPARAM); void UpdateMenu(); void AdjustWindow(); void UpdateTrackbarState(); void UncheckAudioTracks(); void AddPluginsToMenu(); void UncheckPlugins(); int PopFileSaveDlg(char *filename, char *defextension); HBITMAP CreateBitmapObjectFromDibFile(HDC hdc, PTSTR szFileName); HWND hMainWnd; HWND hProgressDlg; HWND hAudioProgressDlg; HINSTANCE hInstance; HBITMAP hWallpaper; VideoFrame frame_buffer; Progress progress; extern Plugins plugins; extern compStdParms stdParms; MPEGStream stream; // main application object char outfilename[256]; char audiofilename[256]; int total_frames; // frames to convert bool exportyv12; bool allframes; void ReportProblem(HWND hWnd, const char *component, const char *problem) { char szMessage[200]; if (component) { sprintf(szMessage, "Component '%s' reports the following problem:\n%s", component, problem); MessageBox(hWnd, szMessage, "MPEG Mediator", MB_ICONEXCLAMATION); } else MessageBox(hWnd, problem, "MPEG Mediator", MB_ICONEXCLAMATION); } int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { MSG msg; WNDCLASS wndclass; char *szAppName = "MPEG Mediator"; HDC hdc; HACCEL hAccel; if (!mmx_available()) { ReportProblem(NULL, 0, "This program requires an MMX-enhanced CPU."); return 0; } hInstance = hInst; wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON)); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); wndclass.lpszMenuName = MAKEINTRESOURCE(IDR_MAINMENU); wndclass.lpszClassName = szAppName; if (!RegisterClass(&wndclass)) { MessageBox(NULL, TEXT("This program needs Windows NT or higher."), szAppName, MB_ICONERROR); return 0; } hMainWnd = CreateWindow(szAppName, TEXT("MPEG Mediator"), WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); CreateWindow(TRACKBAR_CLASS, NULL, WS_CHILD | WS_VISIBLE | WS_DISABLED | TBS_NOTICKS | TBS_BOTH, 0, 100, 300, TRACKBAR_HEIGHT, hMainWnd, (HMENU)IDC_TRACKBAR, hInstance, NULL); AdjustWindow(); AddPluginsToMenu(); ShowWindow(hMainWnd, iCmdShow); hdc = GetDC(hMainWnd); hWallpaper = CreateBitmapObjectFromDibFile(hdc, "wallpaper.bmp"); ReleaseDC(hMainWnd, hdc); UpdateWindow(hMainWnd); hAccel = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR1)); while (GetMessage(&msg, NULL, 0, 0)) { if ((hProgressDlg == 0 || !IsDialogMessage(hProgressDlg, &msg)) && (hAudioProgressDlg == 0 || !IsDialogMessage(hAudioProgressDlg, &msg)) ) { if (!TranslateAccelerator(hMainWnd, hAccel, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } } if (hWallpaper) DeleteObject(hWallpaper); return msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { BITMAP bitmap; FILE *file; static BITMAPINFO bmi; HMENU hMenu; PAINTSTRUCT ps; static int cxClient, cyClient; int i, j; char sztemp[80]; switch (message) { case WM_CREATE: LoadPlugins(); outfilename[0] = 0; audiofilename[0] = 0; exportyv12 = false; return 0; case WM_COMMAND: switch (LOWORD(wParam)) { case IDM_OPEN: if (DialogBox(hInstance, MAKEINTRESOURCE(IDD_OPEN), hwnd, OpenDlgProc)) { UpdateMenu(); AdjustWindow(); UpdateTrackbarState(); InvalidateRect(hwnd, NULL, TRUE); } return 0; case IDM_CLOSE: if (stream.IsOpen()) { stream.Close(); UpdateMenu(); AdjustWindow(); UpdateTrackbarState(); InvalidateRect(hwnd, NULL, TRUE); } return 0; case IDM_PROPERTIES: DialogBox(hInstance, MAKEINTRESOURCE(IDD_PROPERTIES), hwnd, PropertiesDlgProc); return 0; case IDM_EXIT: if (stream.IsOpen()) stream.Close(); DestroyWindow(hMainWnd); return 0; case IDM_EXPORTYV12: exportyv12 = !exportyv12; hMenu = GetMenu(hMainWnd); CheckMenuItem(hMenu, IDM_EXPORTYV12, exportyv12 ? MF_CHECKED : MF_UNCHECKED); return 0; case IDM_PLUGINS_CONFIGURE: compGetFilePrefsRec fileprefs; fileprefs.compilerPrefs = plugins.plugins[plugins.current].compilerPrefs; plugins.plugins[plugins.current].CompileEntry(compGetFilePrefs, &stdParms, (long)&fileprefs, 0); plugins.plugins[plugins.current].compilerPrefs = fileprefs.compilerPrefs; return 0; case IDM_PLUGINS_SETOUTPUTFILE: PopFileSaveDlg(outfilename, 0); return 0; case IDM_NOAUDIO: hMenu = GetMenu(hMainWnd); stream.SelectAudioTrack(MPEGStream::AUDIO_NONE, 0); UncheckAudioTracks(); CheckMenuItem(hMenu, LOWORD(wParam), MF_CHECKED); EnableMenuItem(hMenu, IDM_EXTRACTAUDIO, MF_GRAYED); return 0; case IDM_ASPECTRATIO_11: case IDM_ASPECTRATIO_43: case IDM_ASPECTRATIO_169: case IDM_ASPECTRATIO_2211: { PostProcess::Config *cfg = stream.GetPostProcessor()->GetConfig(); hMenu = GetMenu(hMainWnd); CheckMenuItem(hMenu, IDM_ASPECTRATIO_11, MF_UNCHECKED); CheckMenuItem(hMenu, IDM_ASPECTRATIO_43, MF_UNCHECKED); CheckMenuItem(hMenu, IDM_ASPECTRATIO_169, MF_UNCHECKED); CheckMenuItem(hMenu, IDM_ASPECTRATIO_2211, MF_UNCHECKED); CheckMenuItem(hMenu, LOWORD(wParam), MF_CHECKED); cfg->Reset(LOWORD(wParam) - IDM_ASPECTRATIO_11 + 1); stream.AdjustFrameDimensions(&frame_buffer); stream.GetFrame(&frame_buffer, true); AdjustWindow(); InvalidateRect(hwnd, NULL, TRUE); return 0; } case IDM_RESIZE_DECWIDTH: { PostProcess::Config *cfg = stream.GetPostProcessor()->GetConfig(); cfg->DecreaseResizeWidth(); stream.GetFrame(&frame_buffer, true); InvalidateRect(hwnd, NULL, TRUE); return 0; } case IDM_RESIZE_INCWIDTH: { PostProcess::Config *cfg = stream.GetPostProcessor()->GetConfig(); cfg->IncreaseResizeWidth(); stream.GetFrame(&frame_buffer, true); InvalidateRect(hwnd, NULL, TRUE); return 0; } case IDM_RESIZE_DECHEIGHT: { PostProcess::Config *cfg = stream.GetPostProcessor()->GetConfig(); cfg->DecreaseResizeHeight(); stream.GetFrame(&frame_buffer, true); InvalidateRect(hwnd, NULL, TRUE); return 0; } case IDM_RESIZE_INCHEIGHT: { PostProcess::Config *cfg = stream.GetPostProcessor()->GetConfig(); cfg->IncreaseResizeHeight(); stream.GetFrame(&frame_buffer, true); InvalidateRect(hwnd, NULL, TRUE); return 0; } case IDM_RESIZE_LOCKRATIO: { PostProcess::Config *cfg = stream.GetPostProcessor()->GetConfig(); CheckMenuItem(GetMenu(hMainWnd), IDM_RESIZE_LOCKRATIO, cfg->ToggleAspectRatioLock() ? MF_CHECKED : MF_UNCHECKED); stream.GetFrame(&frame_buffer, true); InvalidateRect(hwnd, NULL, TRUE); return 0; } case IDM_CROP_DECWIDTH: { PostProcess::Config *cfg = stream.GetPostProcessor()->GetConfig(); cfg->DecreaseCropWidth(); stream.AdjustFrameDimensions(&frame_buffer); stream.GetFrame(&frame_buffer, true); AdjustWindow(); InvalidateRect(hwnd, NULL, TRUE); sprintf(sztemp, "MPEG Mediator [%d x %d]", cfg->GetCropWidth(), cfg->GetCropHeight()); SetWindowText(hwnd, sztemp); KillTimer(hwnd, 1); SetTimer(hwnd, 1, 2000, 0); return 0; } case IDM_CROP_INCWIDTH: { PostProcess::Config *cfg = stream.GetPostProcessor()->GetConfig(); cfg->IncreaseCropWidth(); stream.AdjustFrameDimensions(&frame_buffer); stream.GetFrame(&frame_buffer, true); AdjustWindow(); InvalidateRect(hwnd, NULL, TRUE); sprintf(sztemp, "MPEG Mediator [%d x %d]", cfg->GetCropWidth(), cfg->GetCropHeight()); SetWindowText(hwnd, sztemp); KillTimer(hwnd, 1); SetTimer(hwnd, 1, 2000, 0); return 0; } case IDM_CROP_DECHEIGHT: { PostProcess::Config *cfg = stream.GetPostProcessor()->GetConfig(); cfg->DecreaseCropHeight(); stream.AdjustFrameDimensions(&frame_buffer); stream.GetFrame(&frame_buffer, true); AdjustWindow(); InvalidateRect(hwnd, NULL, TRUE); sprintf(sztemp, "MPEG Mediator [%d x %d]", cfg->GetCropWidth(), cfg->GetCropHeight()); SetWindowText(hwnd, sztemp); KillTimer(hwnd, 1); SetTimer(hwnd, 1, 2000, 0); return 0; } case IDM_CROP_INCHEIGHT: { PostProcess::Config *cfg = stream.GetPostProcessor()->GetConfig(); cfg->IncreaseCropHeight(); stream.AdjustFrameDimensions(&frame_buffer); stream.GetFrame(&frame_buffer, true); AdjustWindow(); InvalidateRect(hwnd, NULL, TRUE); sprintf(sztemp, "MPEG Mediator [%d x %d]", cfg->GetCropWidth(), cfg->GetCropHeight()); SetWindowText(hwnd, sztemp); KillTimer(hwnd, 1); SetTimer(hwnd, 1, 2000, 0); return 0; } case IDM_DEINTERLACING_AUTO: case IDM_DEINTERLACING_ON: case IDM_DEINTERLACING_OFF: stream.SetDeinterlacing(LOWORD(wParam) - IDM_DEINTERLACING_AUTO); hMenu = GetMenu(hMainWnd); CheckMenuItem(hMenu, IDM_DEINTERLACING_AUTO, MF_UNCHECKED); CheckMenuItem(hMenu, IDM_DEINTERLACING_ON, MF_UNCHECKED); CheckMenuItem(hMenu, IDM_DEINTERLACING_OFF, MF_UNCHECKED); CheckMenuItem(hMenu, LOWORD(wParam), MF_CHECKED); if (stream.IsOpen()) { stream.GetFrame(&frame_buffer, true); InvalidateRect(hwnd, NULL, TRUE); } return 0; case IDM_INVERSETELECINE: hMenu = GetMenu(hMainWnd); stream.SetIVTC(!stream.GetIVTC()); CheckMenuItem(hMenu, IDM_INVERSETELECINE, stream.GetIVTC() ? MF_CHECKED : MF_UNCHECKED); return 0; case IDM_STARTCONVERSION: case IDM_CONVERTNFRAMES: if (strlen(outfilename) == 0) { ReportProblem(NULL, 0, "No output file selected"); return 0; } if ((plugins.plugins[plugins.current].inforec.fileType == 'LSVA') || (LOWORD(wParam) == IDM_CONVERTNFRAMES)) { if (DialogBox(hInstance, MAKEINTRESOURCE(IDD_FRAMES), hwnd, FramesDlgProc) == FALSE) return 0; allframes = false; } else { total_frames = 500000; allframes = true; } try { stream.BeginConversion(); } catch (Except &e) { ReportProblem(hwnd, e.Who(), e.What()); return 0; } hMenu = GetMenu(hMainWnd); for (i = 0; i < 6; i++) EnableMenuItem(hMenu, i, MF_BYPOSITION | MF_GRAYED); DrawMenuBar(hMainWnd); EnableWindow(GetDlgItem(hMainWnd, IDC_TRACKBAR), FALSE); hProgressDlg = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_PROGRESS), hwnd, ProgressDlgProc); InvalidateRect(hwnd, NULL, TRUE); return 0; case IDM_EXTRACTAUDIO: if (!PopFileSaveDlg(audiofilename, "wav")) return 0; file = fopen(audiofilename, "rb"); if (file) { fclose(file); if (MessageBox(hwnd, "Output file already exists. Continue anyway?", "MPEG Mediator", MB_YESNO) != IDYES) return 0; } try { stream.BeginConversion(); } catch (Except &e) { ReportProblem(hwnd, e.Who(), e.What()); return 0; } hMenu = GetMenu(hMainWnd); for (i = 0; i < 6; i++) EnableMenuItem(hMenu, i, MF_BYPOSITION | MF_GRAYED); DrawMenuBar(hMainWnd); EnableWindow(GetDlgItem(hMainWnd, IDC_TRACKBAR), FALSE); hAudioProgressDlg = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_AUDIOPROGRESS), hwnd, AudioProgressDlgProc); return 0; case IDM_HOMEPAGE: ShellExecute(NULL, "open", "http://www.mpeg-mediator.com", NULL, NULL, SW_SHOWNORMAL); return 0; case IDM_ABOUT: DialogBox(hInstance, MAKEINTRESOURCE(IDD_ABOUT), hwnd, AboutDlgProc); return 0; default: hMenu = GetMenu(hMainWnd); try { if ((LOWORD(wParam) >= IDM_AC3_0) && (LOWORD(wParam) <= IDM_AC3_7)) { stream.SelectAudioTrack(MPEGStream::AUDIO_AC3, LOWORD(wParam) - IDM_AC3_0); UncheckAudioTracks(); CheckMenuItem(hMenu, LOWORD(wParam), MF_CHECKED); EnableMenuItem(hMenu, IDM_EXTRACTAUDIO, MF_ENABLED); } else if ((LOWORD(wParam) >= IDM_MPA_0) && (LOWORD(wParam) <= IDM_MPA_1F)) { stream.SelectAudioTrack(MPEGStream::AUDIO_MPEG, LOWORD(wParam) - IDM_MPA_0); UncheckAudioTracks(); CheckMenuItem(hMenu, LOWORD(wParam), MF_CHECKED); EnableMenuItem(hMenu, IDM_EXTRACTAUDIO, MF_ENABLED); } else if ((LOWORD(wParam) >= IDM_LPCM_0) && (LOWORD(wParam) <= IDM_LPCM_7)) { stream.SelectAudioTrack(MPEGStream::AUDIO_LPCM, LOWORD(wParam) - IDM_LPCM_0); UncheckAudioTracks(); CheckMenuItem(hMenu, LOWORD(wParam), MF_CHECKED); EnableMenuItem(hMenu, IDM_EXTRACTAUDIO, MF_ENABLED); } } catch (Except &e) { stream.Close(); ReportProblem(hMainWnd, e.Who(), e.What()); UpdateMenu(); AdjustWindow(); UpdateTrackbarState(); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); } if ((LOWORD(wParam) >= IDM_PLUGIN_0) && (LOWORD(wParam) <= IDM_PLUGIN_F)) { UncheckPlugins(); plugins.current = LOWORD(wParam) - IDM_PLUGIN_0; CheckMenuItem(hMenu, LOWORD(wParam), MF_CHECKED); if (plugins.plugins[plugins.current].extended_api) { EnableMenuItem(hMenu, IDM_EXPORTYV12, MF_ENABLED); CheckMenuItem(hMenu, IDM_EXPORTYV12, MF_CHECKED); exportyv12 = true; } else { EnableMenuItem(hMenu, IDM_EXPORTYV12, MF_GRAYED); CheckMenuItem(hMenu, IDM_EXPORTYV12, MF_UNCHECKED); exportyv12 = false; } } } break; case WM_DONE: stream.EndConversion(); hMenu = GetMenu(hMainWnd); for (i = 0; i < 6; i++) EnableMenuItem(hMenu, i, MF_BYPOSITION | MF_ENABLED); DrawMenuBar(hMainWnd); EnableWindow(GetDlgItem(hMainWnd, IDC_TRACKBAR), TRUE); try { stream.Seek(stream.GetStartPos()); stream.GetFrame(&frame_buffer, true); } catch (Except &e) { stream.Close(); ReportProblem(hMainWnd, e.Who(), e.What()); UpdateMenu(); AdjustWindow(); UpdateTrackbarState(); } InvalidateRect(hwnd, NULL, TRUE); return 0; case WM_HSCROLL: if ((int)LOWORD(wParam) != SB_ENDSCROLL) return 0; if (!(stream.IsOpen())) return 0; try { stream.Seek((__int64)SendMessage((HWND)lParam, TBM_GETPOS, 0, 0) * 2048); stream.GetFrame(&frame_buffer, true); } catch (Except &e) { stream.Close(); ReportProblem(hMainWnd, e.Who(), e.What()); UpdateMenu(); AdjustWindow(); UpdateTrackbarState(); } InvalidateRect(hwnd, NULL, TRUE); return 0; case WM_SIZE: cxClient = LOWORD(lParam); cyClient = HIWORD(lParam); MoveWindow(GetDlgItem(hwnd, IDC_TRACKBAR), 0, cyClient - TRACKBAR_HEIGHT, cxClient, TRACKBAR_HEIGHT, TRUE); return 0; case WM_PAINT: { PostProcess::Config *cfg; HDC hdc; hdc = BeginPaint(hwnd, &ps); if (stream.IsOpen() && (hProgressDlg == 0)) { cfg = stream.GetPostProcessor()->GetConfig(); bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biWidth = cfg->GetCropWidth(); bmi.bmiHeader.biHeight= cfg->GetCropHeight(); bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = 24; bmi.bmiHeader.biCompression = BI_RGB; SetDIBitsToDevice(hdc, 0, 0, cfg->GetCropWidth(), cfg->GetCropHeight(), 0, 0, 0, cfg->GetCropHeight(), frame_buffer.GetRGB24Representation(), &bmi, DIB_RGB_COLORS); } else if (hWallpaper) { GetObject(hWallpaper, sizeof(BITMAP), &bitmap); HDC hdcMem = CreateCompatibleDC(hdc); SelectObject(hdcMem, hWallpaper); for (i = 0; i < cyClient; i += bitmap.bmHeight) for (j = 0; j < cxClient; j += bitmap.bmWidth) BitBlt(hdc, j, i, bitmap.bmWidth, bitmap.bmHeight, hdcMem, 0, 0, SRCCOPY); DeleteDC(hdcMem); } EndPaint(hwnd, &ps); return 0; } case WM_TIMER: KillTimer(hwnd, 1); SetWindowText(hwnd, "MPEG Mediator"); return 0; case WM_CLOSE: if (hProgressDlg || hAudioProgressDlg) { ReportProblem(hwnd, 0, "Cannot exit while being busy"); return 0; } if (stream.IsOpen()) stream.Close(); DestroyWindow(hwnd); return 0; case WM_DESTROY: UnloadPlugins(); PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, message, wParam, lParam); } BOOL CALLBACK OpenDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { using namespace std; HDROP hDrop; unsigned int iFiles; static char szFilename[256]; static char szDlgFile[400]; static bool bSort = true; char *str; unsigned int i; int iPathEnd; LONG iCurSel; static OPENFILENAME ofn; static const char *errors[] = { "MPEG-Stream is empty", "Packetized Elementary Streams not supported", "Transport Streams not supported", "No MPEG-Video stream" }; static const char *szFilter = "MPEG video files (*.mpg;*.mpeg;*.vob;*.m1v;*.m2v;*.mpv)\0*.mpg;*.mpeg;*.vob;*.m1v;*.m2v;*.mpv\0" "All files (*.*)\0*.*\0"; switch (message) { case WM_INITDIALOG: CheckDlgButton(hDlg, IDC_SORTFILES, bSort ? BST_CHECKED : BST_UNCHECKED); return TRUE; case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: iFiles = SendDlgItemMessage(hDlg, IDC_FILES, LB_GETCOUNT, 0, 0); if (iFiles == 0) { EndDialog(hDlg, FALSE); return TRUE; } if (stream.IsOpen()) stream.Close(); for (i = 0; i < iFiles; i++) { SendDlgItemMessage(hDlg, IDC_FILES, LB_GETTEXT, (WPARAM)i, (LPARAM)szFilename); stream.AddFilename(szFilename); } try { i = stream.Open(); if (i != 0) ReportProblem(hDlg, 0, errors[i - 1]); else { stream.AdjustFrameDimensions(&frame_buffer); stream.GetFrame(&frame_buffer, true); } } catch (Except &e) { ReportProblem(hDlg, e.Who(), e.What()); stream.Close(); } EndDialog(hDlg, TRUE); return TRUE; case IDCANCEL: EndDialog(hDlg, FALSE); return TRUE; case IDC_ADD: szDlgFile[0] = '\0'; ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = hDlg; ofn.lpstrFilter = szFilter ; ofn.nMaxFile = 400; ofn.lpstrFile = szDlgFile; ofn.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_EXPLORER | OFN_ALLOWMULTISELECT; if (GetOpenFileName(&ofn)) { iPathEnd = (int)strlen(szDlgFile); strcpy(szFilename, szDlgFile); if (strlen(&szDlgFile[iPathEnd + 1]) == 0) { if (bSort) SendDlgItemMessage(hDlg, IDC_FILES, LB_ADDSTRING, 0, (LPARAM)szFilename); else SendDlgItemMessage(hDlg, IDC_FILES, LB_INSERTSTRING, -1, (LPARAM)szFilename); } else { str = &szDlgFile[iPathEnd + 1]; if (szFilename[iPathEnd - 1] != '\\') szFilename[iPathEnd++] = '\\'; while (strlen(str) > 0) { strcpy(&szFilename[iPathEnd], str); if (bSort) SendDlgItemMessage(hDlg, IDC_FILES, LB_ADDSTRING, 0, (LPARAM)szFilename); else SendDlgItemMessage(hDlg, IDC_FILES, LB_INSERTSTRING, -1, (LPARAM)szFilename); str += strlen(str) + 1; } } } return TRUE; case IDC_REMOVE: iCurSel = SendDlgItemMessage(hDlg, IDC_FILES, LB_GETCURSEL, 0, 0); if (iCurSel != LB_ERR) SendDlgItemMessage(hDlg, IDC_FILES, LB_DELETESTRING, (WPARAM)iCurSel, 0); return TRUE; case IDC_REMOVEALL: SendDlgItemMessage(hDlg, IDC_FILES, LB_RESETCONTENT, 0, 0); return TRUE; case IDC_SORTFILES: bSort = (IsDlgButtonChecked(hDlg, IDC_SORTFILES) == BST_CHECKED) ? true : false; if (bSort) { if ((iFiles = SendDlgItemMessage(hDlg, IDC_FILES, LB_GETCOUNT, 0, 0)) == 0) return TRUE; vector filenames; for (i = 0; i < iFiles; i++) { SendDlgItemMessage(hDlg, IDC_FILES, LB_GETTEXT, (WPARAM)i, (LPARAM)szFilename); filenames.push_back(string(szFilename)); } SendDlgItemMessage(hDlg, IDC_FILES, LB_RESETCONTENT, 0, 0); for (i = 0; i < iFiles; i++) SendDlgItemMessage(hDlg, IDC_FILES, LB_ADDSTRING, 0, (LPARAM)filenames[i].c_str()); } return TRUE; } break; case WM_DROPFILES: hDrop = (HDROP)wParam; iFiles = DragQueryFile(hDrop, 0xffffffff, NULL, 256); for (i = 0; i < iFiles; i++) { DragQueryFile(hDrop, i, szFilename, 256); if (bSort) SendDlgItemMessage(hDlg, IDC_FILES, LB_ADDSTRING, 0, (LPARAM)szFilename); else SendDlgItemMessage(hDlg, IDC_FILES, LB_INSERTSTRING, -1, (LPARAM)szFilename); } return TRUE; } return FALSE; } int PopFileSaveDlg(char *filename, char *defextension) { static OPENFILENAME ofn; static const char *szFilter = "All files (*.*)\0*.*\0"; ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = hMainWnd; ofn.lpstrFilter = szFilter; ofn.nMaxFile = 256; ofn.lpstrFile = filename; ofn.lpstrDefExt = defextension; ofn.Flags = OFN_HIDEREADONLY; return GetSaveFileName(&ofn); } BOOL CALLBACK PropertiesDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { PostProcess::Config *cfg = stream.GetPostProcessor()->GetConfig(); char szBuffer[80]; int i; static const char *szRateStrings[] = { "23.976", "24", "25", "29.97", "30", "50", "59.94", "60" }; static const char *szMPEG1AspectStrings[] = { "1.0", "0.6735", "0.7031", "0.7615", "0.8055", "0.8437", "0.8935", "0.9157", "0.9815", "1.0255", "1.0695", "1.0950", "1.1575", "1.2015" }; static const char *szMPEG2AspectStrings[] = { "1:1 (Square Pixels)", "4:3", "16:9 (Widescreen)", "2.21:1", }; static const char *szAudioStrings[] = { "n/a", "AC-3", "MPEG", "LPCM" }; switch (message) { case WM_INITDIALOG: if (stream.GetStreamType() == MPEGStream::MPEG2_PROGRAM) SetDlgItemText(hDlg, IDC_STREAMTYPE, "MPEG-2 Program Stream"); else if (stream.GetStreamType() == MPEGStream::MPEG1_PROGRAM) SetDlgItemText(hDlg, IDC_STREAMTYPE, "MPEG-1 Program Stream"); else SetDlgItemText(hDlg, IDC_STREAMTYPE, "Video Elementary Stream"); sprintf(szBuffer, "%I64d bytes", stream.GetStreamSize()); SetDlgItemText(hDlg, IDC_STREAMSIZE, szBuffer); if (stream.IsMPEG2Video()) SetDlgItemText(hDlg, IDC_VIDEOTYPE, "MPEG-2"); else SetDlgItemText(hDlg, IDC_VIDEOTYPE, "MPEG-1"); sprintf(szBuffer, "%d x %d", cfg->GetSourceWidth(), cfg->GetSourceHeight()); SetDlgItemText(hDlg, IDC_RESOLUTION, szBuffer); i = stream.GetFramerateCode(); if ((i < 1) || (i > 8)) sprintf(szBuffer, "unknown"); else sprintf(szBuffer, "%s fps", szRateStrings[i - 1]); SetDlgItemText(hDlg, IDC_FRAMERATE, szBuffer); i = stream.GetAspectratioCode(); if ((i < 1) || (i > 14)) sprintf(szBuffer, "unknown"); else if (stream.IsMPEG2Video()) { if (i > 4) sprintf(szBuffer, "unknown"); else sprintf(szBuffer, "%s", szMPEG2AspectStrings[i - 1]); } else sprintf(szBuffer, "%s", szMPEG1AspectStrings[i - 1]); SetDlgItemText(hDlg, IDC_ASPECTRATIO, szBuffer); i = stream.GetAudioType(); SetDlgItemText(hDlg, IDC_AUDIOTYPE, szAudioStrings[i]); if (i == MPEGStream::AUDIO_NONE) { SetDlgItemText(hDlg, IDC_CHANNELS, szAudioStrings[0]); SetDlgItemText(hDlg, IDC_SAMPLERATE, szAudioStrings[0]); SetDlgItemText(hDlg, IDC_SAMPLERESOLUTION, szAudioStrings[0]); } else { if (i == MPEGStream::AUDIO_AC3) SetDlgItemText(hDlg, IDC_CHANNELS, stream.GetAC3ChannelString()); else { if (stream.IsStereo()) SetDlgItemText(hDlg, IDC_CHANNELS, "2 (Stereo)"); else SetDlgItemText(hDlg, IDC_CHANNELS, "1 (Mono)"); } sprintf(szBuffer, "%d Hz", stream.GetSampleRate()); SetDlgItemText(hDlg, IDC_SAMPLERATE, szBuffer); SetDlgItemText(hDlg, IDC_SAMPLERESOLUTION, "16 bit"); } return TRUE; case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: case IDCANCEL: EndDialog(hDlg, FALSE); return TRUE; } } return FALSE; } BOOL CALLBACK AboutDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: case IDCANCEL: EndDialog(hDlg, TRUE); return TRUE; } } return FALSE; } BOOL CALLBACK FramesDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { unsigned int l; switch (message) { case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: l = GetDlgItemInt(hDlg, IDC_FRAMES, 0, FALSE); if (l > 0) { total_frames = (int)l; EndDialog(hDlg, TRUE); } return TRUE; case IDCANCEL: EndDialog(hDlg, FALSE); return TRUE; } } return FALSE; } void TimePrint(char *szBuffer, int nSeconds) { int hours = nSeconds / (60 * 60); int minutes = (nSeconds / 60) % 60; int seconds = nSeconds % 60; sprintf(szBuffer, "%02d:%02d:%02d", hours, minutes, seconds); } BOOL CALLBACK ProgressDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { static HANDLE hThread = 0; char sztemp[256]; int nseconds; static double frame_duration; static bool bThreadSuspended = false; switch (message) { case WM_INITDIALOG: InitializeCriticalSection(&progress.cs); progress.hEvent = CreateEvent(0, FALSE, FALSE, 0); progress.bytes_done = 0; progress.total_bytes = stream.GetStreamSize() - stream.GetStartPos(); progress.audio_frame = 0; progress.video_frame = 0; progress.abort = false; progress.seconds_passed = 0; SendDlgItemMessage(hDlg, IDC_RENDERFRAME, CB_RESETCONTENT, 0, 0); SendDlgItemMessage(hDlg, IDC_RENDERFRAME, CB_ADDSTRING, 0, (LPARAM)"no Frames"); SendDlgItemMessage(hDlg, IDC_RENDERFRAME, CB_ADDSTRING, 0, (LPARAM)"every Frame"); SendDlgItemMessage(hDlg, IDC_RENDERFRAME, CB_ADDSTRING, 0, (LPARAM)"every 2nd Frame"); SendDlgItemMessage(hDlg, IDC_RENDERFRAME, CB_ADDSTRING, 0, (LPARAM)"every 4th Frame"); SendDlgItemMessage(hDlg, IDC_RENDERFRAME, CB_ADDSTRING, 0, (LPARAM)"every 8th Frame"); SendDlgItemMessage(hDlg, IDC_RENDERFRAME, CB_ADDSTRING, 0, (LPARAM)"every 16th Frame"); SendDlgItemMessage(hDlg, IDC_RENDERFRAME, CB_ADDSTRING, 0, (LPARAM)"every 32nd Frame"); progress.display_video = 0; SendDlgItemMessage(hDlg, IDC_RENDERFRAME, CB_SETCURSEL, progress.display_video, 0); SetDlgItemText(hDlg, IDC_OUTPUTFILE, outfilename); SetDlgItemText(hDlg, IDC_VIDEOFRAME, ""); SetDlgItemText(hDlg, IDC_AUDIOFRAME, ""); SetDlgItemText(hDlg, IDC_TIMEELAPSED, ""); SetDlgItemText(hDlg, IDC_TIMEREMAINING, ""); SetDlgItemText(hDlg, IDC_VIDEOTIME, ""); SetDlgItemText(hDlg, IDC_AUDIOTIME, ""); SetDlgItemText(hDlg, IDC_PROGRESSPERCENT, ""); SetDlgItemText(hDlg, IDC_PAUSE, "Pause"); bThreadSuspended = false; if (allframes) SendDlgItemMessage(hDlg, IDC_PROGRESS, PBM_SETRANGE32, 0, (int)(progress.total_bytes / 2048)); else SendDlgItemMessage(hDlg, IDC_PROGRESS, PBM_SETRANGE32, 0, total_frames); frame_duration = stream.GetFinalFrameDuration(); hThread = (HANDLE)_beginthread(ConverterThread, 0, 0); SetTimer(hDlg, 1, 1000, NULL); return TRUE; case WM_CLOSE: progress.abort = true; if (bThreadSuspended) ResumeThread(hThread); return TRUE; case WM_TIMER: if (WaitForSingleObject(progress.hEvent, 0) == WAIT_OBJECT_0) DestroyWindow(hDlg); else { if (bThreadSuspended) return TRUE; EnterCriticalSection(&progress.cs); if (allframes) SendDlgItemMessage(hDlg, IDC_PROGRESS, PBM_SETPOS, (int)(progress.bytes_done / 2048), 0); else SendDlgItemMessage(hDlg, IDC_PROGRESS, PBM_SETPOS, progress.video_frame, 0); sprintf(sztemp, "%d", progress.video_frame); SetDlgItemText(hDlg, IDC_VIDEOFRAME, sztemp); sprintf(sztemp, "%d", progress.audio_frame); SetDlgItemText(hDlg, IDC_AUDIOFRAME, sztemp); TimePrint(sztemp, (int)(progress.video_frame * frame_duration)); SetDlgItemText(hDlg, IDC_VIDEOTIME, sztemp); TimePrint(sztemp, (int)(progress.audio_frame * frame_duration)); SetDlgItemText(hDlg, IDC_AUDIOTIME, sztemp); if (allframes) sprintf(sztemp, "%.1f%%", (double)progress.bytes_done * 100.0 / progress.total_bytes); else sprintf(sztemp, "%.1f%%", (double)progress.video_frame * 100.0 / total_frames); SetDlgItemText(hDlg, IDC_PROGRESSPERCENT, sztemp); if (progress.video_frame > 1) { progress.seconds_passed++; TimePrint(sztemp, progress.seconds_passed); SetDlgItemText(hDlg, IDC_TIMEELAPSED, sztemp); if (allframes) nseconds = (int)((progress.total_bytes * progress.seconds_passed) / progress.bytes_done) - progress.seconds_passed; else nseconds = (int)((total_frames * progress.seconds_passed) / progress.video_frame) - progress.seconds_passed; TimePrint(sztemp, nseconds); SetDlgItemText(hDlg, IDC_TIMEREMAINING, sztemp); } LeaveCriticalSection(&progress.cs); } return TRUE; case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: case IDCANCEL: progress.abort = true; if (bThreadSuspended) ResumeThread(hThread); return TRUE; case IDC_RENDERFRAME: EnterCriticalSection(&progress.cs); progress.display_video = (int)SendDlgItemMessage(hDlg, IDC_RENDERFRAME, CB_GETCURSEL, 0, 0); if (progress.display_video == 0) InvalidateRect(hMainWnd, NULL, TRUE); LeaveCriticalSection(&progress.cs); return TRUE; case IDC_PAUSE: bThreadSuspended = !bThreadSuspended; if (bThreadSuspended) { SuspendThread(hThread); SetDlgItemText(hDlg, IDC_PAUSE, "Continue"); } else { ResumeThread(hThread); SetDlgItemText(hDlg, IDC_PAUSE, "Pause"); } return TRUE; } return FALSE; case WM_DESTROY: KillTimer(hDlg, 1); hProgressDlg = 0; CloseHandle(progress.hEvent); DeleteCriticalSection(&progress.cs); SendMessage(hMainWnd, WM_DONE, 0, 0); return TRUE; } return FALSE; } BOOL CALLBACK AudioProgressDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG: InitializeCriticalSection(&progress.cs); progress.hEvent = CreateEvent(0, FALSE, FALSE, 0); progress.bytes_done = 0; progress.total_bytes = stream.GetStreamSize() - stream.GetStartPos(); progress.abort = false; SendDlgItemMessage(hDlg, IDC_AUDIOPROGRESS, PBM_SETRANGE32, 0, (int)(progress.total_bytes / 2048)); _beginthread(AudioExtractionThread, 0, 0); SetTimer(hDlg, 1, 1000, NULL); return TRUE; case WM_CLOSE: progress.abort = true; return TRUE; case WM_TIMER: if (WaitForSingleObject(progress.hEvent, 0) == WAIT_OBJECT_0) DestroyWindow(hDlg); else { EnterCriticalSection(&progress.cs); SendDlgItemMessage(hDlg, IDC_AUDIOPROGRESS, PBM_SETPOS, (int)(progress.bytes_done / 2048), 0); LeaveCriticalSection(&progress.cs); } return TRUE; case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: case IDCANCEL: progress.abort = true; return TRUE; } return FALSE; case WM_DESTROY: KillTimer(hDlg, 1); hAudioProgressDlg = 0; CloseHandle(progress.hEvent); DeleteCriticalSection(&progress.cs); SendMessage(hMainWnd, WM_DONE, 0, 0); return TRUE; } return FALSE; } void UncheckAudioTracks() { static MENUITEMINFO info; HMENU hMenu, hAudioMenu; int items, i; hMenu = GetMenu(hMainWnd); info.cbSize = sizeof(MENUITEMINFO); info.fMask = MIIM_SUBMENU; GetMenuItemInfo(hMenu, 2, TRUE, &info); hAudioMenu = info.hSubMenu; items = GetMenuItemCount(hAudioMenu); for (i = 0; i < items; i++) CheckMenuItem(hAudioMenu, i, MF_BYPOSITION | MF_UNCHECKED); } void UpdateMenu() { PostProcess::Config *cfg; static MENUITEMINFO info; HMENU hMenu, hAudioMenu; char label[30]; int audiotype, track; int i, count; hMenu = GetMenu(hMainWnd); info.cbSize = sizeof(MENUITEMINFO); info.fMask = MIIM_SUBMENU; GetMenuItemInfo(hMenu, 2, TRUE, &info); hAudioMenu = info.hSubMenu; if (stream.IsOpen()) { EnableMenuItem(hMenu, IDM_CLOSE, MF_ENABLED); EnableMenuItem(hMenu, IDM_PROPERTIES, MF_ENABLED); if (plugins.count > 0) EnableMenuItem(hMenu, IDM_PLUGINS_CONFIGURE, MF_ENABLED); EnableMenuItem(hMenu, IDM_RESIZECROP, MF_ENABLED); if (plugins.count > 0) { EnableMenuItem(hMenu, IDM_STARTCONVERSION, MF_ENABLED); EnableMenuItem(hMenu, IDM_CONVERTNFRAMES, MF_ENABLED); } EnableMenuItem(hMenu, IDM_ASPECTRATIO_11, MF_ENABLED); EnableMenuItem(hMenu, IDM_ASPECTRATIO_43, MF_ENABLED); EnableMenuItem(hMenu, IDM_ASPECTRATIO_169, MF_ENABLED); EnableMenuItem(hMenu, IDM_ASPECTRATIO_2211, MF_ENABLED); CheckMenuItem(hMenu, IDM_ASPECTRATIO_11, MF_UNCHECKED); CheckMenuItem(hMenu, IDM_ASPECTRATIO_43, MF_UNCHECKED); CheckMenuItem(hMenu, IDM_ASPECTRATIO_169, MF_UNCHECKED); CheckMenuItem(hMenu, IDM_ASPECTRATIO_2211, MF_UNCHECKED); i = stream.GetAspectratioCode(); if ((i < 1) || (i > 4)) i = 1; CheckMenuItem(hMenu, IDM_ASPECTRATIO_11 + i - 1, MF_CHECKED); EnableMenuItem(hMenu, IDM_RESIZE_DECWIDTH, MF_ENABLED); EnableMenuItem(hMenu, IDM_RESIZE_INCWIDTH, MF_ENABLED); EnableMenuItem(hMenu, IDM_RESIZE_DECHEIGHT, MF_ENABLED); EnableMenuItem(hMenu, IDM_RESIZE_INCHEIGHT, MF_ENABLED); EnableMenuItem(hMenu, IDM_RESIZE_LOCKRATIO, MF_ENABLED); cfg = stream.GetPostProcessor()->GetConfig(); CheckMenuItem(hMenu, IDM_RESIZE_LOCKRATIO, cfg->IsAspectRatioLocked() ? MF_CHECKED : MF_UNCHECKED); EnableMenuItem(hMenu, IDM_CROP_DECWIDTH, MF_ENABLED); EnableMenuItem(hMenu, IDM_CROP_INCWIDTH, MF_ENABLED); EnableMenuItem(hMenu, IDM_CROP_DECHEIGHT, MF_ENABLED); EnableMenuItem(hMenu, IDM_CROP_INCHEIGHT, MF_ENABLED); if (stream.IsTelecined()) { EnableMenuItem(hMenu, IDM_INVERSETELECINE, MF_ENABLED); CheckMenuItem(hMenu, IDM_INVERSETELECINE, stream.GetIVTC() ? MF_CHECKED : MF_UNCHECKED); } else { EnableMenuItem(hMenu, IDM_INVERSETELECINE, MF_GRAYED); CheckMenuItem(hMenu, IDM_INVERSETELECINE, MF_UNCHECKED); } while (RemoveMenu(hAudioMenu, 0, MF_BYPOSITION)); audiotype = stream.GetAudioType(); track = stream.GetAudioTrack(); info.fMask = MIIM_TYPE | MIIM_ID; info.fType = MFT_STRING; info.dwTypeData = label; count = 0; for (i = 0; i < 8; i++) { if (stream.HasAudioTrack(MPEGStream::AUDIO_AC3, i)) { sprintf(label, "AC-3, Track %d", i); info.wID = IDM_AC3_0 + i; InsertMenuItem(hAudioMenu, count, TRUE, &info); if ((audiotype == MPEGStream::AUDIO_AC3) && (i == track)) CheckMenuItem(hAudioMenu, count, MF_BYPOSITION | MF_CHECKED); count++; } } for (i = 0; i < 32; i++) { if (stream.HasAudioTrack(MPEGStream::AUDIO_MPEG, i)) { sprintf(label, "MPEG, Track %d", i); info.wID = IDM_MPA_0 + i; InsertMenuItem(hAudioMenu, count, TRUE, &info); if ((audiotype == MPEGStream::AUDIO_MPEG) && (i == track)) CheckMenuItem(hAudioMenu, count, MF_BYPOSITION | MF_CHECKED); count++; } } for (i = 0; i < 16; i++) { if (stream.HasAudioTrack(MPEGStream::AUDIO_LPCM, i)) { sprintf(label, "LPCM, Track %d", i); info.wID = IDM_LPCM_0 + i; InsertMenuItem(hAudioMenu, count, TRUE, &info); if ((audiotype == MPEGStream::AUDIO_LPCM) && (i == track)) CheckMenuItem(hAudioMenu, count, MF_BYPOSITION | MF_CHECKED); count++; } } if (count == 0) { info.fMask = MIIM_TYPE | MIIM_STATE; info.fType = MFT_STRING; info.fState = MFS_GRAYED; info.dwTypeData = " "; InsertMenuItem(hAudioMenu, 0, TRUE, &info); EnableMenuItem(hMenu, IDM_EXTRACTAUDIO, MF_GRAYED); } else { info.fMask = MIIM_TYPE; info.fType = MFT_SEPARATOR; InsertMenuItem(hAudioMenu, count++, TRUE, &info); info.fMask = MIIM_TYPE | MIIM_ID; info.fType = MFT_STRING; info.wID = IDM_NOAUDIO; info.dwTypeData = "No Audio"; InsertMenuItem(hAudioMenu, count, TRUE, &info); EnableMenuItem(hMenu, IDM_EXTRACTAUDIO, MF_ENABLED); } } else { EnableMenuItem(hMenu, IDM_CLOSE, MF_GRAYED); EnableMenuItem(hMenu, IDM_PROPERTIES, MF_GRAYED); EnableMenuItem(hMenu, IDM_PLUGINS_CONFIGURE, MF_GRAYED); EnableMenuItem(hMenu, IDM_RESIZECROP, MF_GRAYED); EnableMenuItem(hMenu, IDM_STARTCONVERSION, MF_GRAYED); EnableMenuItem(hMenu, IDM_CONVERTNFRAMES, MF_GRAYED); EnableMenuItem(hMenu, IDM_EXTRACTAUDIO, MF_GRAYED); EnableMenuItem(hMenu, IDM_ASPECTRATIO_11, MF_GRAYED); EnableMenuItem(hMenu, IDM_ASPECTRATIO_43, MF_GRAYED); EnableMenuItem(hMenu, IDM_ASPECTRATIO_169, MF_GRAYED); EnableMenuItem(hMenu, IDM_ASPECTRATIO_2211, MF_GRAYED); CheckMenuItem(hMenu, IDM_ASPECTRATIO_11, MF_UNCHECKED); CheckMenuItem(hMenu, IDM_ASPECTRATIO_43, MF_UNCHECKED); CheckMenuItem(hMenu, IDM_ASPECTRATIO_169, MF_UNCHECKED); CheckMenuItem(hMenu, IDM_ASPECTRATIO_2211, MF_UNCHECKED); EnableMenuItem(hMenu, IDM_RESIZE_DECWIDTH, MF_GRAYED); EnableMenuItem(hMenu, IDM_RESIZE_INCWIDTH, MF_GRAYED); EnableMenuItem(hMenu, IDM_RESIZE_DECHEIGHT, MF_GRAYED); EnableMenuItem(hMenu, IDM_RESIZE_INCHEIGHT, MF_GRAYED); EnableMenuItem(hMenu, IDM_RESIZE_LOCKRATIO, MF_GRAYED); CheckMenuItem(hMenu, IDM_RESIZE_LOCKRATIO, MF_UNCHECKED); EnableMenuItem(hMenu, IDM_CROP_DECWIDTH, MF_GRAYED); EnableMenuItem(hMenu, IDM_CROP_INCWIDTH, MF_GRAYED); EnableMenuItem(hMenu, IDM_CROP_DECHEIGHT, MF_GRAYED); EnableMenuItem(hMenu, IDM_CROP_INCHEIGHT, MF_GRAYED); EnableMenuItem(hMenu, IDM_INVERSETELECINE, MF_GRAYED); CheckMenuItem(hMenu, IDM_INVERSETELECINE, MF_UNCHECKED); while (RemoveMenu(hAudioMenu, 0, MF_BYPOSITION)); info.fMask = MIIM_TYPE | MIIM_STATE; info.fType = MFT_STRING; info.fState = MFS_GRAYED; info.dwTypeData = " "; InsertMenuItem(hAudioMenu, 0, TRUE, &info); } } void AddPluginsToMenu() { static MENUITEMINFO info; HMENU hMenu, hPluginMenu; hMenu = GetMenu(hMainWnd); info.cbSize = sizeof(MENUITEMINFO); info.fMask = MIIM_SUBMENU; GetMenuItemInfo(hMenu, 1, TRUE, &info); hPluginMenu = info.hSubMenu; info.fMask = MIIM_TYPE | MIIM_ID; info.fType = MFT_STRING; for (int i = 0; i < plugins.count; i++) { info.dwTypeData = plugins.plugins[i].inforec.compilerName; info.wID = IDM_PLUGIN_0 + i; InsertMenuItem(hPluginMenu, i, TRUE, &info); if (i == plugins.current) { CheckMenuItem(hPluginMenu, i, MF_BYPOSITION | MF_CHECKED); if (plugins.plugins[i].extended_api) { EnableMenuItem(hMenu, IDM_EXPORTYV12, MF_ENABLED); CheckMenuItem(hMenu, IDM_EXPORTYV12, MF_CHECKED); exportyv12 = true; } else exportyv12 = false; } } } void UncheckPlugins() { static MENUITEMINFO info; HMENU hMenu, hPluginMenu; hMenu = GetMenu(hMainWnd); info.cbSize = sizeof(MENUITEMINFO); info.fMask = MIIM_SUBMENU; GetMenuItemInfo(hMenu, 1, TRUE, &info); hPluginMenu = info.hSubMenu; for (int i = 0; i < plugins.count; i++) CheckMenuItem(hPluginMenu, i, MF_BYPOSITION | MF_UNCHECKED); } void AdjustWindow() { PostProcess::Config *cfg; RECT rect, wrect, crect; int delta; if (!stream.IsOpen()) { SetRect(&rect, 0, 0, INIT_WIDTH, TRACKBAR_HEIGHT + INIT_HEIGHT); SetRect(&wrect, 0, 0, INIT_WIDTH, TRACKBAR_HEIGHT + INIT_HEIGHT); } else { cfg = stream.GetPostProcessor()->GetConfig(); SetRect(&rect, 0, 0, cfg->GetCropWidth(), TRACKBAR_HEIGHT + cfg->GetCropHeight()); SetRect(&wrect, 0, 0, cfg->GetCropWidth(), TRACKBAR_HEIGHT + cfg->GetCropHeight()); } GetClientRect(hMainWnd, &crect); // adjust size of window if necessary if ((rect.right != crect.right) || (rect.bottom != crect.bottom)) { AdjustWindowRect(&wrect, GetWindowLong(hMainWnd, GWL_STYLE), TRUE); OffsetRect(&wrect, -wrect.left, -wrect.top); SetWindowPos(hMainWnd, HWND_TOP, 0, 0, wrect.right, wrect.bottom, SWP_NOMOVE); // handle menu-wraps (not perfect for weird cases (3-times wrap)) GetClientRect(hMainWnd, &crect); delta = rect.bottom - crect.bottom; GetWindowRect(hMainWnd, &wrect); SetWindowPos(hMainWnd, HWND_TOP, 0, 0, wrect.right - wrect.left, wrect.bottom - wrect.top + delta, SWP_NOMOVE); } } void UpdateTrackbarState() { if (stream.IsOpen()) { EnableWindow(GetDlgItem(hMainWnd, IDC_TRACKBAR), TRUE); SendDlgItemMessage(hMainWnd, IDC_TRACKBAR, TBM_SETRANGEMIN, (WPARAM)FALSE, 0); SendDlgItemMessage(hMainWnd, IDC_TRACKBAR, TBM_SETRANGEMAX, (WPARAM)FALSE, (long)(stream.GetStreamSize() / 2048)); SendDlgItemMessage(hMainWnd, IDC_TRACKBAR, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)0); } else { SendDlgItemMessage(hMainWnd, IDC_TRACKBAR, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)0); EnableWindow(GetDlgItem(hMainWnd, IDC_TRACKBAR), FALSE); } } HBITMAP CreateBitmapObjectFromDibFile(HDC hdc, PTSTR szFileName) { BITMAPFILEHEADER *pbmfh; BOOL bSuccess; DWORD dwFileSize, dwHighSize, dwBytesRead; HANDLE hFile; HBITMAP hBitmap; hFile = CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL); if (hFile == INVALID_HANDLE_VALUE) return NULL; dwFileSize = GetFileSize(hFile, &dwHighSize); if (dwHighSize) { CloseHandle(hFile); return NULL; } pbmfh = (BITMAPFILEHEADER *)malloc(dwFileSize); if (!pbmfh) { CloseHandle(hFile); return NULL; } bSuccess = ReadFile(hFile, pbmfh, dwFileSize, &dwBytesRead, NULL); CloseHandle(hFile); if (!bSuccess || (dwBytesRead != dwFileSize) || (pbmfh->bfType != *(WORD *)"BM") || (pbmfh->bfSize != dwFileSize)) { free(pbmfh); return NULL; } hBitmap = CreateDIBitmap(hdc, (BITMAPINFOHEADER *)(pbmfh + 1), CBM_INIT, (BYTE *)pbmfh + pbmfh->bfOffBits, (BITMAPINFO *)(pbmfh + 1), DIB_RGB_COLORS); free(pbmfh); return hBitmap; }