From 6bcf419d2e8f739b432d4790d1ba9d48ab65365b Mon Sep 17 00:00:00 2001 From: fcolin Date: Fri, 18 Nov 2011 12:14:12 +0000 Subject: --- ARMFCaptureD3D/winmain.cpp | 1416 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1416 insertions(+) create mode 100644 ARMFCaptureD3D/winmain.cpp (limited to 'ARMFCaptureD3D/winmain.cpp') diff --git a/ARMFCaptureD3D/winmain.cpp b/ARMFCaptureD3D/winmain.cpp new file mode 100644 index 0000000..02ad991 --- /dev/null +++ b/ARMFCaptureD3D/winmain.cpp @@ -0,0 +1,1416 @@ +////////////////////////////////////////////////////////////////////////// +// +// winmain.cpp : Application entry-point +// +// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A +// PARTICULAR PURPOSE. +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +////////////////////////////////////////////////////////////////////////// + +#include "ARMFCaptureD3D.h" +#include "resource.h" +#include "ConfigFile\ConfigFile.h" +#include "debug.h" +#include "options.h" +#include "ARAnalyse.h" + +// Include the v6 common controls in the manifest +#pragma comment(linker, \ + "\"/manifestdependency:type='Win32' "\ + "name='Microsoft.Windows.Common-Controls' "\ + "version='6.0.0.0' "\ + "processorArchitecture='*' "\ + "publicKeyToken='6595b64144ccf1df' "\ + "language='*'\"") + + +// +// ChooseDeviceParam structure +// +// Holds an array of IMFActivate pointers that represent video +// capture devices. +// + +struct ChooseDeviceParam +{ + IMFActivate **ppDevices; // Array of IMFActivate pointers. + UINT32 count; // Number of elements in the array. + UINT32 selection; // Selected device, by array index. +}; + + +// +// ChooseDeviceParam structure +// +// Holds an array of IMFActivate pointers that represent video +// capture devices. +// + +struct ChooseVideoParam +{ + IMFMediaType **ppTypes; // Array of IMFMediaType pointers. + UINT32 count; // Number of elements in the array. + UINT32 selection; // Selected device, by array index. +}; + +BOOL InitializeApplication(); +BOOL InitializeWindow(HWND *pHwnd); +void CleanUp(); +INT MessageLoop(HWND hwnd); + +LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +INT_PTR CALLBACK DeviceDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +INT_PTR CALLBACK VideoDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +void ShowErrorMessage(PCWSTR format, HRESULT hr); + +// Window message handlers +BOOL OnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct); +void OnClose(HWND hwnd); +void OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify); +void OnSize(HWND hwnd, UINT state, int cx, int cy); +void OnDeviceChange(HWND hwnd, DEV_BROADCAST_HDR *pHdr); +void OnPaint(HWND hwnd); +void OnInitMenu(HWND hwnd, HMENU menu); + +// Command handlers +void OnChooseDevice(HWND hwnd, BOOL bPrompt, const WCHAR *name, int instance); +void OnChooseFormat(HWND hwnd, BOOL bPrompt, int index); +int DeviceGetByName(ChooseDeviceParam *pParam , const WCHAR* name, int instance); + + +// Constants +const WCHAR CLASS_NAME[] = L"MFCapture Window Class"; +const WCHAR WINDOW_NAME[] = L"MFCapture Sample Application"; + + + +// Global variables +HWND g_hVideo = NULL; +HWND g_hStatus = NULL; +HWND g_hTrack = NULL; +int g_Threshold = 125; + +HWND g_hTrackSeuilMin = NULL; +int g_ThresholdMin = 127; + +HWND g_hTrackSeuilMax = NULL; +int g_ThresholdMax = 127; + +CPreview *g_pPreview = NULL; +HDEVNOTIFY g_hdevnotify = NULL; +ARAnalyse *g_pAnalyse = NULL; +ConfigFile *g_config = NULL; + +std::wstring g_camera_name; +int g_camera_instance = 0; +std::string g_ivy_domain; +int g_format_video = 0; +bool g_toggle_video = false; +bool g_read_calibrationfile = false; + +// command line options + +std::wstring widen( const string& str ) +{ + std::wostringstream wstm ; + const std::ctype& ctfacet = std::use_facet< std::ctype >( wstm.getloc() ) ; + for( size_t i=0 ; i& ctfacet = std::use_facet< std::ctype >( stm.getloc() ) ; + for( size_t i=0 ; i default: Logitech", + "i:instcam default: 0", + "b:bus ", + "v|video non affichage video", + "f:format ", + "p:projection Read ProjectionFile ", + NULL + } ; + + Options opts("ARIvy", optv); + opts.ctrls( Options::LONG_ONLY ); + OptStrTokIter iter(argv); + + while( (optchar = opts(iter, pa_optarg)) != 0 ) { + switch (optchar) { + + case 'c': + g_camera_name = widen( pa_optarg ); + break; + case 'i': + g_camera_instance = atoi( pa_optarg ); + break; + + case 'b': + g_ivy_domain = pa_optarg; + break; + case 'v': + g_toggle_video = true; + break; + case 'f': + g_format_video = atoi( pa_optarg ); + break; + case 'p': + g_read_calibrationfile = true; + break; + case 'h': // Help + default: + ++errors; + break; + } + } + + if (errors) { + opts.usage(std::cout,""); + getchar(); + exit(0); + } + +} + +//------------------------------------------------------------------- +// WinMain +// +// Application entry-point. +//------------------------------------------------------------------- + +INT WINAPI wWinMain(HINSTANCE/* hInstance*/, HINSTANCE /*hPrevInstance*/,LPWSTR lpCmdLine, INT /*nCmdShow*/ ) +{ + + HWND hwnd = 0; + char *cmdLine = narrow(lpCmdLine) ; + + parse_args(cmdLine); + free( cmdLine ); + try + { + g_config = new ConfigFile("data\\config.inp"); + HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0); + + // camera param + if ( g_camera_name.length() == 0 ) + g_camera_name = widen(g_config->read("CameraName", "Logitech")); + + // Ivy + if ( g_ivy_domain.length() == 0 ) + g_ivy_domain = g_config->read("IvyBus",""); + + if (InitializeApplication() && InitializeWindow(&hwnd)) + { + MessageLoop(hwnd); + } + + CleanUp(); + + return 0; + } + catch(ConfigFile::file_not_found ex) + { + WCHAR msg[MAX_PATH]; + HRESULT hr = S_OK; + hr = StringCbPrintfW(msg, sizeof(msg), L"Fichier de configuration not trouve: %S", ex.filename.c_str()); + + if (SUCCEEDED(hr)) + { + MessageBox(NULL, msg, L"Error", MB_ICONERROR); + } + return -1; + } + catch( ConfigFile::key_not_found ex) + { + WCHAR msg[MAX_PATH]; + HRESULT hr = S_OK; + hr = StringCbPrintfW(msg, sizeof(msg), L"cle manquante dans le fichier de configuration: %S", ex.key.c_str()); + + if (SUCCEEDED(hr)) + { + MessageBox(NULL, msg, L"Error", MB_ICONERROR); + }return -1; + } + +} + + +//------------------------------------------------------------------- +// WindowProc +// +// Window procedure. +//------------------------------------------------------------------- + +LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) + { + HANDLE_MSG(hwnd, WM_CREATE, OnCreate); + HANDLE_MSG(hwnd, WM_CLOSE, OnClose); + HANDLE_MSG(hwnd, WM_COMMAND, OnCommand); + HANDLE_MSG(hwnd, WM_SIZE, OnSize); + HANDLE_MSG(hwnd, WM_INITMENU, OnInitMenu); + + case WM_APP_PREVIEW_ERROR: + ShowErrorMessage(L"Error", (HRESULT)wParam); + break; + + case WM_DEVICECHANGE: + OnDeviceChange(hwnd, (PDEV_BROADCAST_HDR)lParam); + break; + case WM_ERASEBKGND: + // Suppress window erasing, to reduce flickering while the video is playing. + return 1; + //case WM_PAINT: + // OnPaint(hwnd); + // break; + case WM_HSCROLL: + { + g_Threshold = SendMessage(g_hTrack, TBM_GETPOS, 0, 0); + g_ThresholdMin = SendMessage(g_hTrackSeuilMin, TBM_GETPOS, 0, 0); + g_ThresholdMax = SendMessage(g_hTrackSeuilMax, TBM_GETPOS, 0, 0); + + if ( g_pAnalyse ) + g_pAnalyse->setThreshold( g_Threshold ); + } + break; + + } + return DefWindowProc(hwnd, uMsg, wParam, lParam); +} + + +//------------------------------------------------------------------- +// InitializeApplication +// +// Initializes the application. +//------------------------------------------------------------------- + +BOOL InitializeApplication() +{ + HRESULT hr = S_OK; + + InitCommonControls(); + + hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); + + if (SUCCEEDED(hr)) + { + hr = MFStartup(MF_VERSION); + } + + return (SUCCEEDED(hr)); +} + +//------------------------------------------------------------------- +// CleanUp +// +// Releases resources. +//------------------------------------------------------------------- + +void CleanUp() +{ + if (g_hdevnotify) + { + UnregisterDeviceNotification(g_hdevnotify); + } + + if (g_pPreview) + { + g_pPreview->CloseDevice(); + } + + SafeRelease(&g_pPreview); + + MFShutdown(); + CoUninitialize(); +} + + +//------------------------------------------------------------------- +// InitializeWindow +// +// Creates the application window. +//------------------------------------------------------------------- + +BOOL InitializeWindow(HWND *pHwnd) +{ + WNDCLASS wc = {0}; + + wc.lpfnWndProc = WindowProc; + wc.hInstance = GetModuleHandle(NULL); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.lpszClassName = CLASS_NAME; + wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1); + + if (!RegisterClass(&wc)) + { + return FALSE; + } + + HWND hwnd = CreateWindow( + CLASS_NAME, + WINDOW_NAME, + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + NULL, + NULL, + GetModuleHandle(NULL), + NULL + ); + + if (!hwnd) + { + return FALSE; + } + + + ShowWindow(hwnd, SW_SHOWDEFAULT); + UpdateWindow(hwnd); + + *pHwnd = hwnd; + + return TRUE; +} + + +//------------------------------------------------------------------- +// MessageLoop +// +// Implements the window message loop. +//------------------------------------------------------------------- + +INT MessageLoop(HWND hwnd) +{ + MSG msg = {0}; + + while (GetMessage(&msg, NULL, 0, 0)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + DestroyWindow(hwnd); + + return INT(msg.wParam); +} +HWND CreateSlider( HWND parent, int pos, int min, int max, int val) +{ +HWND hwndTrack = CreateWindowEx( + 0, // no extended styles + TRACKBAR_CLASS, // class name + TEXT("Trackbar Control"), // title (caption) + WS_CHILD | WS_VISIBLE | + TBS_NOTICKS , // style + pos, 0, // position + 200, 20, // size + parent, // parent window + NULL, // control identifier + NULL, // instance + NULL // no WM_CREATE parameter + ); + + SendMessage(hwndTrack, TBM_SETRANGE, + (WPARAM) TRUE, // redraw flag + (LPARAM) MAKELONG(min, max)); // min. & max. positions + + SendMessage(hwndTrack, TBM_SETPAGESIZE, + 0, (LPARAM) 1); // new page size + + //SendMessage(hwndTrack, TBM_SETSEL, + // (WPARAM) FALSE, // redraw flag + // (LPARAM) MAKELONG(0, 255)); + + SendMessage(hwndTrack, TBM_SETPOS, + (WPARAM) TRUE, // redraw flag + (LPARAM) val); + return hwndTrack; +} +//------------------------------------------------------------------- +// OnCreate +// +// Handles the WM_CREATE message. +//------------------------------------------------------------------- + +BOOL OnCreate(HWND hwnd, LPCREATESTRUCT) +{ + HRESULT hr = S_OK; + + // Register this window to get device notification messages. + + DEV_BROADCAST_DEVICEINTERFACE di = { 0 }; + di.dbcc_size = sizeof(di); + di.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; + di.dbcc_classguid = KSCATEGORY_CAPTURE; + + g_hdevnotify = RegisterDeviceNotification( + hwnd, + &di, + DEVICE_NOTIFY_WINDOW_HANDLE + ); + + if (g_hdevnotify == NULL) + { + ShowErrorMessage(L"RegisterDeviceNotification failed.", HRESULT_FROM_WIN32(GetLastError())); + return FALSE; + } + + // Create status bar + HWND hStatus = CreateStatusWindow( WS_CHILD | WS_VISIBLE, L"Status text" , hwnd, 100 ); + + // Create slider bar + HWND hwndTrack = CreateSlider( hwnd, 0, 0, 255, g_Threshold); + HWND hwndTrack1 = CreateSlider( hwnd, 210, 0, 255, g_ThresholdMin); + HWND hwndTrack2 = CreateSlider( hwnd, 420, 0, 255, g_ThresholdMax); + + + HWND hVideo = CreateWindow( + TEXT("STATIC"), + NULL, + WS_CHILD | WS_VISIBLE, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + hwnd, + NULL, + GetModuleHandle(NULL), + NULL + ); + + if (!hVideo) + { + ShowErrorMessage(L"Create Child Window failed.", GetLastError()); + return FALSE; + } + RECT rcTrackBar; + int iTrackHeight; + + RECT rcStatus; + int iStatusHeight; + + int iEditHeight; + RECT rcClient; + + // Size status bar and get height + + SendMessage(hStatus, WM_SIZE, 0, 0); + + GetWindowRect(hwndTrack, &rcTrackBar); + GetWindowRect(hStatus, &rcStatus); + iStatusHeight = rcStatus.bottom - rcStatus.top; + iTrackHeight = rcTrackBar.bottom - rcTrackBar.top; + // Calculate remaining height and size edit + + GetClientRect(hwnd, &rcClient); + + iEditHeight = rcClient.bottom - iStatusHeight - iTrackHeight; + + SetWindowPos(hVideo, NULL, 0, iTrackHeight, rcClient.right, iEditHeight, SWP_NOZORDER); + + g_hVideo = hVideo; + g_hStatus = hStatus; + g_hTrack = hwndTrack; + g_hTrackSeuilMin = hwndTrack1; + g_hTrackSeuilMax = hwndTrack2; + + // Create ArToolKit Analyser + g_pAnalyse = new ARAnalyse(); + + // Create the object that manages video preview. + if ( g_hVideo ) + { + hr = CPreview::CreateInstance(g_hVideo, g_hVideo, &g_pPreview); + + if (FAILED(hr)) + { + ShowErrorMessage(L"CPreview::CreateInstance failed.", hr); + return FALSE; + } + // Select the first available device (if any). + OnChooseDevice(hwnd, FALSE, g_camera_name.length() ? g_camera_name.c_str() : NULL, g_camera_instance ); + + } + + + + if ( g_toggle_video ) + g_pPreview->ToggleVideo(); + // start Ivy + g_pAnalyse->IvyInit(g_ivy_domain.c_str()); + return TRUE; +} + + + +//------------------------------------------------------------------- +// OnClose +// +// Handles WM_CLOSE messages. +//------------------------------------------------------------------- + +void OnClose(HWND /*hwnd*/) +{ + PostQuitMessage(0); +} + + + +//------------------------------------------------------------------- +// OnSize +// +// Handles WM_SIZE messages. +//------------------------------------------------------------------- + +void OnSize(HWND hwnd, UINT state, int cx, int cy) +{ + // Size status bar and get height + RECT rcStatus; + int iStatusHeight; + int iVideoHeight; + int iTrackHeight; + + + // iconified + if ( state == SIZE_MINIMIZED ) return; + + GetWindowRect(g_hStatus, &rcStatus); + iStatusHeight = rcStatus.bottom - rcStatus.top; + GetWindowRect(g_hTrack, &rcStatus); + iTrackHeight = rcStatus.bottom - rcStatus.top; + + // Calculate remaining height and size edit + + iVideoHeight = cy - iStatusHeight -iTrackHeight; + + SetWindowPos(g_hVideo, NULL, 0, iTrackHeight, cx, iVideoHeight, SWP_NOZORDER); + if (g_pPreview) + { + g_pPreview->ResizeVideo((WORD)cx, (WORD)iVideoHeight); + + InvalidateRect(hwnd, NULL, FALSE); + } + // Auto-resize statusbar (Send WM_SIZE message does just that) + SendMessage(g_hStatus, WM_SIZE, 0, 0); +} + + + +//------------------------------------------------------------------- +// OnPaint +// +// Handles WM_PAINT messages. +//------------------------------------------------------------------- + +//void OnPaint(HWND hwnd) +//{ +// +// PAINTSTRUCT ps; +// HDC hdc = BeginPaint(hwnd, &ps); +// +// // The video is not playing, so we must paint the application window. +// RECT rc; +// GetClientRect(hwnd, &rc); +// FillRect(hdc, &rc, (HBRUSH) COLOR_WINDOW); +// DrawText( hdc, L"ESSAI",5, &rc, 0); +// EndPaint(hwnd, &ps); +// +// +//} +//------------------------------------------------------------------- +// OnInitMenuChange +// +// Handles WM_INITMENU messages. +//------------------------------------------------------------------- + +void OnInitMenu(HWND hwnd, HMENU menu) +{ + + EnableMenuItem( menu, ID_ACTION_CALIBRATE, g_pAnalyse->IsCalibrationEnabled() ? MF_ENABLED : MF_DISABLED ); + EnableMenuItem( menu, ID_ACTION_SAVEPROJECTIONDATA, g_pAnalyse->IsCalibrated() ? MF_ENABLED : MF_DISABLED ); + CheckMenuItem( menu, ID_ACTION_CALIBRATE, g_pAnalyse->IsCalibrated() ? MF_CHECKED : MF_UNCHECKED ); + // Blur pass + CheckMenuItem( menu, ID_BLURPASSE_0PASS, g_pAnalyse->BlurPass == 0 ? MF_CHECKED : MF_UNCHECKED ); + CheckMenuItem( menu, ID_BLURPASSE_1PASS, g_pAnalyse->BlurPass == 1 ? MF_CHECKED : MF_UNCHECKED ); + CheckMenuItem( menu, ID_BLURPASSE_2PASS, g_pAnalyse->BlurPass == 2 ? MF_CHECKED : MF_UNCHECKED ); + CheckMenuItem( menu, ID_BLURPASSE_3PASS, g_pAnalyse->BlurPass == 3 ? MF_CHECKED : MF_UNCHECKED ); + CheckMenuItem( menu, ID_BLURPASSE_4PASS, g_pAnalyse->BlurPass == 4 ? MF_CHECKED : MF_UNCHECKED ); + CheckMenuItem( menu, ID_BLURPASSE_4PASS, g_pAnalyse->BlurPass == 5 ? MF_CHECKED : MF_UNCHECKED ); + CheckMenuItem( menu, ID_BLURPASSE_4PASS, g_pAnalyse->BlurPass == 6 ? MF_CHECKED : MF_UNCHECKED ); + CheckMenuItem( menu, ID_BLURPASSE_4PASS, g_pAnalyse->BlurPass == 10 ? MF_CHECKED : MF_UNCHECKED ); + // DownSample + CheckMenuItem( menu, ID_DOWNSAMPLE_FACTEUR1, g_pAnalyse->DownSample == 1 ? MF_CHECKED : MF_UNCHECKED ); + CheckMenuItem( menu, ID_DOWNSAMPLE_FACTEUR2, g_pAnalyse->DownSample == 2 ? MF_CHECKED : MF_UNCHECKED ); + CheckMenuItem( menu, ID_DOWNSAMPLE_FACTEUR4, g_pAnalyse->DownSample == 4 ? MF_CHECKED : MF_UNCHECKED ); + CheckMenuItem( menu, ID_DOWNSAMPLE_FACTEUR8, g_pAnalyse->DownSample == 8 ? MF_CHECKED : MF_UNCHECKED ); + // Affichage + CheckMenuItem( menu, ID_AFFICHAGE_GRAYSCALE, g_pAnalyse->Display == ARAnalyse::GrayScale ? MF_CHECKED : MF_UNCHECKED ); + CheckMenuItem( menu, ID_AFFICHAGE_BLUR, g_pAnalyse->Display == ARAnalyse::Blur ? MF_CHECKED : MF_UNCHECKED ); + CheckMenuItem( menu, ID_AFFICHAGE_DIFF, g_pAnalyse->Display == ARAnalyse::Diff ? MF_CHECKED : MF_UNCHECKED ); + CheckMenuItem( menu, ID_AFFICHAGE_THRESHOLD, g_pAnalyse->Display == ARAnalyse::Threshold ? MF_CHECKED : MF_UNCHECKED ); + CheckMenuItem( menu, ID_AFFICHAGE_MOYEN, g_pAnalyse->Display == ARAnalyse::Moyen ? MF_CHECKED : MF_UNCHECKED ); + // Filter + CheckMenuItem( menu, ID_FILTER_MOYEN, g_pAnalyse->filter == ARAnalyse::FMoyen ? MF_CHECKED : MF_UNCHECKED ); + CheckMenuItem( menu, ID_FILTER_LAPLACIEN4, g_pAnalyse->filter == ARAnalyse::FLaplacien4 ? MF_CHECKED : MF_UNCHECKED ); + CheckMenuItem( menu, ID_FILTER_LAPLACIEN8, g_pAnalyse->filter == ARAnalyse::FLaplacien8 ? MF_CHECKED : MF_UNCHECKED ); + CheckMenuItem( menu, ID_FILTER_LAPLACIEND, g_pAnalyse->filter == ARAnalyse::FLaplaciend ? MF_CHECKED : MF_UNCHECKED ); + CheckMenuItem( menu, ID_FILTER_SOBEL, g_pAnalyse->filter == ARAnalyse::FSobel ? MF_CHECKED : MF_UNCHECKED ); + CheckMenuItem( menu, ID_FILTER_PREWITT, g_pAnalyse->filter == ARAnalyse::FPrewitt ? MF_CHECKED : MF_UNCHECKED ); + CheckMenuItem( menu, ID_FILTER_GAUSSIAN, g_pAnalyse->filter == ARAnalyse::FGaussian ? MF_CHECKED : MF_UNCHECKED ); +} +//------------------------------------------------------------------- +// OnCommand +// +// Handles WM_COMMAND messages +//------------------------------------------------------------------- + +void OnCommand(HWND hwnd, int id, HWND /*hwndCtl*/, UINT /*codeNotify*/) +{ + switch (id) + { + case ID_ACTION_CHOOSEDEVICE: + OnChooseDevice(hwnd, TRUE, NULL,0); + break; + case ID_ACTION_CHOOSEFORMAT: + OnChooseFormat(hwnd, TRUE, 0); + break; + case ID_ACTION_DISPLAYVIDEO: + if (g_pPreview) + { + bool video = g_pPreview->ToggleVideo(); + CheckMenuItem( GetMenu( hwnd ), ID_ACTION_DISPLAYVIDEO, video ? MF_CHECKED : MF_UNCHECKED ); + } + + break; + case ID_ACTION_CALCMOYEN: + if (g_pPreview) + { + bool moy = g_pPreview->ToggleMoyen(); + CheckMenuItem( GetMenu( hwnd ), ID_ACTION_CALCMOYEN, moy ? MF_CHECKED : MF_UNCHECKED ); + } + + break;case ID_ACTION_TRANSFORM: + if (g_pPreview) + { + bool trsf = g_pPreview->ToggleTransform(); + CheckMenuItem( GetMenu( hwnd ), ID_ACTION_TRANSFORM, trsf ? MF_CHECKED : MF_UNCHECKED ); + } + break; + case ID_ACTION_AUTOTHRESHOLD: + if (g_pAnalyse) + { + bool auto_threshold = g_pAnalyse->ToggleAutoThreshold(); + CheckMenuItem( GetMenu( hwnd ), ID_ACTION_AUTOTHRESHOLD, auto_threshold ? MF_CHECKED : MF_UNCHECKED ); + if ( ! auto_threshold ) + { + SendMessage(g_hTrack, TBM_SETPOS, + (WPARAM) TRUE, // redraw flag + (LPARAM) g_pAnalyse->getThreshold()); + } + } + + break; + case ID_ACTION_CALIBRATE: + if (g_pAnalyse) + { + bool cal = g_pAnalyse->Calibrate(); + CheckMenuItem( GetMenu( hwnd ), ID_ACTION_CALIBRATE, cal ? MF_CHECKED : MF_UNCHECKED ); + } + break; + case ID_ACTION_SAVEPROJECTIONDATA: + if ( g_pAnalyse ) + { + g_pAnalyse->SaveCalibration(); + } + break; + case ID_BLURPASSE_0PASS: + if (g_pAnalyse) + { + g_pAnalyse->BlurPass = 0; + } + break; + + case ID_BLURPASSE_1PASS: + if (g_pAnalyse) + { + g_pAnalyse->BlurPass = 1; + } + break; + + case ID_BLURPASSE_2PASS: + if (g_pAnalyse) + { + g_pAnalyse->BlurPass = 2; + } + break; + + case ID_BLURPASSE_3PASS: + if (g_pAnalyse) + { + g_pAnalyse->BlurPass = 3; + } + break; + case ID_BLURPASSE_4PASS: + if (g_pAnalyse) + { + g_pAnalyse->BlurPass = 4; + } + break; + case ID_BLURPASSE_5PASS: + if (g_pAnalyse) + { + g_pAnalyse->BlurPass = 5; + } + break; + case ID_BLURPASSE_6PASS: + if (g_pAnalyse) + { + g_pAnalyse->BlurPass = 6; + } + break; + case ID_BLURPASSE_10PASS: + if (g_pAnalyse) + { + g_pAnalyse->BlurPass = 10; + } + break; + case ID_DOWNSAMPLE_FACTEUR1: + if (g_pAnalyse) + { + g_pAnalyse->DownSample = 1; + } + break; + case ID_DOWNSAMPLE_FACTEUR2: + if (g_pAnalyse) + { + g_pAnalyse->DownSample = 2; + } + break; + case ID_DOWNSAMPLE_FACTEUR4: + if (g_pAnalyse) + { + g_pAnalyse->DownSample = 4; + } + break; + case ID_DOWNSAMPLE_FACTEUR8: + if (g_pAnalyse) + { + g_pAnalyse->DownSample = 8; + } + break; + + case ID_AFFICHAGE_GRAYSCALE: + if (g_pAnalyse) + { + g_pAnalyse->Display = ARAnalyse::GrayScale; + } + break; + case ID_AFFICHAGE_BLUR: + if (g_pAnalyse) + { + g_pAnalyse->Display = ARAnalyse::Blur; + } + break; + case ID_AFFICHAGE_DIFF: + if (g_pAnalyse) + { + g_pAnalyse->Display = ARAnalyse::Diff; + } + break; + case ID_AFFICHAGE_THRESHOLD: + if (g_pAnalyse) + { + g_pAnalyse->Display = ARAnalyse::Threshold; + } + break; + case ID_AFFICHAGE_MOYEN: + if (g_pAnalyse) + { + g_pAnalyse->Display = ARAnalyse::Moyen; + } + break; + case ID_FILTER_MOYEN: + if (g_pAnalyse) + { + g_pAnalyse->filter = ARAnalyse::FMoyen; + } + break; + case ID_FILTER_LAPLACIEN4: + if (g_pAnalyse) + { + g_pAnalyse->filter = ARAnalyse::FLaplacien4; + } + break; + case ID_FILTER_LAPLACIEN8: + if (g_pAnalyse) + { + g_pAnalyse->filter = ARAnalyse::FLaplacien8; + } + break; + case ID_FILTER_LAPLACIEND: + if (g_pAnalyse) + { + g_pAnalyse->filter = ARAnalyse::FLaplaciend; + } + break; + case ID_FILTER_SOBEL: + if (g_pAnalyse) + { + g_pAnalyse->filter = ARAnalyse::FSobel; + } + break; + case ID_FILTER_PREWITT: + if (g_pAnalyse) + { + g_pAnalyse->filter = ARAnalyse::FPrewitt; + } + break; + case ID_FILTER_GAUSSIAN: + if (g_pAnalyse) + { + g_pAnalyse->filter = ARAnalyse::FGaussian; + } + break; + } +} + +//------------------------------------------------------------------- +// OnChooseDevice +// +// Select a video capture device. +// +// hwnd: A handle to the application window. +/// bPrompt: If TRUE, prompt to user to select the device. Otherwise, +// select the first device in the list. +//------------------------------------------------------------------- + +void OnChooseDevice(HWND hwnd, BOOL bPrompt, const WCHAR* name, int instance) +{ + HRESULT hr = S_OK; + ChooseDeviceParam param = { 0,0,0 }; + + UINT iDevice = 0; // Index into the array of devices + BOOL bCancel = FALSE; + + IMFAttributes *pAttributes = NULL; + + // Initialize an attribute store to specify enumeration parameters. + + hr = MFCreateAttributes(&pAttributes, 1); + + if (FAILED(hr)) { goto done; } + + // Ask for source type = video capture devices. + + hr = pAttributes->SetGUID( + MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, + MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID + ); + + if (FAILED(hr)) { goto done; } + + // Enumerate devices. + hr = MFEnumDeviceSources(pAttributes, ¶m.ppDevices, ¶m.count); + + if (FAILED(hr)) { goto done; } + + // NOTE: param.count might be zero. + + if (bPrompt || name == NULL) + { + // Ask the user to select a device. + + INT_PTR result = DialogBoxParam( + GetModuleHandle(NULL), + MAKEINTRESOURCE(IDD_CHOOSE_DEVICE), + hwnd, + DeviceDlgProc, + (LPARAM)¶m + ); + + if (result == IDOK) + { + iDevice = param.selection; + } + else + { + bCancel = TRUE; // User cancelled + } + } + else + { + iDevice = DeviceGetByName( ¶m, name, instance ); + } + + if (!bCancel && (param.count > 0)) + { + // Give this source to the CPlayer object for preview. + hr = g_pPreview->SetDevice( param.ppDevices[iDevice], g_format_video ); + } + +done: + + SafeRelease(&pAttributes); + + for (DWORD i = 0; i < param.count; i++) + { + SafeRelease(¶m.ppDevices[i]); + } + CoTaskMemFree(param.ppDevices); + + if (FAILED(hr)) + { + ShowErrorMessage(L"Cannot create a video capture device", hr); + } +} + + +//------------------------------------------------------------------- +// OnChooseFormat +// +// Select a video format capture. +// +// hwnd: A handle to the application window. +/// bPrompt: If TRUE, prompt to user to select the device. Otherwise, +// select the first device in the list. +//------------------------------------------------------------------- + +void OnChooseFormat(HWND hwnd, BOOL bPrompt, int index) +{ + HRESULT hr = S_OK; + ChooseVideoParam param = { 0, 0, 0 }; + + UINT iFormat = 0; // Index into the array of devices + BOOL bCancel = FALSE; + + hr = g_pPreview->EnumerateCaptureFormats( ¶m.ppTypes, ¶m.count); + + // NOTE: param.count might be zero. + + if (bPrompt) + { + // Ask the user to select a device. + + INT_PTR result = DialogBoxParam( + GetModuleHandle(NULL), + MAKEINTRESOURCE(IDD_CHOOSE_VIDEO), + hwnd, + VideoDlgProc, + (LPARAM)¶m + ); + + if (result == IDOK) + { + iFormat = param.selection; + } + else + { + bCancel = TRUE; // User cancelled + } + } + else + { + iFormat = index; + } + if (!bCancel && (param.count > 0)) + { + // Give this format to the CPlayer object for preview. + hr = g_pPreview->SetFormat( param.ppTypes[iFormat] ); + } + + + + for (DWORD i = 0; i < param.count; i++) + { + SafeRelease(¶m.ppTypes[i]); + } + CoTaskMemFree(param.ppTypes); + + if (FAILED(hr)) + { + ShowErrorMessage(L"Cannot select a video format", hr); + } +} + +//------------------------------------------------------------------- +// OnDeviceChange +// +// Handles WM_DEVICECHANGE messages. +//------------------------------------------------------------------- + +void OnDeviceChange(HWND hwnd, DEV_BROADCAST_HDR *pHdr) +{ + if (g_pPreview == NULL || pHdr == NULL) + { + return; + } + + HRESULT hr = S_OK; + BOOL bDeviceLost = FALSE; + + // Check if the current device was lost. + + hr = g_pPreview->CheckDeviceLost(pHdr, &bDeviceLost); + + if (FAILED(hr) || bDeviceLost) + { + g_pPreview->CloseDevice(); + + MessageBox(hwnd, L"Lost the capture device.", WINDOW_NAME, MB_OK); + } +} + + +///////////////////////////////////////////////////////////////////// + +// Dialog functions + +int DeviceGetByName(ChooseDeviceParam *pParam , const WCHAR* name, int instance) +{ + HRESULT hr = S_OK; + DWORD iDevice = 0; + int current_inst = 0; + bool NameFound = false; + for (DWORD i = 0; i < pParam->count; i++) + { + WCHAR *szFriendlyName = NULL; + + hr = pParam->ppDevices[i]->GetAllocatedString( + MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME, + &szFriendlyName, + NULL + ); + if (FAILED(hr)) + { + break; + } + NameFound = wcsstr( szFriendlyName, name ) != NULL; + CoTaskMemFree(szFriendlyName); + // check if devioce containt name + if ( NameFound ) + { + iDevice = i; + if ( current_inst == instance ) + break; + current_inst++; + + } + + } + + return iDevice; +} + +//------------------------------------------------------------------- +// OnInitDialog +// +// Handles the WM_INITDIALOG message. +//------------------------------------------------------------------- + +void DeviceOnInitDialog(HWND hwnd, ChooseDeviceParam *pParam) +{ + HRESULT hr = S_OK; + + // Populate the list with the friendly names of the devices. + + HWND hList = GetDlgItem(hwnd, IDC_DEVICE_LIST); + + for (DWORD i = 0; i < pParam->count; i++) + { + WCHAR *szFriendlyName = NULL; + + hr = pParam->ppDevices[i]->GetAllocatedString( + MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME, + &szFriendlyName, + NULL + ); + + if (FAILED(hr)) + { + break; + } + + + int index = ListBox_AddString(hList, szFriendlyName); + + ListBox_SetItemData(hList, index, i); + + CoTaskMemFree(szFriendlyName); + } + + // Assume no selection for now. + pParam->selection = (UINT32)-1; + + if (pParam->count == 0) + { + // If there are no devices, disable the "OK" button. + EnableWindow(GetDlgItem(hwnd, IDOK), FALSE); + } +} + + +HRESULT DeviceOnOK(HWND hwnd, ChooseDeviceParam *pParam) +{ + HWND hList = GetDlgItem(hwnd, IDC_DEVICE_LIST); + + int sel = ListBox_GetCurSel(hList); + + if (sel != LB_ERR) + { + pParam->selection = (UINT32)ListBox_GetItemData(hList, sel); + } + + return S_OK; +} + + +//------------------------------------------------------------------- +// DeviceDlgProc +// +// Dialog procedure for the "Select Device" dialog. +//------------------------------------------------------------------- + +INT_PTR CALLBACK DeviceDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static ChooseDeviceParam *pParam = NULL; + + switch (msg) + { + case WM_INITDIALOG: + pParam = (ChooseDeviceParam*)lParam; + DeviceOnInitDialog(hwnd, pParam); + return TRUE; + + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDOK: + DeviceOnOK(hwnd, pParam); + EndDialog(hwnd, LOWORD(wParam)); + return TRUE; + + case IDCANCEL: + EndDialog(hwnd, LOWORD(wParam)); + return TRUE; + } + break; + } + + return FALSE; +} + + + +void ShowErrorMessage(PCWSTR format, HRESULT hrErr) +{ + HRESULT hr = S_OK; + int dwBufferLength; + + WCHAR msg[MAX_PATH]; + static LPCVOID s_hModule = 0; + const LPCWSTR MESSAGEFILE = L"mferror.dll"; + DWORD dwFormatFlags = + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS | + FORMAT_MESSAGE_MAX_WIDTH_MASK; + + WCHAR *lpMsgBuf = 0; + dwBufferLength = FormatMessage( + dwFormatFlags, + NULL, + hrErr, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR)&lpMsgBuf, + 0, + NULL ); + //lpMsgBuf[strlen(lpMsgBuf) -2] = '\0'; // remove last \n + + // Not a system message. In theory, you should be able to get both with one call. + // In practice (at least on my 64bit box), you need to make 2 calls. + if (dwBufferLength == 0) + { + if (s_hModule == 0) + { + // Load the Media Foundation error message dll + s_hModule = LoadLibraryEx(MESSAGEFILE, NULL, LOAD_LIBRARY_AS_DATAFILE); + } + + if (s_hModule != 0) + { + // If the load succeeds, make sure we look in it + dwFormatFlags |= FORMAT_MESSAGE_FROM_HMODULE; + + // Scan both the Windows Media library, and the system library looking for the message + dwBufferLength = FormatMessage( + dwFormatFlags, + s_hModule, // module to get message from (NULL == system) + hrErr, // error number to get message for + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // default language + (LPTSTR)&lpMsgBuf, + 0, + NULL + ); + } + } + hr = StringCbPrintf(msg, sizeof(msg), L"%s (hr=0x%X) \n%s", format, hrErr, lpMsgBuf); + // Free the buffer. + LocalFree( lpMsgBuf ); + if (SUCCEEDED(hr)) + { + MessageBox(NULL, msg, L"Error", MB_ICONERROR); + } + else + { + DebugBreak(); + } +} + +// Dialog functions + +//------------------------------------------------------------------- +// VideoOnInitDialog +// +// Handles the WM_INITDIALOG message. +//------------------------------------------------------------------- + +void VideoOnInitDialog(HWND hwnd, ChooseVideoParam *pParam) +{ + HRESULT hr = S_OK; + PROPVARIANT var; + UINT32 rate_num; + UINT32 rate_denum; + UINT32 width; + UINT32 height; + WCHAR msg[MAX_PATH]; + + // Populate the list with the friendly names of the devices. + + HWND hList = GetDlgItem(hwnd, IDC_VIDEO_LIST); + + for (DWORD i = 0; i < pParam->count; i++) + { + + WCHAR *szSubTypeName = NULL; + + hr = pParam->ppTypes[i]->GetItem( MF_MT_SUBTYPE, &var ); + if (FAILED(hr)) + { + break; + } + + hr = GetGUIDName(*var.puuid, &szSubTypeName); + if (FAILED(hr)) + { + break; + } + + hr = MFGetAttributeSize( pParam->ppTypes[i], MF_MT_FRAME_RATE, &rate_num, &rate_denum ); + if (FAILED(hr)) + { + break; + } + hr = MFGetAttributeSize( pParam->ppTypes[i], MF_MT_FRAME_SIZE, &width, &height); + if (FAILED(hr)) + { + break; + } + + + if (SUCCEEDED(StringCchPrintf(msg, sizeof(msg), TEXT("%02d %s %dx%d pixel %.01f FPS"), i,szSubTypeName, width,height,((float)rate_num/rate_denum)))) + { + int index = ListBox_AddString(hList, msg); + + ListBox_SetItemData(hList, index, i); + } + + + CoTaskMemFree(szSubTypeName); + } + + // Assume no selection for now. + pParam->selection = (UINT32)-1; + + if (pParam->count == 0) + { + // If there are no devices, disable the "OK" button. + EnableWindow(GetDlgItem(hwnd, IDOK), FALSE); + } +} + + +HRESULT VideoOnOK(HWND hwnd, ChooseVideoParam *pParam) +{ + HWND hList = GetDlgItem(hwnd, IDC_DEVICE_LIST); + + int sel = ListBox_GetCurSel(hList); + + if (sel != LB_ERR) + { + pParam->selection = (UINT32)ListBox_GetItemData(hList, sel); + } + + return S_OK; +} + + + + +//------------------------------------------------------------------- +// DeviceDlgProc +// +// Dialog procedure for the "Select Device" dialog. +//------------------------------------------------------------------- + +INT_PTR CALLBACK VideoDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static ChooseVideoParam *pParam = NULL; + + switch (msg) + { + case WM_INITDIALOG: + pParam = (ChooseVideoParam*)lParam; + VideoOnInitDialog(hwnd, pParam); + return TRUE; + + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDOK: + VideoOnOK(hwnd, pParam); + EndDialog(hwnd, LOWORD(wParam)); + return TRUE; + + case IDCANCEL: + EndDialog(hwnd, LOWORD(wParam)); + return TRUE; + } + break; + } + + return FALSE; +} + + -- cgit v1.1