Update the changelog
[opencv] / apps / CamShiftDemo / mainfrm.cpp
1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 //  By downloading, copying, installing or using the software you agree to this license.
6 //  If you do not agree to this license, do not download, install,
7 //  copy or use the software.
8 //
9 //
10 //                        Intel License Agreement
11 //                For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
15 //
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
18 //
19 //   * Redistribution's of source code must retain the above copyright notice,
20 //     this list of conditions and the following disclaimer.
21 //
22 //   * Redistribution's in binary form must reproduce the above copyright notice,
23 //     this list of conditions and the following disclaimer in the documentation
24 //     and/or other materials provided with the distribution.
25 //
26 //   * The name of Intel Corporation may not be used to endorse or promote products
27 //     derived from this software without specific prior written permission.
28 //
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
39 //
40 //M*/
41 // MainFrm.cpp : implementation of the CMainFrame class
42 //
43
44 #include "stdafx.h"
45 #include "cvstreams.h"
46
47 #include "CamShiftDemo.h"
48 #include "objbase.h"
49 #include "initguid.h"
50 #include "MainFrm.h"
51
52 #ifdef _DEBUG
53 #define new DEBUG_NEW
54 #undef THIS_FILE
55 static char THIS_FILE[] = __FILE__;
56 #endif
57
58 /////////////////////////////////////////////////////////////////////////////
59 // CMainFrame
60
61 IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)
62
63 BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
64     //{{AFX_MSG_MAP(CMainFrame)
65     ON_WM_CREATE()
66     ON_WM_DESTROY()
67     ON_WM_SIZE()
68     ON_COMMAND(ID_CAMERA, OnCamera )
69     ON_COMMAND(ID_BALL, OnBall )
70     ON_COMMAND(ID_FILE, OnFile)
71     ON_COMMAND(ID_PLAYPAUSE, OnPlayPause)
72     ON_UPDATE_COMMAND_UI(ID_CAMERA, OnUpdateCamera )
73     ON_UPDATE_COMMAND_UI(ID_BALL, OnUpdateBall )
74     ON_UPDATE_COMMAND_UI(ID_FILE, OnUpdateFile )
75     ON_UPDATE_COMMAND_UI(ID_PLAYPAUSE, OnUpdatePlayPause)
76     //}}AFX_MSG_MAP
77 END_MESSAGE_MAP()
78
79 static UINT indicators[] =
80 {
81     ID_SEPARATOR,           // status line indicator
82     ID_INDICATOR_CAPS,
83     ID_INDICATOR_NUM,
84     ID_INDICATOR_SCRL,
85 };
86
87 /////////////////////////////////////////////////////////////////////////////
88 // CMainFrame construction/destruction
89
90 CMainFrame::CMainFrame()
91 {
92     m_GraphBuilder  = 0;
93     m_FilterGraph   = 0;
94     m_MediaControl  = 0;
95     m_MediaEventEx  = 0;
96     m_VideoWindow   = 0;
97     m_SourceFilter = 0;
98     
99     m_CamShift      = 0;
100     m_CamShiftProp  = 0;
101
102     m_input = -1;
103
104     m_src_rect = CRect(0,0,0,0);
105 }
106
107 CMainFrame::~CMainFrame()
108 {
109 }
110
111
112 static IPin* get_pin( IBaseFilter* pFilter, PIN_DIRECTION dir )
113 {
114     IEnumPins*  pEnumPins = 0;
115     IPin*       pPin = 0;
116
117     if( pFilter )
118     {
119         pFilter->EnumPins( &pEnumPins );
120         if( pEnumPins != 0 )
121         {
122             for(;;)
123             {
124                 ULONG  cFetched = 0;
125                 PIN_DIRECTION pinDir = PIN_DIRECTION(-1); 
126                 pPin = 0;
127
128                 pEnumPins->Next( 1, &pPin, &cFetched );
129                 if( cFetched == 0 || pPin == 0 ) break;
130
131                 pPin->QueryDirection( &pinDir );
132                 if( pinDir == dir ) break;
133                 pPin->Release();
134             }
135             pEnumPins->Release();
136         }
137     }
138
139     return pPin;
140 }
141
142 static void show_prop_page( IBaseFilter* pFilter, const WCHAR* name )
143 {
144     if( pFilter )
145     {
146         ISpecifyPropertyPages* pispp = 0;
147         pFilter->QueryInterface( IID_ISpecifyPropertyPages, (void **)&pispp);
148         if( pispp )
149         {
150             CAUUID caGUID;
151
152             if( SUCCEEDED( pispp->GetPages( &caGUID )))
153             {
154                 OleCreatePropertyFrame(
155                     0, 0, 0,
156                     name,                 // Caption for the dialog box
157                     1,                    // Number of filters
158                     (IUnknown**)&pFilter, // Pointer to the filter whose property 
159                     caGUID.cElems,
160                     caGUID.pElems,
161                     0, 0, 0 );
162             }
163             SafeRelease( pispp );
164         }
165     }
166 }
167
168
169 bool CMainFrame::CreateCamShift()
170 {
171     CoCreateInstance( CLSID_CamShift, NULL, CLSCTX_INPROC_SERVER, 
172                       IID_IBaseFilter, (void**)&m_CamShift );
173     if( m_CamShift )
174     {
175         m_CamShift->QueryInterface(IID_ICamShift,(void**)&m_CamShiftProp);
176     }
177
178     if( m_CamShiftProp == 0)
179     {
180         SafeRelease( m_CamShift );
181     }
182     
183     return m_CamShiftProp != 0;
184 }
185
186
187 bool CMainFrame::CreateCamera( int idx )
188 {
189     ICreateDevEnum* pCreateDevEnum = 0;
190     IEnumMoniker*   pEnumMon = 0;
191     ULONG           cFetched = 0;
192     
193     SafeRelease( m_SourceFilter );
194     
195     CoCreateInstance( CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
196                       IID_ICreateDevEnum, (void**)&pCreateDevEnum );
197     
198     /* Create capture device */
199     if( pCreateDevEnum )
200     {
201         IMoniker* pMon = 0;
202         pCreateDevEnum->CreateClassEnumerator( CLSID_VideoInputDeviceCategory, &pEnumMon, 0);
203         
204         if( idx > 0 )
205             pEnumMon->Skip( idx );
206
207         if( pEnumMon && SUCCEEDED( pEnumMon->Next(1, &pMon, &cFetched)) && cFetched == 1 )
208         {
209             pMon->BindToObject(0, 0, IID_IBaseFilter, (void **)&m_SourceFilter );
210             SafeRelease( pMon );
211         }
212         SafeRelease( pEnumMon );
213         SafeRelease( pCreateDevEnum );
214     }
215
216     return m_SourceFilter != 0;
217 }
218
219
220 static const GUID CLSID_BouncingBall = 
221 {0xFD501041,0x8EBE,0x11CE, {0x81, 0x83, 0x00, 0xAA, 0x00, 0x57, 0x7D, 0xA1 }};
222
223 /*static const GUID CLSID_AsyncFile = 
224 {0xE436EBB5,0x524F,0x11CE,{0x9F,0x53,0x00,0x20,0xAF,0x0B,0xA7,0x70}};*/
225
226 static const GUID CLSID_ColorSpaceConverter = 
227 {0x1643E180,0x90F5,0x11CE, {0x97, 0xD5, 0x00, 0xAA, 0x00, 0x55, 0x59, 0x5A }};
228
229 void CMainFrame::CreateBouncingBall()
230 {
231     SafeRelease( m_SourceFilter );
232     
233     CoCreateInstance( CLSID_BouncingBall, NULL, CLSCTX_INPROC_SERVER, 
234                       IID_IBaseFilter, (void **)&m_SourceFilter );
235 }
236
237 /* Create filter graph */
238 bool CMainFrame::CreateFilterGraph()
239 {
240     HRESULT hr = S_OK;
241
242     /* create graph objects */
243     if( m_CamShiftProp != 0 )
244     {
245         CoCreateInstance( CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, 
246                           IID_IGraphBuilder, (void **)&m_GraphBuilder );
247
248         if( m_GraphBuilder != 0 )
249         {
250             m_GraphBuilder->QueryInterface(IID_IMediaControl,(void**)&m_MediaControl);
251             m_GraphBuilder->QueryInterface(IID_IMediaEventEx,(void**)&m_MediaEventEx);
252             m_GraphBuilder->QueryInterface(IID_IVideoWindow, (void**)&m_VideoWindow );
253             m_GraphBuilder->QueryInterface(IID_IFilterGraph, (void**)&m_FilterGraph);
254
255             if( m_MediaEventEx )
256             {
257                 // Have the graph signal event via window callbacks for performance
258                 m_MediaEventEx->SetNotifyWindow((OAHWND)m_hWnd, WM_GRAPHNOTIFY, 0);
259             }
260         }
261     }
262
263     /* link filters */
264     if( m_FilterGraph )
265     {
266         if( m_input == 2 )
267         {
268             WCHAR wname[1000] = L"";
269             CFileDialog open_dlg( true, 0, 0, OFN_FILEMUSTEXIST, "All files|*.*||", this );
270     
271             if( open_dlg.DoModal() )
272             {
273                 CString str = open_dlg.GetPathName();
274                 if( str.GetLength() > 0 )
275                 {
276                     MultiByteToWideChar( CP_ACP, 0, str, -1, wname, sizeof(wname)/2 );
277                     m_FilterGraph->AddFilter( m_CamShift, L"CamShift" );
278                     m_GraphBuilder->RenderFile( wname, 0 );
279                 }
280             }
281         }
282         else if( m_SourceFilter )
283         {
284             hr = m_FilterGraph->AddFilter( m_SourceFilter, L"Video Source" );
285
286             /*if( SUCCEEDED(hr))
287                 hr = m_SourceFilter->JoinFilterGraph( m_FilterGraph, L"Video Source" );*/
288
289             IPin* pSourceOut    = get_pin( m_SourceFilter, PINDIR_OUTPUT );
290             IPin* pCamShiftIn   = get_pin( m_CamShift, PINDIR_INPUT );
291             IPin* pCamShiftOut  = get_pin( m_CamShift, PINDIR_OUTPUT );
292
293             if( SUCCEEDED(hr))
294                 hr = m_FilterGraph->AddFilter( m_CamShift, L"CamShift" );
295
296             if( SUCCEEDED(hr))
297                 hr = m_GraphBuilder->Connect( pSourceOut, pCamShiftIn );
298
299             if( SUCCEEDED(hr))
300                 hr = m_GraphBuilder->Render( pCamShiftOut );
301
302             SafeRelease( pSourceOut );
303             SafeRelease( pCamShiftIn );
304             SafeRelease( pCamShiftOut );
305
306             if( FAILED(hr))
307                 DestroyFilterGraph();
308         }
309     }
310
311     return m_FilterGraph != 0 && hr >= 0;
312 }
313
314
315 void CMainFrame::ClearFilterGraph()
316 {
317     if( m_FilterGraph )
318     {
319         IEnumFilters* pEnumFilters = 0;
320         m_FilterGraph->EnumFilters( &pEnumFilters );
321
322         if( pEnumFilters )
323         {
324             IBaseFilter* pFilter = 0;
325             ULONG cFetched = 0;
326             while( pEnumFilters->Next( 1, &pFilter, &cFetched ) == S_OK && pFilter != 0 )
327             {
328                 m_FilterGraph->RemoveFilter( pFilter );
329                 SafeRelease( pFilter );
330                 cFetched = 0;
331             }
332             SafeRelease( pEnumFilters );
333         }
334     }
335 }
336
337
338 // Destroy DirectShow Filter Graph
339 void CMainFrame::DestroyFilterGraph()
340 {
341     StopGraph();
342     ClearFilterGraph();
343     
344     SafeRelease( m_VideoWindow  );
345     SafeRelease( m_FilterGraph );
346     SafeRelease( m_GraphBuilder );
347     SafeRelease( m_MediaControl );
348     SafeRelease( m_MediaEventEx );
349     SafeRelease( m_SourceFilter );
350 }
351
352
353 int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
354 {
355     if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
356         return -1;
357     
358     if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
359         | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
360         !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
361     {
362         TRACE0("Failed to create toolbar\n");
363         return -1;      // fail to create
364     }
365     
366     if (!m_wndStatusBar.Create(this) ||
367         !m_wndStatusBar.SetIndicators(indicators,
368         sizeof(indicators)/sizeof(UINT)))
369     {
370         TRACE0("Failed to create status bar\n");
371         return -1;      // fail to create
372     }
373     
374     m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
375     EnableDocking(CBRS_ALIGN_ANY);
376     DockControlBar(&m_wndToolBar);
377
378     m_wndBar.Create( this, IDD_BAR,CBRS_BOTTOM, IDC_BAR );
379
380     CoInitialize(0);
381
382     if( !CreateCamShift())
383     {
384         MessageBox("Can't create CamShift filter");
385         return -1;
386     }
387     
388     // Initialize sliders
389     CSliderCtrl* threshold = (CSliderCtrl*)m_wndBar.GetDlgItem(IDC_THRESHOLD);
390     CSliderCtrl* bins      = (CSliderCtrl*)m_wndBar.GetDlgItem(IDC_BINS);
391     CSliderCtrl* smin      = (CSliderCtrl*)m_wndBar.GetDlgItem(IDC_SMIN);
392     CSliderCtrl* vmin      = (CSliderCtrl*)m_wndBar.GetDlgItem(IDC_VMIN);
393     CSliderCtrl* vmax      = (CSliderCtrl*)m_wndBar.GetDlgItem(IDC_VMAX);
394     CSliderCtrl* wndWidth  = (CSliderCtrl*)m_wndBar.GetDlgItem(IDC_WIN_WIDTH);
395     CSliderCtrl* wndHeight = (CSliderCtrl*)m_wndBar.GetDlgItem(IDC_WIN_HEIGHT);
396
397     CvCamShiftParams params;
398     m_CamShiftProp->GetParams( &params );
399
400     smin->SetRange( 0, 255 );
401     vmin->SetRange( 0, 255 );
402     vmax->SetRange( 0, 255 );
403     threshold->SetRange( 0, 255 );
404     threshold->SetTicFreq( 16 );
405     bins->SetRange( 2, 255 );
406     bins->SetTicFreq( 10 );
407     
408     m_wndBar.WriteParamsToControls( params );
409
410
411     wndWidth->SetRange( 10, 100 );
412     wndHeight->SetRange( 10, 100 );
413     wndWidth->SetPos( 100 );
414     wndHeight->SetPos( 100 );
415
416     return 0;
417 }
418
419 BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
420 {
421     if( !CFrameWnd::PreCreateWindow(cs) )
422         return FALSE;
423     return TRUE;
424 }
425
426 /////////////////////////////////////////////////////////////////////////////
427 // CMainFrame diagnostics
428
429 #ifdef _DEBUG
430 void CMainFrame::AssertValid() const
431 {
432     CFrameWnd::AssertValid();
433 }
434
435 void CMainFrame::Dump(CDumpContext& dc) const
436 {
437     CFrameWnd::Dump(dc);
438 }
439
440 #endif //_DEBUG
441
442 /////////////////////////////////////////////////////////////////////////////
443 // CMainFrame message handlers
444
445
446 void CMainFrame::OnDestroy() 
447 {
448     DestroyFilterGraph();
449
450     SafeRelease( m_FilterGraph );
451     SafeRelease( m_CamShift );
452     SafeRelease( m_CamShiftProp );
453     SafeRelease( m_SourceFilter );
454
455     CoUninitialize();
456     CFrameWnd::OnDestroy();
457 }
458
459 void CMainFrame::StartGraph() 
460 {
461     if( m_MediaControl )
462     {
463         CWnd* av = GetActiveView();
464
465         m_VideoWindow->put_Owner((OAHWND)av->m_hWnd);
466         m_VideoWindow->put_WindowStyle(WS_CHILD|WS_CLIPSIBLINGS|WS_CLIPCHILDREN);
467         m_VideoWindow->put_MessageDrain((OAHWND)av->m_hWnd);
468         //m_CamShiftProp->StartTracking();
469
470         SetVideoWindowSize(); 
471         m_MediaControl->Run();
472     }
473 }
474
475 void CMainFrame::StopGraph() 
476 {
477     if( m_CamShiftProp ) m_CamShiftProp->StopTracking();
478     if( m_MediaControl )
479     {
480         m_MediaControl->Stop();
481         m_VideoWindow->put_Visible(OAFALSE);
482         m_VideoWindow->put_Owner(NULL);
483         m_VideoWindow->put_MessageDrain(0);
484     }
485 }
486
487 void CMainFrame::OnSize(UINT nType, int cx, int cy) 
488 {
489     CFrameWnd::OnSize(nType, cx, cy);
490     SetVideoWindowSize();
491 }
492
493
494 CRect  CMainFrame::StartTrackerInit()
495 {
496     CRect r( 0, 0, 320, 240 );
497     if( m_MediaControl )
498     {
499         AM_MEDIA_TYPE am;
500         OAFilterState fs = State_Stopped;
501         m_MediaControl->GetState( 0, &fs );
502
503         if( fs == State_Running )
504         {
505             if( m_input != 0 )
506                 m_MediaControl->Pause();
507             else
508                 m_MediaControl->Stop();
509         }
510         
511         IPin* pCamShiftIn = get_pin( m_CamShift, PINDIR_INPUT );
512         pCamShiftIn->ConnectionMediaType( &am );
513
514         if( am.pbFormat )
515         {
516             r.right  = ((VIDEOINFOHEADER*)am.pbFormat)->bmiHeader.biWidth;
517             r.bottom = ((VIDEOINFOHEADER*)am.pbFormat)->bmiHeader.biHeight;
518             r.bottom = abs( r.bottom );
519         }
520         else
521         {
522             r.SetRect(0,0,0,0);
523         }
524
525         pCamShiftIn->Release();
526     }
527
528     m_src_rect = r;
529
530     return r;
531 }
532
533
534 void  CMainFrame::EndTrackerInit( CRect r )
535 {
536     if( m_MediaControl && m_CamShiftProp &&
537         !r.IsRectEmpty() && !m_src_rect.IsRectEmpty())
538     {
539         CvCamShiftParams params;
540         m_wndBar.ReadParamsFromControls( params );
541
542         params.x = ((float)r.left)/max(m_src_rect.Width(),1);
543         params.y = ((float)r.top)/max(m_src_rect.Height(),1);
544         params.width = ((float)r.Width())/max(m_src_rect.Width(),1);
545         params.height = ((float)r.Height())/max(m_src_rect.Height(),1);
546
547         m_CamShiftProp->SetParams( &params ); 
548         if( !r.IsRectEmpty() )
549             m_CamShiftProp->StartTracking();
550         else
551             m_CamShiftProp->StopTracking();
552
553         m_MediaControl->Run();
554     }
555 }
556
557 void  CMainFrame::OnCamera()
558 {
559     m_input = 0;
560     ChangeSource();
561 }
562
563 void CMainFrame::OnUpdateCamera(CCmdUI* pCmdUI) 
564 {
565     pCmdUI->SetCheck( m_input == 0 );
566 }
567
568
569 void  CMainFrame::OnBall()
570 {
571     m_input = 1;
572     ChangeSource();
573 }
574
575 void CMainFrame::OnUpdateBall(CCmdUI* pCmdUI) 
576 {
577     pCmdUI->SetCheck( m_input == 1 );
578 }
579
580 void CMainFrame::OnFile() 
581 {
582     m_input = 2;
583     ChangeSource();
584 }
585
586
587 void CMainFrame::OnUpdateFile(CCmdUI* pCmdUI) 
588 {
589     pCmdUI->SetCheck( m_input == 2 );
590 }
591
592 void CMainFrame::ChangeSource()
593 {
594     StopGraph();
595     DestroyFilterGraph();
596
597     if( m_input < 2 )
598     {
599         switch( m_input )
600         {
601         case 0: /* camera */ CreateCamera();
602             break;
603         default: /* ball */ CreateBouncingBall();
604             break;
605         }
606
607         if( m_SourceFilter == 0 )
608         {
609             m_input = -1;
610             return;
611         }
612     }
613
614     if( !CreateFilterGraph() && m_input == 0 )
615     {
616         for( int i = 1; i <= 10; i++ )
617         {
618             CreateCamera(i);
619             if( CreateFilterGraph())
620                 break;
621         }
622     }
623
624     if( m_SourceFilter )
625         show_prop_page( m_SourceFilter, L"Video Source Properties" );
626
627     StartGraph();
628 }
629
630
631 void CMainFrame::OnPlayPause() 
632 {
633     if( m_MediaControl )
634     {
635         OAFilterState fs = State_Stopped;
636         if( m_MediaControl->GetState( 0, &fs ) == S_OK )
637         {
638             if( fs == State_Running )
639                 m_MediaControl->Pause();
640             else if( fs == State_Paused )
641                 m_MediaControl->Run();
642         }
643     }
644 }
645
646
647 void CMainFrame::OnUpdatePlayPause(CCmdUI* pCmdUI) 
648 {
649     OAFilterState fs = State_Stopped;
650     if( m_MediaControl )
651     {
652         m_MediaControl->GetState( 0, &fs );
653     }
654     pCmdUI->SetCheck( fs == State_Running );
655     pCmdUI->Enable( fs == State_Running || fs == State_Paused );
656 }
657
658
659 void CMainFrame::GetScaleFactor( int& sx, int &sy )
660 {
661     sx = ((CSliderCtrl*)m_wndBar.GetDlgItem(IDC_WIN_WIDTH))->GetPos();
662     sy = ((CSliderCtrl*)m_wndBar.GetDlgItem(IDC_WIN_HEIGHT))->GetPos();
663 }
664
665 CRect CMainFrame::GetVideoWindowSize() 
666 {
667     CWnd* av = GetActiveView();
668     CRect rc;
669     if( av )
670     {
671         int width, height;
672         GetScaleFactor( width, height );
673
674         av->GetClientRect( &rc );
675
676         rc.right  = rc.right * width / 100;
677         rc.bottom = rc.bottom * height / 100;
678     }
679
680     return rc;
681 }
682
683
684 void CMainFrame::SetVideoWindowSize() 
685 {
686     CRect rc = GetVideoWindowSize();
687     if( m_VideoWindow )
688     {
689         m_VideoWindow->SetWindowPosition( rc.left, rc.top, rc.right, rc.bottom );
690     }
691 }
692
693
694 /////////////////////////////////////////////////////////////////////////////
695 // CBar dialog
696
697
698 CBar::CBar() : CDialogBar()
699 {
700     //{{AFX_DATA_INIT(CBar)
701     m_Threshold = 0;
702     m_Smin = 0;
703     m_Vmax = 0;
704     m_Vmin = 0;
705     m_Bins = 0;
706     m_ShowPicture = TRUE;
707     m_ShowBackProject = FALSE;
708     m_ShowHistogram = FALSE;
709     //}}AFX_DATA_INIT
710 }
711
712
713 void CBar::DoDataExchange(CDataExchange* pDX)
714 {
715     CDialogBar::DoDataExchange(pDX);
716     //{{AFX_DATA_MAP(CBar)
717     DDX_Check(pDX,  IDC_PICTURE, m_ShowPicture );
718     DDX_Check(pDX,  IDC_BACKPROJECT, m_ShowBackProject );
719     DDX_Check(pDX,  IDC_HISTOGRAM, m_ShowHistogram );
720     DDX_Slider(pDX, IDC_SMIN, m_Smin);
721     DDX_Slider(pDX, IDC_THRESHOLD, m_Threshold);
722     DDX_Slider(pDX, IDC_VMAX, m_Vmax);
723     DDX_Slider(pDX, IDC_VMIN, m_Vmin);
724     DDX_Slider(pDX, IDC_BINS, m_Bins);
725     //}}AFX_DATA_MAP
726 }
727
728
729 BEGIN_MESSAGE_MAP(CBar, CDialogBar)
730     //{{AFX_MSG_MAP(CBar)
731     ON_WM_HSCROLL()
732     ON_BN_CLICKED(IDC_PICTURE, OnPicture)
733     ON_BN_CLICKED(IDC_BACKPROJECT, OnBackProject)
734     ON_BN_CLICKED(IDC_HISTOGRAM, OnHistogram)
735     //}}AFX_MSG_MAP
736 END_MESSAGE_MAP()
737
738 /////////////////////////////////////////////////////////////////////////////
739 // CBar message handlers
740
741 void CBar::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
742 {
743     int  code = pScrollBar->GetDlgCtrlID();
744     CMainFrame* mainframe = (CMainFrame*)AfxGetMainWnd();
745
746     UpdateData(1);
747     
748     switch( code )
749     {
750     case IDC_SMIN:
751     case IDC_VMIN:
752     case IDC_VMAX:
753     case IDC_THRESHOLD:
754     case IDC_BINS:
755         if( mainframe->m_CamShiftProp )
756         {
757             CvCamShiftParams params;
758             mainframe->m_CamShiftProp->GetParams( &params );
759             int bins = params.bins;
760             ReadParamsFromControls( params );
761             mainframe->m_CamShiftProp->SetParams( &params );
762             if( bins != params.bins )
763             {
764                 mainframe->m_CamShiftProp->StartTracking();
765             }
766         }
767         break;
768     case IDC_WIN_WIDTH:
769     case IDC_WIN_HEIGHT:
770         mainframe->SetVideoWindowSize();
771         break;
772     default:
773         ASSERT(0);
774     }
775 }
776
777 void CBar::OnPicture() 
778 {
779     UpdateData(1);
780     CMainFrame* mainframe = (CMainFrame*)AfxGetMainWnd();
781     if( mainframe->m_CamShiftProp )
782     {
783         CvCamShiftParams params;
784         mainframe->m_CamShiftProp->GetParams( &params );
785         params.view = 0;
786         mainframe->m_CamShiftProp->SetParams( &params );
787     }
788 }
789
790 void CBar::OnBackProject() 
791 {
792     UpdateData(1);
793     CMainFrame* mainframe = (CMainFrame*)AfxGetMainWnd();
794     if( mainframe->m_CamShiftProp )
795     {
796         CvCamShiftParams params;
797         mainframe->m_CamShiftProp->GetParams( &params );
798         params.view = 1;
799         mainframe->m_CamShiftProp->SetParams( &params );
800     }
801 }
802
803 void CBar::OnHistogram() 
804 {
805     UpdateData(1);
806     CMainFrame* mainframe = (CMainFrame*)AfxGetMainWnd();
807     if( mainframe->m_CamShiftProp )
808     {
809         CvCamShiftParams params;
810         mainframe->m_CamShiftProp->GetParams( &params );
811         params.view = 2;
812         mainframe->m_CamShiftProp->SetParams( &params );
813     }
814 }
815
816
817 CBar::ReadParamsFromControls( CvCamShiftParams& params )
818 {
819     CSliderCtrl* threshold = (CSliderCtrl*)GetDlgItem(IDC_THRESHOLD);
820     CSliderCtrl* bins      = (CSliderCtrl*)GetDlgItem(IDC_BINS);
821     CSliderCtrl* smin      = (CSliderCtrl*)GetDlgItem(IDC_SMIN);
822     CSliderCtrl* vmin      = (CSliderCtrl*)GetDlgItem(IDC_VMIN);
823     CSliderCtrl* vmax      = (CSliderCtrl*)GetDlgItem(IDC_VMAX);
824     params.view = ((CButton*)GetDlgItem(IDC_PICTURE))->GetCheck() ? 0 :
825                   ((CButton*)GetDlgItem(IDC_BACKPROJECT))->GetCheck() ? 1 : 2;
826     
827     params.Smin = smin->GetPos();
828     params.Vmin = vmin->GetPos();
829     params.Vmax = vmax->GetPos();
830
831     params.threshold = threshold->GetPos();
832
833     params.bins = bins->GetPos();
834 }
835
836
837 CBar::WriteParamsToControls( CvCamShiftParams& params )
838 {
839     CSliderCtrl* threshold = (CSliderCtrl*)GetDlgItem(IDC_THRESHOLD);
840     CSliderCtrl* bins      = (CSliderCtrl*)GetDlgItem(IDC_BINS);
841     CSliderCtrl* smin      = (CSliderCtrl*)GetDlgItem(IDC_SMIN);
842     CSliderCtrl* vmin      = (CSliderCtrl*)GetDlgItem(IDC_VMIN);
843     CSliderCtrl* vmax      = (CSliderCtrl*)GetDlgItem(IDC_VMAX);
844     
845     smin->SetPos( params.Smin );
846
847     vmin->SetRange( 0, 255 );
848     vmin->SetPos( params.Vmin );
849
850     vmax->SetRange( 0, 255 );
851     vmax->SetPos( params.Vmax );
852
853     threshold->SetRange( 0, 255 );
854     threshold->SetPos( params.threshold );
855     threshold->SetTicFreq( 16 );
856
857     bins->SetRange( 2, 255 );
858     bins->SetPos( params.bins );
859     bins->SetTicFreq( 10 );
860
861     ((CButton*)GetDlgItem(IDC_PICTURE))->SetCheck( params.view == 0 );
862     ((CButton*)GetDlgItem(IDC_BACKPROJECT))->SetCheck( params.view == 1 );
863     ((CButton*)GetDlgItem(IDC_HISTOGRAM))->SetCheck( params.view == 2 );
864 }
865