00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "stdafx.h"
00026 #include "mplayerc.h"
00027
00028 #include "MainFrm.h"
00029
00030 #include <math.h>
00031
00032 #include <afxpriv.h>
00033
00034 #include <atlconv.h>
00035 #include <atlrx.h>
00036 #include <atlsync.h>
00037
00038 #include "OpenDlg.h"
00039 #include "SaveDlg.h"
00040 #include "GoToDlg.h"
00041 #include "PnSPresetsDlg.h"
00042 #include "MediaTypesDlg.h"
00043 #include "SaveTextFileDialog.h"
00044 #include "FavoriteAddDlg.h"
00045 #include "FavoriteOrganizeDlg.h"
00046 #include "ShaderEditorDlg.h"
00047 #include "ConvertDlg.h"
00048
00049 #include <mtype.h>
00050 #include <Mpconfig.h>
00051 #include <ks.h>
00052 #include <ksmedia.h>
00053 #include <dvdevcod.h>
00054 #include <dsound.h>
00055
00056 #include <initguid.h>
00057 #include <uuids.h>
00058 #include "..\..\..\include\moreuuids.h"
00059 #include "..\..\..\include\Ogg\OggDS.h"
00060 #include <Qnetwork.h>
00061 #include <qedit.h>
00062
00063 #include "..\..\DSUtil\DSUtil.h"
00064
00065 #include "GraphBuilder.h"
00066
00067 #include "textpassthrufilter.h"
00068 #include "..\..\filters\filters.h"
00069
00070 #include "DX7AllocatorPresenter.h"
00071 #include "DX9AllocatorPresenter.h"
00072
00073 #include "..\..\..\include\matroska\matroska.h"
00074
00075 #define DEFCLIENTW 292
00076 #define DEFCLIENTH 200
00077
00078 static UINT s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated"));
00079 static UINT WM_NOTIFYICON = RegisterWindowMessage(TEXT("MYWM_NOTIFYICON"));
00080
00081 #include "..\..\filters\transform\vsfilter\IDirectVobSub.h"
00082
00083 class CSubClock : public CUnknown, public ISubClock
00084 {
00085 STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv)
00086 {
00087 return
00088 QI(ISubClock)
00089 CUnknown::NonDelegatingQueryInterface(riid, ppv);
00090 }
00091
00092 REFERENCE_TIME m_rt;
00093
00094 public:
00095 CSubClock() : CUnknown(NAME("CSubClock"), NULL) {m_rt = 0;}
00096
00097 DECLARE_IUNKNOWN;
00098
00099
00100 STDMETHODIMP SetTime(REFERENCE_TIME rt) {m_rt = rt; return S_OK;}
00101 STDMETHODIMP_(REFERENCE_TIME) GetTime() {return(m_rt);}
00102 };
00103
00104
00105
00106 #define SaveMediaState \
00107 OAFilterState __fs = GetMediaState(); \
00108 \
00109 REFERENCE_TIME __rt = 0; \
00110 if(m_iMediaLoadState == MLS_LOADED) __rt = GetPos(); \
00111 \
00112 if(__fs != State_Stopped) \
00113 SendMessage(WM_COMMAND, ID_PLAY_STOP); \
00114
00115
00116 #define RestoreMediaState \
00117 if(m_iMediaLoadState == MLS_LOADED) \
00118 { \
00119 SeekTo(__rt); \
00120 \
00121 if(__fs == State_Stopped) \
00122 SendMessage(WM_COMMAND, ID_PLAY_STOP); \
00123 else if(__fs == State_Paused) \
00124 SendMessage(WM_COMMAND, ID_PLAY_PAUSE); \
00125 else if(__fs == State_Running) \
00126 SendMessage(WM_COMMAND, ID_PLAY_PLAY); \
00127 } \
00128
00129
00130
00131
00132
00133
00134
00135
00137
00138
00139 IMPLEMENT_DYNAMIC(CMainFrame, CFrameWnd)
00140
00141 BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
00142 ON_WM_CREATE()
00143 ON_WM_DESTROY()
00144 ON_WM_CLOSE()
00145
00146 ON_REGISTERED_MESSAGE(s_uTaskbarRestart, OnTaskBarRestart)
00147 ON_REGISTERED_MESSAGE(WM_NOTIFYICON, OnNotifyIcon)
00148
00149 ON_WM_SETFOCUS()
00150 ON_WM_GETMINMAXINFO()
00151 ON_WM_MOVE()
00152 ON_WM_SIZE()
00153 ON_MESSAGE_VOID(WM_DISPLAYCHANGE, OnDisplayChange)
00154
00155 ON_WM_SYSCOMMAND()
00156 ON_WM_ACTIVATEAPP()
00157 ON_MESSAGE(WM_APPCOMMAND, OnAppCommand)
00158
00159 ON_WM_TIMER()
00160
00161 ON_MESSAGE(WM_GRAPHNOTIFY, OnGraphNotify)
00162 ON_MESSAGE(WM_REARRANGERENDERLESS, OnRepaintRenderLess)
00163 ON_MESSAGE(WM_RESUMEFROMSTATE, OnResumeFromState)
00164
00165 ON_WM_LBUTTONDOWN()
00166 ON_WM_LBUTTONUP()
00167 ON_WM_LBUTTONDBLCLK()
00168 ON_WM_MBUTTONDOWN()
00169 ON_WM_MBUTTONUP()
00170 ON_WM_MBUTTONDBLCLK()
00171 ON_WM_RBUTTONDOWN()
00172 ON_WM_RBUTTONUP()
00173 ON_WM_RBUTTONDBLCLK()
00174 ON_MESSAGE(WM_XBUTTONDOWN, OnXButtonDown)
00175 ON_MESSAGE(WM_XBUTTONUP, OnXButtonUp)
00176 ON_MESSAGE(WM_XBUTTONDBLCLK, OnXButtonDblClk)
00177 ON_WM_MOUSEWHEEL()
00178 ON_WM_MOUSEMOVE()
00179
00180 ON_WM_NCHITTEST()
00181
00182 ON_WM_HSCROLL()
00183
00184 ON_WM_INITMENU()
00185 ON_WM_INITMENUPOPUP()
00186
00187 ON_COMMAND(ID_MENU_PLAYER_SHORT, OnMenuPlayerShort)
00188 ON_COMMAND(ID_MENU_PLAYER_LONG, OnMenuPlayerLong)
00189 ON_COMMAND(ID_MENU_FILTERS, OnMenuFilters)
00190
00191 ON_UPDATE_COMMAND_UI(ID_PLAYERSTATUS, OnUpdatePlayerStatus)
00192
00193 ON_COMMAND(ID_FILE_POST_OPENMEDIA, OnFilePostOpenmedia)
00194 ON_UPDATE_COMMAND_UI(ID_FILE_POST_OPENMEDIA, OnUpdateFilePostOpenmedia)
00195 ON_COMMAND(ID_FILE_POST_CLOSEMEDIA, OnFilePostClosemedia)
00196 ON_UPDATE_COMMAND_UI(ID_FILE_POST_CLOSEMEDIA, OnUpdateFilePostClosemedia)
00197
00198 ON_COMMAND(ID_BOSS, OnBossKey)
00199
00200 ON_COMMAND_RANGE(ID_STREAM_AUDIO_NEXT, ID_STREAM_AUDIO_PREV, OnStreamAudio)
00201 ON_COMMAND_RANGE(ID_STREAM_SUB_NEXT, ID_STREAM_SUB_PREV, OnStreamSub)
00202 ON_COMMAND(ID_STREAM_SUB_ONOFF, OnStreamSubOnOff)
00203 ON_COMMAND_RANGE(ID_OGM_AUDIO_NEXT, ID_OGM_AUDIO_PREV, OnOgmAudio)
00204 ON_COMMAND_RANGE(ID_OGM_SUB_NEXT, ID_OGM_SUB_PREV, OnOgmSub)
00205 ON_COMMAND_RANGE(ID_DVD_ANGLE_NEXT, ID_DVD_ANGLE_PREV, OnDvdAngle)
00206 ON_COMMAND_RANGE(ID_DVD_AUDIO_NEXT, ID_DVD_AUDIO_PREV, OnDvdAudio)
00207 ON_COMMAND_RANGE(ID_DVD_SUB_NEXT, ID_DVD_SUB_PREV, OnDvdSub)
00208 ON_COMMAND(ID_DVD_SUB_ONOFF, OnDvdSubOnOff)
00209
00210 ON_COMMAND(ID_FILE_OPENMEDIA, OnFileOpenmedia)
00211 ON_UPDATE_COMMAND_UI(ID_FILE_OPENMEDIA, OnUpdateFileOpen)
00212 ON_WM_COPYDATA()
00213 ON_COMMAND(ID_FILE_OPENDVD, OnFileOpendvd)
00214 ON_UPDATE_COMMAND_UI(ID_FILE_OPENDVD, OnUpdateFileOpen)
00215 ON_COMMAND(ID_FILE_OPENDEVICE, OnFileOpendevice)
00216 ON_UPDATE_COMMAND_UI(ID_FILE_OPENDEVICE, OnUpdateFileOpen)
00217 ON_COMMAND_RANGE(ID_FILE_OPEN_CD_START, ID_FILE_OPEN_CD_END, OnFileOpenCD)
00218 ON_UPDATE_COMMAND_UI_RANGE(ID_FILE_OPEN_CD_START, ID_FILE_OPEN_CD_END, OnUpdateFileOpen)
00219 ON_WM_DROPFILES()
00220 ON_COMMAND(ID_FILE_SAVEAS, OnFileSaveas)
00221 ON_UPDATE_COMMAND_UI(ID_FILE_SAVEAS, OnUpdateFileSaveas)
00222 ON_COMMAND(ID_FILE_SAVE_IMAGE, OnFileSaveImage)
00223 ON_COMMAND(ID_FILE_SAVE_IMAGE_AUTO, OnFileSaveImageAuto)
00224 ON_UPDATE_COMMAND_UI(ID_FILE_SAVE_IMAGE, OnUpdateFileSaveImage)
00225 ON_UPDATE_COMMAND_UI(ID_FILE_SAVE_IMAGE_AUTO, OnUpdateFileSaveImage)
00226 ON_COMMAND(ID_FILE_CONVERT, OnFileConvert)
00227 ON_UPDATE_COMMAND_UI(ID_FILE_CONVERT, OnUpdateFileConvert)
00228 ON_COMMAND(ID_FILE_LOADSUBTITLE, OnFileLoadsubtitles)
00229 ON_UPDATE_COMMAND_UI(ID_FILE_LOADSUBTITLE, OnUpdateFileLoadsubtitles)
00230 ON_COMMAND(ID_FILE_SAVESUBTITLES, OnFileSavesubtitles)
00231 ON_UPDATE_COMMAND_UI(ID_FILE_SAVESUBTITLES, OnUpdateFileSavesubtitles)
00232 ON_COMMAND(ID_SUBTITLEDATABASE_SEARCH, OnSubtitledatabaseSearch)
00233 ON_UPDATE_COMMAND_UI(ID_SUBTITLEDATABASE_SEARCH, OnUpdateSubtitledatabaseSearch)
00234 ON_COMMAND(ID_SUBTITLEDATABASE_UPLOAD, OnSubtitledatabaseUpload)
00235 ON_UPDATE_COMMAND_UI(ID_SUBTITLEDATABASE_UPLOAD, OnUpdateSubtitledatabaseUpload)
00236 ON_COMMAND(ID_SUBTITLEDATABASE_DOWNLOAD, OnSubtitledatabaseDownload)
00237 ON_UPDATE_COMMAND_UI(ID_SUBTITLEDATABASE_DOWNLOAD, OnUpdateSubtitledatabaseDownload)
00238 ON_COMMAND(ID_FILE_PROPERTIES, OnFileProperties)
00239 ON_UPDATE_COMMAND_UI(ID_FILE_PROPERTIES, OnUpdateFileProperties)
00240 ON_COMMAND(ID_FILE_CLOSEPLAYLIST, OnFileClosePlaylist)
00241 ON_COMMAND(ID_FILE_CLOSEMEDIA, OnFileCloseMedia)
00242 ON_UPDATE_COMMAND_UI(ID_FILE_CLOSEMEDIA, OnUpdateFileClose)
00243
00244 ON_COMMAND(ID_VIEW_CAPTIONMENU, OnViewCaptionmenu)
00245 ON_UPDATE_COMMAND_UI(ID_VIEW_CAPTIONMENU, OnUpdateViewCaptionmenu)
00246 ON_COMMAND_RANGE(ID_VIEW_SEEKER, ID_VIEW_STATUS, OnViewControlBar)
00247 ON_UPDATE_COMMAND_UI_RANGE(ID_VIEW_SEEKER, ID_VIEW_STATUS, OnUpdateViewControlBar)
00248 ON_COMMAND(ID_VIEW_SUBRESYNC, OnViewSubresync)
00249 ON_UPDATE_COMMAND_UI(ID_VIEW_SUBRESYNC, OnUpdateViewSubresync)
00250 ON_COMMAND(ID_VIEW_PLAYLIST, OnViewPlaylist)
00251 ON_UPDATE_COMMAND_UI(ID_VIEW_PLAYLIST, OnUpdateViewPlaylist)
00252 ON_COMMAND(ID_VIEW_CAPTURE, OnViewCapture)
00253 ON_UPDATE_COMMAND_UI(ID_VIEW_CAPTURE, OnUpdateViewCapture)
00254 ON_COMMAND(ID_VIEW_PRESETS_MINIMAL, OnViewMinimal)
00255 ON_UPDATE_COMMAND_UI(ID_VIEW_PRESETS_MINIMAL, OnUpdateViewMinimal)
00256 ON_COMMAND(ID_VIEW_PRESETS_COMPACT, OnViewCompact)
00257 ON_UPDATE_COMMAND_UI(ID_VIEW_PRESETS_COMPACT, OnUpdateViewCompact)
00258 ON_COMMAND(ID_VIEW_PRESETS_NORMAL, OnViewNormal)
00259 ON_UPDATE_COMMAND_UI(ID_VIEW_PRESETS_NORMAL, OnUpdateViewNormal)
00260 ON_COMMAND(ID_VIEW_FULLSCREEN, OnViewFullscreen)
00261 ON_COMMAND(ID_VIEW_FULLSCREEN_SECONDARY, OnViewFullscreenSecondary)
00262 ON_UPDATE_COMMAND_UI(ID_VIEW_FULLSCREEN, OnUpdateViewFullscreen)
00263 ON_COMMAND_RANGE(ID_VIEW_ZOOM_50, ID_VIEW_ZOOM_200, OnViewZoom)
00264 ON_UPDATE_COMMAND_UI_RANGE(ID_VIEW_ZOOM_50, ID_VIEW_ZOOM_200, OnUpdateViewZoom)
00265 ON_COMMAND_RANGE(ID_VIEW_VF_HALF, ID_VIEW_VF_FROMOUTSIDE, OnViewDefaultVideoFrame)
00266 ON_UPDATE_COMMAND_UI_RANGE(ID_VIEW_VF_HALF, ID_VIEW_VF_FROMOUTSIDE, OnUpdateViewDefaultVideoFrame)
00267 ON_COMMAND(ID_VIEW_VF_KEEPASPECTRATIO, OnViewKeepaspectratio)
00268 ON_UPDATE_COMMAND_UI(ID_VIEW_VF_KEEPASPECTRATIO, OnUpdateViewKeepaspectratio)
00269 ON_COMMAND(ID_VIEW_VF_COMPMONDESKARDIFF, OnViewCompMonDeskARDiff)
00270 ON_UPDATE_COMMAND_UI(ID_VIEW_VF_COMPMONDESKARDIFF, OnUpdateViewCompMonDeskARDiff)
00271 ON_COMMAND_RANGE(ID_VIEW_INCSIZE, ID_VIEW_RESET, OnViewPanNScan)
00272 ON_UPDATE_COMMAND_UI_RANGE(ID_VIEW_INCSIZE, ID_VIEW_RESET, OnUpdateViewPanNScan)
00273 ON_COMMAND_RANGE(ID_PANSCAN_MOVELEFT, ID_PANSCAN_CENTER, OnViewPanNScan)
00274 ON_UPDATE_COMMAND_UI_RANGE(ID_PANSCAN_MOVELEFT, ID_PANSCAN_CENTER, OnUpdateViewPanNScan)
00275 ON_COMMAND_RANGE(ID_PANNSCAN_PRESETS_START, ID_PANNSCAN_PRESETS_END, OnViewPanNScanPresets)
00276 ON_UPDATE_COMMAND_UI_RANGE(ID_PANNSCAN_PRESETS_START, ID_PANNSCAN_PRESETS_END, OnUpdateViewPanNScanPresets)
00277 ON_COMMAND_RANGE(ID_PANSCAN_ROTATEXP, ID_PANSCAN_ROTATEZM, OnViewRotate)
00278 ON_UPDATE_COMMAND_UI_RANGE(ID_PANSCAN_ROTATEXP, ID_PANSCAN_ROTATEZM, OnUpdateViewRotate)
00279 ON_COMMAND_RANGE(ID_ASPECTRATIO_START, ID_ASPECTRATIO_END, OnViewAspectRatio)
00280 ON_UPDATE_COMMAND_UI_RANGE(ID_ASPECTRATIO_START, ID_ASPECTRATIO_END, OnUpdateViewAspectRatio)
00281 ON_COMMAND_RANGE(ID_ONTOP_NEVER, ID_ONTOP_WHILEPLAYING, OnViewOntop)
00282 ON_UPDATE_COMMAND_UI_RANGE(ID_ONTOP_NEVER, ID_ONTOP_WHILEPLAYING, OnUpdateViewOntop)
00283 ON_COMMAND(ID_VIEW_OPTIONS, OnViewOptions)
00284
00285 ON_COMMAND(ID_PLAY_PLAY, OnPlayPlay)
00286 ON_COMMAND(ID_PLAY_PAUSE, OnPlayPause)
00287 ON_COMMAND(ID_PLAY_PLAYPAUSE, OnPlayPlaypause)
00288 ON_COMMAND(ID_PLAY_STOP, OnPlayStop)
00289 ON_UPDATE_COMMAND_UI(ID_PLAY_PLAY, OnUpdatePlayPauseStop)
00290 ON_UPDATE_COMMAND_UI(ID_PLAY_PAUSE, OnUpdatePlayPauseStop)
00291 ON_UPDATE_COMMAND_UI(ID_PLAY_PLAYPAUSE, OnUpdatePlayPauseStop)
00292 ON_UPDATE_COMMAND_UI(ID_PLAY_STOP, OnUpdatePlayPauseStop)
00293 ON_COMMAND_RANGE(ID_PLAY_FRAMESTEP, ID_PLAY_FRAMESTEPCANCEL, OnPlayFramestep)
00294 ON_UPDATE_COMMAND_UI_RANGE(ID_PLAY_FRAMESTEP, ID_PLAY_FRAMESTEPCANCEL, OnUpdatePlayFramestep)
00295 ON_COMMAND_RANGE(ID_PLAY_SEEKBACKWARDSMALL, ID_PLAY_SEEKFORWARDLARGE, OnPlaySeek)
00296 ON_COMMAND_RANGE(ID_PLAY_SEEKKEYBACKWARD, ID_PLAY_SEEKKEYFORWARD, OnPlaySeekKey)
00297 ON_UPDATE_COMMAND_UI_RANGE(ID_PLAY_SEEKBACKWARDSMALL, ID_PLAY_SEEKFORWARDLARGE, OnUpdatePlaySeek)
00298 ON_UPDATE_COMMAND_UI_RANGE(ID_PLAY_SEEKKEYBACKWARD, ID_PLAY_SEEKKEYFORWARD, OnUpdatePlaySeek)
00299 ON_COMMAND(ID_PLAY_GOTO, OnPlayGoto)
00300 ON_UPDATE_COMMAND_UI(ID_PLAY_GOTO, OnUpdateGoto)
00301 ON_COMMAND_RANGE(ID_PLAY_DECRATE, ID_PLAY_INCRATE, OnPlayChangeRate)
00302 ON_UPDATE_COMMAND_UI_RANGE(ID_PLAY_DECRATE, ID_PLAY_INCRATE, OnUpdatePlayChangeRate)
00303 ON_COMMAND(ID_PLAY_RESETRATE, OnPlayResetRate)
00304 ON_UPDATE_COMMAND_UI(ID_PLAY_RESETRATE, OnUpdatePlayResetRate)
00305 ON_COMMAND_RANGE(ID_PLAY_INCAUDDELAY, ID_PLAY_DECAUDDELAY, OnPlayChangeAudDelay)
00306 ON_UPDATE_COMMAND_UI_RANGE(ID_PLAY_INCAUDDELAY, ID_PLAY_DECAUDDELAY, OnUpdatePlayChangeAudDelay)
00307 ON_COMMAND_RANGE(ID_FILTERS_SUBITEM_START, ID_FILTERS_SUBITEM_END, OnPlayFilters)
00308 ON_UPDATE_COMMAND_UI_RANGE(ID_FILTERS_SUBITEM_START, ID_FILTERS_SUBITEM_END, OnUpdatePlayFilters)
00309 ON_COMMAND_RANGE(ID_SHADERS_START, ID_SHADERS_END, OnPlayShaders)
00310 ON_UPDATE_COMMAND_UI_RANGE(ID_SHADERS_START, ID_SHADERS_END, OnUpdatePlayShaders)
00311 ON_COMMAND_RANGE(ID_AUDIO_SUBITEM_START, ID_AUDIO_SUBITEM_END, OnPlayAudio)
00312 ON_UPDATE_COMMAND_UI_RANGE(ID_AUDIO_SUBITEM_START, ID_AUDIO_SUBITEM_END, OnUpdatePlayAudio)
00313 ON_COMMAND_RANGE(ID_SUBTITLES_SUBITEM_START, ID_SUBTITLES_SUBITEM_END, OnPlaySubtitles)
00314 ON_UPDATE_COMMAND_UI_RANGE(ID_SUBTITLES_SUBITEM_START, ID_SUBTITLES_SUBITEM_END, OnUpdatePlaySubtitles)
00315 ON_COMMAND_RANGE(ID_FILTERSTREAMS_SUBITEM_START, ID_FILTERSTREAMS_SUBITEM_END, OnPlayLanguage)
00316 ON_UPDATE_COMMAND_UI_RANGE(ID_FILTERSTREAMS_SUBITEM_START, ID_FILTERSTREAMS_SUBITEM_END, OnUpdatePlayLanguage)
00317 ON_COMMAND_RANGE(ID_VOLUME_UP, ID_VOLUME_MUTE, OnPlayVolume)
00318 ON_COMMAND_RANGE(ID_AFTERPLAYBACK_CLOSE, ID_AFTERPLAYBACK_DONOTHING, OnAfterplayback)
00319 ON_UPDATE_COMMAND_UI_RANGE(ID_AFTERPLAYBACK_CLOSE, ID_AFTERPLAYBACK_DONOTHING, OnUpdateAfterplayback)
00320
00321 ON_COMMAND_RANGE(ID_NAVIGATE_SKIPBACK, ID_NAVIGATE_SKIPFORWARD, OnNavigateSkip)
00322 ON_UPDATE_COMMAND_UI_RANGE(ID_NAVIGATE_SKIPBACK, ID_NAVIGATE_SKIPFORWARD, OnUpdateNavigateSkip)
00323 ON_COMMAND_RANGE(ID_NAVIGATE_SKIPBACKPLITEM, ID_NAVIGATE_SKIPFORWARDPLITEM, OnNavigateSkipPlaylistItem)
00324 ON_UPDATE_COMMAND_UI_RANGE(ID_NAVIGATE_SKIPBACKPLITEM, ID_NAVIGATE_SKIPFORWARDPLITEM, OnUpdateNavigateSkipPlaylistItem)
00325 ON_COMMAND_RANGE(ID_NAVIGATE_TITLEMENU, ID_NAVIGATE_CHAPTERMENU, OnNavigateMenu)
00326 ON_UPDATE_COMMAND_UI_RANGE(ID_NAVIGATE_TITLEMENU, ID_NAVIGATE_CHAPTERMENU, OnUpdateNavigateMenu)
00327 ON_COMMAND_RANGE(ID_NAVIGATE_AUDIO_SUBITEM_START, ID_NAVIGATE_AUDIO_SUBITEM_END, OnNavigateAudio)
00328 ON_COMMAND_RANGE(ID_NAVIGATE_SUBP_SUBITEM_START, ID_NAVIGATE_SUBP_SUBITEM_END, OnNavigateSubpic)
00329 ON_COMMAND_RANGE(ID_NAVIGATE_ANGLE_SUBITEM_START, ID_NAVIGATE_ANGLE_SUBITEM_END, OnNavigateAngle)
00330 ON_COMMAND_RANGE(ID_NAVIGATE_CHAP_SUBITEM_START, ID_NAVIGATE_CHAP_SUBITEM_END, OnNavigateChapters)
00331 ON_COMMAND_RANGE(ID_NAVIGATE_MENU_LEFT, ID_NAVIGATE_MENU_LEAVE, OnNavigateMenuItem)
00332 ON_UPDATE_COMMAND_UI_RANGE(ID_NAVIGATE_MENU_LEFT, ID_NAVIGATE_MENU_LEAVE, OnUpdateNavigateMenuItem)
00333
00334 ON_COMMAND(ID_FAVORITES_ADD, OnFavoritesAdd)
00335 ON_UPDATE_COMMAND_UI(ID_FAVORITES_ADD, OnUpdateFavoritesAdd)
00336 ON_COMMAND(ID_FAVORITES_ORGANIZE, OnFavoritesOrganize)
00337 ON_UPDATE_COMMAND_UI(ID_FAVORITES_ORGANIZE, OnUpdateFavoritesOrganize)
00338 ON_COMMAND_RANGE(ID_FAVORITES_FILE_START, ID_FAVORITES_FILE_END, OnFavoritesFile)
00339 ON_UPDATE_COMMAND_UI_RANGE(ID_FAVORITES_FILE_START, ID_FAVORITES_FILE_END, OnUpdateFavoritesFile)
00340 ON_COMMAND_RANGE(ID_FAVORITES_DVD_START, ID_FAVORITES_DVD_END, OnFavoritesDVD)
00341 ON_UPDATE_COMMAND_UI_RANGE(ID_FAVORITES_DVD_START, ID_FAVORITES_DVD_END, OnUpdateFavoritesDVD)
00342 ON_COMMAND_RANGE(ID_FAVORITES_DEVICE_START, ID_FAVORITES_DEVICE_END, OnFavoritesDevice)
00343 ON_UPDATE_COMMAND_UI_RANGE(ID_FAVORITES_DEVICE_START, ID_FAVORITES_DEVICE_END, OnUpdateFavoritesDevice)
00344
00345 ON_COMMAND(ID_HELP_HOMEPAGE, OnHelpHomepage)
00346 ON_COMMAND(ID_HELP_DOCUMENTATION, OnHelpDocumentation)
00347 ON_COMMAND(ID_HELP_DONATE, OnHelpDonate)
00348
00349 ON_WM_SIZING()
00350 END_MESSAGE_MAP()
00351
00352
00353
00354
00355 #pragma warning(disable : 4355)
00356
00357 CMainFrame::CMainFrame() :
00358 m_dwRegister(0),
00359 m_iMediaLoadState(MLS_CLOSED),
00360 m_iPlaybackMode(PM_NONE),
00361 m_iSpeedLevel(0),
00362 m_rtDurationOverride(-1),
00363 m_fFullScreen(false),
00364 m_fHideCursor(false),
00365 m_lastMouseMove(-1, -1),
00366 m_pLastBar(NULL),
00367 m_nLoops(0),
00368 m_iSubtitleSel(-1),
00369 m_ZoomX(1), m_ZoomY(1), m_PosX(0.5), m_PosY(0.5),
00370 m_AngleX(0), m_AngleY(0), m_AngleZ(0),
00371 m_fCustomGraph(false),
00372 m_fRealMediaGraph(false), m_fShockwaveGraph(false), m_fQuicktimeGraph(false),
00373 m_fFrameSteppingActive(false),
00374 m_fEndOfStream(false),
00375 m_fCapturing(false),
00376 m_fLiveWM(false),
00377 m_fOpeningAborted(false),
00378 m_fBuffering(false),
00379 m_fileDropTarget(this),
00380 m_fTrayIcon(false)
00381 {
00382
00383
00384 }
00385
00386 CMainFrame::~CMainFrame()
00387 {
00388
00389 }
00390
00391 int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
00392 {
00393 if(__super::OnCreate(lpCreateStruct) == -1)
00394 return -1;
00395
00396 m_popup.LoadMenu(IDR_POPUP);
00397 m_popupmain.LoadMenu(IDR_POPUPMAIN);
00398
00399 GetMenu()->ModifyMenu(ID_FAVORITES, MF_BYCOMMAND|MF_STRING, IDR_MAINFRAME, ResStr(IDS_FAVORITES_POPUP));
00400
00401
00402 if(!m_wndView.Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,
00403 CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, NULL))
00404 {
00405 TRACE0("Failed to create view window\n");
00406 return -1;
00407 }
00408
00409
00410
00411 if(!m_wndStatusBar.Create(this)
00412 || !m_wndStatsBar.Create(this)
00413 || !m_wndInfoBar.Create(this)
00414 || !m_wndToolBar.Create(this)
00415 || !m_wndSeekBar.Create(this))
00416 {
00417 TRACE0("Failed to create all control bars\n");
00418 return -1;
00419 }
00420
00421 m_bars.AddTail(&m_wndSeekBar);
00422 m_bars.AddTail(&m_wndToolBar);
00423 m_bars.AddTail(&m_wndInfoBar);
00424 m_bars.AddTail(&m_wndStatsBar);
00425 m_bars.AddTail(&m_wndStatusBar);
00426
00427 m_wndSeekBar.Enable(false);
00428
00429
00430
00431 EnableDocking(CBRS_ALIGN_ANY);
00432
00433 m_wndSubresyncBar.Create(this, &m_csSubLock);
00434 m_wndSubresyncBar.SetBarStyle(m_wndSubresyncBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
00435 m_wndSubresyncBar.EnableDocking(CBRS_ALIGN_ANY);
00436 m_wndSubresyncBar.SetHeight(200);
00437 LoadControlBar(&m_wndSubresyncBar, _T("ToolBars\\Subresync"), AFX_IDW_DOCKBAR_TOP);
00438
00439 m_wndPlaylistBar.Create(this);
00440 m_wndPlaylistBar.SetBarStyle(m_wndPlaylistBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
00441 m_wndPlaylistBar.EnableDocking(CBRS_ALIGN_ANY);
00442 m_wndPlaylistBar.SetHeight(100);
00443 LoadControlBar(&m_wndPlaylistBar, _T("ToolBars\\Playlist"), AFX_IDW_DOCKBAR_BOTTOM);
00444 m_wndPlaylistBar.LoadPlaylist();
00445
00446 m_wndCaptureBar.Create(this);
00447 m_wndCaptureBar.SetBarStyle(m_wndCaptureBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
00448 m_wndCaptureBar.EnableDocking(CBRS_ALIGN_LEFT|CBRS_ALIGN_RIGHT);
00449 LoadControlBar(&m_wndCaptureBar, _T("ToolBars\\Capture"), AFX_IDW_DOCKBAR_LEFT);
00450
00451 m_dockingbars.AddTail(&m_wndSubresyncBar);
00452 m_dockingbars.AddTail(&m_wndPlaylistBar);
00453 m_dockingbars.AddTail(&m_wndCaptureBar);
00454
00455 m_fileDropTarget.Register(this);
00456
00457 AppSettings& s = AfxGetAppSettings();
00458
00459 ShowControls(s.nCS);
00460
00461 SetAlwaysOnTop(s.iOnTop);
00462
00463 ShowTrayIcon(s.fTrayIcon);
00464
00465 SetFocus();
00466
00467 m_pGraphThread = (CGraphThread*)AfxBeginThread(RUNTIME_CLASS(CGraphThread));
00468
00469 if(m_pGraphThread)
00470 m_pGraphThread->SetMainFrame(this);
00471
00472 if(s.fEnableWebServer)
00473 StartWebServer(s.nWebServerPort);
00474
00475 return 0;
00476 }
00477
00478 void CMainFrame::OnDestroy()
00479 {
00480 ShowTrayIcon(false);
00481
00482 m_fileDropTarget.Revoke();
00483
00484 if(m_pGraphThread)
00485 {
00486 CAMEvent e;
00487 m_pGraphThread->PostThreadMessage(CGraphThread::TM_EXIT, 0, (LPARAM)&e);
00488 if(!e.Wait(5000))
00489 {
00490 TRACE(_T("ERROR: Must call TerminateThread() on CMainFrame::m_pGraphThread->m_hThread\n"));
00491 TerminateThread(m_pGraphThread->m_hThread, -1);
00492 }
00493 }
00494
00495 __super::OnDestroy();
00496 }
00497
00498 void CMainFrame::OnClose()
00499 {
00500 m_wndPlaylistBar.SavePlaylist();
00501
00502 SaveControlBar(&m_wndSubresyncBar, _T("ToolBars\\Subresync"));
00503 SaveControlBar(&m_wndPlaylistBar, _T("ToolBars\\Playlist"));
00504 SaveControlBar(&m_wndCaptureBar, _T("ToolBars\\Capture"));
00505
00506 ShowWindow(SW_HIDE);
00507
00508 CloseMedia();
00509
00510 __super::OnClose();
00511 }
00512
00513 DROPEFFECT CMainFrame::OnDragEnter(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point)
00514 {
00515 return DROPEFFECT_NONE;
00516 }
00517 DROPEFFECT CMainFrame::OnDragOver(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point)
00518 {
00519 UINT CF_URL = RegisterClipboardFormat(_T("UniformResourceLocator"));
00520 return pDataObject->IsDataAvailable(CF_URL) ? DROPEFFECT_COPY : DROPEFFECT_NONE;
00521 }
00522 BOOL CMainFrame::OnDrop(COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point)
00523 {
00524 UINT CF_URL = RegisterClipboardFormat(_T("UniformResourceLocator"));
00525
00526 BOOL bResult = FALSE;
00527
00528 if(pDataObject->IsDataAvailable(CF_URL))
00529 {
00530 FORMATETC fmt = {CF_URL, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
00531 if(HGLOBAL hGlobal = pDataObject->GetGlobalData(CF_URL, &fmt))
00532 {
00533 LPCSTR pText = (LPCSTR)GlobalLock(hGlobal);
00534 if(AfxIsValidString(pText))
00535 {
00536 CStringA url(pText);
00537
00538 SetForegroundWindow();
00539
00540 CList<CString> sl;
00541 sl.AddTail(CString(url));
00542
00543 if(m_wndPlaylistBar.IsWindowVisible())
00544 {
00545 m_wndPlaylistBar.Append(sl, true);
00546 }
00547 else
00548 {
00549 m_wndPlaylistBar.Open(sl, true);
00550 OpenCurPlaylistItem();
00551 }
00552
00553 GlobalUnlock(hGlobal);
00554 bResult = TRUE;
00555 }
00556 }
00557 }
00558
00559 return bResult;
00560 }
00561 DROPEFFECT CMainFrame::OnDropEx(COleDataObject* pDataObject, DROPEFFECT dropDefault, DROPEFFECT dropList, CPoint point)
00562 {
00563 return (DROPEFFECT)-1;
00564 }
00565 void CMainFrame::OnDragLeave()
00566 {
00567 }
00568 DROPEFFECT CMainFrame::OnDragScroll(DWORD dwKeyState, CPoint point)
00569 {
00570 return DROPEFFECT_NONE;
00571 }
00572
00573 void CMainFrame::LoadControlBar(CControlBar* pBar, CString section, UINT defDockBarID)
00574 {
00575 if(!pBar || section.IsEmpty()) return;
00576
00577 CWinApp* pApp = AfxGetApp();
00578
00579 UINT nID = pApp->GetProfileInt(section, _T("DockState"), defDockBarID);
00580
00581 if(nID != AFX_IDW_DOCKBAR_FLOAT)
00582 {
00583 DockControlBar(pBar, nID);
00584 }
00585 else
00586 {
00587
00588 CRect r;
00589 GetWindowRect(r);
00590 CPoint p;
00591 p.x = r.left + pApp->GetProfileInt(section, _T("DockPosX"), r.Width());
00592 p.y = r.top + pApp->GetProfileInt(section, _T("DockPosY"), 0);
00593 FloatControlBar(pBar, p);
00594 }
00595
00596 pBar->ShowWindow(
00597 pApp->GetProfileInt(section, _T("Visible"), FALSE) && pBar != &m_wndSubresyncBar && pBar != &m_wndCaptureBar
00598 ? SW_SHOW
00599 : SW_HIDE);
00600
00601 if(pBar->IsKindOf(RUNTIME_CLASS(CSizingControlBar)))
00602 {
00603 ((CSizingControlBar*)(pBar))->LoadState(section + _T("\\State"));
00604 }
00605 }
00606
00607 void CMainFrame::SaveControlBar(CControlBar* pBar, CString section)
00608 {
00609 if(!pBar || section.IsEmpty()) return;
00610
00611 CWinApp* pApp = AfxGetApp();
00612
00613 pApp->WriteProfileInt(section, _T("Visible"), pBar->IsWindowVisible());
00614
00615 if(pBar->IsKindOf(RUNTIME_CLASS(CSizingControlBar)))
00616 ((CSizingControlBar*)(pBar))->SaveState(section + _T("\\State"));
00617
00618 UINT nID = pBar->GetParent()->GetDlgCtrlID();
00619
00620 if(nID == AFX_IDW_DOCKBAR_FLOAT)
00621 {
00622 return;
00623
00624 CRect r1, r2;
00625 GetWindowRect(r1);
00626 pBar->GetWindowRect(r2);
00627 pApp->WriteProfileInt(section, _T("DockPosX"), r2.left - r1.left);
00628 pApp->WriteProfileInt(section, _T("DockPosY"), r2.top - r1.top);
00629 }
00630
00631 pApp->WriteProfileInt(section, _T("DockState"), nID);
00632
00633 }
00634
00635 LRESULT CMainFrame::OnTaskBarRestart(WPARAM, LPARAM)
00636 {
00637 m_fTrayIcon = false;
00638 ShowTrayIcon(AfxGetAppSettings().fTrayIcon);
00639
00640 return 0;
00641 }
00642
00643 LRESULT CMainFrame::OnNotifyIcon(WPARAM wParam, LPARAM lParam)
00644 {
00645 if((UINT)wParam != IDR_MAINFRAME)
00646 return -1;
00647
00648 switch((UINT)lParam)
00649 {
00650 case WM_LBUTTONDOWN:
00651 ShowWindow(SW_SHOW);
00652 MoveVideoWindow();
00653 SetForegroundWindow();
00654 break;
00655
00656 case WM_LBUTTONDBLCLK:
00657 PostMessage(WM_COMMAND, ID_FILE_OPENMEDIA);
00658 break;
00659
00660 case WM_RBUTTONDOWN:
00661 {
00662 POINT p;
00663 GetCursorPos(&p);
00664 SetForegroundWindow();
00665 m_popupmain.GetSubMenu(0)->TrackPopupMenu(TPM_RIGHTBUTTON|TPM_NOANIMATION, p.x, p.y, this);
00666 PostMessage(WM_NULL);
00667 break;
00668 }
00669
00670 case WM_MOUSEMOVE:
00671 {
00672 CString str;
00673 GetWindowText(str);
00674 SetTrayTip(str);
00675 break;
00676 }
00677
00678 default:
00679 break;
00680 }
00681
00682 return 0;
00683 }
00684
00685 void CMainFrame::ShowTrayIcon(bool fShow)
00686 {
00687 BOOL bWasVisible = ShowWindow(SW_HIDE);
00688
00689 if(fShow)
00690 {
00691 if(!m_fTrayIcon)
00692 {
00693 NOTIFYICONDATA tnid;
00694 tnid.cbSize = sizeof(NOTIFYICONDATA);
00695 tnid.hWnd = m_hWnd;
00696 tnid.uID = IDR_MAINFRAME;
00697
00698 tnid.hIcon = (HICON)LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
00699 tnid.uFlags = NIF_MESSAGE|NIF_ICON|NIF_TIP;
00700 tnid.uCallbackMessage = WM_NOTIFYICON;
00701 lstrcpyn(tnid.szTip, TEXT("Media Player Classic"), sizeof(tnid.szTip));
00702 Shell_NotifyIcon(NIM_ADD, &tnid);
00703
00704 m_fTrayIcon = true;
00705 }
00706 }
00707 else
00708 {
00709 if(m_fTrayIcon)
00710 {
00711 NOTIFYICONDATA tnid;
00712 tnid.cbSize = sizeof(NOTIFYICONDATA);
00713 tnid.hWnd = m_hWnd;
00714 tnid.uID = IDR_MAINFRAME;
00715 Shell_NotifyIcon(NIM_DELETE, &tnid);
00716
00717 m_fTrayIcon = false;
00718 }
00719 }
00720
00721 if(bWasVisible)
00722 ShowWindow(SW_SHOW);
00723 }
00724
00725 void CMainFrame::SetTrayTip(CString str)
00726 {
00727 NOTIFYICONDATA tnid;
00728 tnid.cbSize = sizeof(NOTIFYICONDATA);
00729 tnid.hWnd = m_hWnd;
00730 tnid.uID = IDR_MAINFRAME;
00731 tnid.uFlags = NIF_TIP;
00732 lstrcpyn(tnid.szTip, str, sizeof(tnid.szTip));
00733 Shell_NotifyIcon(NIM_MODIFY, &tnid);
00734 }
00735
00736 BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
00737 {
00738 if(!__super::PreCreateWindow(cs))
00739 return FALSE;
00740
00741 cs.dwExStyle &= ~WS_EX_CLIENTEDGE;
00742 cs.lpszClass = MPC_WND_CLASS_NAME;
00743
00744 return TRUE;
00745 }
00746
00747 BOOL CMainFrame::PreTranslateMessage(MSG* pMsg)
00748 {
00749 if(pMsg->message == WM_KEYDOWN)
00750 {
00751
00752
00753
00754
00755
00756 if(pMsg->wParam == VK_ESCAPE && m_iMediaLoadState == MLS_LOADED && m_fFullScreen)
00757 {
00758 OnViewFullscreen();
00759 PostMessage(WM_COMMAND, ID_PLAY_PAUSE);
00760 return TRUE;
00761 }
00762 else if(pMsg->wParam == VK_ESCAPE && (IsCaptionMenuHidden()))
00763 {
00764 PostMessage(WM_COMMAND, ID_VIEW_CAPTIONMENU);
00765 return TRUE;
00766 }
00767 else if(pMsg->wParam == VK_LEFT && pAMTuner)
00768 {
00769 PostMessage(WM_COMMAND, ID_NAVIGATE_SKIPBACK);
00770 return TRUE;
00771 }
00772 else if(pMsg->wParam == VK_RIGHT && pAMTuner)
00773 {
00774 PostMessage(WM_COMMAND, ID_NAVIGATE_SKIPFORWARD);
00775 return TRUE;
00776 }
00777 }
00778
00779 return __super::PreTranslateMessage(pMsg);
00780 }
00781
00782 void CMainFrame::RecalcLayout(BOOL bNotify)
00783 {
00784 __super::RecalcLayout(bNotify);
00785
00786 CRect r;
00787 GetWindowRect(&r);
00788 MINMAXINFO mmi;
00789 memset(&mmi, 0, sizeof(mmi));
00790 SendMessage(WM_GETMINMAXINFO, 0, (LPARAM)&mmi);
00791 r |= CRect(r.TopLeft(), CSize(r.Width(), mmi.ptMinTrackSize.y));
00792 MoveWindow(&r);
00793 }
00794
00796
00797
00798 #ifdef _DEBUG
00799 void CMainFrame::AssertValid() const
00800 {
00801 __super::AssertValid();
00802 }
00803
00804 void CMainFrame::Dump(CDumpContext& dc) const
00805 {
00806 __super::Dump(dc);
00807 }
00808
00809 #endif //_DEBUG
00810
00812
00813 void CMainFrame::OnSetFocus(CWnd* pOldWnd)
00814 {
00815 SetAlwaysOnTop(AfxGetAppSettings().iOnTop);
00816
00817
00818 if(IsWindow(m_wndView.m_hWnd))
00819 m_wndView.SetFocus();
00820 }
00821
00822 BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
00823 {
00824
00825 if(m_wndView.OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
00826 return TRUE;
00827
00828 POSITION pos = m_bars.GetHeadPosition();
00829 while(pos)
00830 {
00831 if(m_bars.GetNext(pos)->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
00832 return TRUE;
00833 }
00834
00835 pos = m_dockingbars.GetHeadPosition();
00836 while(pos)
00837 {
00838 if(m_dockingbars.GetNext(pos)->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
00839 return TRUE;
00840 }
00841
00842
00843 return __super::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
00844 }
00845
00846 void CMainFrame::OnGetMinMaxInfo(MINMAXINFO* lpMMI)
00847 {
00848 DWORD style = GetStyle();
00849
00850 MENUBARINFO mbi;
00851 memset(&mbi, 0, sizeof(mbi));
00852 mbi.cbSize = sizeof(mbi);
00853 ::GetMenuBarInfo(m_hWnd, OBJID_MENU, 0, &mbi);
00854
00855 lpMMI->ptMinTrackSize.x = 0;
00856 if(!IsCaptionMenuHidden())
00857 {
00858 lpMMI->ptMinTrackSize.x = 10;
00859 CRect r;
00860 for(int i = 0; ::GetMenuItemRect(m_hWnd, mbi.hMenu, i, &r); i++)
00861 lpMMI->ptMinTrackSize.x += r.Width();
00862 lpMMI->ptMinTrackSize.x = max(DEFCLIENTW, lpMMI->ptMinTrackSize.x);
00863 }
00864 if(style&WS_THICKFRAME) lpMMI->ptMinTrackSize.x += GetSystemMetrics((style&WS_CAPTION)?SM_CXSIZEFRAME:SM_CXFIXEDFRAME)*2;
00865
00866 memset(&mbi, 0, sizeof(mbi));
00867 mbi.cbSize = sizeof(mbi);
00868 ::GetMenuBarInfo(m_hWnd, OBJID_MENU, 0, &mbi);
00869
00870 lpMMI->ptMinTrackSize.y = 0;
00871 if(style&WS_CAPTION) lpMMI->ptMinTrackSize.y += GetSystemMetrics(SM_CYCAPTION);
00872 if(style&WS_THICKFRAME) lpMMI->ptMinTrackSize.y += GetSystemMetrics((style&WS_CAPTION)?SM_CYSIZEFRAME:SM_CYFIXEDFRAME)*2;
00873 lpMMI->ptMinTrackSize.y += (mbi.rcBar.bottom - mbi.rcBar.top);
00874 if(!AfxGetAppSettings().fHideCaptionMenu) lpMMI->ptMinTrackSize.y += 3;
00875
00876 POSITION pos = m_bars.GetHeadPosition();
00877 while(pos)
00878 {
00879 CControlBar* pCB = m_bars.GetNext(pos);
00880 if(!IsWindow(pCB->m_hWnd) || !pCB->IsVisible()) continue;
00881
00882 lpMMI->ptMinTrackSize.y += pCB->CalcFixedLayout(TRUE, TRUE).cy;
00883 }
00884
00885 if(IsWindow(m_wndSubresyncBar.m_hWnd) && m_wndSubresyncBar.IsWindowVisible() && !m_wndSubresyncBar.IsFloating())
00886 lpMMI->ptMinTrackSize.y += m_wndSubresyncBar.CalcFixedLayout(TRUE, TRUE).cy-2;
00887
00888 if(IsWindow(m_wndPlaylistBar.m_hWnd) && m_wndPlaylistBar.IsWindowVisible() && !m_wndPlaylistBar.IsFloating())
00889 lpMMI->ptMinTrackSize.y += m_wndPlaylistBar.CalcFixedLayout(TRUE, TRUE).cy-2;
00890
00891 if(IsWindow(m_wndCaptureBar.m_hWnd) && m_wndCaptureBar.IsWindowVisible() && !m_wndCaptureBar.IsFloating())
00892 lpMMI->ptMinTrackSize.y += m_wndCaptureBar.CalcFixedLayout(TRUE, TRUE).cy-2;
00893
00894 __super::OnGetMinMaxInfo(lpMMI);
00895 }
00896
00897 void CMainFrame::OnMove(int x, int y)
00898 {
00899 __super::OnMove(x, y);
00900
00901 MoveVideoWindow();
00902
00903 WINDOWPLACEMENT wp;
00904 GetWindowPlacement(&wp);
00905 if(!m_fFullScreen && wp.flags != WPF_RESTORETOMAXIMIZED && wp.showCmd != SW_SHOWMINIMIZED)
00906 GetWindowRect(AfxGetAppSettings().rcLastWindowPos);
00907 }
00908
00909 void CMainFrame::OnSize(UINT nType, int cx, int cy)
00910 {
00911 __super::OnSize(nType, cx, cy);
00912
00913 if(nType == SIZE_RESTORED && m_fTrayIcon)
00914 {
00915 ShowWindow(SW_SHOW);
00916 }
00917
00918 if(!m_fFullScreen)
00919 {
00920 AppSettings& s = AfxGetAppSettings();
00921 if(nType != SIZE_MAXIMIZED && nType != SIZE_MINIMIZED)
00922 GetWindowRect(s.rcLastWindowPos);
00923 s.lastWindowType = nType;
00924 }
00925 }
00926
00927 void CMainFrame::OnSizing(UINT fwSide, LPRECT pRect)
00928 {
00929 __super::OnSizing(fwSide, pRect);
00930
00931 AppSettings& s = AfxGetAppSettings();
00932
00933 bool fCtrl = !!(GetAsyncKeyState(VK_CONTROL)&0x80000000);
00934
00935 if(m_iMediaLoadState != MLS_LOADED || m_fFullScreen
00936 || s.iDefaultVideoSize == DVS_STRETCH
00937 || (fCtrl ^ s.fFreeWindowResizing))
00938 return;
00939
00940 CSize wsize(pRect->right - pRect->left, pRect->bottom - pRect->top);
00941 CSize vsize = GetVideoSize();
00942 CSize fsize(0, 0);
00943
00944 if(!vsize.cx || !vsize.cy)
00945 return;
00946
00947
00948 {
00949 DWORD style = GetStyle();
00950
00951 MENUBARINFO mbi;
00952 memset(&mbi, 0, sizeof(mbi));
00953 mbi.cbSize = sizeof(mbi);
00954 ::GetMenuBarInfo(m_hWnd, OBJID_MENU, 0, &mbi);
00955
00956 fsize.cx += GetSystemMetrics((style&WS_CAPTION)?SM_CXSIZEFRAME:SM_CXFIXEDFRAME)*2;
00957
00958 if(style&WS_CAPTION) fsize.cy += GetSystemMetrics(SM_CYCAPTION);
00959 if(style&WS_THICKFRAME) fsize.cy += GetSystemMetrics((style&WS_CAPTION)?SM_CYSIZEFRAME:SM_CYFIXEDFRAME)*2;
00960 fsize.cy += mbi.rcBar.bottom - mbi.rcBar.top;
00961 if(!AfxGetAppSettings().fHideCaptionMenu) fsize.cy += 3;
00962
00963 POSITION pos = m_bars.GetHeadPosition();
00964 while(pos)
00965 {
00966 CControlBar* pCB = m_bars.GetNext(pos);
00967 if(IsWindow(pCB->m_hWnd) && pCB->IsVisible())
00968 fsize.cy += pCB->CalcFixedLayout(TRUE, TRUE).cy;
00969 }
00970
00971 if(IsWindow(m_wndSubresyncBar.m_hWnd) && m_wndSubresyncBar.IsWindowVisible())
00972 {
00973 if(m_wndSubresyncBar.IsHorzDocked())
00974 fsize.cy += m_wndSubresyncBar.CalcFixedLayout(TRUE, TRUE).cy-2;
00975 else if(m_wndSubresyncBar.IsVertDocked())
00976 fsize.cx += m_wndSubresyncBar.CalcFixedLayout(TRUE, FALSE).cx;
00977 }
00978
00979 if(IsWindow(m_wndPlaylistBar.m_hWnd) && m_wndPlaylistBar.IsWindowVisible())
00980 {
00981 if(m_wndPlaylistBar.IsHorzDocked())
00982 fsize.cy += m_wndPlaylistBar.CalcFixedLayout(TRUE, TRUE).cy-2;
00983 else if(m_wndPlaylistBar.IsVertDocked())
00984 fsize.cx += m_wndPlaylistBar.CalcFixedLayout(TRUE, FALSE).cx;
00985 }
00986
00987 if(IsWindow(m_wndCaptureBar.m_hWnd) && m_wndCaptureBar.IsWindowVisible())
00988 {
00989 if(m_wndCaptureBar.IsHorzDocked())
00990 fsize.cy += m_wndCaptureBar.CalcFixedLayout(TRUE, TRUE).cy-2;
00991 else if(m_wndCaptureBar.IsVertDocked())
00992 fsize.cx += m_wndCaptureBar.CalcFixedLayout(TRUE, FALSE).cx;
00993 }
00994 }
00995
00996 wsize -= fsize;
00997
00998 bool fWider = wsize.cy < wsize.cx;
00999
01000 wsize.SetSize(
01001 wsize.cy * vsize.cx / vsize.cy,
01002 wsize.cx * vsize.cy / vsize.cx);
01003
01004 wsize += fsize;
01005
01006 if(fwSide == WMSZ_TOP || fwSide == WMSZ_BOTTOM || !fWider && (fwSide == WMSZ_TOPRIGHT || fwSide == WMSZ_BOTTOMRIGHT))
01007 {
01008 pRect->right = pRect->left + wsize.cx;
01009 }
01010 else if(fwSide == WMSZ_LEFT || fwSide == WMSZ_RIGHT || fWider && (fwSide == WMSZ_BOTTOMLEFT || fwSide == WMSZ_BOTTOMRIGHT))
01011 {
01012 pRect->bottom = pRect->top + wsize.cy;
01013 }
01014 else if(!fWider && (fwSide == WMSZ_TOPLEFT || fwSide == WMSZ_BOTTOMLEFT))
01015 {
01016 pRect->left = pRect->right - wsize.cx;
01017 }
01018 else if(fWider && (fwSide == WMSZ_TOPLEFT || fwSide == WMSZ_TOPRIGHT))
01019 {
01020 pRect->top = pRect->bottom - wsize.cy;
01021 }
01022 }
01023
01024 void CMainFrame::OnDisplayChange()
01025 {
01026 TRACE(_T("*** CMainFrame::OnDisplayChange()\n"));
01027
01028
01029
01030
01031 }
01032
01033 void CMainFrame::OnSysCommand(UINT nID, LPARAM lParam)
01034 {
01035 if((nID & 0xFFF0) == SC_SCREENSAVE)
01036 {
01037 TRACE(_T("SC_SCREENSAVE, nID = %d, lParam = %d\n"), nID, lParam);
01038 }
01039 else if((nID & 0xFFF0) == SC_MINIMIZE && m_fTrayIcon)
01040 {
01041 ShowWindow(SW_HIDE);
01042 return;
01043 }
01044
01045 __super::OnSysCommand(nID, lParam);
01046 }
01047
01048 void CMainFrame::OnActivateApp(BOOL bActive, DWORD dwThreadID)
01049 {
01050 __super::OnActivateApp(bActive, dwThreadID);
01051
01052 MONITORINFO mi;
01053 mi.cbSize = sizeof(MONITORINFO);
01054 GetMonitorInfo(MonitorFromWindow(m_hWnd, MONITOR_DEFAULTTONEAREST), &mi);
01055
01056 if(m_iMediaLoadState == MLS_LOADED && m_fFullScreen && !bActive && (mi.dwFlags&MONITORINFOF_PRIMARY))
01057 {
01058 OnViewFullscreen();
01059 }
01060 }
01061
01062 LRESULT CMainFrame::OnAppCommand(WPARAM wParam, LPARAM lParam)
01063 {
01064 UINT cmd = GET_APPCOMMAND_LPARAM(lParam);
01065 UINT uDevice = GET_DEVICE_LPARAM(lParam);
01066 UINT dwKeys = GET_KEYSTATE_LPARAM(lParam);
01067
01068 if(uDevice != FAPPCOMMAND_OEM)
01069 {
01070 AppSettings& s = AfxGetAppSettings();
01071
01072 BOOL fRet = FALSE;
01073
01074 POSITION pos = s.wmcmds.GetHeadPosition();
01075 while(pos)
01076 {
01077 wmcmd& wc = s.wmcmds.GetNext(pos);
01078 if(wc.appcmd == cmd && TRUE == SendMessage(WM_COMMAND, wc.cmd))
01079 fRet = TRUE;
01080 }
01081
01082 if(fRet) return TRUE;
01083 }
01084
01085 return Default();
01086 }
01087
01088 void CMainFrame::OnTimer(UINT nIDEvent)
01089 {
01090 if(nIDEvent == TIMER_STREAMPOSPOLLER && m_iMediaLoadState == MLS_LOADED)
01091 {
01092 REFERENCE_TIME rtNow = 0, rtDur = 0;
01093
01094 if(m_iPlaybackMode == PM_FILE)
01095 {
01096 pMS->GetCurrentPosition(&rtNow);
01097 pMS->GetDuration(&rtDur);
01098
01099 if(m_rtDurationOverride >= 0) rtDur = m_rtDurationOverride;
01100
01101 m_wndSeekBar.Enable(rtDur > 0);
01102 m_wndSeekBar.SetRange(0, rtDur);
01103 m_wndSeekBar.SetPos(rtNow);
01104 }
01105 else if(m_iPlaybackMode == PM_CAPTURE)
01106 {
01107 if(m_fCapturing && m_wndCaptureBar.m_capdlg.m_pMux)
01108 {
01109 CComQIPtr<IMediaSeeking> pMuxMS = m_wndCaptureBar.m_capdlg.m_pMux;
01110 if(!pMuxMS || FAILED(pMuxMS->GetCurrentPosition(&rtNow))) rtNow = 0;
01111 }
01112
01113 if(m_rtDurationOverride >= 0) rtDur = m_rtDurationOverride;
01114
01115 m_wndSeekBar.Enable(false);
01116 m_wndSeekBar.SetRange(0, rtDur);
01117 m_wndSeekBar.SetPos(rtNow);
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127 }
01128
01129 if(m_pCAP && m_iPlaybackMode != PM_FILE) m_pCAP->SetTime(m_wndSeekBar.GetPos());
01130 }
01131 else if(nIDEvent == TIMER_STREAMPOSPOLLER2 && m_iMediaLoadState == MLS_LOADED)
01132 {
01133 __int64 start, stop, pos;
01134 m_wndSeekBar.GetRange(start, stop);
01135 pos = m_wndSeekBar.GetPosReal();
01136
01137 GUID tf;
01138 pMS->GetTimeFormat(&tf);
01139
01140 if(m_iPlaybackMode == PM_CAPTURE && !m_fCapturing)
01141 {
01142 CString str = _T("Live");
01143
01144 long lChannel = 0, lVivSub = 0, lAudSub = 0;
01145 if(pAMTuner
01146 && m_wndCaptureBar.m_capdlg.IsTunerActive()
01147 && SUCCEEDED(pAMTuner->get_Channel(&lChannel, &lVivSub, &lAudSub)))
01148 {
01149 CString ch;
01150 ch.Format(_T(" (ch%d)"), lChannel);
01151 str += ch;
01152 }
01153
01154 m_wndStatusBar.SetStatusTimer(str);
01155 }
01156 else
01157 {
01158 m_wndStatusBar.SetStatusTimer(pos, stop, !!m_wndSubresyncBar.IsWindowVisible(), &tf);
01159 }
01160
01161 m_wndSubresyncBar.SetTime(pos);
01162
01163 if(m_pCAP && GetMediaState() == State_Paused) m_pCAP->Paint(true);
01164 }
01165 else if(nIDEvent == TIMER_FULLSCREENCONTROLBARHIDER)
01166 {
01167 CPoint p;
01168 GetCursorPos(&p);
01169
01170 CRect r;
01171 GetWindowRect(r);
01172 bool fCursorOutside = !r.PtInRect(p);
01173
01174 CWnd* pWnd = WindowFromPoint(p);
01175 if(pWnd && (m_wndView == *pWnd || m_wndView.IsChild(pWnd) || fCursorOutside))
01176 {
01177 if(AfxGetAppSettings().nShowBarsWhenFullScreenTimeOut >= 0)
01178 ShowControls(CS_NONE, false);
01179 }
01180 }
01181 else if(nIDEvent == TIMER_FULLSCREENMOUSEHIDER)
01182 {
01183 CPoint p;
01184 GetCursorPos(&p);
01185
01186 CRect r;
01187 GetWindowRect(r);
01188 bool fCursorOutside = !r.PtInRect(p);
01189
01190 CWnd* pWnd = WindowFromPoint(p);
01191 if(pWnd && (m_wndView == *pWnd || m_wndView.IsChild(pWnd) || fCursorOutside))
01192 {
01193 m_fHideCursor = true;
01194 SetCursor(NULL);
01195 }
01196 }
01197 else if(nIDEvent == TIMER_STATS)
01198 {
01199 if(pQP)
01200 {
01201 CString rate;
01202 if(m_iSpeedLevel >= -11 && m_iSpeedLevel <= 3 && m_iSpeedLevel != -4)
01203 {
01204 CString speeds[] = {_T("1/8"),_T("1/4"),_T("1/2"),_T("1"),_T("2"),_T("4"),_T("8")};
01205 rate = speeds[(m_iSpeedLevel >= -3 ? m_iSpeedLevel : (-m_iSpeedLevel - 8)) + 3];
01206 if(m_iSpeedLevel < -4) rate = _T("-") + rate;
01207 if(!rate.IsEmpty()) rate = _T("(") + rate + _T("X)");
01208 }
01209
01210 CString info;
01211 int val;
01212
01213 pQP->get_AvgFrameRate(&val);
01214 info.Format(_T("%d.%02d %s"), val/100, val%100, rate);
01215 m_wndStatsBar.SetLine(_T("Frame-rate"), info);
01216
01217 int avg, dev;
01218 pQP->get_AvgSyncOffset(&avg);
01219 pQP->get_DevSyncOffset(&dev);
01220 info.Format(_T("avg: %d ms, dev: %d ms"), avg, dev);
01221 m_wndStatsBar.SetLine(_T("Sync Offset"), info);
01222
01223 int drawn, dropped;
01224 pQP->get_FramesDrawn(&drawn);
01225 pQP->get_FramesDroppedInRenderer(&dropped);
01226 info.Format(_T("drawn: %d, dropped: %d"), drawn, dropped);
01227 m_wndStatsBar.SetLine(_T("Frames"), info);
01228
01229 pQP->get_Jitter(&val);
01230 info.Format(_T("%d ms"), val);
01231 m_wndStatsBar.SetLine(_T("Jitter"), info);
01232 }
01233
01234 if(pBI)
01235 {
01236 CList<CString> sl;
01237
01238 for(int i = 0, j = pBI->GetCount(); i < j; i++)
01239 {
01240 int samples, size;
01241 if(S_OK == pBI->GetStatus(i, samples, size))
01242 {
01243 CString str;
01244 str.Format(_T("[%d]: %03d/%d KB"), i, samples, size / 1024);
01245 sl.AddTail(str);
01246 }
01247 }
01248
01249 if(!sl.IsEmpty())
01250 {
01251 CString str;
01252 str.Format(_T("%s (p%d)"), Implode(sl, ' '), pBI->GetPriority());
01253
01254 m_wndStatsBar.SetLine(_T("Buffers"), str);
01255 }
01256 }
01257
01258 CInterfaceList<IBitRateInfo> pBRIs;
01259
01260 BeginEnumFilters(pGB, pEF, pBF)
01261 {
01262 BeginEnumPins(pBF, pEP, pPin)
01263 {
01264 if(CComQIPtr<IBitRateInfo> pBRI = pPin)
01265 {
01266 pBRIs.AddTail(pBRI);
01267 }
01268 }
01269 EndEnumPins
01270
01271 if(!pBRIs.IsEmpty())
01272 {
01273 CList<CString> sl;
01274
01275 POSITION pos = pBRIs.GetHeadPosition();
01276 for(int i = 0; pos; i++)
01277 {
01278 IBitRateInfo* pBRI = pBRIs.GetNext(pos);
01279
01280 DWORD cur = pBRI->GetCurrentBitRate() / 1000;
01281 DWORD avg = pBRI->GetAverageBitRate() / 1000;
01282
01283 if(avg == 0) continue;
01284
01285 CString str;
01286 if(cur != avg) str.Format(_T("[%d]: %d/%d Kb/s"), i, avg, cur);
01287 else str.Format(_T("[%d]: %d Kb/s"), i, avg);
01288 sl.AddTail(str);
01289 }
01290
01291 if(!sl.IsEmpty())
01292 {
01293 m_wndStatsBar.SetLine(_T("Bitrate"), Implode(sl, ' ') + _T(" (avg/cur)"));
01294 }
01295
01296 break;
01297 }
01298 }
01299 EndEnumFilters
01300
01301 if(m_iPlaybackMode == PM_FILE)
01302 {
01303 SetupChapters();
01304 }
01305
01306 if(m_iPlaybackMode == PM_DVD)
01307 {
01308 ULONG ulAvailable, ulCurrent;
01309
01310
01311
01312 CString Domain('-');
01313
01314 DVD_DOMAIN dom;
01315
01316 if(SUCCEEDED(pDVDI->GetCurrentDomain(&dom)))
01317 {
01318 switch(dom)
01319 {
01320 case DVD_DOMAIN_FirstPlay: Domain = _T("First Play"); break;
01321 case DVD_DOMAIN_VideoManagerMenu: Domain = _T("Video Manager Menu"); break;
01322 case DVD_DOMAIN_VideoTitleSetMenu: Domain = _T("Video Title Set Menu"); break;
01323 case DVD_DOMAIN_Title: Domain = _T("Title"); break;
01324 case DVD_DOMAIN_Stop: Domain = _T("Stop"); break;
01325 default: Domain = _T("-"); break;
01326 }
01327 }
01328
01329 m_wndInfoBar.SetLine(_T("Domain"), Domain);
01330
01331
01332
01333 CString Location('-');
01334
01335 DVD_PLAYBACK_LOCATION2 loc;
01336 ULONG ulNumOfVolumes, ulVolume;
01337 DVD_DISC_SIDE Side;
01338 ULONG ulNumOfTitles;
01339 ULONG ulNumOfChapters;
01340
01341 if(SUCCEEDED(pDVDI->GetCurrentLocation(&loc))
01342 && SUCCEEDED(pDVDI->GetNumberOfChapters(loc.TitleNum, &ulNumOfChapters))
01343 && SUCCEEDED(pDVDI->GetDVDVolumeInfo(&ulNumOfVolumes, &ulVolume, &Side, &ulNumOfTitles)))
01344 {
01345 Location.Format(_T("Volume: %02d/%02d, Title: %02d/%02d, Chapter: %02d/%02d"),
01346 ulVolume, ulNumOfVolumes,
01347 loc.TitleNum, ulNumOfTitles,
01348 loc.ChapterNum, ulNumOfChapters);
01349 }
01350
01351 m_wndInfoBar.SetLine(_T("Location"), Location);
01352
01353
01354
01355 CString Video('-');
01356
01357 DVD_VideoAttributes VATR;
01358
01359 if(SUCCEEDED(pDVDI->GetCurrentAngle(&ulAvailable, &ulCurrent))
01360 && SUCCEEDED(pDVDI->GetCurrentVideoAttributes(&VATR)))
01361 {
01362 Video.Format(_T("Angle: %02d/%02d, %dx%d %dHz %d:%d"),
01363 ulAvailable, ulCurrent,
01364 VATR.ulSourceResolutionX, VATR.ulSourceResolutionY, VATR.ulFrameRate,
01365 VATR.ulAspectX, VATR.ulAspectY);
01366 }
01367
01368 m_wndInfoBar.SetLine(_T("Video"), Video);
01369
01370
01371
01372 CString Audio('-');
01373
01374 DVD_AudioAttributes AATR;
01375
01376 if(SUCCEEDED(pDVDI->GetCurrentAudio(&ulAvailable, &ulCurrent))
01377 && SUCCEEDED(pDVDI->GetAudioAttributes(ulCurrent, &AATR)))
01378 {
01379 CString lang;
01380 int len = GetLocaleInfo(AATR.Language, LOCALE_SENGLANGUAGE, lang.GetBuffer(64), 64);
01381 lang.ReleaseBufferSetLength(max(len-1, 0));
01382
01383 switch(AATR.LanguageExtension)
01384 {
01385 case DVD_AUD_EXT_NotSpecified:
01386 default: break;
01387 case DVD_AUD_EXT_Captions: lang += _T(" (Captions)"); break;
01388 case DVD_AUD_EXT_VisuallyImpaired: lang += _T(" (Visually Impaired)"); break;
01389 case DVD_AUD_EXT_DirectorComments1: lang += _T(" (Director Comments 1)"); break;
01390 case DVD_AUD_EXT_DirectorComments2: lang += _T(" (Director Comments 2)"); break;
01391 }
01392
01393 CString format;
01394 switch(AATR.AudioFormat)
01395 {
01396 case DVD_AudioFormat_AC3: format = _T("AC3"); break;
01397 case DVD_AudioFormat_MPEG1:
01398 case DVD_AudioFormat_MPEG1_DRC: format = _T("MPEG1"); break;
01399 case DVD_AudioFormat_MPEG2:
01400 case DVD_AudioFormat_MPEG2_DRC: format = _T("MPEG2"); break;
01401 case DVD_AudioFormat_LPCM: format = _T("LPCM"); break;
01402 case DVD_AudioFormat_DTS: format = _T("DTS"); break;
01403 case DVD_AudioFormat_SDDS: format = _T("SDDS"); break;
01404 case DVD_AudioFormat_Other:
01405 default: format = _T("Unknown format"); break;
01406 }
01407
01408 Audio.Format(_T("%s, %s %dHz %dbits %d channel(s)"),
01409 lang,
01410 format,
01411 AATR.dwFrequency,
01412 AATR.bQuantization,
01413 AATR.bNumberOfChannels);
01414
01415 m_wndStatusBar.SetStatusBitmap(
01416 AATR.bNumberOfChannels == 1 ? IDB_MONO
01417 : AATR.bNumberOfChannels >= 2 ? IDB_STEREO
01418 : IDB_NOAUDIO);
01419 }
01420
01421 m_wndInfoBar.SetLine(_T("Audio"), Audio);
01422
01423
01424
01425 CString Subtitles('-');
01426
01427 BOOL bIsDisabled;
01428 DVD_SubpictureAttributes SATR;
01429
01430 if(SUCCEEDED(pDVDI->GetCurrentSubpicture(&ulAvailable, &ulCurrent, &bIsDisabled))
01431 && SUCCEEDED(pDVDI->GetSubpictureAttributes(ulCurrent, &SATR)))
01432 {
01433 CString lang;
01434 int len = GetLocaleInfo(SATR.Language, LOCALE_SENGLANGUAGE, lang.GetBuffer(64), 64);
01435 lang.ReleaseBufferSetLength(max(len-1, 0));
01436
01437 switch(SATR.LanguageExtension)
01438 {
01439 case DVD_SP_EXT_NotSpecified:
01440 default: break;
01441 case DVD_SP_EXT_Caption_Normal: lang += _T(""); break;
01442 case DVD_SP_EXT_Caption_Big: lang += _T(" (Big)"); break;
01443 case DVD_SP_EXT_Caption_Children: lang += _T(" (Children)"); break;
01444 case DVD_SP_EXT_CC_Normal: lang += _T(" (CC)"); break;
01445 case DVD_SP_EXT_CC_Big: lang += _T(" (CC Big)"); break;
01446 case DVD_SP_EXT_CC_Children: lang += _T(" (CC Children)"); break;
01447 case DVD_SP_EXT_Forced: lang += _T(" (Forced)"); break;
01448 case DVD_SP_EXT_DirectorComments_Normal: lang += _T(" (Director Comments)"); break;
01449 case DVD_SP_EXT_DirectorComments_Big: lang += _T(" (Director Comments, Big)"); break;
01450 case DVD_SP_EXT_DirectorComments_Children: lang += _T(" (Director Comments, Children)"); break;
01451 }
01452
01453 if(bIsDisabled) lang = _T("-");
01454
01455 Subtitles.Format(_T("%s"),
01456 lang);
01457 }
01458
01459 m_wndInfoBar.SetLine(_T("Subtitles"), Subtitles);
01460 }
01461
01462 if(GetMediaState() == State_Running)
01463 {
01464 UINT fSaverActive = 0;
01465 if(SystemParametersInfo(SPI_GETSCREENSAVEACTIVE, 0, (PVOID)&fSaverActive, 0))
01466 {
01467 SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 0, 0, SPIF_SENDWININICHANGE);
01468 SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, fSaverActive, 0, SPIF_SENDWININICHANGE);
01469 }
01470
01471 fSaverActive = 0;
01472 if(SystemParametersInfo(SPI_GETPOWEROFFACTIVE, 0, (PVOID)&fSaverActive, 0))
01473 {
01474 SystemParametersInfo(SPI_SETPOWEROFFACTIVE, 0, 0, SPIF_SENDWININICHANGE);
01475 SystemParametersInfo(SPI_SETPOWEROFFACTIVE, fSaverActive, 0, SPIF_SENDWININICHANGE);
01476 }
01477 }
01478 }
01479 else if(nIDEvent == TIMER_STATUSERASER)
01480 {
01481 KillTimer(TIMER_STATUSERASER);
01482 m_playingmsg.Empty();
01483 }
01484
01485 __super::OnTimer(nIDEvent);
01486 }
01487
01488 static bool SetShutdownPrivilege()
01489 {
01490 HANDLE hToken;
01491 TOKEN_PRIVILEGES tkp;
01492
01493
01494
01495 if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
01496 return(false);
01497
01498
01499
01500 LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);
01501
01502 tkp.PrivilegeCount = 1;
01503 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
01504
01505
01506
01507 AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
01508
01509 if(GetLastError() != ERROR_SUCCESS)
01510 return false;
01511
01512 return true;
01513 }
01514
01515 bool CMainFrame::DoAfterPlaybackEvent()
01516 {
01517 AppSettings& s = AfxGetAppSettings();
01518
01519 bool fExit = false;
01520
01521 if(s.nCLSwitches&CLSW_CLOSE)
01522 {
01523 fExit = true;
01524 }
01525
01526 if(s.nCLSwitches&CLSW_STANDBY)
01527 {
01528 SetShutdownPrivilege();
01529 SetSystemPowerState(TRUE, TRUE);
01530 fExit = true;
01531 }
01532 else if(s.nCLSwitches&CLSW_HIBERNATE)
01533 {
01534 SetShutdownPrivilege();
01535 SetSystemPowerState(FALSE, TRUE);
01536 fExit = true;
01537 }
01538 else if(s.nCLSwitches&CLSW_SHUTDOWN)
01539 {
01540 SetShutdownPrivilege();
01541 ExitWindowsEx(EWX_SHUTDOWN|EWX_POWEROFF|EWX_FORCEIFHUNG, 0);
01542 fExit = true;
01543 }
01544 else if(s.nCLSwitches&CLSW_LOGOFF)
01545 {
01546 SetShutdownPrivilege();
01547 ExitWindowsEx(EWX_LOGOFF|EWX_FORCEIFHUNG, 0);
01548 fExit = true;
01549 }
01550
01551 if(!fExit) return false;
01552
01553 SendMessage(WM_COMMAND, ID_FILE_EXIT);
01554
01555 return true;
01556 }
01557
01558
01559
01560
01561 #include <comdef.h>
01562 LRESULT CMainFrame::OnGraphNotify(WPARAM wParam, LPARAM lParam)
01563 {
01564 HRESULT hr = S_OK;
01565
01566 LONG evCode, evParam1, evParam2;
01567 while(pME && SUCCEEDED(pME->GetEvent(&evCode, (LONG_PTR*)&evParam1, (LONG_PTR*)&evParam2, 0)))
01568 {
01569 CString str;
01570
01571 if(m_fCustomGraph)
01572 {
01573 if(EC_BG_ERROR == evCode)
01574 {
01575 str = CString((char*)evParam1);
01576 }
01577 }
01578
01579 hr = pME->FreeEventParams(evCode, evParam1, evParam2);
01580
01581 if(EC_COMPLETE == evCode)
01582 {
01583 AppSettings& s = AfxGetAppSettings();
01584
01585 if(m_wndPlaylistBar.GetCount() <= 1)
01586 {
01587 m_nLoops++;
01588
01589 if(DoAfterPlaybackEvent()) return hr;
01590
01591 if(s.fLoopForever || m_nLoops < s.nLoops)
01592 {
01593 if(GetMediaState() == State_Stopped)
01594 {
01595 SendMessage(WM_COMMAND, ID_PLAY_PLAY);
01596 }
01597 else
01598 {
01599 LONGLONG pos = 0;
01600 pMS->SetPositions(&pos, AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning);
01601
01602 if(GetMediaState() == State_Paused)
01603 {
01604 SendMessage(WM_COMMAND, ID_PLAY_PLAY);
01605 }
01606 }
01607 }
01608 else
01609 {
01610 if(s.fRewind) SendMessage(WM_COMMAND, ID_PLAY_STOP);
01611 else m_fEndOfStream = true;
01612 SendMessage(WM_COMMAND, ID_PLAY_PAUSE);
01613
01614 if(m_fFullScreen && s.fExitFullScreenAtTheEnd)
01615 OnViewFullscreen();
01616 }
01617 }
01618 else if(m_wndPlaylistBar.GetCount() > 1)
01619 {
01620 if(m_wndPlaylistBar.IsAtEnd())
01621 {
01622 if(DoAfterPlaybackEvent()) return hr;
01623
01624 m_nLoops++;
01625 }
01626
01627 if(s.fLoopForever || m_nLoops < s.nLoops)
01628 {
01629 int nLoops = m_nLoops;
01630 PostMessage(WM_COMMAND, ID_NAVIGATE_SKIPFORWARD);
01631 m_nLoops = nLoops;
01632 }
01633 else
01634 {
01635 if(m_fFullScreen && s.fExitFullScreenAtTheEnd)
01636 OnViewFullscreen();
01637
01638 if(s.fRewind)
01639 {
01640 AfxGetAppSettings().nCLSwitches |= CLSW_OPEN;
01641 PostMessage(WM_COMMAND, ID_NAVIGATE_SKIPFORWARD);
01642 }
01643 else
01644 {
01645 m_fEndOfStream = true;
01646 PostMessage(WM_COMMAND, ID_PLAY_PAUSE);
01647 }
01648 }
01649 }
01650 }
01651 else if(EC_ERRORABORT == evCode)
01652 {
01653 TRACE(_T("EC_ERRORABORT, hr = %08x\n"), (HRESULT)evParam1);
01654
01655
01656 }
01657 else if(EC_REPAINT == evCode)
01658 {
01659 TRACE(_T("EC_REPAINT\n"));
01660 }
01661 else if(EC_BUFFERING_DATA == evCode)
01662 {
01663 TRACE(_T("EC_BUFFERING_DATA, %d, %d\n"), (HRESULT)evParam1, evParam2);
01664
01665 m_fBuffering = ((HRESULT)evParam1 != S_OK);
01666 }
01667 else if(EC_STEP_COMPLETE == evCode)
01668 {
01669 if(m_fFrameSteppingActive)
01670 {
01671 m_fFrameSteppingActive = false;
01672 pBA->put_Volume(m_VolumeBeforeFrameStepping);
01673 }
01674 }
01675 else if(EC_DEVICE_LOST == evCode)
01676 {
01677 CComQIPtr<IBaseFilter> pBF;
01678 if(m_iPlaybackMode == PM_CAPTURE
01679 && (!pVidCap && pVidCap == (pBF = (IUnknown*)evParam1)
01680 || !pAudCap && pAudCap == (pBF = (IUnknown*)evParam1))
01681 && evParam2 == 0)
01682 {
01683 SendMessage(WM_COMMAND, ID_FILE_CLOSEMEDIA);
01684 }
01685 }
01686 else if(EC_DVD_TITLE_CHANGE == evCode)
01687 {
01688 if(m_iPlaybackMode == PM_FILE)
01689 SetupChapters();
01690 }
01691 else if(EC_DVD_DOMAIN_CHANGE == evCode)
01692 {
01693 m_iDVDDomain = (DVD_DOMAIN)evParam1;
01694 TRACE(_T("EC_DVD_DOMAIN_CHANGE %d\n"), m_iDVDDomain);
01695 MoveVideoWindow();
01696 }
01697 else if(EC_DVD_CURRENT_HMSF_TIME == evCode)
01698 {
01699 REFERENCE_TIME rtNow = 0, rtDur = 0;
01700
01701 double fps = evParam2 == DVD_TC_FLAG_25fps ? 25.0
01702 : evParam2 == DVD_TC_FLAG_30fps ? 30.0
01703 : evParam2 == DVD_TC_FLAG_DropFrame ? 29.97
01704 : 25.0;
01705
01706 rtNow = HMSF2RT(*((DVD_HMSF_TIMECODE*)&evParam1), fps);
01707
01708 DVD_HMSF_TIMECODE tcDur;
01709 ULONG ulFlags;
01710 if(SUCCEEDED(pDVDI->GetTotalTitleTime(&tcDur, &ulFlags)))
01711 {
01712 rtDur = HMSF2RT(tcDur, fps);
01713 }
01714
01715 m_wndSeekBar.Enable(rtDur > 0);
01716 m_wndSeekBar.SetRange(0, rtDur);
01717 m_wndSeekBar.SetPos(rtNow);
01718
01719 if(m_pSubClock) m_pSubClock->SetTime(rtNow);
01720 }
01721 else if(EC_DVD_ERROR == evCode)
01722 {
01723 TRACE(_T("EC_DVD_ERROR %d %d\n"), evParam1, evParam2);
01724
01725 CString err;
01726
01727 switch(evParam1)
01728 {
01729 case DVD_ERROR_Unexpected: default: err = _T("DVD: Unexpected error"); break;
01730 case DVD_ERROR_CopyProtectFail: err = _T("DVD: Copy-Protect Fail"); break;
01731 case DVD_ERROR_InvalidDVD1_0Disc: err = _T("DVD: Invalid DVD 1.x Disc"); break;
01732 case DVD_ERROR_InvalidDiscRegion: err = _T("DVD: Invalid Disc Region"); break;
01733 case DVD_ERROR_LowParentalLevel: err = _T("DVD: Low Parental Level"); break;
01734 case DVD_ERROR_MacrovisionFail: err = _T("DVD: Macrovision Fail"); break;
01735 case DVD_ERROR_IncompatibleSystemAndDecoderRegions: err = _T("DVD: Incompatible System And Decoder Regions"); break;
01736 case DVD_ERROR_IncompatibleDiscAndDecoderRegions: err = _T("DVD: Incompatible Disc And Decoder Regions"); break;
01737 }
01738
01739 SendMessage(WM_COMMAND, ID_FILE_CLOSEMEDIA);
01740
01741 m_closingmsg = err;
01742 }
01743 else if(EC_DVD_WARNING == evCode)
01744 {
01745 TRACE(_T("EC_DVD_WARNING %d %d\n"), evParam1, evParam2);
01746 }
01747 else if(EC_VIDEO_SIZE_CHANGED == evCode)
01748 {
01749 TRACE(_T("EC_VIDEO_SIZE_CHANGED %dx%d\n"), CSize(evParam1));
01750
01751 WINDOWPLACEMENT wp;
01752 wp.length = sizeof(wp);
01753 GetWindowPlacement(&wp);
01754
01755 CSize size(evParam1);
01756 m_fAudioOnly = (size.cx <= 0 || size.cy <= 0);
01757
01758 if(AfxGetAppSettings().fRememberZoomLevel
01759 && !(m_fFullScreen || wp.showCmd == SW_SHOWMAXIMIZED || wp.showCmd == SW_SHOWMINIMIZED))
01760 {
01761 ZoomVideoWindow();
01762 }
01763 else
01764 {
01765 MoveVideoWindow();
01766 }
01767
01768 if(m_iMediaLoadState == MLS_LOADED
01769 && !m_fAudioOnly && (AfxGetAppSettings().nCLSwitches&CLSW_FULLSCREEN))
01770 {
01771 PostMessage(WM_COMMAND, ID_VIEW_FULLSCREEN);
01772 AfxGetAppSettings().nCLSwitches &= ~CLSW_FULLSCREEN;
01773 }
01774 }
01775 else if(EC_LENGTH_CHANGED == evCode)
01776 {
01777 __int64 rtDur = 0;
01778 pMS->GetDuration(&rtDur);
01779 m_wndPlaylistBar.SetCurTime(rtDur);
01780 }
01781 else if(!m_fCustomGraph)
01782 {
01783 TRACE(_T("%d\n"), evCode);
01784 }
01785 else if(EC_BG_AUDIO_CHANGED == evCode)
01786 {
01787 int nAudioChannels = evParam1;
01788
01789 m_wndStatusBar.SetStatusBitmap(nAudioChannels == 1 ? IDB_MONO
01790 : nAudioChannels >= 2 ? IDB_STEREO
01791 : IDB_NOAUDIO);
01792 }
01793 else if(EC_BG_ERROR == evCode)
01794 {
01795 SendMessage(WM_COMMAND, ID_FILE_CLOSEMEDIA);
01796 m_closingmsg = !str.IsEmpty() ? str : _T("Unspecified graph error");
01797 m_wndPlaylistBar.SetCurValid(false);
01798 break;
01799 }
01800 }
01801
01802 return hr;
01803 }
01804
01805 LRESULT CMainFrame::OnRepaintRenderLess(WPARAM wParam, LPARAM lParam)
01806 {
01807 MoveVideoWindow();
01808 return TRUE;
01809 }
01810
01811 LRESULT CMainFrame::OnResumeFromState(WPARAM wParam, LPARAM lParam)
01812 {
01813 int iPlaybackMode = (int)wParam;
01814
01815 if(iPlaybackMode == PM_FILE)
01816 {
01817 SeekTo(10000i64*int(lParam));
01818 }
01819 else if(iPlaybackMode == PM_DVD)
01820 {
01821 CComPtr<IDvdState> pDvdState;
01822 pDvdState.Attach((IDvdState*)lParam);
01823 if(pDVDC) pDVDC->SetState(pDvdState, DVD_CMD_FLAG_Block, NULL);
01824 }
01825 else if(iPlaybackMode == PM_CAPTURE)
01826 {
01827
01828 }
01829 else
01830 {
01831 ASSERT(0);
01832 return FALSE;
01833 }
01834
01835 return TRUE;
01836 }
01837
01838 BOOL CMainFrame::OnButton(UINT id, UINT nFlags, CPoint point)
01839 {
01840 SetFocus();
01841
01842 CRect r;
01843 m_wndView.GetClientRect(r);
01844 m_wndView.MapWindowPoints(this, &r);
01845
01846 if(id != wmcmd::WDOWN && id != wmcmd::WUP && !r.PtInRect(point)) return FALSE;
01847
01848 BOOL ret = FALSE;
01849
01850 AppSettings& s = AfxGetAppSettings();
01851 POSITION pos = s.wmcmds.GetHeadPosition();
01852 while(pos)
01853 {
01854 wmcmd& wc = s.wmcmds.GetNext(pos);
01855 if(wc.mouse == id)
01856 {
01857 SendMessage(WM_COMMAND, wc.cmd);
01858 ret = true;
01859 }
01860 }
01861
01862 return ret;
01863 }
01864
01865 static bool s_fLDown = false;
01866
01867 void CMainFrame::OnLButtonDown(UINT nFlags, CPoint point)
01868 {
01869 SetFocus();
01870
01871 bool fClicked = false;
01872
01873 if(m_iPlaybackMode == PM_DVD)
01874 {
01875 CPoint p = point - m_wndView.GetVideoRect().TopLeft();
01876
01877 if(SUCCEEDED(pDVDC->ActivateAtPosition(p))
01878 || m_iDVDDomain == DVD_DOMAIN_VideoManagerMenu
01879 || m_iDVDDomain == DVD_DOMAIN_VideoTitleSetMenu)
01880 fClicked = true;
01881 }
01882
01883 if(!fClicked)
01884 {
01885 bool fLeftMouseBtnUnassigned = true;
01886 AppSettings& s = AfxGetAppSettings();
01887 POSITION pos = s.wmcmds.GetHeadPosition();
01888 while(pos && fLeftMouseBtnUnassigned)
01889 if(s.wmcmds.GetNext(pos).mouse == wmcmd::LDOWN)
01890 fLeftMouseBtnUnassigned = false;
01891
01892 if(!m_fFullScreen && (IsCaptionMenuHidden() || fLeftMouseBtnUnassigned))
01893 {
01894 PostMessage(WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x, point.y));
01895 }
01896 else
01897 {
01898 s_fLDown = true;
01899 if(OnButton(wmcmd::LDOWN, nFlags, point))
01900 return;
01901 }
01902 }
01903
01904 __super::OnLButtonDown(nFlags, point);
01905 }
01906
01907 void CMainFrame::OnLButtonUp(UINT nFlags, CPoint point)
01908 {
01909 if(!OnButton(wmcmd::LUP, nFlags, point))
01910 __super::OnLButtonUp(nFlags, point);
01911 }
01912
01913 void CMainFrame::OnLButtonDblClk(UINT nFlags, CPoint point)
01914 {
01915 if(s_fLDown)
01916 {
01917 SendMessage(WM_LBUTTONDOWN, nFlags, MAKELPARAM(point.x, point.y));
01918 s_fLDown = false;
01919 }
01920 if(!OnButton(wmcmd::LDBLCLK, nFlags, point))
01921 __super::OnLButtonDblClk(nFlags, point);
01922 }
01923
01924 void CMainFrame::OnMButtonDown(UINT nFlags, CPoint point)
01925 {
01926 SendMessage(WM_CANCELMODE);
01927 if(!OnButton(wmcmd::MDOWN, nFlags, point))
01928 __super::OnMButtonDown(nFlags, point);
01929 }
01930
01931 void CMainFrame::OnMButtonUp(UINT nFlags, CPoint point)
01932 {
01933 if(!OnButton(wmcmd::MUP, nFlags, point))
01934 __super::OnMButtonUp(nFlags, point);
01935 }
01936
01937 void CMainFrame::OnMButtonDblClk(UINT nFlags, CPoint point)
01938 {
01939 SendMessage(WM_MBUTTONDOWN, nFlags, MAKELPARAM(point.x, point.y));
01940 if(!OnButton(wmcmd::MDBLCLK, nFlags, point))
01941 __super::OnMButtonDblClk(nFlags, point);
01942 }
01943
01944 void CMainFrame::OnRButtonDown(UINT nFlags, CPoint point)
01945 {
01946 if(!OnButton(wmcmd::RDOWN, nFlags, point))
01947 __super::OnRButtonDown(nFlags, point);
01948 }
01949
01950 void CMainFrame::OnRButtonUp(UINT nFlags, CPoint point)
01951 {
01952 if(!OnButton(wmcmd::RUP, nFlags, point))
01953 __super::OnRButtonUp(nFlags, point);
01954 }
01955
01956 void CMainFrame::OnRButtonDblClk(UINT nFlags, CPoint point)
01957 {
01958 SendMessage(WM_RBUTTONDOWN, nFlags, MAKELPARAM(point.x, point.y));
01959 if(!OnButton(wmcmd::RDBLCLK, nFlags, point))
01960 __super::OnRButtonDblClk(nFlags, point);
01961 }
01962
01963 LRESULT CMainFrame::OnXButtonDown(WPARAM wParam, LPARAM lParam)
01964 {
01965 SendMessage(WM_CANCELMODE);
01966 UINT fwButton = GET_XBUTTON_WPARAM(wParam);
01967 return OnButton(fwButton == XBUTTON1 ? wmcmd::X1DOWN : fwButton == XBUTTON2 ? wmcmd::X2DOWN : wmcmd::NONE,
01968 GET_KEYSTATE_WPARAM(wParam), CPoint(lParam));
01969 }
01970
01971 LRESULT CMainFrame::OnXButtonUp(WPARAM wParam, LPARAM lParam)
01972 {
01973 UINT fwButton = GET_XBUTTON_WPARAM(wParam);
01974 return OnButton(fwButton == XBUTTON1 ? wmcmd::X1UP : fwButton == XBUTTON2 ? wmcmd::X2UP : wmcmd::NONE,
01975 GET_KEYSTATE_WPARAM(wParam), CPoint(lParam));
01976 }
01977
01978 LRESULT CMainFrame::OnXButtonDblClk(WPARAM wParam, LPARAM lParam)
01979 {
01980 SendMessage(WM_XBUTTONDOWN, wParam, lParam);
01981 UINT fwButton = GET_XBUTTON_WPARAM(wParam);
01982 return OnButton(fwButton == XBUTTON1 ? wmcmd::X1DBLCLK : fwButton == XBUTTON2 ? wmcmd::X2DBLCLK : wmcmd::NONE,
01983 GET_KEYSTATE_WPARAM(wParam), CPoint(lParam));
01984 }
01985
01986 BOOL CMainFrame::OnMouseWheel(UINT nFlags, short zDelta, CPoint point)
01987 {
01988 ScreenToClient(&point);
01989
01990 BOOL fRet =
01991 zDelta > 0 ? OnButton(wmcmd::WUP, nFlags, point) :
01992 zDelta < 0 ? OnButton(wmcmd::WDOWN, nFlags, point) :
01993 FALSE;
01994
01995 return fRet;
01996 }
01997
01998 void CMainFrame::OnMouseMove(UINT nFlags, CPoint point)
01999 {
02000 if(m_iPlaybackMode == PM_DVD)
02001 {
02002 CPoint vp = point - m_wndView.GetVideoRect().TopLeft();
02003 pDVDC->SelectAtPosition(vp);
02004 }
02005
02006 CSize diff = m_lastMouseMove - point;
02007
02008 if(m_fFullScreen && (abs(diff.cx)+abs(diff.cy)) >= 1)
02009 {
02010 int nTimeOut = AfxGetAppSettings().nShowBarsWhenFullScreenTimeOut;
02011
02012 if(nTimeOut < 0)
02013 {
02014 m_fHideCursor = false;
02015 if(AfxGetAppSettings().fShowBarsWhenFullScreen)
02016 ShowControls(AfxGetAppSettings().nCS);
02017
02018 KillTimer(TIMER_FULLSCREENCONTROLBARHIDER);
02019 SetTimer(TIMER_FULLSCREENMOUSEHIDER, 2000, NULL);
02020 }
02021 else if(nTimeOut == 0)
02022 {
02023 CRect r;
02024 GetClientRect(r);
02025 r.top = r.bottom;
02026
02027 POSITION pos = m_bars.GetHeadPosition();
02028 for(int i = 1; pos; i <<= 1)
02029 {
02030 CControlBar* pNext = m_bars.GetNext(pos);
02031 CSize s = pNext->CalcFixedLayout(FALSE, TRUE);
02032 if(AfxGetAppSettings().nCS&i) r.top -= s.cy;
02033 }
02034
02035
02036 if(m_iPlaybackMode == PM_DVD
02037 && (m_iDVDDomain == DVD_DOMAIN_VideoManagerMenu
02038 || m_iDVDDomain == DVD_DOMAIN_VideoTitleSetMenu))
02039 r.top = r.bottom - 10;
02040
02041 m_fHideCursor = false;
02042
02043 if(r.PtInRect(point))
02044 {
02045 if(AfxGetAppSettings().fShowBarsWhenFullScreen)
02046 ShowControls(AfxGetAppSettings().nCS);
02047 }
02048 else
02049 {
02050 if(AfxGetAppSettings().fShowBarsWhenFullScreen)
02051 ShowControls(CS_NONE, false);
02052 }
02053
02054 SetTimer(TIMER_FULLSCREENMOUSEHIDER, 2000, NULL);
02055 }
02056 else
02057 {
02058 m_fHideCursor = false;
02059 if(AfxGetAppSettings().fShowBarsWhenFullScreen)
02060 ShowControls(AfxGetAppSettings().nCS);
02061
02062 SetTimer(TIMER_FULLSCREENCONTROLBARHIDER, nTimeOut*1000, NULL);
02063 SetTimer(TIMER_FULLSCREENMOUSEHIDER, max(nTimeOut*1000, 2000), NULL);
02064 }
02065 }
02066
02067 m_lastMouseMove = point;
02068
02069 __super::OnMouseMove(nFlags, point);
02070 }
02071
02072 LRESULT CMainFrame::OnNcHitTest(CPoint point)
02073 {
02074 LRESULT nHitTest = __super::OnNcHitTest(point);
02075 return ((IsCaptionMenuHidden()) && nHitTest == HTCLIENT) ? HTCAPTION : nHitTest;
02076 }
02077
02078 void CMainFrame::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
02079 {
02080 if(pScrollBar->IsKindOf(RUNTIME_CLASS(CVolumeCtrl)))
02081 {
02082 OnPlayVolume(0);
02083 }
02084 else if(pScrollBar->IsKindOf(RUNTIME_CLASS(CPlayerSeekBar)) && m_iMediaLoadState == MLS_LOADED)
02085 {
02086 SeekTo(m_wndSeekBar.GetPos(), !!(::GetKeyState(VK_SHIFT)&0x8000));
02087 }
02088
02089 __super::OnHScroll(nSBCode, nPos, pScrollBar);
02090 }
02091
02092 void CMainFrame::OnInitMenu(CMenu* pMenu)
02093 {
02094 __super::OnInitMenu(pMenu);
02095
02096 MENUITEMINFO mii;
02097 mii.cbSize = sizeof(mii);
02098
02099 for(UINT i = 0, j = pMenu->GetMenuItemCount(); i < j; i++)
02100 {
02101 CString str;
02102 pMenu->GetMenuString(i, str, MF_BYPOSITION);
02103
02104 CMenu* pSubMenu = NULL;
02105
02106 if(str == ResStr(IDS_FAVORITES_POPUP))
02107 {
02108 SetupFavoritesSubMenu();
02109 pSubMenu = &m_favorites;
02110 }
02111
02112 if(pSubMenu)
02113 {
02114 mii.fMask = MIIM_STATE|MIIM_SUBMENU;
02115 mii.fType = MF_POPUP;
02116 mii.hSubMenu = pSubMenu->m_hMenu;
02117 mii.fState = (pSubMenu->GetMenuItemCount() > 0 ? MF_ENABLED : (MF_DISABLED|MF_GRAYED));
02118 pMenu->SetMenuItemInfo(i, &mii, TRUE);
02119 }
02120 }
02121 }
02122
02123 void CMainFrame::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu)
02124 {
02125 __super::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu);
02126
02127 static CAtlMap<CString, UINT, CStringElementTraits<CString> > transl;
02128
02129 if(transl.IsEmpty())
02130 {
02131 transl[_T("Navigate")] = IDS_NAVIGATE_POPUP;
02132 transl[_T("Open CD-ROM")] = IDS_OPENCDROM_POPUP;
02133 transl[_T("Filters")] = IDS_FILTERS_POPUP;
02134 transl[_T("Audio")] = IDS_AUDIO_POPUP;
02135 transl[_T("Subtitles")] = IDS_SUBTITLES_POPUP;
02136 transl[_T("Audio Language")] = IDS_AUDIOLANGUAGE_POPUP;
02137 transl[_T("Subtitle Language")] = IDS_SUBTITLELANGUAGE_POPUP;
02138 transl[_T("Video Angle")] = IDS_VIDEOANGLE_POPUP;
02139 transl[_T("Jump To...")] = IDS_JUMPTO_POPUP;
02140 transl[_T("Favorites")] = IDS_FAVORITES_POPUP;
02141 transl[_T("Shaders")] = IDS_SHADER_POPUP;
02142 transl[_T("Video Frame")] = IDS_VIDEOFRAME_POPUP;
02143 transl[_T("PanScan")] = IDS_PANSCAN_POPUP;
02144 transl[_T("Aspect Ratio")] = IDS_ASPECTRATIO_POPUP;
02145 transl[_T("Zoom")] = IDS_ZOOM_POPUP;
02146 }
02147
02148 MENUITEMINFO mii;
02149 mii.cbSize = sizeof(mii);
02150
02151 for(UINT i = 0, j = pPopupMenu->GetMenuItemCount(); i < j; i++)
02152 {
02153 CString str;
02154 pPopupMenu->GetMenuString(i, str, MF_BYPOSITION);
02155
02156 CString lookupstr = str;
02157 lookupstr.Remove('&');
02158
02159 CMenu* pSubMenu = NULL;
02160
02161 UINT id;
02162 if(transl.Lookup(lookupstr, id))
02163 {
02164 str = ResStr(id);
02165
02166 MENUITEMINFO mii;
02167 mii.cbSize = sizeof(mii);
02168 mii.fMask = MIIM_STRING;
02169 mii.dwTypeData = (LPTSTR)(LPCTSTR)str;
02170 pPopupMenu->SetMenuItemInfo(i, &mii, TRUE);
02171 }
02172
02173 if(str == ResStr(IDS_NAVIGATE_POPUP))
02174 {
02175 UINT fState = (m_iMediaLoadState == MLS_LOADED
02176 && (1))
02177 ? MF_ENABLED
02178 : (MF_DISABLED|MF_GRAYED);
02179
02180 pPopupMenu->EnableMenuItem(i, MF_BYPOSITION|fState);
02181 }
02182 else if(str == ResStr(IDS_VIDEOFRAME_POPUP)
02183 || str == ResStr(IDS_PANSCAN_POPUP)
02184 || str == ResStr(IDS_ASPECTRATIO_POPUP)
02185 || str == ResStr(IDS_ZOOM_POPUP))
02186 {
02187 UINT fState = (m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly)
02188 ? MF_ENABLED
02189 : (MF_DISABLED|MF_GRAYED);
02190
02191 pPopupMenu->EnableMenuItem(i, MF_BYPOSITION|fState);
02192 }
02193 else if(str == ResStr(IDS_OPENCDROM_POPUP))
02194 {
02195 SetupOpenCDSubMenu();
02196 pSubMenu = &m_opencds;
02197 }
02198 else if(str == ResStr(IDS_FILTERS_POPUP))
02199 {
02200 SetupFiltersSubMenu();
02201 pSubMenu = &m_filters;
02202 }
02203 else if(str == ResStr(IDS_AUDIO_POPUP))
02204 {
02205 SetupAudioSwitcherSubMenu();
02206 pSubMenu = &m_audios;
02207 }
02208 else if(str == ResStr(IDS_SUBTITLES_POPUP))
02209 {
02210 SetupSubtitlesSubMenu();
02211 pSubMenu = &m_subtitles;
02212 }
02213 else if(str == ResStr(IDS_AUDIOLANGUAGE_POPUP))
02214 {
02215 SetupNavAudioSubMenu();
02216 pSubMenu = &m_navaudio;
02217 }
02218 else if(str == ResStr(IDS_SUBTITLELANGUAGE_POPUP))
02219 {
02220 SetupNavSubtitleSubMenu();
02221 pSubMenu = &m_navsubtitle;
02222 }
02223 else if(str == ResStr(IDS_VIDEOANGLE_POPUP))
02224 {
02225 SetupNavAngleSubMenu();
02226 pSubMenu = &m_navangle;
02227 }
02228 else if(str == ResStr(IDS_JUMPTO_POPUP))
02229 {
02230 SetupNavChaptersSubMenu();
02231 pSubMenu = &m_navchapters;
02232 }
02233 else if(str == ResStr(IDS_FAVORITES_POPUP))
02234 {
02235 SetupFavoritesSubMenu();
02236 pSubMenu = &m_favorites;
02237 }
02238 else if(str == ResStr(IDS_SHADER_POPUP))
02239 {
02240 SetupShadersSubMenu();
02241 pSubMenu = &m_shaders;
02242 }
02243
02244 if(pSubMenu)
02245 {
02246 mii.fMask = MIIM_STATE|MIIM_SUBMENU;
02247 mii.fType = MF_POPUP;
02248 mii.hSubMenu = pSubMenu->m_hMenu;
02249 mii.fState = (pSubMenu->GetMenuItemCount() > 0 ? MF_ENABLED : (MF_DISABLED|MF_GRAYED));
02250 pPopupMenu->SetMenuItemInfo(i, &mii, TRUE);
02251 }
02252 }
02253
02254
02255
02256 for(UINT i = 0, j = pPopupMenu->GetMenuItemCount(); i < j; i++)
02257 {
02258 UINT nID = pPopupMenu->GetMenuItemID(i);
02259 if(nID == ID_SEPARATOR || nID == -1
02260 || nID >= ID_FAVORITES_FILE_START && nID <= ID_FAVORITES_FILE_END
02261 || nID >= ID_NAVIGATE_CHAP_SUBITEM_START && nID <= ID_NAVIGATE_CHAP_SUBITEM_END)
02262 continue;
02263
02264 CString str;
02265 pPopupMenu->GetMenuString(i, str, MF_BYPOSITION);
02266 int k = str.Find('\t');
02267 if(k > 0) str = str.Left(k);
02268
02269 CString key = CPPageAccelTbl::MakeAccelShortcutLabel(nID);
02270 if(!key.IsEmpty()) str += _T("\t") + key;
02271
02272 if(key.IsEmpty() && i < 0) continue;
02273
02274
02275
02276
02277
02278 MENUITEMINFO mii;
02279 mii.cbSize = sizeof(mii);
02280 mii.fMask = MIIM_STRING;
02281 mii.dwTypeData = (LPTSTR)(LPCTSTR)str;
02282 pPopupMenu->SetMenuItemInfo(i, &mii, TRUE);
02283
02284 }
02285
02286
02287
02288 bool fPnSPresets = false;
02289
02290 for(UINT i = 0, j = pPopupMenu->GetMenuItemCount(); i < j; i++)
02291 {
02292 UINT nID = pPopupMenu->GetMenuItemID(i);
02293
02294 if(nID >= ID_PANNSCAN_PRESETS_START && nID < ID_PANNSCAN_PRESETS_END)
02295 {
02296 do
02297 {
02298 nID = pPopupMenu->GetMenuItemID(i);
02299 pPopupMenu->DeleteMenu(i, MF_BYPOSITION);
02300 j--;
02301 }
02302 while(i < j && nID >= ID_PANNSCAN_PRESETS_START && nID < ID_PANNSCAN_PRESETS_END);
02303
02304 nID = pPopupMenu->GetMenuItemID(i);
02305 }
02306
02307 if(nID == ID_VIEW_RESET)
02308 {
02309 fPnSPresets = true;
02310 }
02311 }
02312
02313 if(fPnSPresets)
02314 {
02315 AppSettings& s = AfxGetAppSettings();
02316 int i = 0, j = s.m_pnspresets.GetCount();
02317 for(; i < j; i++)
02318 {
02319 int k = 0;
02320 CString label = s.m_pnspresets[i].Tokenize(_T(","), k);
02321 pPopupMenu->InsertMenu(ID_VIEW_RESET, MF_BYCOMMAND, ID_PANNSCAN_PRESETS_START+i, label);
02322 }
02323
02324 {
02325 pPopupMenu->InsertMenu(ID_VIEW_RESET, MF_BYCOMMAND, ID_PANNSCAN_PRESETS_START+i, _T("Edit..."));
02326 pPopupMenu->InsertMenu(ID_VIEW_RESET, MF_BYCOMMAND|MF_SEPARATOR);
02327 }
02328 }
02329 }
02330
02331 BOOL CMainFrame::OnMenu(CMenu* pMenu)
02332 {
02333 if(!pMenu) return FALSE;
02334
02335 KillTimer(TIMER_FULLSCREENMOUSEHIDER);
02336 m_fHideCursor = false;
02337
02338 CPoint point;
02339 GetCursorPos(&point);
02340
02341 pMenu->TrackPopupMenu(TPM_RIGHTBUTTON|TPM_NOANIMATION, point.x, point.y, this);
02342
02343 return TRUE;
02344 }
02345
02346 void CMainFrame::OnMenuPlayerShort()
02347 {
02348 if(IsCaptionMenuHidden())
02349 {
02350 OnMenu(m_popupmain.GetSubMenu(0));
02351 }
02352 else
02353 {
02354 OnMenu(m_popup.GetSubMenu(0));
02355 }
02356 }
02357
02358 void CMainFrame::OnMenuPlayerLong()
02359 {
02360 OnMenu(m_popupmain.GetSubMenu(0));
02361 }
02362
02363 void CMainFrame::OnMenuFilters()
02364 {
02365 SetupFiltersSubMenu();
02366 OnMenu(&m_filters);
02367 }
02368
02369 void CMainFrame::OnUpdatePlayerStatus(CCmdUI* pCmdUI)
02370 {
02371 if(m_iMediaLoadState == MLS_LOADING)
02372 {
02373 pCmdUI->SetText(_T("Opening..."));
02374 }
02375 else if(m_iMediaLoadState == MLS_LOADED)
02376 {
02377 CString msg;
02378
02379 if(!m_playingmsg.IsEmpty())
02380 {
02381 msg = m_playingmsg;
02382 }
02383 else if(m_fCapturing)
02384 {
02385 msg = _T("Capturing...");
02386
02387 if(pAMDF)
02388 {
02389 long lDropped = 0;
02390 pAMDF->GetNumDropped(&lDropped);
02391 long lNotDropped = 0;
02392 pAMDF->GetNumNotDropped(&lNotDropped);
02393
02394 if((lDropped + lNotDropped) > 0)
02395 {
02396 CString str;
02397 str.Format(_T(", Total: %d, Dropped: %d"), lDropped + lNotDropped, lDropped);
02398 msg += str;
02399 }
02400 }
02401
02402 CComPtr<IPin> pPin;
02403 if(SUCCEEDED(pCGB->FindPin(m_wndCaptureBar.m_capdlg.m_pDst, PINDIR_INPUT, NULL, NULL, FALSE, 0, &pPin)))
02404 {
02405 LONGLONG size = 0;
02406 if(CComQIPtr<IStream> pStream = pPin)
02407 {
02408 pStream->Commit(STGC_DEFAULT);
02409
02410 WIN32_FIND_DATA findFileData;
02411 HANDLE h = FindFirstFile(m_wndCaptureBar.m_capdlg.m_file, &findFileData);
02412 if(h != INVALID_HANDLE_VALUE)
02413 {
02414 size = ((LONGLONG)findFileData.nFileSizeHigh << 32) | findFileData.nFileSizeLow;
02415
02416 CString str;
02417 if(size < 1024i64*1024)
02418 str.Format(_T(", Size: %I64dKB"), size/1024);
02419 else
02420 str.Format(_T(", Size: %I64dMB"), size/1024/1024);
02421 msg += str;
02422
02423 FindClose(h);
02424 }
02425 }
02426
02427 ULARGE_INTEGER FreeBytesAvailable, TotalNumberOfBytes, TotalNumberOfFreeBytes;
02428 if(GetDiskFreeSpaceEx(
02429 m_wndCaptureBar.m_capdlg.m_file.Left(m_wndCaptureBar.m_capdlg.m_file.ReverseFind('\\')+1),
02430 &FreeBytesAvailable, &TotalNumberOfBytes, &TotalNumberOfFreeBytes))
02431 {
02432 CString str;
02433 if(FreeBytesAvailable.QuadPart < 1024i64*1024)
02434 str.Format(_T(", Free: %I64dKB"), FreeBytesAvailable.QuadPart/1024);
02435 else
02436 str.Format(_T(", Free: %I64dMB"), FreeBytesAvailable.QuadPart/1024/1024);
02437 msg += str;
02438 }
02439
02440 if(m_wndCaptureBar.m_capdlg.m_pMux)
02441 {
02442 __int64 pos = 0;
02443 CComQIPtr<IMediaSeeking> pMuxMS = m_wndCaptureBar.m_capdlg.m_pMux;
02444 if(pMuxMS && SUCCEEDED(pMuxMS->GetCurrentPosition(&pos)) && pos > 0)
02445 {
02446 double bytepersec = 10000000.0 * size / pos;
02447 if(bytepersec > 0)
02448 m_rtDurationOverride = __int64(10000000.0 * (FreeBytesAvailable.QuadPart+size) / bytepersec);
02449 }
02450 }
02451
02452 if(m_wndCaptureBar.m_capdlg.m_pVidBuffer
02453 || m_wndCaptureBar.m_capdlg.m_pAudBuffer)
02454 {
02455 int nFreeVidBuffers = 0, nFreeAudBuffers = 0;
02456 if(CComQIPtr<IBufferFilter> pVB = m_wndCaptureBar.m_capdlg.m_pVidBuffer)
02457 nFreeVidBuffers = pVB->GetFreeBuffers();
02458 if(CComQIPtr<IBufferFilter> pAB = m_wndCaptureBar.m_capdlg.m_pAudBuffer)
02459 nFreeAudBuffers = pAB->GetFreeBuffers();
02460
02461 CString str;
02462 str.Format(_T(", Free V/A Buffers: %03d/%03d"), nFreeVidBuffers, nFreeAudBuffers);
02463 msg += str;
02464 }
02465 }
02466 }
02467 else if(m_fBuffering)
02468 {
02469 BeginEnumFilters(pGB, pEF, pBF)
02470 {
02471 if(CComQIPtr<IAMNetworkStatus, &IID_IAMNetworkStatus> pAMNS = pBF)
02472 {
02473 long BufferingProgress = 0;
02474 if(SUCCEEDED(pAMNS->get_BufferingProgress(&BufferingProgress)) && BufferingProgress > 0)
02475 {
02476 msg.Format(_T("Buffering... (%d%%)"), BufferingProgress);
02477
02478 __int64 start = 0, stop = 0;
02479 m_wndSeekBar.GetRange(start, stop);
02480 m_fLiveWM = (stop == start);
02481 }
02482 break;
02483 }
02484 }
02485 EndEnumFilters
02486 }
02487 else if(pAMOP)
02488 {
02489 __int64 t = 0, c = 0;
02490 if(SUCCEEDED(pAMOP->QueryProgress(&t, &c)) && t > 0 && c < t)
02491 msg.Format(_T("Buffering... (%d%%)"), c*100/t);
02492
02493 if(m_fUpdateInfoBar)
02494 OpenSetupInfoBar();
02495 }
02496
02497 OAFilterState fs = GetMediaState();
02498 pCmdUI->SetText(
02499 !msg.IsEmpty() ? msg :
02500 fs == State_Stopped ? _T("Stopped") :
02501 (fs == State_Paused || m_fFrameSteppingActive) ? _T("Paused") :
02502 fs == State_Running ? _T("Playing") :
02503 _T(""));
02504 }
02505 else if(m_iMediaLoadState == MLS_CLOSING)
02506 {
02507 pCmdUI->SetText(_T("Closing..."));
02508 }
02509 else
02510 {
02511 pCmdUI->SetText(m_closingmsg);
02512 }
02513 }
02514
02515 void CMainFrame::OnFilePostOpenmedia()
02516 {
02517 OpenSetupInfoBar();
02518
02519 OpenSetupStatsBar();
02520
02521 OpenSetupStatusBar();
02522
02523
02524
02525 OpenSetupCaptureBar();
02526
02527 __int64 rtDur = 0;
02528 pMS->GetDuration(&rtDur);
02529 m_wndPlaylistBar.SetCurTime(rtDur);
02530
02531 if(m_iPlaybackMode == PM_CAPTURE)
02532 {
02533 ShowControlBar(&m_wndSubresyncBar, FALSE, TRUE);
02534
02535
02536 }
02537
02538 m_iMediaLoadState = MLS_LOADED;
02539
02540
02541
02542
02543
02544
02545 {
02546 WINDOWPLACEMENT wp;
02547 wp.length = sizeof(wp);
02548 GetWindowPlacement(&wp);
02549
02550
02551 if(IsWindowVisible() && AfxGetAppSettings().fRememberZoomLevel
02552 && !(m_fFullScreen || wp.showCmd == SW_SHOWMAXIMIZED || wp.showCmd == SW_SHOWMINIMIZED))
02553 {
02554 ZoomVideoWindow();
02555 }
02556 }
02557
02558 if(!m_fAudioOnly && (AfxGetAppSettings().nCLSwitches&CLSW_FULLSCREEN))
02559 {
02560 SendMessage(WM_COMMAND, ID_VIEW_FULLSCREEN);
02561 AfxGetAppSettings().nCLSwitches &= ~CLSW_FULLSCREEN;
02562 }
02563
02564 SendNowPlayingToMSN();
02565 }
02566
02567 void CMainFrame::OnUpdateFilePostOpenmedia(CCmdUI* pCmdUI)
02568 {
02569 pCmdUI->Enable(m_iMediaLoadState == MLS_LOADING);
02570 }
02571
02572 void CMainFrame::OnFilePostClosemedia()
02573 {
02574 m_wndView.SetVideoRect();
02575 m_wndSeekBar.Enable(false);
02576 m_wndSeekBar.SetPos(0);
02577 m_wndInfoBar.RemoveAllLines();
02578 m_wndStatsBar.RemoveAllLines();
02579 m_wndStatusBar.Clear();
02580 m_wndStatusBar.ShowTimer(false);
02581
02582 if(IsWindow(m_wndSubresyncBar.m_hWnd))
02583 {
02584 ShowControlBar(&m_wndSubresyncBar, FALSE, TRUE);
02585 SetSubtitle(NULL);
02586 }
02587
02588 if(IsWindow(m_wndCaptureBar.m_hWnd))
02589 {
02590 ShowControlBar(&m_wndCaptureBar, FALSE, TRUE);
02591 m_wndCaptureBar.m_capdlg.SetupVideoControls(_T(""), NULL, NULL, NULL);
02592 m_wndCaptureBar.m_capdlg.SetupAudioControls(_T(""), NULL, CInterfaceArray<IAMAudioInputMixer>());
02593 }
02594
02595 RecalcLayout();
02596
02597 SetWindowText(ResStr(IDR_MAINFRAME));
02598
02599 SetAlwaysOnTop(AfxGetAppSettings().iOnTop);
02600
02601
02602 SetupFiltersSubMenu();
02603 SetupAudioSwitcherSubMenu();
02604 SetupSubtitlesSubMenu();
02605 SetupNavAudioSubMenu();
02606 SetupNavSubtitleSubMenu();
02607 SetupNavAngleSubMenu();
02608 SetupNavChaptersSubMenu();
02609 SetupFavoritesSubMenu();
02610
02611 SendNowPlayingToMSN();
02612 }
02613
02614 void CMainFrame::OnUpdateFilePostClosemedia(CCmdUI* pCmdUI)
02615 {
02616 pCmdUI->Enable(!!m_hWnd && m_iMediaLoadState == MLS_CLOSING);
02617 }
02618
02619 void CMainFrame::OnBossKey()
02620 {
02621 SendMessage(WM_COMMAND, ID_PLAY_PAUSE);
02622 if(m_fFullScreen) SendMessage(WM_COMMAND, ID_VIEW_FULLSCREEN);
02623 SendMessage(WM_SYSCOMMAND, SC_MINIMIZE, -1);
02624 }
02625
02626 void CMainFrame::OnStreamAudio(UINT nID)
02627 {
02628 nID -= ID_STREAM_AUDIO_NEXT;
02629
02630 if(m_iMediaLoadState != MLS_LOADED) return;
02631
02632 CComQIPtr<IAMStreamSelect> pSS = FindFilter(__uuidof(CAudioSwitcherFilter), pGB);
02633 if(!pSS) pSS = FindFilter(L"{D3CD7858-971A-4838-ACEC-40CA5D529DC8}", pGB);
02634
02635 DWORD cStreams = 0;
02636 if(pSS && SUCCEEDED(pSS->Count(&cStreams)) && cStreams > 1)
02637 {
02638 for(int i = 0; i < (int)cStreams; i++)
02639 {
02640 AM_MEDIA_TYPE* pmt = NULL;
02641 DWORD dwFlags = 0;
02642 LCID lcid = 0;
02643 DWORD dwGroup = 0;
02644 WCHAR* pszName = NULL;
02645 if(FAILED(pSS->Info(i, &pmt, &dwFlags, &lcid, &dwGroup, &pszName, NULL, NULL)))
02646 return;
02647 if(pmt) DeleteMediaType(pmt);
02648 if(pszName) CoTaskMemFree(pszName);
02649
02650 if(dwFlags&(AMSTREAMSELECTINFO_ENABLED|AMSTREAMSELECTINFO_EXCLUSIVE))
02651 {
02652 pSS->Enable((i+(nID==0?1:cStreams-1))%cStreams, AMSTREAMSELECTENABLE_ENABLE);
02653 break;
02654 }
02655 }
02656 }
02657 else if(m_iPlaybackMode == PM_FILE) SendMessage(WM_COMMAND, ID_OGM_AUDIO_NEXT+nID);
02658 else if(m_iPlaybackMode == PM_DVD) SendMessage(WM_COMMAND, ID_DVD_AUDIO_NEXT+nID);
02659 }
02660
02661 void CMainFrame::OnStreamSub(UINT nID)
02662 {
02663 nID -= ID_STREAM_SUB_NEXT;
02664
02665 if(m_iMediaLoadState != MLS_LOADED) return;
02666
02667 int cnt = 0;
02668 POSITION pos = m_pSubStreams.GetHeadPosition();
02669 while(pos) cnt += m_pSubStreams.GetNext(pos)->GetStreamCount();
02670
02671 if(cnt > 1)
02672 {
02673 int i = ((m_iSubtitleSel&0x7fffffff)+(nID==0?1:cnt-1))%cnt;
02674 m_iSubtitleSel = i | (m_iSubtitleSel&0x80000000);
02675 UpdateSubtitle();
02676 SetFocus();
02677 }
02678 else if(m_iPlaybackMode == PM_FILE) SendMessage(WM_COMMAND, ID_OGM_SUB_NEXT+nID);
02679 else if(m_iPlaybackMode == PM_DVD) SendMessage(WM_COMMAND, ID_DVD_SUB_NEXT+nID);
02680 }
02681
02682 void CMainFrame::OnStreamSubOnOff()
02683 {
02684 if(m_iMediaLoadState != MLS_LOADED) return;
02685
02686 int cnt = 0;
02687 POSITION pos = m_pSubStreams.GetHeadPosition();
02688 while(pos) cnt += m_pSubStreams.GetNext(pos)->GetStreamCount();
02689
02690 if(cnt > 0)
02691 {
02692 m_iSubtitleSel ^= 0x80000000;
02693 UpdateSubtitle();
02694 SetFocus();
02695 }
02696 else if(m_iPlaybackMode == PM_DVD) SendMessage(WM_COMMAND, ID_DVD_SUB_ONOFF);
02697 }
02698
02699 void CMainFrame::OnOgmAudio(UINT nID)
02700 {
02701 nID -= ID_OGM_AUDIO_NEXT;
02702
02703 if(m_iMediaLoadState != MLS_LOADED) return;
02704
02705 CComQIPtr<IAMStreamSelect> pSS = FindFilter(CLSID_OggSplitter, pGB);
02706 if(!pSS) pSS = FindFilter(L"{55DA30FC-F16B-49fc-BAA5-AE59FC65F82D}", pGB);
02707 if(!pSS) return;
02708
02709 CArray<int> snds;
02710 int iSel = -1;
02711
02712 DWORD cStreams = 0;
02713 if(SUCCEEDED(pSS->Count(&cStreams)) && cStreams > 1)
02714 {
02715 for(int i = 0; i < (int)cStreams; i++)
02716 {
02717 AM_MEDIA_TYPE* pmt = NULL;
02718 DWORD dwFlags = 0;
02719 LCID lcid = 0;
02720 DWORD dwGroup = 0;
02721 WCHAR* pszName = NULL;
02722 if(FAILED(pSS->Info(i, &pmt, &dwFlags, &lcid, &dwGroup, &pszName, NULL, NULL)))
02723 return;
02724
02725 if(dwGroup == 1)
02726 {
02727 if(dwFlags&(AMSTREAMSELECTINFO_ENABLED|AMSTREAMSELECTINFO_EXCLUSIVE))
02728 iSel = snds.GetCount();
02729 snds.Add(i);
02730 }
02731
02732 if(pmt) DeleteMediaType(pmt);
02733 if(pszName) CoTaskMemFree(pszName);
02734
02735 }
02736
02737 int cnt = snds.GetCount();
02738 if(cnt > 1 && iSel >= 0)
02739 pSS->Enable(snds[(iSel+(nID==0?1:cnt-1))%cnt], AMSTREAMSELECTENABLE_ENABLE);
02740 }
02741 }
02742
02743 void CMainFrame::OnOgmSub(UINT nID)
02744 {
02745 nID -= ID_OGM_SUB_NEXT;
02746
02747 if(m_iMediaLoadState != MLS_LOADED) return;
02748
02749 CComQIPtr<IAMStreamSelect> pSS = FindFilter(CLSID_OggSplitter, pGB);
02750 if(!pSS) pSS = FindFilter(L"{55DA30FC-F16B-49fc-BAA5-AE59FC65F82D}", pGB);
02751 if(!pSS) return;
02752
02753 CArray<int> subs;
02754 int iSel = -1;
02755
02756 DWORD cStreams = 0;
02757 if(SUCCEEDED(pSS->Count(&cStreams)) && cStreams > 1)
02758 {
02759 for(int i = 0; i < (int)cStreams; i++)
02760 {
02761 AM_MEDIA_TYPE* pmt = NULL;
02762 DWORD dwFlags = 0;
02763 LCID lcid = 0;
02764 DWORD dwGroup = 0;
02765 WCHAR* pszName = NULL;
02766 if(FAILED(pSS->Info(i, &pmt, &dwFlags, &lcid, &dwGroup, &pszName, NULL, NULL)))
02767 return;
02768
02769 if(dwGroup == 2)
02770 {
02771 if(dwFlags&(AMSTREAMSELECTINFO_ENABLED|AMSTREAMSELECTINFO_EXCLUSIVE))
02772 iSel = subs.GetCount();
02773 subs.Add(i);
02774 }
02775
02776 if(pmt) DeleteMediaType(pmt);
02777 if(pszName) CoTaskMemFree(pszName);
02778
02779 }
02780
02781 int cnt = subs.GetCount();
02782 if(cnt > 1 && iSel >= 0)
02783 pSS->Enable(subs[(iSel+(nID==0?1:cnt-1))%cnt], AMSTREAMSELECTENABLE_ENABLE);
02784 }
02785 }
02786
02787 void CMainFrame::OnDvdAngle(UINT nID)
02788 {
02789 nID -= ID_DVD_ANGLE_NEXT;
02790
02791 if(m_iMediaLoadState != MLS_LOADED) return;
02792
02793 if(pDVDI && pDVDC)
02794 {
02795 ULONG ulAnglesAvailable, ulCurrentAngle;
02796 if(SUCCEEDED(pDVDI->GetCurrentAngle(&ulAnglesAvailable, &ulCurrentAngle))
02797 && ulAnglesAvailable > 1)
02798 {
02799 pDVDC->SelectAngle(
02800 (ulCurrentAngle+(nID==0?1:ulAnglesAvailable-1))%ulAnglesAvailable,
02801 DVD_CMD_FLAG_Block, NULL);
02802 }
02803 }
02804 }
02805
02806 void CMainFrame::OnDvdAudio(UINT nID)
02807 {
02808 nID -= ID_DVD_AUDIO_NEXT;
02809
02810 if(m_iMediaLoadState != MLS_LOADED) return;
02811
02812 if(pDVDI && pDVDC)
02813 {
02814 ULONG nStreamsAvailable, nCurrentStream;
02815 if(SUCCEEDED(pDVDI->GetCurrentAudio(&nStreamsAvailable, &nCurrentStream))
02816 && nStreamsAvailable > 1)
02817 {
02818 pDVDC->SelectAudioStream(
02819 (nCurrentStream+(nID==0?1:nStreamsAvailable-1))%nStreamsAvailable,
02820 DVD_CMD_FLAG_Block, NULL);
02821 }
02822 }
02823 }
02824
02825 void CMainFrame::OnDvdSub(UINT nID)
02826 {
02827 nID -= ID_DVD_SUB_NEXT;
02828
02829 if(m_iMediaLoadState != MLS_LOADED) return;
02830
02831 if(pDVDI && pDVDC)
02832 {
02833 ULONG ulStreamsAvailable, ulCurrentStream;
02834 BOOL bIsDisabled;
02835 if(SUCCEEDED(pDVDI->GetCurrentSubpicture(&ulStreamsAvailable, &ulCurrentStream, &bIsDisabled))
02836 && ulStreamsAvailable > 1)
02837 {
02838 pDVDC->SelectSubpictureStream(
02839 (ulCurrentStream+(nID==0?1:ulStreamsAvailable-1))%ulStreamsAvailable,
02840 DVD_CMD_FLAG_Block, NULL);
02841 }
02842 }
02843 }
02844
02845 void CMainFrame::OnDvdSubOnOff()
02846 {
02847 if(m_iMediaLoadState != MLS_LOADED) return;
02848
02849 if(pDVDI && pDVDC)
02850 {
02851 ULONG ulStreamsAvailable, ulCurrentStream;
02852 BOOL bIsDisabled;
02853 if(SUCCEEDED(pDVDI->GetCurrentSubpicture(&ulStreamsAvailable, &ulCurrentStream, &bIsDisabled)))
02854 {
02855 pDVDC->SetSubpictureState(bIsDisabled, DVD_CMD_FLAG_Block, NULL);
02856 }
02857 }
02858 }
02859
02860
02861
02862
02863
02864
02865
02866 void CMainFrame::OnFileOpenmedia()
02867 {
02868 if(m_iMediaLoadState == MLS_LOADING || !IsWindow(m_wndPlaylistBar)) return;
02869
02870 COpenDlg dlg;
02871 if(dlg.DoModal() != IDOK || dlg.m_fns.GetCount() == 0) return;
02872
02873 SendMessage(WM_COMMAND, ID_FILE_CLOSEMEDIA);
02874
02875 ShowWindow(SW_SHOW);
02876 SetForegroundWindow();
02877
02878 m_wndPlaylistBar.Open(dlg.m_fns, dlg.m_fMultipleFiles);
02879
02880 if(m_wndPlaylistBar.GetCount() == 1 && m_wndPlaylistBar.IsWindowVisible() && !m_wndPlaylistBar.IsFloating())
02881 {
02882 ShowControlBar(&m_wndPlaylistBar, FALSE, TRUE);
02883 }
02884
02885 OpenCurPlaylistItem();
02886 }
02887
02888 void CMainFrame::OnUpdateFileOpen(CCmdUI* pCmdUI)
02889 {
02890 pCmdUI->Enable(m_iMediaLoadState != MLS_LOADING);
02891 }
02892
02893 BOOL CMainFrame::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCDS)
02894 {
02895 if(m_iMediaLoadState == MLS_LOADING || !IsWindow(m_wndPlaylistBar))
02896 return FALSE;
02897
02898 if(pCDS->dwData != 0x6ABE51 || pCDS->cbData < sizeof(DWORD))
02899 return FALSE;
02900
02901 DWORD len = *((DWORD*)pCDS->lpData);
02902 TCHAR* pBuff = (TCHAR*)((DWORD*)pCDS->lpData + 1);
02903 TCHAR* pBuffEnd = (TCHAR*)((BYTE*)pBuff + pCDS->cbData - sizeof(DWORD));
02904
02905 CList<CString> cmdln;
02906
02907 while(len-- > 0)
02908 {
02909 CString str;
02910 while(pBuff < pBuffEnd && *pBuff) str += *pBuff++;
02911 pBuff++;
02912 cmdln.AddTail(str);
02913 }
02914
02915 AppSettings& s = AfxGetAppSettings();
02916
02917 s.ParseCommandLine(cmdln);
02918
02919 POSITION pos = s.slFilters.GetHeadPosition();
02920 while(pos)
02921 {
02922 CString fullpath = MakeFullPath(s.slFilters.GetNext(pos));
02923
02924 CPath tmp(fullpath);
02925 tmp.RemoveFileSpec();
02926 tmp.AddBackslash();
02927 CString path = tmp;
02928
02929 WIN32_FIND_DATA fd = {0};
02930 HANDLE hFind = FindFirstFile(fullpath, &fd);
02931 if(hFind != INVALID_HANDLE_VALUE)
02932 {
02933 do
02934 {
02935 if(fd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) continue;
02936
02937 CFilterMapper2 fm2(false);
02938 fm2.Register(path + fd.cFileName);
02939 while(!fm2.m_filters.IsEmpty())
02940 {
02941 if(Filter* f = fm2.m_filters.RemoveTail())
02942 {
02943 f->fTemporary = true;
02944
02945 bool fFound = false;
02946
02947 POSITION pos2 = s.filters.GetHeadPosition();
02948 while(pos2)
02949 {
02950 Filter* f2 = s.filters.GetNext(pos2);
02951 if(f2->type == Filter::EXTERNAL && !f2->path.CompareNoCase(f->path))
02952 {
02953 fFound = true;
02954 break;
02955 }
02956 }
02957
02958 if(!fFound)
02959 {
02960 CAutoPtr<Filter> p(f);
02961 s.filters.AddHead(p);
02962 }
02963 }
02964 }
02965 }
02966 while(FindNextFile(hFind, &fd));
02967
02968 FindClose(hFind);
02969 }
02970 }
02971
02972 bool fSetForegroundWindow = false;
02973
02974 if((s.nCLSwitches&CLSW_DVD) && !s.slFiles.IsEmpty())
02975 {
02976 SendMessage(WM_COMMAND, ID_FILE_CLOSEMEDIA);
02977 fSetForegroundWindow = true;
02978
02979 CAutoPtr<OpenDVDData> p(new OpenDVDData());
02980 if(p) {p->path = s.slFiles.GetHead(); p->subs.AddTail(&s.slSubs);}
02981 OpenMedia(p);
02982 }
02983 else if(s.nCLSwitches&CLSW_CD)
02984 {
02985 SendMessage(WM_COMMAND, ID_FILE_CLOSEMEDIA);
02986 fSetForegroundWindow = true;
02987
02988 CList<CString> sl;
02989
02990 if(!s.slFiles.IsEmpty())
02991 {
02992 GetCDROMType(s.slFiles.GetHead()[0], sl);
02993 }
02994 else
02995 {
02996 CString dir;
02997 dir.ReleaseBufferSetLength(GetCurrentDirectory(MAX_PATH, dir.GetBuffer(MAX_PATH)));
02998
02999 GetCDROMType(dir[0], sl);
03000
03001 for(TCHAR drive = 'C'; sl.IsEmpty() && drive <= 'Z'; drive++)
03002 {
03003 GetCDROMType(drive, sl);
03004 }
03005 }
03006
03007 m_wndPlaylistBar.Open(sl, true);
03008 OpenCurPlaylistItem();
03009 }
03010 else if(!s.slFiles.IsEmpty())
03011 {
03012 bool fMulti = s.slFiles.GetCount() > 1;
03013
03014 CList<CString> sl;
03015 sl.AddTail((CList<CString>*)&s.slFiles);
03016 if(!fMulti) sl.AddTail((CList<CString>*)&s.slDubs);
03017
03018 if((s.nCLSwitches&CLSW_ADD) && m_wndPlaylistBar.GetCount() > 0)
03019 {
03020 m_wndPlaylistBar.Append(sl, fMulti, &s.slSubs);
03021
03022 if(s.nCLSwitches&(CLSW_OPEN|CLSW_PLAY))
03023 {
03024 m_wndPlaylistBar.SetLast();
03025 OpenCurPlaylistItem();
03026 }
03027 }
03028 else
03029 {
03030 SendMessage(WM_COMMAND, ID_FILE_CLOSEMEDIA);
03031 fSetForegroundWindow = true;
03032
03033 m_wndPlaylistBar.Open(sl, fMulti, &s.slSubs);
03034 OpenCurPlaylistItem((s.nCLSwitches&CLSW_STARTVALID) ? s.rtStart : 0);
03035
03036 s.nCLSwitches &= ~CLSW_STARTVALID;
03037 s.rtStart = 0;
03038 }
03039 }
03040 else
03041 {
03042 s.nCLSwitches = CLSW_NONE;
03043 }
03044
03045 if(fSetForegroundWindow && !(s.nCLSwitches&CLSW_NOFOCUS))
03046 SetForegroundWindow();
03047
03048 s.nCLSwitches &= ~CLSW_NOFOCUS;
03049
03050 return TRUE;
03051 }
03052
03053 void CMainFrame::OnFileOpendvd()
03054 {
03055 if(m_iMediaLoadState == MLS_LOADING) return;
03056
03057 SendMessage(WM_COMMAND, ID_FILE_CLOSEMEDIA);
03058 SetForegroundWindow();
03059
03060 ShowWindow(SW_SHOW);
03061
03062 CAutoPtr<OpenDVDData> p(new OpenDVDData());
03063 if(p)
03064 {
03065 AppSettings& s = AfxGetAppSettings();
03066 if(s.fUseDVDPath && !s.sDVDPath.IsEmpty())
03067 {
03068 p->path = s.sDVDPath;
03069 p->path.Replace('/', '\\');
03070 if(p->path[p->path.GetLength()-1] != '\\') p->path += '\\';
03071 }
03072 }
03073 OpenMedia(p);
03074 }
03075
03076 void CMainFrame::OnFileOpendevice()
03077 {
03078 if(m_iMediaLoadState == MLS_LOADING) return;
03079
03080 COpenCapDeviceDlg capdlg;
03081 if(capdlg.DoModal() != IDOK)
03082 return;
03083
03084 SendMessage(WM_COMMAND, ID_FILE_CLOSEMEDIA);
03085 SetForegroundWindow();
03086
03087 ShowWindow(SW_SHOW);
03088
03089 m_wndPlaylistBar.Empty();
03090
03091 CAutoPtr<OpenDeviceData> p(new OpenDeviceData());
03092 if(p) {p->DisplayName[0] = capdlg.m_vidstr; p->DisplayName[1] = capdlg.m_audstr;}
03093 OpenMedia(p);
03094 }
03095
03096 void CMainFrame::OnFileOpenCD(UINT nID)
03097 {
03098 nID -= ID_FILE_OPEN_CD_START;
03099
03100 nID++;
03101 for(TCHAR drive = 'C'; drive <= 'Z'; drive++)
03102 {
03103 CList<CString> sl;
03104
03105 switch(GetCDROMType(drive, sl))
03106 {
03107 case CDROM_Audio:
03108 case CDROM_VideoCD:
03109 case CDROM_DVDVideo:
03110 nID--;
03111 break;
03112 default:
03113 break;
03114 }
03115
03116 if(nID == 0)
03117 {
03118 SendMessage(WM_COMMAND, ID_FILE_CLOSEMEDIA);
03119 SetForegroundWindow();
03120
03121 ShowWindow(SW_SHOW);
03122
03123 m_wndPlaylistBar.Open(sl, true);
03124 OpenCurPlaylistItem();
03125
03126 break;
03127 }
03128 }
03129 }
03130
03131 void CMainFrame::OnDropFiles(HDROP hDropInfo)
03132 {
03133 SetForegroundWindow();
03134
03135 if(m_wndPlaylistBar.IsWindowVisible())
03136 {
03137 m_wndPlaylistBar.OnDropFiles(hDropInfo);
03138 return;
03139 }
03140
03141 CList<CString> sl;
03142
03143 UINT nFiles = ::DragQueryFile(hDropInfo, (UINT)-1, NULL, 0);
03144 for(UINT iFile = 0; iFile < nFiles; iFile++)
03145 {
03146 CString fn;
03147 fn.ReleaseBuffer(::DragQueryFile(hDropInfo, iFile, fn.GetBuffer(MAX_PATH), MAX_PATH));
03148 sl.AddTail(fn);
03149 }
03150 ::DragFinish(hDropInfo);
03151
03152 if(!sl.IsEmpty())
03153 {
03154 m_wndPlaylistBar.Open(sl, true);
03155 OpenCurPlaylistItem();
03156 }
03157 }
03158
03159 void CMainFrame::OnFileSaveas()
03160 {
03161 CString ext, in = m_wndPlaylistBar.GetCur(), out = in;
03162
03163 if(out.Find(_T("://")) < 0)
03164 {
03165 ext = CString(CPath(out).GetExtension()).MakeLower();
03166 if(ext == _T(".cda")) out = out.Left(out.GetLength()-4) + _T(".wav");
03167 else if(ext == _T(".ifo")) out = out.Left(out.GetLength()-4) + _T(".vob");
03168 }
03169 else
03170 {
03171 out.Empty();
03172 }
03173
03174 CFileDialog fd(FALSE, 0, out,
03175 OFN_EXPLORER|OFN_ENABLESIZING|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_PATHMUSTEXIST,
03176 _T("All files (*.*)|*.*||"), this, 0);
03177 if(fd.DoModal() != IDOK || !in.CompareNoCase(fd.GetPathName())) return;
03178
03179 CPath p(fd.GetPathName());
03180 if(!ext.IsEmpty()) p.AddExtension(ext);
03181
03182 OAFilterState fs = State_Stopped;
03183 pMC->GetState(0, &fs);
03184 if(fs == State_Running) pMC->Pause();
03185
03186 CSaveDlg dlg(in, p);
03187 dlg.DoModal();
03188
03189 if(fs == State_Running) pMC->Run();
03190 }
03191
03192 void CMainFrame::OnUpdateFileSaveas(CCmdUI* pCmdUI)
03193 {
03194 if(m_iMediaLoadState != MLS_LOADED || m_iPlaybackMode != PM_FILE)
03195 {
03196 pCmdUI->Enable(FALSE);
03197 return;
03198 }
03199
03200 CString fn = m_wndPlaylistBar.GetCur();
03201 CString ext = fn.Mid(fn.ReverseFind('.')+1).MakeLower();
03202
03203 if(fn.Find(_T("://")) >= 0)
03204 {
03205 pCmdUI->Enable(FALSE);
03206 return;
03207 }
03208
03209 if((GetVersion()&0x80000000) && (ext == _T("cda") || ext == _T("ifo")))
03210 {
03211 pCmdUI->Enable(FALSE);
03212 return;
03213 }
03214
03215 pCmdUI->Enable(TRUE);
03216 }
03217
03218 bool CMainFrame::GetDIB(BYTE** ppData, long& size, bool fSilent)
03219 {
03220 if(!ppData) return false;
03221
03222 *ppData = NULL;
03223 size = 0;
03224
03225 bool fNeedsToPause = !m_pCAP;
03226 if(fNeedsToPause) fNeedsToPause = !IsVMR7InGraph(pGB);
03227 if(fNeedsToPause) fNeedsToPause = !IsVMR9InGraph(pGB);
03228
03229 OAFilterState fs = GetMediaState();
03230
03231 if(!(m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly && (fs == State_Paused || fs == State_Running)))
03232 return false;
03233
03234 if(fs == State_Running && fNeedsToPause)
03235 {
03236 pMC->Pause();
03237 GetMediaState();
03238 }
03239
03240 HRESULT hr;
03241 CString errmsg;
03242
03243 do
03244 {
03245 if(m_pCAP)
03246 {
03247 hr = m_pCAP->GetDIB(NULL, (DWORD*)&size);
03248 if(FAILED(hr)) {errmsg.Format(_T("GetDIB failed, hr = %08x"), hr); break;}
03249
03250 if(!(*ppData = new BYTE[size])) return false;
03251
03252 hr = m_pCAP->GetDIB(*ppData, (DWORD*)&size);
03253 if(FAILED(hr)) {errmsg.Format(_T("GetDIB failed, hr = %08x"), hr); break;}
03254 }
03255 else
03256 {
03257 hr = pBV->GetCurrentImage(&size, NULL);
03258 if(FAILED(hr) || size == 0) {errmsg.Format(_T("GetCurrentImage failed, hr = %08x"), hr); break;}
03259
03260 if(!(*ppData = new BYTE[size])) return false;
03261
03262 hr = pBV->GetCurrentImage(&size, (long*)*ppData);
03263 if(FAILED(hr)) {errmsg.Format(_T("GetCurrentImage failed, hr = %08x"), hr); break;}
03264 }
03265 }
03266 while(0);
03267
03268 if(!fSilent)
03269 {
03270 if(!errmsg.IsEmpty())
03271 {
03272 AfxMessageBox(errmsg, MB_OK);
03273 }
03274 }
03275
03276 if(fs == State_Running && GetMediaState() != State_Running)
03277 {
03278 pMC->Run();
03279 }
03280
03281 return !!*ppData;
03282 }
03283
03284 #include "jpeg.h"
03285
03286 void CMainFrame::SaveImage(LPCTSTR fn)
03287 {
03288 BYTE* pData = NULL;
03289 long size = 0;
03290 if(GetDIB(&pData, size))
03291 {
03292 CString ext = CString(CPath(fn).GetExtension()).MakeLower();
03293
03294 if(ext == _T(".bmp"))
03295 {
03296 if(FILE* f = _tfopen(fn, _T("wb")))
03297 {
03298 BITMAPINFO* bi = (BITMAPINFO*)pData;
03299
03300 BITMAPFILEHEADER bfh;
03301 bfh.bfType = 'MB';
03302 bfh.bfOffBits = sizeof(bfh) + sizeof(bi->bmiHeader);
03303 bfh.bfSize = sizeof(bfh) + size;
03304 bfh.bfReserved1 = bfh.bfReserved2 = 0;
03305
03306 if(bi->bmiHeader.biBitCount <= 8)
03307 {
03308 if(bi->bmiHeader.biClrUsed) bfh.bfOffBits += bi->bmiHeader.biClrUsed * sizeof(bi->bmiColors[0]);
03309 else bfh.bfOffBits += (1 << bi->bmiHeader.biBitCount) * sizeof(bi->bmiColors[0]);
03310 }
03311
03312 fwrite(&bfh, 1, sizeof(bfh), f);
03313 fwrite(pData, 1, size, f);
03314
03315 fclose(f);
03316 }
03317 else
03318 {
03319 AfxMessageBox(_T("Cannot create file"), MB_OK);
03320 }
03321 }
03322 else if(ext == _T(".jpg"))
03323 {
03324 CJpegEncoderFile(fn).Encode(pData);
03325 }
03326
03327 delete [] pData;
03328
03329 CPath p(fn);
03330
03331 if(CDC* pDC = m_wndStatusBar.m_status.GetDC())
03332 {
03333 CRect r;
03334 m_wndStatusBar.m_status.GetClientRect(r);
03335 p.CompactPath(pDC->m_hDC, r.Width());
03336 m_wndStatusBar.m_status.ReleaseDC(pDC);
03337 }
03338
03339 SendStatusMessage((LPCTSTR)p, 3000);
03340 }
03341 }
03342
03343 static CString MakeSnapshotFileName()
03344 {
03345 CTime t = CTime::GetCurrentTime();
03346 CString fn;
03347 fn.Format(_T("snapshot%s%s"),
03348 t.Format(_T("%Y%m%d%H%M%S")), AfxGetAppSettings().SnapShotExt);
03349 return fn;
03350 }
03351
03352 void CMainFrame::OnFileSaveImage()
03353 {
03354 AppSettings& s = AfxGetAppSettings();
03355
03356 CPath psrc(s.SnapShotPath);
03357 psrc.Combine(s.SnapShotPath, MakeSnapshotFileName());
03358
03359 CFileDialog fd(FALSE, 0, (LPCTSTR)psrc,
03360 OFN_EXPLORER|OFN_ENABLESIZING|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_PATHMUSTEXIST,
03361 _T("Bitmaps (*.bmp)|*.bmp|Jpeg (*.jpg)|*.jpg||"), this, 0);
03362
03363 if(s.SnapShotExt == _T(".bmp")) fd.m_pOFN->nFilterIndex = 1;
03364 else if(s.SnapShotExt == _T(".jpg")) fd.m_pOFN->nFilterIndex = 2;
03365
03366 if(fd.DoModal() != IDOK) return;
03367
03368 if(fd.m_pOFN->nFilterIndex == 1) s.SnapShotExt = _T(".bmp");
03369 else if(fd.m_pOFN->nFilterIndex = 2) s.SnapShotExt = _T(".jpg");
03370
03371 CPath pdst(fd.GetPathName());
03372 pdst.AddExtension(s.SnapShotExt);
03373 CString path = (LPCTSTR)pdst;
03374 pdst.RemoveFileSpec();
03375 s.SnapShotPath = (LPCTSTR)pdst;
03376
03377 SaveImage(path);
03378 }
03379
03380 void CMainFrame::OnFileSaveImageAuto()
03381 {
03382 CString fn;
03383 fn.Format(_T("%s\\%s"), AfxGetAppSettings().SnapShotPath, MakeSnapshotFileName());
03384 SaveImage(fn);
03385 }
03386
03387 void CMainFrame::OnUpdateFileSaveImage(CCmdUI* pCmdUI)
03388 {
03389 OAFilterState fs = GetMediaState();
03390 pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly
03391 && (fs == State_Paused || fs == State_Running));
03392 }
03393
03394 void CMainFrame::OnFileConvert()
03395 {
03396 CConvertDlg().DoModal();
03397 }
03398
03399 void CMainFrame::OnUpdateFileConvert(CCmdUI* pCmdUI)
03400 {
03401
03402 }
03403
03404 void CMainFrame::OnFileLoadsubtitles()
03405 {
03406 if(!m_pCAP)
03407 {
03408 AfxMessageBox(_T("To load subtitles you have change the video renderer type and reopen the file.\n")
03409 _T("- DirectShow: VMR7 or VMR9 renderless\n")
03410 _T("- RealMedia: Special renderer for RealMedia, or open it through DirectShow\n")
03411 _T("- Quicktime: DX7 or DX9 renderer for QuickTime\n")
03412 _T("- ShockWave: n/a\n")
03413 , MB_OK);
03414 return;
03415 }
03416
03417 static TCHAR BASED_CODE szFilter[] =
03418 _T(".srt .sub .ssa .ass .smi .psb .txt .idx .usf .xss|")
03419 _T("*.srt;*.sub;*.ssa;*.ass;*smi;*.psb;*.txt;*.idx;*.usf;*.xss||");
03420
03421 CFileDialog fd(TRUE, NULL, NULL,
03422 OFN_EXPLORER | OFN_ENABLESIZING | OFN_HIDEREADONLY,
03423 szFilter, this, 0);
03424
03425 if(fd.DoModal() != IDOK) return;
03426
03427 if(LoadSubtitle(fd.GetPathName()))
03428 SetSubtitle(m_pSubStreams.GetTail());
03429 }
03430
03431 void CMainFrame::OnUpdateFileLoadsubtitles(CCmdUI *pCmdUI)
03432 {
03433 pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly);
03434 }
03435
03436 void CMainFrame::OnFileSavesubtitles()
03437 {
03438 int i = m_iSubtitleSel;
03439
03440 POSITION pos = m_pSubStreams.GetHeadPosition();
03441 while(pos && i >= 0)
03442 {
03443 CComPtr<ISubStream> pSubStream = m_pSubStreams.GetNext(pos);
03444
03445 if(i < pSubStream->GetStreamCount())
03446 {
03447 CLSID clsid;
03448 if(FAILED(pSubStream->GetClassID(&clsid)))
03449 continue;
03450
03451 if(clsid == __uuidof(CVobSubFile))
03452 {
03453 CVobSubFile* pVSF = (CVobSubFile*)(ISubStream*)pSubStream;
03454
03455 CFileDialog fd(FALSE, NULL, NULL,
03456 OFN_EXPLORER|OFN_ENABLESIZING|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_PATHMUSTEXIST,
03457 _T("VobSub (*.idx, *.sub)|*.idx;*.sub||"), this, 0);
03458
03459 if(fd.DoModal() == IDOK)
03460 {
03461 CAutoLock cAutoLock(&m_csSubLock);
03462 pVSF->Save(fd.GetPathName());
03463 }
03464
03465 return;
03466 }
03467 else if(clsid == __uuidof(CRenderedTextSubtitle))
03468 {
03469 CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)pSubStream;
03470
03471 CString filter;
03472 filter += _T("Subripper (*.srt)|*.srt|");
03473 filter += _T("Microdvd (*.sub)|*.sub|");
03474 filter += _T("Sami (*.smi)|*.smi|");
03475 filter += _T("Psb (*.psb)|*.psb|");
03476 filter += _T("Sub Station Alpha (*.ssa)|*.ssa|");
03477 filter += _T("Advanced Sub Station Alpha (*.ass)|*.ass|");
03478 filter += _T("|");
03479
03480 CSaveTextFileDialog fd(pRTS->m_encoding, NULL, NULL, filter, this);
03481
03482 if(fd.DoModal() == IDOK)
03483 {
03484 CAutoLock cAutoLock(&m_csSubLock);
03485 pRTS->SaveAs(fd.GetPathName(), (exttype)(fd.m_ofn.nFilterIndex-1), m_pCAP->GetFPS(), fd.GetEncoding());
03486 }
03487
03488 return;
03489 }
03490 }
03491
03492 i -= pSubStream->GetStreamCount();
03493 }
03494 }
03495
03496 void CMainFrame::OnUpdateFileSavesubtitles(CCmdUI* pCmdUI)
03497 {
03498 pCmdUI->Enable(m_iSubtitleSel >= 0);
03499 }
03500
03502
03503 #include "SubtitleDlDlg.h"
03504 #include "ISDb.h"
03505
03506 void CMainFrame::OnSubtitledatabaseSearch()
03507 {
03508 CStringA url = "http://" + AfxGetAppSettings().ISDb + "/index.php?";
03509 CStringA args = makeargs(m_wndPlaylistBar.m_pl);
03510 ShellExecute(m_hWnd, _T("open"), CString(url+args), NULL, NULL, SW_SHOWDEFAULT);
03511 }
03512
03513 void CMainFrame::OnUpdateSubtitledatabaseSearch(CCmdUI *pCmdUI)
03514 {
03515 pCmdUI->Enable(TRUE);
03516 }
03517
03518 void CMainFrame::OnSubtitledatabaseUpload()
03519 {
03520 CStringA url = "http://" + AfxGetAppSettings().ISDb + "/ul.php?";
03521 CStringA args = makeargs(m_wndPlaylistBar.m_pl);
03522 ShellExecute(m_hWnd, _T("open"), CString(url+args), NULL, NULL, SW_SHOWDEFAULT);
03523 }
03524
03525 void CMainFrame::OnUpdateSubtitledatabaseUpload(CCmdUI *pCmdUI)
03526 {
03527 pCmdUI->Enable(m_wndPlaylistBar.GetCount() > 0);
03528 }
03529
03530 void CMainFrame::OnSubtitledatabaseDownload()
03531 {
03532 filehash fh;
03533 if(!hash(m_wndPlaylistBar.GetCur(), fh))
03534 {
03535 MessageBeep(-1);
03536 return;
03537 }
03538
03539
03540
03541 CStringA url = "http://" + AfxGetAppSettings().ISDb + "/index.php?";
03542 CStringA args;
03543 args.Format("player=mpc&name[0]=%s&size[0]=%016I64x&hash[0]=%016I64x",
03544 UrlEncode(CStringA(fh.name)), fh.size, fh.hash);
03545
03546 try
03547 {
03548 CInternetSession is;
03549
03550 CStringA str;
03551 if(!OpenUrl(is, CString(url+args), str))
03552 {
03553 MessageBeep(-1);
03554 return;
03555 }
03556
03557 CStringA ticket;
03558 CList<isdb_movie> movies;
03559 isdb_movie m;
03560 isdb_subtitle s;
03561
03562 CList<CStringA> sl;
03563 Explode(str, sl, '\n');
03564
03565 POSITION pos = sl.GetHeadPosition();
03566 while(pos)
03567 {
03568 str = sl.GetNext(pos);
03569
03570 CStringA param = str.Left(max(0, str.Find('=')));
03571 CStringA value = str.Mid(str.Find('=')+1);
03572
03573 if(param == "ticket") ticket = value;
03574 else if(param == "movie") {m.reset(); Explode(value, m.titles, '|');}
03575 else if(param == "subtitle") {s.reset(); s.id = atoi(value);}
03576 else if(param == "name") s.name = value;
03577 else if(param == "discs") s.discs = atoi(value);
03578 else if(param == "disc_no") s.disc_no = atoi(value);
03579 else if(param == "format") s.format = value;
03580 else if(param == "iso639_2") s.iso639_2 = value;
03581 else if(param == "language") s.language = value;
03582 else if(param == "nick") s.nick = value;
03583 else if(param == "email") s.email = value;
03584 else if(param == "" && value == "endsubtitle") {m.subs.AddTail(s);}
03585 else if(param == "" && value == "endmovie") {movies.AddTail(m);}
03586 else if(param == "" && value == "end") break;
03587 }
03588
03589 CSubtitleDlDlg dlg(movies, this);
03590 if(IDOK == dlg.DoModal())
03591 {
03592 if(dlg.m_fReplaceSubs)
03593 m_pSubStreams.RemoveAll();
03594
03595 CComPtr<ISubStream> pSubStreamToSet;
03596
03597 POSITION pos = dlg.m_selsubs.GetHeadPosition();
03598 while(pos)
03599 {
03600 isdb_subtitle& s = dlg.m_selsubs.GetNext(pos);
03601
03602 CStringA url = "http://" + AfxGetAppSettings().ISDb + "/dl.php?";
03603 CStringA args;
03604 args.Format("id=%d&ticket=%s", s.id, UrlEncode(ticket));
03605
03606 if(OpenUrl(is, CString(url+args), str))
03607 {
03608 CAutoPtr<CRenderedTextSubtitle> pRTS(new CRenderedTextSubtitle(&m_csSubLock));
03609 if(pRTS && pRTS->Open((BYTE*)(LPCSTR)str, str.GetLength(), DEFAULT_CHARSET, CString(s.name)) && pRTS->GetStreamCount() > 0)
03610 {
03611 CComPtr<ISubStream> pSubStream = pRTS.Detach();
03612 m_pSubStreams.AddTail(pSubStream);
03613 if(!pSubStreamToSet) pSubStreamToSet = pSubStream;
03614 }
03615 }
03616 }
03617
03618 if(pSubStreamToSet)
03619 SetSubtitle(pSubStreamToSet);
03620 }
03621 }
03622 catch(CInternetException* ie)
03623 {
03624 ie->Delete();
03625 return;
03626 }
03627 }
03628
03629 void CMainFrame::OnUpdateSubtitledatabaseDownload(CCmdUI *pCmdUI)
03630 {
03631 pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && m_pCAP && !m_fAudioOnly);
03632 }
03633
03634 void CMainFrame::OnFileProperties()
03635 {
03636 CPPageFileInfoSheet m_fileinfo(m_wndPlaylistBar.GetCur(), this);
03637 m_fileinfo.DoModal();
03638 }
03639
03640 void CMainFrame::OnUpdateFileProperties(CCmdUI* pCmdUI)
03641 {
03642 pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && m_iPlaybackMode == PM_FILE);
03643 }
03644
03645 void CMainFrame::OnFileCloseMedia()
03646 {
03647 CloseMedia();
03648 }
03649
03650 void CMainFrame::OnFileClosePlaylist()
03651 {
03652 SendMessage(WM_COMMAND, ID_FILE_CLOSEMEDIA);
03653 RestoreDefaultWindowRect();
03654 }
03655
03656 void CMainFrame::OnUpdateFileClose(CCmdUI* pCmdUI)
03657 {
03658 pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED || m_iMediaLoadState == MLS_LOADING);
03659 }
03660
03661
03662
03663 void CMainFrame::OnViewCaptionmenu()
03664 {
03665 bool fHideCaptionMenu = AfxGetAppSettings().fHideCaptionMenu;
03666
03667 AfxGetAppSettings().fHideCaptionMenu = !fHideCaptionMenu;
03668
03669 if(m_fFullScreen) return;
03670
03671 DWORD dwRemove = 0, dwAdd = 0;
03672 HMENU hMenu;
03673
03674 if(!fHideCaptionMenu)
03675 {
03676 dwRemove = WS_CAPTION;
03677 hMenu = NULL;
03678 }
03679 else
03680 {
03681 dwAdd = WS_CAPTION;
03682 hMenu = m_hMenuDefault;
03683 }
03684
03685 ModifyStyle(dwRemove, dwAdd, SWP_NOZORDER);
03686 ::SetMenu(m_hWnd, hMenu);
03687 SetWindowPos(NULL, 0, 0, 0, 0, SWP_FRAMECHANGED|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER);
03688
03689 MoveVideoWindow();
03690 }
03691
03692 void CMainFrame::OnUpdateViewCaptionmenu(CCmdUI* pCmdUI)
03693 {
03694 pCmdUI->SetCheck(!AfxGetAppSettings().fHideCaptionMenu);
03695 }
03696
03697 void CMainFrame::OnViewControlBar(UINT nID)
03698 {
03699 nID -= ID_VIEW_SEEKER;
03700 ShowControls(AfxGetAppSettings().nCS ^ (1<<nID));
03701 }
03702
03703 void CMainFrame::OnUpdateViewControlBar(CCmdUI* pCmdUI)
03704 {
03705 UINT nID = pCmdUI->m_nID - ID_VIEW_SEEKER;
03706 pCmdUI->SetCheck(!!(AfxGetAppSettings().nCS & (1<<nID)));
03707 }
03708
03709 void CMainFrame::OnViewSubresync()
03710 {
03711 ShowControlBar(&m_wndSubresyncBar, !m_wndSubresyncBar.IsWindowVisible(), TRUE);
03712 }
03713
03714 void CMainFrame::OnUpdateViewSubresync(CCmdUI* pCmdUI)
03715 {
03716 pCmdUI->SetCheck(m_wndSubresyncBar.IsWindowVisible());
03717 pCmdUI->Enable(m_pCAP && m_iSubtitleSel >= 0);
03718 }
03719
03720 void CMainFrame::OnViewPlaylist()
03721 {
03722 ShowControlBar(&m_wndPlaylistBar, !m_wndPlaylistBar.IsWindowVisible(), TRUE);
03723 }
03724
03725 void CMainFrame::OnUpdateViewPlaylist(CCmdUI* pCmdUI)
03726 {
03727 pCmdUI->SetCheck(m_wndPlaylistBar.IsWindowVisible());
03728 pCmdUI->Enable(m_iMediaLoadState == MLS_CLOSED && m_iMediaLoadState != MLS_LOADED
03729 || m_iMediaLoadState == MLS_LOADED );
03730 }
03731
03732 void CMainFrame::OnViewCapture()
03733 {
03734 ShowControlBar(&m_wndCaptureBar, !m_wndCaptureBar.IsWindowVisible(), TRUE);
03735 }
03736
03737 void CMainFrame::OnUpdateViewCapture(CCmdUI* pCmdUI)
03738 {
03739 pCmdUI->SetCheck(m_wndCaptureBar.IsWindowVisible());
03740 pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && m_iPlaybackMode == PM_CAPTURE);
03741 }
03742
03743 void CMainFrame::OnViewMinimal()
03744 {
03745 if(!AfxGetAppSettings().fHideCaptionMenu)
03746 SendMessage(WM_COMMAND, ID_VIEW_CAPTIONMENU);
03747 ShowControls(0);
03748 }
03749
03750 void CMainFrame::OnUpdateViewMinimal(CCmdUI* pCmdUI)
03751 {
03752 }
03753
03754 void CMainFrame::OnViewCompact()
03755 {
03756 if(AfxGetAppSettings().fHideCaptionMenu)
03757 SendMessage(WM_COMMAND, ID_VIEW_CAPTIONMENU);
03758 ShowControls(CS_TOOLBAR);
03759 }
03760
03761 void CMainFrame::OnUpdateViewCompact(CCmdUI* pCmdUI)
03762 {
03763 }
03764
03765 void CMainFrame::OnViewNormal()
03766 {
03767 if(AfxGetAppSettings().fHideCaptionMenu)
03768 SendMessage(WM_COMMAND, ID_VIEW_CAPTIONMENU);
03769 ShowControls(CS_SEEKBAR|CS_TOOLBAR|CS_STATUSBAR|CS_INFOBAR);
03770 }
03771
03772 void CMainFrame::OnUpdateViewNormal(CCmdUI* pCmdUI)
03773 {
03774 }
03775
03776 void CMainFrame::OnViewFullscreen()
03777 {
03778 ToggleFullscreen(true, true);
03779 }
03780
03781 void CMainFrame::OnViewFullscreenSecondary()
03782 {
03783 ToggleFullscreen(true, false);
03784 }
03785
03786 void CMainFrame::OnUpdateViewFullscreen(CCmdUI* pCmdUI)
03787 {
03788 pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly || m_fFullScreen);
03789 pCmdUI->SetCheck(m_fFullScreen);
03790 }
03791
03792 void CMainFrame::OnViewZoom(UINT nID)
03793 {
03794 ZoomVideoWindow(nID == ID_VIEW_ZOOM_50 ? 0.5 : nID == ID_VIEW_ZOOM_200 ? 2.0 : 1.0);
03795 }
03796
03797 void CMainFrame::OnUpdateViewZoom(CCmdUI* pCmdUI)
03798 {
03799 pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly);
03800 }
03801
03802 void CMainFrame::OnViewDefaultVideoFrame(UINT nID)
03803 {
03804 AfxGetAppSettings().iDefaultVideoSize = nID - ID_VIEW_VF_HALF;
03805 m_ZoomX = m_ZoomY = 1;
03806 m_PosX = m_PosY = 0.5;
03807 MoveVideoWindow();
03808 }
03809
03810 void CMainFrame::OnUpdateViewDefaultVideoFrame(CCmdUI* pCmdUI)
03811 {
03812 pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly);
03813 pCmdUI->SetRadio(AfxGetAppSettings().iDefaultVideoSize == (pCmdUI->m_nID - ID_VIEW_VF_HALF));
03814 }
03815
03816 void CMainFrame::OnViewKeepaspectratio()
03817 {
03818 AfxGetAppSettings().fKeepAspectRatio = !AfxGetAppSettings().fKeepAspectRatio;
03819 MoveVideoWindow();
03820 }
03821
03822 void CMainFrame::OnUpdateViewKeepaspectratio(CCmdUI* pCmdUI)
03823 {
03824 pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly);
03825 pCmdUI->SetCheck(AfxGetAppSettings().fKeepAspectRatio);
03826 }
03827
03828 void CMainFrame::OnViewCompMonDeskARDiff()
03829 {
03830 AfxGetAppSettings().fCompMonDeskARDiff = !AfxGetAppSettings().fCompMonDeskARDiff;
03831 MoveVideoWindow();
03832 }
03833
03834 void CMainFrame::OnUpdateViewCompMonDeskARDiff(CCmdUI* pCmdUI)
03835 {
03836 pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly);
03837 pCmdUI->SetCheck(AfxGetAppSettings().fCompMonDeskARDiff);
03838 }
03839
03840 void CMainFrame::OnViewPanNScan(UINT nID)
03841 {
03842 if(m_iMediaLoadState != MLS_LOADED) return;
03843
03844 int x = 0, y = 0;
03845 int dx = 0, dy = 0;
03846
03847 switch(nID)
03848 {
03849 case ID_VIEW_RESET: m_ZoomX = m_ZoomY = 1.0; m_PosX = m_PosY = 0.5; m_AngleX = m_AngleY = m_AngleZ = 0; break;
03850 case ID_VIEW_INCSIZE: x = y = 1; break;
03851 case ID_VIEW_DECSIZE: x = y = -1; break;
03852 case ID_VIEW_INCWIDTH: x = 1; break;
03853 case ID_VIEW_DECWIDTH: x = -1; break;
03854 case ID_VIEW_INCHEIGHT: y = 1; break;
03855 case ID_VIEW_DECHEIGHT: y = -1; break;
03856 case ID_PANSCAN_CENTER: m_PosX = m_PosY = 0.5; break;
03857 case ID_PANSCAN_MOVELEFT: dx = -1; break;
03858 case ID_PANSCAN_MOVERIGHT: dx = 1; break;
03859 case ID_PANSCAN_MOVEUP: dy = -1; break;
03860 case ID_PANSCAN_MOVEDOWN: dy = 1; break;
03861 case ID_PANSCAN_MOVEUPLEFT: dx = dy = -1; break;
03862 case ID_PANSCAN_MOVEUPRIGHT: dx = 1; dy = -1; break;
03863 case ID_PANSCAN_MOVEDOWNLEFT: dx = -1; dy = 1; break;
03864 case ID_PANSCAN_MOVEDOWNRIGHT: dx = dy = 1; break;
03865 default: break;
03866 }
03867
03868 if(x > 0 && m_ZoomX < 3) m_ZoomX *= 1.02;
03869 if(x < 0 && m_ZoomX > 0.2) m_ZoomX /= 1.02;
03870 if(y > 0 && m_ZoomY < 3) m_ZoomY *= 1.02;
03871 if(y < 0 && m_ZoomY > 0.2) m_ZoomY /= 1.02;
03872
03873 if(dx < 0 && m_PosX > 0) m_PosX = max(m_PosX - 0.005*m_ZoomX, 0);
03874 if(dx > 0 && m_PosX < 1) m_PosX = min(m_PosX + 0.005*m_ZoomX, 1);
03875 if(dy < 0 && m_PosY > 0) m_PosY = max(m_PosY - 0.005*m_ZoomY, 0);
03876 if(dy > 0 && m_PosY < 1) m_PosY = min(m_PosY + 0.005*m_ZoomY, 1);
03877
03878 MoveVideoWindow(true);
03879
03880 if(nID == ID_VIEW_RESET && m_pCAP)
03881 {
03882 m_pCAP->SetVideoAngle(Vector(DegToRad(m_AngleX), DegToRad(m_AngleY), DegToRad(m_AngleZ)));
03883 }
03884 }
03885
03886 void CMainFrame::OnUpdateViewPanNScan(CCmdUI* pCmdUI)
03887 {
03888 pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly);
03889 }
03890
03891 void CMainFrame::OnViewPanNScanPresets(UINT nID)
03892 {
03893 if(m_iMediaLoadState != MLS_LOADED) return;
03894
03895 AppSettings& s = AfxGetAppSettings();
03896
03897 nID -= ID_PANNSCAN_PRESETS_START;
03898
03899 if(nID == s.m_pnspresets.GetCount())
03900 {
03901 CPnSPresetsDlg dlg;
03902 dlg.m_pnspresets.Copy(s.m_pnspresets);
03903 if(dlg.DoModal() == IDOK)
03904 {
03905 s.m_pnspresets.Copy(dlg.m_pnspresets);
03906 s.UpdateData(true);
03907 }
03908 return;
03909 }
03910
03911 m_PosX = 0.5;
03912 m_PosY = 0.5;
03913 m_ZoomX = 1.0;
03914 m_ZoomY = 1.0;
03915
03916 CString str = s.m_pnspresets[nID];
03917
03918 int i = 0, j = 0;
03919 for(CString token = str.Tokenize(_T(","), i); !token.IsEmpty(); token = str.Tokenize(_T(","), i), j++)
03920 {
03921 float f = 0;
03922 if(_stscanf(token, _T("%f"), &f) != 1) continue;
03923
03924 switch(j)
03925 {
03926 case 0: break;
03927 case 1: m_PosX = f; break;
03928 case 2: m_PosY = f; break;
03929 case 3: m_ZoomX = f; break;
03930 case 4: m_ZoomY = f; break;
03931 default: break;
03932 }
03933 }
03934
03935 if(j != 5) return;
03936
03937 m_PosX = min(max(m_PosX, 0), 1);
03938 m_PosY = min(max(m_PosY, 0), 1);
03939 m_ZoomX = min(max(m_ZoomX, 0.2), 3);
03940 m_ZoomY = min(max(m_ZoomY, 0.2), 3);
03941
03942 MoveVideoWindow(true);
03943 }
03944
03945 void CMainFrame::OnUpdateViewPanNScanPresets(CCmdUI* pCmdUI)
03946 {
03947 int nID = pCmdUI->m_nID - ID_PANNSCAN_PRESETS_START;
03948 AppSettings& s = AfxGetAppSettings();
03949 pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly && nID >= 0 && nID <= s.m_pnspresets.GetCount());
03950 }
03951
03952 void CMainFrame::OnViewRotate(UINT nID)
03953 {
03954 if(!m_pCAP) return;
03955
03956 switch(nID)
03957 {
03958 case ID_PANSCAN_ROTATEXP: m_AngleX += 2; break;
03959 case ID_PANSCAN_ROTATEXM: m_AngleX -= 2; break;
03960 case ID_PANSCAN_ROTATEYP: m_AngleY += 2; break;
03961 case ID_PANSCAN_ROTATEYM: m_AngleY -= 2; break;
03962 case ID_PANSCAN_ROTATEZP: m_AngleZ += 2; break;
03963 case ID_PANSCAN_ROTATEZM: m_AngleZ -= 2; break;
03964 default: return;
03965 }
03966
03967 m_pCAP->SetVideoAngle(Vector(DegToRad(m_AngleX), DegToRad(m_AngleY), DegToRad(m_AngleZ)));
03968
03969 CString info;
03970 info.Format(_T("x: %d, y: %d, z: %d"), m_AngleX, m_AngleY, m_AngleZ);
03971 SendStatusMessage(info, 3000);
03972 }
03973
03974 void CMainFrame::OnUpdateViewRotate(CCmdUI* pCmdUI)
03975 {
03976 pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly && m_pCAP);
03977 }
03978
03979 void CMainFrame::OnViewAspectRatio(UINT nID)
03980 {
03981 CSize& ar = AfxGetAppSettings().AspectRatio;
03982
03983 switch(nID)
03984 {
03985 default: ar.SetSize(0, 0); break;
03986 case ID_ASPECTRATIO_4: ar.SetSize(4, 3); break;
03987 case ID_ASPECTRATIO_5: ar.SetSize(5, 4); break;
03988 case ID_ASPECTRATIO_16: ar.SetSize(16, 9); break;
03989 }
03990
03991 CString info;
03992 if(ar.cx && ar.cy) info.Format(_T("Aspect Ratio: %d:%d"), ar.cx, ar.cy);
03993 else info.Format(_T("Aspect Ratio: Default"));
03994 SendStatusMessage(info, 3000);
03995
03996 MoveVideoWindow();
03997 }
03998
03999 void CMainFrame::OnUpdateViewAspectRatio(CCmdUI* pCmdUI)
04000 {
04001 const CSize& ar = AfxGetAppSettings().AspectRatio;
04002
04003 switch(pCmdUI->m_nID)
04004 {
04005 default: pCmdUI->SetRadio(ar == CSize(0, 0)); break;
04006 case ID_ASPECTRATIO_4: pCmdUI->SetRadio(ar == CSize(4, 3)); break;
04007 case ID_ASPECTRATIO_5: pCmdUI->SetRadio(ar == CSize(5, 4)); break;
04008 case ID_ASPECTRATIO_16: pCmdUI->SetRadio(ar == CSize(16, 9)); break;
04009 }
04010
04011 pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly);
04012 }
04013
04014 void CMainFrame::OnViewOntop(UINT nID)
04015 {
04016 nID -= ID_ONTOP_NEVER;
04017 if(AfxGetAppSettings().iOnTop == nID)
04018 nID = !nID;
04019 SetAlwaysOnTop(nID);
04020 }
04021
04022 void CMainFrame::OnUpdateViewOntop(CCmdUI* pCmdUI)
04023 {
04024 pCmdUI->SetRadio(AfxGetAppSettings().iOnTop == (pCmdUI->m_nID - ID_ONTOP_NEVER));
04025 }
04026
04027 void CMainFrame::OnViewOptions()
04028 {
04029 ShowOptions();
04030 }
04031
04032
04033
04034 void CMainFrame::OnPlayPlay()
04035 {
04036 if(m_iMediaLoadState == MLS_LOADED)
04037 {
04038 if(GetMediaState() == State_Stopped) m_iSpeedLevel = 0;
04039
04040 if(m_iPlaybackMode == PM_FILE)
04041 {
04042 if(m_fEndOfStream) SendMessage(WM_COMMAND, ID_PLAY_STOP);
04043 pMC->Run();
04044 }
04045 else if(m_iPlaybackMode == PM_DVD)
04046 {
04047 double dRate = 1.0;
04048 if(m_iSpeedLevel != -4 && m_iSpeedLevel != 0)
04049 dRate = pow(2.0, m_iSpeedLevel >= -3 ? m_iSpeedLevel : (-m_iSpeedLevel - 8));
04050
04051 pDVDC->PlayForwards(dRate, DVD_CMD_FLAG_Block, NULL);
04052 pDVDC->Pause(FALSE);
04053 pMC->Run();
04054 }
04055 else if(m_iPlaybackMode == PM_CAPTURE)
04056 {
04057 pMC->Stop();
04058 pMC->Run();
04059 }
04060
04061 SetTimer(TIMER_STREAMPOSPOLLER, 40, NULL);
04062 SetTimer(TIMER_STREAMPOSPOLLER2, 500, NULL);
04063 SetTimer(TIMER_STATS, 1000, NULL);
04064
04065 if(m_fFrameSteppingActive)
04066 {
04067 m_fFrameSteppingActive = false;
04068 pBA->put_Volume(m_VolumeBeforeFrameStepping);
04069 }
04070
04071 SetAlwaysOnTop(AfxGetAppSettings().iOnTop);
04072 }
04073
04074 MoveVideoWindow();
04075 }
04076
04077 void CMainFrame::OnPlayPause()
04078 {
04079 if(m_iMediaLoadState == MLS_LOADED)
04080 {
04081 SetAlwaysOnTop(AfxGetAppSettings().iOnTop);
04082
04083 if(m_iPlaybackMode == PM_FILE)
04084 {
04085 pMC->Pause();
04086 }
04087 else if(m_iPlaybackMode == PM_DVD)
04088 {
04089 pMC->Pause();
04090 }
04091 else if(m_iPlaybackMode == PM_CAPTURE)
04092 {
04093 pMC->Pause();
04094 }
04095
04096 SetTimer(TIMER_STREAMPOSPOLLER, 40, NULL);
04097 SetTimer(TIMER_STREAMPOSPOLLER2, 500, NULL);
04098 SetTimer(TIMER_STATS, 1000, NULL);
04099 }
04100
04101 MoveVideoWindow();
04102 }
04103
04104 void CMainFrame::OnPlayPlaypause()
04105 {
04106 OAFilterState fs = GetMediaState();
04107 if(fs == State_Running) SendMessage(WM_COMMAND, ID_PLAY_PAUSE);
04108 else if(fs == State_Stopped || fs == State_Paused) SendMessage(WM_COMMAND, ID_PLAY_PLAY);
04109 }
04110
04111 void CMainFrame::OnPlayStop()
04112 {
04113 if(m_iMediaLoadState == MLS_LOADED)
04114 {
04115 if(m_iPlaybackMode == PM_FILE)
04116 {
04117 LONGLONG pos = 0;
04118 pMS->SetPositions(&pos, AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning);
04119 pMC->Stop();
04120
04121
04122
04123
04124
04125
04126 BeginEnumFilters(pGB, pEF, pBF)
04127 {
04128 CComQIPtr<IAMNetworkStatus, &IID_IAMNetworkStatus> pAMNS = pBF;
04129 CComQIPtr<IFileSourceFilter> pFSF = pBF;
04130 if(pAMNS && pFSF)
04131 {
04132 WCHAR* pFN = NULL;
04133 AM_MEDIA_TYPE mt;
04134 if(SUCCEEDED(pFSF->GetCurFile(&pFN, &mt)) && pFN && *pFN)
04135 {
04136 pFSF->Load(pFN, NULL);
04137 CoTaskMemFree(pFN);
04138 }
04139 break;
04140 }
04141 }
04142 EndEnumFilters
04143 }
04144 else if(m_iPlaybackMode == PM_DVD)
04145 {
04146 pDVDC->SetOption(DVD_ResetOnStop, TRUE);
04147 pMC->Stop();
04148 pDVDC->SetOption(DVD_ResetOnStop, FALSE);
04149 }
04150 else if(m_iPlaybackMode == PM_CAPTURE)
04151 {
04152 pMC->Stop();
04153 }
04154
04155 m_iSpeedLevel = 0;
04156
04157 if(m_fFrameSteppingActive)
04158 {
04159 m_fFrameSteppingActive = false;
04160 pBA->put_Volume(m_VolumeBeforeFrameStepping);
04161 }
04162
04163 m_fEndOfStream = false;
04164 }
04165
04166 m_nLoops = 0;
04167
04168 if(m_hWnd)
04169 {
04170 KillTimer(TIMER_STREAMPOSPOLLER2);
04171 KillTimer(TIMER_STREAMPOSPOLLER);
04172 KillTimer(TIMER_STATS);
04173
04174 MoveVideoWindow();
04175
04176 if(m_iMediaLoadState == MLS_LOADED)
04177 {
04178 __int64 start, stop;
04179 m_wndSeekBar.GetRange(start, stop);
04180 GUID tf;
04181 pMS->GetTimeFormat(&tf);
04182 m_wndStatusBar.SetStatusTimer(m_wndSeekBar.GetPosReal(), stop, !!m_wndSubresyncBar.IsWindowVisible(), &tf);
04183
04184 SetAlwaysOnTop(AfxGetAppSettings().iOnTop);
04185 }
04186 }
04187 }
04188
04189 void CMainFrame::OnUpdatePlayPauseStop(CCmdUI* pCmdUI)
04190 {
04191 OAFilterState fs = m_fFrameSteppingActive ? State_Paused : GetMediaState();
04192
04193 pCmdUI->SetCheck(fs == State_Running && pCmdUI->m_nID == ID_PLAY_PLAY
04194 || fs == State_Paused && pCmdUI->m_nID == ID_PLAY_PAUSE
04195 || fs == State_Stopped && pCmdUI->m_nID == ID_PLAY_STOP
04196 || (fs == State_Paused || fs == State_Running) && pCmdUI->m_nID == ID_PLAY_PLAYPAUSE);
04197
04198 bool fEnable = false;
04199
04200 if(fs >= 0)
04201 {
04202 if(m_iPlaybackMode == PM_FILE || m_iPlaybackMode == PM_CAPTURE)
04203 {
04204 fEnable = true;
04205
04206 if(fs == State_Stopped && pCmdUI->m_nID == ID_PLAY_PAUSE && m_fRealMediaGraph) fEnable = false;
04207 else if(m_fCapturing) fEnable = false;
04208 else if(m_fLiveWM && pCmdUI->m_nID == ID_PLAY_PAUSE) fEnable = false;
04209 }
04210 else if(m_iPlaybackMode == PM_DVD)
04211 {
04212 fEnable = m_iDVDDomain != DVD_DOMAIN_VideoManagerMenu
04213 && m_iDVDDomain != DVD_DOMAIN_VideoTitleSetMenu;
04214
04215 if(fs == State_Stopped && pCmdUI->m_nID == ID_PLAY_PAUSE) fEnable = false;
04216 }
04217 }
04218
04219 pCmdUI->Enable(fEnable);
04220 }
04221
04222 void CMainFrame::OnPlayFramestep(UINT nID)
04223 {
04224 REFERENCE_TIME rt;
04225
04226 if(pFS && m_fQuicktimeGraph)
04227 {
04228 if(GetMediaState() != State_Paused)
04229 SendMessage(WM_COMMAND, ID_PLAY_PAUSE);
04230
04231 pFS->Step(nID == ID_PLAY_FRAMESTEP ? 1 : -1, NULL);
04232 }
04233 else if(pFS && nID == ID_PLAY_FRAMESTEP)
04234 {
04235 if(GetMediaState() != State_Paused)
04236 SendMessage(WM_COMMAND, ID_PLAY_PAUSE);
04237
04238 m_fFrameSteppingActive = true;
04239
04240 m_VolumeBeforeFrameStepping = m_wndToolBar.Volume;
04241 pBA->put_Volume(-10000);
04242
04243 pFS->Step(1, NULL);
04244 }
04245 else if(S_OK == pMS->IsFormatSupported(&TIME_FORMAT_FRAME))
04246 {
04247 if(GetMediaState() != State_Paused)
04248 SendMessage(WM_COMMAND, ID_PLAY_PAUSE);
04249
04250 pMS->SetTimeFormat(&TIME_FORMAT_FRAME);
04251 pMS->GetCurrentPosition(&rt);
04252 if(nID == ID_PLAY_FRAMESTEP) rt++;
04253 else if(nID == ID_PLAY_FRAMESTEPCANCEL) rt--;
04254 pMS->SetPositions(&rt, AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning);
04255 pMS->SetTimeFormat(&TIME_FORMAT_MEDIA_TIME);
04256 }
04257 }
04258
04259 void CMainFrame::OnUpdatePlayFramestep(CCmdUI* pCmdUI)
04260 {
04261 bool fEnable = false;
04262
04263 if(m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly
04264 && (m_iPlaybackMode != PM_DVD || m_iDVDDomain == DVD_DOMAIN_Title)
04265 && m_iPlaybackMode != PM_CAPTURE
04266 && !m_fLiveWM)
04267 {
04268 REFTIME AvgTimePerFrame = 0;
04269 if(S_OK == pMS->IsFormatSupported(&TIME_FORMAT_FRAME)
04270 || pCmdUI->m_nID == ID_PLAY_FRAMESTEP && pFS && pFS->CanStep(0, NULL) == S_OK
04271 || m_fQuicktimeGraph && pFS)
04272 {
04273 fEnable = true;
04274 }
04275 }
04276
04277 pCmdUI->Enable(fEnable);
04278 }
04279
04280 void CMainFrame::OnPlaySeek(UINT nID)
04281 {
04282 AppSettings& s = AfxGetAppSettings();
04283
04284 REFERENCE_TIME dt =
04285 nID == ID_PLAY_SEEKBACKWARDSMALL ? -10000i64*s.nJumpDistS :
04286 nID == ID_PLAY_SEEKFORWARDSMALL ? +10000i64*s.nJumpDistS :
04287 nID == ID_PLAY_SEEKBACKWARDMED ? -10000i64*s.nJumpDistM :
04288 nID == ID_PLAY_SEEKFORWARDMED ? +10000i64*s.nJumpDistM :
04289 nID == ID_PLAY_SEEKBACKWARDLARGE ? -10000i64*s.nJumpDistL :
04290 nID == ID_PLAY_SEEKFORWARDLARGE ? +10000i64*s.nJumpDistL :
04291 0;
04292
04293 if(!dt) return;
04294
04295
04296 if(m_fShockwaveGraph) dt /= 10000i64*100;
04297
04298 SeekTo(m_wndSeekBar.GetPos() + dt);
04299 }
04300
04301 static int rangebsearch(REFERENCE_TIME val, CArray<REFERENCE_TIME>& rta)
04302 {
04303 int i = 0, j = rta.GetSize() - 1, ret = -1;
04304
04305 if(j >= 0 && val >= rta[j]) return(j);
04306
04307 while(i < j)
04308 {
04309 int mid = (i + j) >> 1;
04310 REFERENCE_TIME midt = rta[mid];
04311 if(val == midt) {ret = mid; break;}
04312 else if(val < midt) {ret = -1; if(j == mid) mid--; j = mid;}
04313 else if(val > midt) {ret = mid; if(i == mid) mid++; i = mid;}
04314 }
04315
04316 return(ret);
04317 }
04318
04319 void CMainFrame::OnPlaySeekKey(UINT nID)
04320 {
04321 if(m_kfs.GetCount() > 0)
04322 {
04323 HRESULT hr;
04324
04325 if(GetMediaState() == State_Stopped)
04326 SendMessage(WM_COMMAND, ID_PLAY_PAUSE);
04327
04328 REFERENCE_TIME rtCurrent, rtDur;
04329 hr = pMS->GetCurrentPosition(&rtCurrent);
04330 hr = pMS->GetDuration(&rtDur);
04331
04332 int dec = 1;
04333 int i = rangebsearch(rtCurrent, m_kfs);
04334 if(i > 0) dec = (UINT)max(min(rtCurrent - m_kfs[i-1], 10000000), 0);
04335
04336 rtCurrent =
04337 nID == ID_PLAY_SEEKKEYBACKWARD ? max(rtCurrent - dec, 0) :
04338 nID == ID_PLAY_SEEKKEYFORWARD ? rtCurrent : 0;
04339
04340 i = rangebsearch(rtCurrent, m_kfs);
04341
04342 if(nID == ID_PLAY_SEEKKEYBACKWARD)
04343 rtCurrent = m_kfs[max(i, 0)];
04344 else if(nID == ID_PLAY_SEEKKEYFORWARD && i < m_kfs.GetCount()-1)
04345 rtCurrent = m_kfs[i+1];
04346 else
04347 return;
04348
04349 hr = pMS->SetPositions(
04350 &rtCurrent, AM_SEEKING_AbsolutePositioning|AM_SEEKING_SeekToKeyFrame,
04351 NULL, AM_SEEKING_NoPositioning);
04352 }
04353 }
04354
04355 void CMainFrame::OnUpdatePlaySeek(CCmdUI* pCmdUI)
04356 {
04357 bool fEnable = false;
04358
04359 OAFilterState fs = GetMediaState();
04360
04361 if(m_iMediaLoadState == MLS_LOADED && (fs == State_Paused || fs == State_Running))
04362 {
04363 fEnable = true;
04364 if(m_iPlaybackMode == PM_DVD && (m_iDVDDomain != DVD_DOMAIN_Title || fs != State_Running)) fEnable = false;
04365 else if(m_iPlaybackMode == PM_CAPTURE) fEnable = false;
04366 }
04367
04368 pCmdUI->Enable(fEnable);
04369 }
04370
04371 void CMainFrame::OnPlayGoto()
04372 {
04373 if(m_iMediaLoadState != MLS_LOADED)
04374 return;
04375
04376 REFTIME atpf = 0;
04377 if(FAILED(pBV->get_AvgTimePerFrame(&atpf)) || atpf < 0)
04378 {
04379 atpf = 0;
04380
04381 BeginEnumFilters(pGB, pEF, pBF)
04382 {
04383 if(atpf > 0) break;
04384
04385 BeginEnumPins(pBF, pEP, pPin)
04386 {
04387 if(atpf > 0) break;
04388
04389 AM_MEDIA_TYPE mt;
04390 pPin->ConnectionMediaType(&mt);
04391
04392 if(mt.majortype == MEDIATYPE_Video && mt.formattype == FORMAT_VideoInfo)
04393 {
04394 atpf = (REFTIME)((VIDEOINFOHEADER*)mt.pbFormat)->AvgTimePerFrame / 10000000i64;
04395 }
04396 else if(mt.majortype == MEDIATYPE_Video && mt.formattype == FORMAT_VideoInfo2)
04397 {
04398 atpf = (REFTIME)((VIDEOINFOHEADER2*)mt.pbFormat)->AvgTimePerFrame / 10000000i64;
04399 }
04400 }
04401 EndEnumPins
04402 }
04403 EndEnumFilters
04404 }
04405
04406 CGoToDlg dlg((int)(m_wndSeekBar.GetPos()/10000), atpf > 0 ? (float)(1.0/atpf) : 0);
04407 if(IDOK != dlg.DoModal() || dlg.m_time < 0) return;
04408
04409 SeekTo(10000i64 * dlg.m_time);
04410 }
04411
04412 void CMainFrame::OnUpdateGoto(CCmdUI* pCmdUI)
04413 {
04414 bool fEnable = false;
04415
04416 if(m_iMediaLoadState == MLS_LOADED)
04417 {
04418 fEnable = true;
04419 if(m_iPlaybackMode == PM_DVD && m_iDVDDomain != DVD_DOMAIN_Title) fEnable = false;
04420 else if(m_iPlaybackMode == PM_CAPTURE) fEnable = false;
04421 }
04422
04423 pCmdUI->Enable(fEnable);
04424 }
04425
04426 void CMainFrame::OnPlayChangeRate(UINT nID)
04427 {
04428 if(m_iMediaLoadState != MLS_LOADED)
04429 return;
04430
04431 if(m_iPlaybackMode == PM_CAPTURE)
04432 {
04433 if(GetMediaState() != State_Running)
04434 SendMessage(WM_COMMAND, ID_PLAY_PLAY);
04435
04436 long lChannelMin = 0, lChannelMax = 0;
04437 pAMTuner->ChannelMinMax(&lChannelMin, &lChannelMax);
04438 long lChannel = 0, lVivSub = 0, lAudSub = 0;
04439 pAMTuner->get_Channel(&lChannel, &lVivSub, &lAudSub);
04440
04441 long lFreqOrg = 0, lFreqNew = -1;
04442 pAMTuner->get_VideoFrequency(&lFreqOrg);
04443
04444
04445 do
04446 {
04447 if(nID == ID_PLAY_DECRATE) lChannel--;
04448 else if(nID == ID_PLAY_INCRATE) lChannel++;
04449
04450
04451
04452
04453 if(lChannel < lChannelMin || lChannel > lChannelMax)
04454 break;
04455
04456 if(FAILED(pAMTuner->put_Channel(lChannel, AMTUNER_SUBCHAN_DEFAULT, AMTUNER_SUBCHAN_DEFAULT)))
04457 break;
04458
04459 long flFoundSignal;
04460 pAMTuner->AutoTune(lChannel, &flFoundSignal);
04461
04462 pAMTuner->get_VideoFrequency(&lFreqNew);
04463
04464 int i = 0;
04465 }
04466 while(FALSE);
04467
04468
04469
04470 }
04471 else
04472 {
04473 int iNewSpeedLevel;
04474
04475 if(nID == ID_PLAY_INCRATE) iNewSpeedLevel = m_iSpeedLevel+1;
04476 else if(nID == ID_PLAY_DECRATE) iNewSpeedLevel = m_iSpeedLevel-1;
04477 else return;
04478
04479 HRESULT hr = E_FAIL;
04480
04481 if(iNewSpeedLevel == -4)
04482 {
04483 if(GetMediaState() != State_Paused)
04484 SendMessage(WM_COMMAND, ID_PLAY_PAUSE);
04485
04486 if(GetMediaState() == State_Paused) hr = S_OK;
04487 }
04488 else
04489 {
04490 double dRate = pow(2.0, iNewSpeedLevel >= -3 ? iNewSpeedLevel : (-iNewSpeedLevel - 8));
04491 if(fabs(dRate - 1.0) < 0.01) dRate = 1.0;
04492
04493 if(GetMediaState() != State_Running)
04494 SendMessage(WM_COMMAND, ID_PLAY_PLAY);
04495
04496 if(m_iPlaybackMode == PM_FILE)
04497 {
04498 hr = pMS->SetRate(dRate);
04499 }
04500 else if(m_iPlaybackMode == PM_DVD)
04501 {
04502 if(iNewSpeedLevel >= -3)
04503 hr = pDVDC->PlayForwards(dRate, DVD_CMD_FLAG_Block, NULL);
04504 else
04505 hr = pDVDC->PlayBackwards(dRate, DVD_CMD_FLAG_Block, NULL);
04506 }
04507 }
04508
04509 if(SUCCEEDED(hr))
04510 m_iSpeedLevel = iNewSpeedLevel;
04511 }
04512 }
04513
04514 void CMainFrame::OnUpdatePlayChangeRate(CCmdUI* pCmdUI)
04515 {
04516 bool fEnable = false;
04517
04518 if(m_iMediaLoadState == MLS_LOADED)
04519 {
04520 bool fInc = pCmdUI->m_nID == ID_PLAY_INCRATE;
04521
04522 fEnable = true;
04523 if(fInc && m_iSpeedLevel >= 3) fEnable = false;
04524 else if(!fInc && m_iPlaybackMode == PM_FILE && m_iSpeedLevel <= -4) fEnable = false;
04525 else if(!fInc && m_iPlaybackMode == PM_DVD && m_iSpeedLevel <= -11) fEnable = false;
04526 else if(m_iPlaybackMode == PM_DVD && m_iDVDDomain != DVD_DOMAIN_Title) fEnable = false;
04527 else if(m_fRealMediaGraph || m_fShockwaveGraph) fEnable = false;
04528 else if(m_iPlaybackMode == PM_CAPTURE && (!m_wndCaptureBar.m_capdlg.IsTunerActive() || m_fCapturing)) fEnable = false;
04529 else if(m_fLiveWM) fEnable = false;
04530 }
04531
04532 pCmdUI->Enable(fEnable);
04533 }
04534
04535 void CMainFrame::OnPlayResetRate()
04536 {
04537 if(m_iMediaLoadState != MLS_LOADED)
04538 return;
04539
04540 HRESULT hr = E_FAIL;
04541
04542 if(GetMediaState() != State_Running)
04543 SendMessage(WM_COMMAND, ID_PLAY_PLAY);
04544
04545 if(m_iPlaybackMode == PM_FILE)
04546 {
04547 hr = pMS->SetRate(1.0);
04548 }
04549 else if(m_iPlaybackMode == PM_DVD)
04550 {
04551 hr = pDVDC->PlayForwards(1.0, DVD_CMD_FLAG_Block, NULL);
04552 }
04553
04554 if(SUCCEEDED(hr))
04555 m_iSpeedLevel = 0;
04556 }
04557
04558 void CMainFrame::OnUpdatePlayResetRate(CCmdUI* pCmdUI)
04559 {
04560 pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED);
04561 }
04562
04563
04564 void CMainFrame::OnPlayChangeAudDelay(UINT nID)
04565 {
04566 if(CComQIPtr<IAudioSwitcherFilter> pAS = FindFilter(__uuidof(CAudioSwitcherFilter), pGB))
04567 {
04568 REFERENCE_TIME rtShift = pAS->GetAudioTimeShift();
04569 rtShift +=
04570 nID == ID_PLAY_INCAUDDELAY ? 100000 :
04571 nID == ID_PLAY_DECAUDDELAY ? -100000 :
04572 0;
04573 pAS->SetAudioTimeShift(rtShift);
04574
04575 CString str;
04576 str.Format(_T("Audio Delay: %I64dms"), rtShift/10000);
04577 SendStatusMessage(str, 3000);
04578 }
04579 }
04580
04581 void CMainFrame::OnUpdatePlayChangeAudDelay(CCmdUI* pCmdUI)
04582 {
04583 pCmdUI->Enable(pGB && !!FindFilter(__uuidof(CAudioSwitcherFilter), pGB));
04584 }
04585
04586 #include "ComPropertySheet.h"
04587 #include ".\mainfrm.h"
04588
04589 void CMainFrame::OnPlayFilters(UINT nID)
04590 {
04591
04592
04593 CComPtr<ISpecifyPropertyPages> pSPP = m_spparray[nID - ID_FILTERS_SUBITEM_START];
04594
04595 CComPropertySheet ps(_T("Properties"), this);
04596 ps.AddPages(pSPP);
04597 ps.DoModal();
04598
04599 OpenSetupStatusBar();
04600 }
04601
04602 void CMainFrame::OnUpdatePlayFilters(CCmdUI* pCmdUI)
04603 {
04604 pCmdUI->Enable(!m_fCapturing);
04605 }
04606
04607 void CMainFrame::OnPlayShaders(UINT nID)
04608 {
04609 if(nID == ID_SHADERS_START)
04610 {
04611 CShaderEditorDlg(m_shaderlabel, m_pCAP, this).DoModal();
04612 }
04613 else if(nID == ID_SHADERS_START+1)
04614 {
04615 m_pCAP->SetPixelShader(NULL, NULL);
04616 m_shaderlabel.Empty();
04617 }
04618 else if(nID >= ID_SHADERS_START+2)
04619 {
04620 nID -= ID_SHADERS_START+2;
04621
04622 CString str;
04623 str.Format(_T("%d"), nID);
04624
04625 CList<CString> sl;
04626 Explode(AfxGetApp()->GetProfileString(_T("Shaders"), str), sl, '|', 3);
04627 if(sl.GetCount() != 3) {AfxMessageBox(_T("Invalid shader data"), S_OK); return;}
04628
04629 CString label = sl.RemoveHead();
04630 CStringA target = CStringA(sl.RemoveHead());
04631 CStringA srcdata = CStringA(sl.RemoveHead());
04632
04633 srcdata.Replace("\\n", "\n");
04634 srcdata.Replace("\\t", "\t");
04635
04636 HRESULT hr = m_pCAP->SetPixelShader(srcdata, target);
04637 if(FAILED(hr)) AfxMessageBox(_T("Could not load shader."), MB_OK);
04638 else {SendStatusMessage(_T("Shader: ") + label, 3000); m_shaderlabel = label;}
04639 }
04640 }
04641
04642 void CMainFrame::OnUpdatePlayShaders(CCmdUI* pCmdUI)
04643 {
04644 if(pCmdUI->m_nID > ID_SHADERS_START)
04645 {
04646 pCmdUI->Enable(!!m_pCAP);
04647
04648 if(pCmdUI->m_nID == ID_SHADERS_START+1)
04649 {
04650 pCmdUI->SetRadio(m_shaderlabel.IsEmpty());
04651 }
04652 else
04653 {
04654 CString str;
04655 m_shaders.GetMenuString(pCmdUI->m_nID, str, MF_BYCOMMAND);
04656 pCmdUI->SetRadio(str == m_shaderlabel);
04657 }
04658 }
04659 }
04660
04661 void CMainFrame::OnPlayAudio(UINT nID)
04662 {
04663 int i = (int)nID - (1 + ID_AUDIO_SUBITEM_START);
04664
04665 CComQIPtr<IAMStreamSelect> pSS = FindFilter(__uuidof(CAudioSwitcherFilter), pGB);
04666 if(!pSS) pSS = FindFilter(L"{D3CD7858-971A-4838-ACEC-40CA5D529DC8}", pGB);
04667
04668 if(i == -1)
04669 {
04670 ShowOptions(CPPageAudioSwitcher::IDD);
04671 }
04672 else if(i >= 0 && pSS)
04673 {
04674 pSS->Enable(i, AMSTREAMSELECTENABLE_ENABLE);
04675 }
04676 }
04677
04678 void CMainFrame::OnUpdatePlayAudio(CCmdUI* pCmdUI)
04679 {
04680 UINT nID = pCmdUI->m_nID;
04681 int i = (int)nID - (1 + ID_AUDIO_SUBITEM_START);
04682
04683 CComQIPtr<IAMStreamSelect> pSS = FindFilter(__uuidof(CAudioSwitcherFilter), pGB);
04684 if(!pSS) pSS = FindFilter(L"{D3CD7858-971A-4838-ACEC-40CA5D529DC8}", pGB);
04685
04686
04687
04688
04689
04690 if(i >= 0 && pSS)
04691 {
04692 DWORD flags = 0;
04693
04694 if(SUCCEEDED(pSS->Info(i, NULL, &flags, NULL, NULL, NULL, NULL, NULL)))
04695 {
04696 if(flags&AMSTREAMSELECTINFO_EXCLUSIVE) pCmdUI->SetRadio(TRUE);
04697 else if(flags&AMSTREAMSELECTINFO_ENABLED) pCmdUI->SetCheck(TRUE);
04698 else pCmdUI->SetCheck(FALSE);
04699 }
04700 else
04701 {
04702 pCmdUI->Enable(FALSE);
04703 }
04704 }
04705 }
04706
04707 void CMainFrame::OnPlaySubtitles(UINT nID)
04708 {
04709 int i = (int)nID - (4 + ID_SUBTITLES_SUBITEM_START);
04710
04711 if(i == -4)
04712 {
04713 ShowOptions(CPPageSubtitles::IDD);
04714 }
04715 else if(i == -3)
04716 {
04717 int i = m_iSubtitleSel;
04718
04719 POSITION pos = m_pSubStreams.GetHeadPosition();
04720 while(pos && i >= 0)
04721 {
04722 CComPtr<ISubStream> pSubStream = m_pSubStreams.GetNext(pos);
04723
04724 if(i < pSubStream->GetStreamCount())
04725 {
04726 CLSID clsid;
04727 if(FAILED(pSubStream->GetClassID(&clsid)))
04728 continue;
04729
04730 if(clsid == __uuidof(CRenderedTextSubtitle))
04731 {
04732 CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)pSubStream;
04733
04734 CAutoPtrArray<CPPageSubStyle> pages;
04735 CArray<STSStyle*> styles;
04736
04737 POSITION pos = pRTS->m_styles.GetStartPosition();
04738 for(int i = 0; pos; i++)
04739 {
04740 CString key;
04741 void* val;
04742 pRTS->m_styles.GetNextAssoc(pos, key, val);
04743
04744 CAutoPtr<CPPageSubStyle> page(new CPPageSubStyle());
04745 page->InitStyle(key, *(STSStyle*)val);
04746 pages.Add(page);
04747 styles.Add((STSStyle*)val);
04748 }
04749
04750 CPropertySheet dlg(_T("Styles..."), this);
04751 for(int i = 0; i < (int)pages.GetCount(); i++)
04752 dlg.AddPage(pages[i]);
04753
04754 if(dlg.DoModal() == IDOK)
04755 {
04756 for(int j = 0; j < (int)pages.GetCount(); j++)
04757 pages[j]->GetStyle(*styles[j]);
04758 UpdateSubtitle(false);
04759 }
04760
04761 return;
04762 }
04763 }
04764
04765 i -= pSubStream->GetStreamCount();
04766 }
04767 }
04768 else if(i == -2)
04769 {
04770 ReloadSubtitle();
04771 }
04772 else if(i == -1)
04773 {
04774 m_iSubtitleSel ^= (1<<31);
04775 UpdateSubtitle();
04776 }
04777 else if(i >= 0)
04778 {
04779 m_iSubtitleSel = i;
04780 UpdateSubtitle();
04781 }
04782 }
04783
04784 void CMainFrame::OnUpdatePlaySubtitles(CCmdUI* pCmdUI)
04785 {
04786 UINT nID = pCmdUI->m_nID;
04787 int i = (int)nID - (4 + ID_SUBTITLES_SUBITEM_START);
04788
04789 pCmdUI->Enable(m_pCAP && !m_fAudioOnly);
04790
04791 if(i == -3)
04792 {
04793 pCmdUI->Enable(FALSE);
04794
04795 int i = m_iSubtitleSel;
04796
04797 POSITION pos = m_pSubStreams.GetHeadPosition();
04798 while(pos && i >= 0)
04799 {
04800 CComPtr<ISubStream> pSubStream = m_pSubStreams.GetNext(pos);
04801
04802 if(i < pSubStream->GetStreamCount())
04803 {
04804 CLSID clsid;
04805 if(FAILED(pSubStream->GetClassID(&clsid)))
04806 continue;
04807
04808 if(clsid == __uuidof(CRenderedTextSubtitle))
04809 {
04810 pCmdUI->Enable(TRUE);
04811 break;
04812 }
04813 }
04814
04815 i -= pSubStream->GetStreamCount();
04816 }
04817 }
04818 else if(i == -1)
04819 {
04820 pCmdUI->SetCheck(m_iSubtitleSel >= 0);
04821 }
04822 else if(i >= 0)
04823 {
04824 pCmdUI->SetRadio(i == abs(m_iSubtitleSel));
04825 }
04826 }
04827
04828 void CMainFrame::OnPlayLanguage(UINT nID)
04829 {
04830 nID -= ID_FILTERSTREAMS_SUBITEM_START;
04831 CComPtr<IAMStreamSelect> pAMSS = m_ssarray[nID];
04832 UINT i = nID;
04833 while(i > 0 && pAMSS == m_ssarray[i-1]) i--;
04834 if(FAILED(pAMSS->Enable(nID-i, AMSTREAMSELECTENABLE_ENABLE)))
04835 MessageBeep(-1);
04836
04837 OpenSetupStatusBar();
04838 }
04839
04840 void CMainFrame::OnUpdatePlayLanguage(CCmdUI* pCmdUI)
04841 {
04842 UINT nID = pCmdUI->m_nID;
04843 nID -= ID_FILTERSTREAMS_SUBITEM_START;
04844 CComPtr<IAMStreamSelect> pAMSS = m_ssarray[nID];
04845 UINT i = nID;
04846 while(i > 0 && pAMSS == m_ssarray[i-1]) i--;
04847 DWORD flags = 0;
04848 pAMSS->Info(nID-i, NULL, &flags, NULL, NULL, NULL, NULL, NULL);
04849 if(flags&AMSTREAMSELECTINFO_EXCLUSIVE) pCmdUI->SetRadio(TRUE);
04850 else if(flags&AMSTREAMSELECTINFO_ENABLED) pCmdUI->SetCheck(TRUE);
04851 else pCmdUI->SetCheck(FALSE);
04852 }
04853
04854 void CMainFrame::OnPlayVolume(UINT nID)
04855 {
04856 if(m_iMediaLoadState == MLS_LOADED)
04857 pBA->put_Volume(m_wndToolBar.Volume);
04858 }
04859
04860 void CMainFrame::OnAfterplayback(UINT nID)
04861 {
04862 AppSettings& s = AfxGetAppSettings();
04863
04864 s.nCLSwitches &= ~CLSW_AFTERPLAYBACK_MASK;
04865
04866 switch(nID)
04867 {
04868 case ID_AFTERPLAYBACK_CLOSE: s.nCLSwitches |= CLSW_CLOSE; break;
04869 case ID_AFTERPLAYBACK_STANDBY: s.nCLSwitches |= CLSW_STANDBY; break;
04870 case ID_AFTERPLAYBACK_HIBERNATE: s.nCLSwitches |= CLSW_HIBERNATE; break;
04871 case ID_AFTERPLAYBACK_SHUTDOWN: s.nCLSwitches |= CLSW_SHUTDOWN; break;
04872 case ID_AFTERPLAYBACK_LOGOFF: s.nCLSwitches |= CLSW_LOGOFF; break;
04873 }
04874 }
04875
04876 void CMainFrame::OnUpdateAfterplayback(CCmdUI* pCmdUI)
04877 {
04878 AppSettings& s = AfxGetAppSettings();
04879
04880 bool fChecked = false;
04881
04882 switch(pCmdUI->m_nID)
04883 {
04884 case ID_AFTERPLAYBACK_CLOSE: fChecked = !!(s.nCLSwitches & CLSW_CLOSE); break;
04885 case ID_AFTERPLAYBACK_STANDBY: fChecked = !!(s.nCLSwitches & CLSW_STANDBY); break;
04886 case ID_AFTERPLAYBACK_HIBERNATE: fChecked = !!(s.nCLSwitches & CLSW_HIBERNATE); break;
04887 case ID_AFTERPLAYBACK_SHUTDOWN: fChecked = !!(s.nCLSwitches & CLSW_SHUTDOWN); break;
04888 case ID_AFTERPLAYBACK_LOGOFF: fChecked = !!(s.nCLSwitches & CLSW_LOGOFF); break;
04889 case ID_AFTERPLAYBACK_DONOTHING: fChecked = !(s.nCLSwitches & CLSW_AFTERPLAYBACK_MASK); break;
04890 }
04891
04892 pCmdUI->SetRadio(fChecked);
04893 }
04894
04895
04896
04897 void CMainFrame::OnNavigateSkip(UINT nID)
04898 {
04899 if(m_iPlaybackMode == PM_FILE || m_iPlaybackMode == PM_CAPTURE)
04900 {
04901 if(m_iPlaybackMode == PM_FILE) SetupChapters();
04902
04903 if(DWORD nChapters = m_pCB->ChapGetCount())
04904 {
04905 REFERENCE_TIME rtCur;
04906 pMS->GetCurrentPosition(&rtCur);
04907
04908 REFERENCE_TIME rt = rtCur;
04909 CComBSTR name;
04910 long i;
04911
04912 if(nID == ID_NAVIGATE_SKIPBACK)
04913 {
04914 rt -= 30000000;
04915 i = m_pCB->ChapLookup(&rt, &name);
04916 }
04917 else if(nID == ID_NAVIGATE_SKIPFORWARD)
04918 {
04919 i = m_pCB->ChapLookup(&rt, &name) + 1;
04920 name.Empty();
04921 if(i < nChapters) m_pCB->ChapGet(i, &rt, &name);
04922 }
04923
04924 if(i >= 0 && i < nChapters)
04925 {
04926 SeekTo(rt);
04927 SendStatusMessage(_T("Chapter: ") + CString(name), 3000);
04928 return;
04929 }
04930 }
04931
04932 if(nID == ID_NAVIGATE_SKIPBACK)
04933 {
04934 SendMessage(WM_COMMAND, ID_NAVIGATE_SKIPBACKPLITEM);
04935 }
04936 else if(nID == ID_NAVIGATE_SKIPFORWARD)
04937 {
04938 SendMessage(WM_COMMAND, ID_NAVIGATE_SKIPFORWARDPLITEM);
04939 }
04940 }
04941 else if(m_iPlaybackMode == PM_DVD)
04942 {
04943 m_iSpeedLevel = 0;
04944
04945 if(GetMediaState() != State_Running)
04946 SendMessage(WM_COMMAND, ID_PLAY_PLAY);
04947
04948 ULONG ulNumOfVolumes, ulVolume;
04949 DVD_DISC_SIDE Side;
04950 ULONG ulNumOfTitles = 0;
04951 pDVDI->GetDVDVolumeInfo(&ulNumOfVolumes, &ulVolume, &Side, &ulNumOfTitles);
04952
04953 DVD_PLAYBACK_LOCATION2 Location;
04954 pDVDI->GetCurrentLocation(&Location);
04955
04956 ULONG ulNumOfChapters = 0;
04957 pDVDI->GetNumberOfChapters(Location.TitleNum, &ulNumOfChapters);
04958
04959 if(nID == ID_NAVIGATE_SKIPBACK)
04960 {
04961 if(Location.ChapterNum == 1 && Location.TitleNum > 1)
04962 {
04963 pDVDI->GetNumberOfChapters(Location.TitleNum-1, &ulNumOfChapters);
04964 pDVDC->PlayChapterInTitle(Location.TitleNum-1, ulNumOfChapters, DVD_CMD_FLAG_Block|DVD_CMD_FLAG_Flush, NULL);
04965 }
04966 else
04967 {
04968 pDVDC->PlayPrevChapter(DVD_CMD_FLAG_Block|DVD_CMD_FLAG_Flush, NULL);
04969 }
04970 }
04971 else if(nID == ID_NAVIGATE_SKIPFORWARD)
04972 {
04973 if(Location.ChapterNum == ulNumOfChapters && Location.TitleNum < ulNumOfTitles)
04974 {
04975 pDVDC->PlayChapterInTitle(Location.TitleNum+1, 1, DVD_CMD_FLAG_Block|DVD_CMD_FLAG_Flush, NULL);
04976 }
04977 else
04978 {
04979 pDVDC->PlayNextChapter(DVD_CMD_FLAG_Block|DVD_CMD_FLAG_Flush, NULL);
04980 }
04981 }
04982
04983
04984
04985
04986
04987
04988 }
04989 }
04990
04991 void CMainFrame::OnUpdateNavigateSkip(CCmdUI* pCmdUI)
04992 {
04993
04994
04995
04996 pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED
04997 && ((m_iPlaybackMode == PM_DVD
04998 && m_iDVDDomain != DVD_DOMAIN_VideoManagerMenu
04999 && m_iDVDDomain != DVD_DOMAIN_VideoTitleSetMenu)
05000 || (m_iPlaybackMode == PM_FILE && (m_wndPlaylistBar.GetCount() > 1 || m_pCB->ChapGetCount() > 1))
05001 || (m_iPlaybackMode == PM_CAPTURE && !m_fCapturing)));
05002 }
05003
05004 void CMainFrame::OnNavigateSkipPlaylistItem(UINT nID)
05005 {
05006 if(m_iPlaybackMode == PM_FILE || m_iPlaybackMode == PM_CAPTURE)
05007 {
05008 if(m_wndPlaylistBar.GetCount() == 1)
05009 {
05010 SendMessage(WM_COMMAND, ID_PLAY_STOP);
05011 SendMessage(WM_COMMAND, ID_PLAY_PLAY);
05012 }
05013 else
05014 {
05015 if(nID == ID_NAVIGATE_SKIPBACKPLITEM)
05016 {
05017 m_wndPlaylistBar.SetPrev();
05018 }
05019 else if(nID == ID_NAVIGATE_SKIPFORWARDPLITEM)
05020 {
05021 m_wndPlaylistBar.SetNext();
05022 }
05023
05024 OpenCurPlaylistItem();
05025 }
05026 }
05027 }
05028
05029 void CMainFrame::OnUpdateNavigateSkipPlaylistItem(CCmdUI* pCmdUI)
05030 {
05031 pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED
05032 && ((m_iPlaybackMode == PM_FILE || m_iPlaybackMode == PM_CAPTURE && !m_fCapturing) && m_wndPlaylistBar.GetCount() > 1));
05033 }
05034
05035 void CMainFrame::OnNavigateMenu(UINT nID)
05036 {
05037 nID -= ID_NAVIGATE_TITLEMENU;
05038
05039 if(m_iMediaLoadState != MLS_LOADED || m_iPlaybackMode != PM_DVD)
05040 return;
05041
05042 m_iSpeedLevel = 0;
05043
05044 if(GetMediaState() != State_Running)
05045 SendMessage(WM_COMMAND, ID_PLAY_PLAY);
05046
05047 pDVDC->ShowMenu((DVD_MENU_ID)(nID+2), DVD_CMD_FLAG_Block|DVD_CMD_FLAG_Flush, NULL);
05048 }
05049
05050 void CMainFrame::OnUpdateNavigateMenu(CCmdUI* pCmdUI)
05051 {
05052 UINT nID = pCmdUI->m_nID - ID_NAVIGATE_TITLEMENU;
05053 ULONG ulUOPs;
05054
05055 if(m_iMediaLoadState != MLS_LOADED || m_iPlaybackMode != PM_DVD
05056 || FAILED(pDVDI->GetCurrentUOPS(&ulUOPs)))
05057 {
05058 pCmdUI->Enable(FALSE);
05059 return;
05060 }
05061
05062 pCmdUI->Enable(!(ulUOPs & (UOP_FLAG_ShowMenu_Title << nID)));
05063 }
05064
05065 void CMainFrame::OnNavigateAudio(UINT nID)
05066 {
05067 nID -= ID_NAVIGATE_AUDIO_SUBITEM_START;
05068
05069 if(m_iPlaybackMode == PM_FILE)
05070 {
05071 OnNavStreamSelectSubMenu(nID, 1);
05072 }
05073 else if(m_iPlaybackMode == PM_DVD)
05074 {
05075 pDVDC->SelectAudioStream(nID, DVD_CMD_FLAG_Block, NULL);
05076 }
05077 }
05078
05079 void CMainFrame::OnNavigateSubpic(UINT nID)
05080 {
05081 if(m_iPlaybackMode == PM_FILE)
05082 {
05083 OnNavStreamSelectSubMenu(nID - ID_NAVIGATE_SUBP_SUBITEM_START, 2);
05084 }
05085 else if(m_iPlaybackMode == PM_DVD)
05086 {
05087 int i = (int)nID - (1 + ID_NAVIGATE_SUBP_SUBITEM_START);
05088
05089 if(i == -1)
05090 {
05091 ULONG ulStreamsAvailable, ulCurrentStream;
05092 BOOL bIsDisabled;
05093 if(SUCCEEDED(pDVDI->GetCurrentSubpicture(&ulStreamsAvailable, &ulCurrentStream, &bIsDisabled)))
05094 pDVDC->SetSubpictureState(bIsDisabled, DVD_CMD_FLAG_Block, NULL);
05095 }
05096 else
05097 {
05098 pDVDC->SelectSubpictureStream(i, DVD_CMD_FLAG_Block, NULL);
05099 pDVDC->SetSubpictureState(TRUE, DVD_CMD_FLAG_Block, NULL);
05100 }
05101 }
05102 }
05103
05104 void CMainFrame::OnNavigateAngle(UINT nID)
05105 {
05106 nID -= ID_NAVIGATE_ANGLE_SUBITEM_START;
05107
05108 if(m_iPlaybackMode == PM_FILE)
05109 {
05110 OnNavStreamSelectSubMenu(nID, 0);
05111 }
05112 else if(m_iPlaybackMode == PM_DVD)
05113 {
05114 pDVDC->SelectAngle(nID, DVD_CMD_FLAG_Block, NULL);
05115 }
05116 }
05117
05118 void CMainFrame::OnNavigateChapters(UINT nID)
05119 {
05120 nID -= ID_NAVIGATE_CHAP_SUBITEM_START;
05121
05122 if(m_iPlaybackMode == PM_FILE)
05123 {
05124 if((int)nID >= 0 && nID < m_pCB->ChapGetCount())
05125 {
05126 REFERENCE_TIME rt;
05127 CComBSTR name;
05128 if(SUCCEEDED(m_pCB->ChapGet(nID, &rt, &name)))
05129 {
05130 SeekTo(rt);
05131 SendStatusMessage(_T("Chapter: ") + CString(name), 3000);
05132 }
05133 return;
05134 }
05135
05136 nID -= m_pCB->ChapGetCount();
05137
05138 if((int)nID >= 0 && (int)nID < m_wndPlaylistBar.GetCount()
05139 && m_wndPlaylistBar.GetSelIdx() != (int)nID)
05140 {
05141 m_wndPlaylistBar.SetSelIdx(nID);
05142 OpenCurPlaylistItem();
05143 }
05144 }
05145 else if(m_iPlaybackMode == PM_DVD)
05146 {
05147 ULONG ulNumOfVolumes, ulVolume;
05148 DVD_DISC_SIDE Side;
05149 ULONG ulNumOfTitles = 0;
05150 pDVDI->GetDVDVolumeInfo(&ulNumOfVolumes, &ulVolume, &Side, &ulNumOfTitles);
05151
05152 DVD_PLAYBACK_LOCATION2 Location;
05153 pDVDI->GetCurrentLocation(&Location);
05154
05155 ULONG ulNumOfChapters = 0;
05156 pDVDI->GetNumberOfChapters(Location.TitleNum, &ulNumOfChapters);
05157
05158 nID++;
05159
05160 if(nID > 0 && nID <= ulNumOfTitles)
05161 {
05162 pDVDC->PlayTitle(nID, DVD_CMD_FLAG_Block|DVD_CMD_FLAG_Flush, NULL);
05163 pDVDC->PlayChapterInTitle(nID, 1, DVD_CMD_FLAG_Block|DVD_CMD_FLAG_Flush, NULL);
05164 return;
05165 }
05166
05167 nID -= ulNumOfTitles;
05168
05169 if(nID > 0 && nID <= ulNumOfChapters)
05170 {
05171 pDVDC->PlayChapter(nID, DVD_CMD_FLAG_Block|DVD_CMD_FLAG_Flush, NULL);
05172 return;
05173 }
05174 }
05175 }
05176
05177 void CMainFrame::OnNavigateMenuItem(UINT nID)
05178 {
05179 nID -= ID_NAVIGATE_MENU_LEFT;
05180
05181 if(m_iPlaybackMode == PM_DVD)
05182 {
05183 switch(nID)
05184 {
05185 case 0: pDVDC->SelectRelativeButton(DVD_Relative_Left); break;
05186 case 1: pDVDC->SelectRelativeButton(DVD_Relative_Right); break;
05187 case 2: pDVDC->SelectRelativeButton(DVD_Relative_Upper); break;
05188 case 3: pDVDC->SelectRelativeButton(DVD_Relative_Lower); break;
05189 case 4: pDVDC->ActivateButton(); break;
05190 case 5: pDVDC->ReturnFromSubmenu(DVD_CMD_FLAG_Block|DVD_CMD_FLAG_Flush, NULL); break;
05191 case 6: pDVDC->Resume(DVD_CMD_FLAG_Block|DVD_CMD_FLAG_Flush, NULL); break;
05192 default: break;
05193 }
05194 }
05195 }
05196
05197 void CMainFrame::OnUpdateNavigateMenuItem(CCmdUI* pCmdUI)
05198 {
05199 UINT nID = pCmdUI->m_nID - ID_NAVIGATE_MENU_LEFT;
05200 pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && m_iPlaybackMode == PM_DVD);
05201 }
05202
05203
05204
05205 class CDVDStateStream : public CUnknown, public IStream
05206 {
05207 STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv)
05208 {
05209 return
05210 QI(IStream)
05211 CUnknown::NonDelegatingQueryInterface(riid, ppv);
05212 }
05213
05214 __int64 m_pos;
05215
05216 public:
05217 CDVDStateStream() : CUnknown(NAME("CDVDStateStream"), NULL) {m_pos = 0;}
05218
05219 DECLARE_IUNKNOWN;
05220
05221 CByteArray m_data;
05222
05223
05224 STDMETHODIMP Read(void* pv, ULONG cb, ULONG* pcbRead)
05225 {
05226 __int64 cbRead = min(m_data.GetCount() - m_pos, (__int64)cb);
05227 cbRead = max(cbRead, 0);
05228 memcpy(pv, &m_data[(INT_PTR)m_pos], (int)cbRead);
05229 if(pcbRead) *pcbRead = (ULONG)cbRead;
05230 m_pos += cbRead;
05231 return S_OK;
05232 }
05233 STDMETHODIMP Write(const void* pv, ULONG cb, ULONG* pcbWritten)
05234 {
05235 BYTE* p = (BYTE*)pv;
05236 ULONG cbWritten = -1;
05237 while(++cbWritten < cb)
05238 m_data.Add(*p++);
05239 if(pcbWritten) *pcbWritten = cbWritten;
05240 return S_OK;
05241 }
05242
05243
05244 STDMETHODIMP Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition) {return E_NOTIMPL;}
05245 STDMETHODIMP SetSize(ULARGE_INTEGER libNewSize) {return E_NOTIMPL;}
05246 STDMETHODIMP CopyTo(IStream* pstm, ULARGE_INTEGER cb, ULARGE_INTEGER* pcbRead, ULARGE_INTEGER* pcbWritten) {return E_NOTIMPL;}
05247 STDMETHODIMP Commit(DWORD grfCommitFlags) {return E_NOTIMPL;}
05248 STDMETHODIMP Revert() {return E_NOTIMPL;}
05249 STDMETHODIMP LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) {return E_NOTIMPL;}
05250 STDMETHODIMP UnlockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) {return E_NOTIMPL;}
05251 STDMETHODIMP Stat(STATSTG* pstatstg, DWORD grfStatFlag) {return E_NOTIMPL;}
05252 STDMETHODIMP Clone(IStream** ppstm) {return E_NOTIMPL;}
05253 };
05254
05255
05256 void CMainFrame::OnFavoritesAdd()
05257 {
05258 AppSettings& s = AfxGetAppSettings();
05259
05260 if(m_iPlaybackMode == PM_FILE)
05261 {
05262 CString fn = m_wndPlaylistBar.GetCur();
05263 if(fn.IsEmpty()) return;
05264
05265 CString desc = fn;
05266 desc.Replace('\\', '/');
05267 int i = desc.Find(_T("://")), j = desc.Find(_T("?")), k = desc.ReverseFind('/');
05268 if(i >= 0) desc = j >= 0 ? desc.Left(j) : desc;
05269 else if(k >= 0) desc = desc.Mid(k+1);
05270
05271 CFavoriteAddDlg dlg(desc, fn);
05272 if(dlg.DoModal() != IDOK) return;
05273
05274 CString str = dlg.m_name;
05275 str.Remove(';');
05276
05277 CString pos(_T("0"));
05278 if(dlg.m_fRememberPos)
05279 pos.Format(_T("%I64d"), GetPos());
05280
05281 str += ';';
05282 str += pos;
05283
05284 CPlaylistItem pli;
05285 if(m_wndPlaylistBar.GetCur(pli))
05286 {
05287 POSITION pos = pli.m_fns.GetHeadPosition();
05288 while(pos) str += _T(";") + pli.m_fns.GetNext(pos);
05289 }
05290
05291 s.AddFav(FAV_FILE, str);
05292 }
05293 else if(m_iPlaybackMode == PM_DVD)
05294 {
05295 WCHAR path[MAX_PATH];
05296 ULONG len = 0;
05297 pDVDI->GetDVDDirectory(path, MAX_PATH, &len);
05298 CString fn = path;
05299 fn.TrimRight(_T("/\\"));
05300
05301 DVD_PLAYBACK_LOCATION2 Location;
05302 pDVDI->GetCurrentLocation(&Location);
05303 CString desc;
05304 desc.Format(_T("%s - T%02d C%02d - %02d:%02d:%02d"), fn, Location.TitleNum, Location.ChapterNum,
05305 Location.TimeCode.bHours, Location.TimeCode.bMinutes, Location.TimeCode.bSeconds);
05306
05307 CFavoriteAddDlg dlg(fn, desc);
05308 if(dlg.DoModal() != IDOK) return;
05309
05310 CString str = dlg.m_name;
05311 str.Remove(';');
05312
05313 CString pos(_T("0"));
05314 if(dlg.m_fRememberPos)
05315 {
05316 CDVDStateStream stream;
05317 stream.AddRef();
05318
05319 CComPtr<IDvdState> pStateData;
05320 CComQIPtr<IPersistStream> pPersistStream;
05321 if(SUCCEEDED(pDVDI->GetState(&pStateData))
05322 && (pPersistStream = pStateData)
05323 && SUCCEEDED(OleSaveToStream(pPersistStream, (IStream*)&stream)))
05324 {
05325 pos = BinToString(stream.m_data.GetData(), stream.m_data.GetCount());
05326 }
05327 }
05328
05329 str += ';';
05330 str += pos;
05331
05332 str += ';';
05333 str += fn;
05334
05335 s.AddFav(FAV_DVD, str);
05336 }
05337 else if(m_iPlaybackMode == PM_CAPTURE)
05338 {
05339
05340 }
05341 }
05342
05343 void CMainFrame::OnUpdateFavoritesAdd(CCmdUI* pCmdUI)
05344 {
05345 pCmdUI->Enable(m_iPlaybackMode == PM_FILE || m_iPlaybackMode == PM_DVD);
05346 }
05347
05348 void CMainFrame::OnFavoritesOrganize()
05349 {
05350 CFavoriteOrganizeDlg dlg;
05351 dlg.DoModal();
05352 }
05353
05354 void CMainFrame::OnUpdateFavoritesOrganize(CCmdUI* pCmdUI)
05355 {
05356
05357 }
05358
05359 void CMainFrame::OnFavoritesFile(UINT nID)
05360 {
05361 nID -= ID_FAVORITES_FILE_START;
05362
05363 CList<CString> sl;
05364 AfxGetAppSettings().GetFav(FAV_FILE, sl);
05365
05366 if(POSITION pos = sl.FindIndex(nID))
05367 {
05368 CList<CString> fns;
05369 REFERENCE_TIME rtStart = 0;
05370
05371 int i = 0, j = 0;
05372 for(CString s1 = sl.GetAt(pos), s2 = s1.Tokenize(_T(";"), i);
05373 !s2.IsEmpty();
05374 s2 = s1.Tokenize(_T(";"), i), j++)
05375 {
05376 if(j == 0) ;
05377 else if(j == 1) _stscanf(s2, _T("%I64d"), &rtStart);
05378 else fns.AddTail(s2);
05379 }
05380
05381 m_wndPlaylistBar.Open(fns, false);
05382 OpenCurPlaylistItem(max(rtStart, 0));
05383 }
05384 }
05385
05386 void CMainFrame::OnUpdateFavoritesFile(CCmdUI* pCmdUI)
05387 {
05388 UINT nID = pCmdUI->m_nID - ID_FAVORITES_FILE_START;
05389 }
05390
05391 void CMainFrame::OnFavoritesDVD(UINT nID)
05392 {
05393 nID -= ID_FAVORITES_DVD_START;
05394
05395 CList<CString> sl;
05396 AfxGetAppSettings().GetFav(FAV_DVD, sl);
05397
05398 if(POSITION pos = sl.FindIndex(nID))
05399 {
05400 CString fn;
05401
05402 CDVDStateStream stream;
05403 stream.AddRef();
05404
05405 int i = 0, j = 0;
05406 for(CString s1 = sl.GetAt(pos), s2 = s1.Tokenize(_T(";"), i);
05407 !s2.IsEmpty();
05408 s2 = s1.Tokenize(_T(";"), i), j++)
05409 {
05410 if(j == 0) ;
05411 else if(j == 1 && s2 != _T("0"))
05412 {
05413 StringToBin(s2, stream.m_data);
05414 }
05415 else if(j == 2) fn = s2;
05416 }
05417
05418 SendMessage(WM_COMMAND, ID_FILE_CLOSEMEDIA);
05419
05420 CComPtr<IDvdState> pDvdState;
05421 HRESULT hr = OleLoadFromStream((IStream*)&stream, IID_IDvdState, (void**)&pDvdState);
05422
05423 CAutoPtr<OpenDVDData> p(new OpenDVDData());
05424 if(p) {p->path = fn; p->pDvdState = pDvdState;}
05425 OpenMedia(p);
05426 }
05427 }
05428
05429 void CMainFrame::OnUpdateFavoritesDVD(CCmdUI* pCmdUI)
05430 {
05431 UINT nID = pCmdUI->m_nID - ID_FAVORITES_DVD_START;
05432 }
05433
05434 void CMainFrame::OnFavoritesDevice(UINT nID)
05435 {
05436 nID -= ID_FAVORITES_DEVICE_START;
05437 }
05438
05439 void CMainFrame::OnUpdateFavoritesDevice(CCmdUI* pCmdUI)
05440 {
05441 UINT nID = pCmdUI->m_nID - ID_FAVORITES_DEVICE_START;
05442 }
05443
05444
05445
05446 void CMainFrame::OnHelpHomepage()
05447 {
05448 ShellExecute(m_hWnd, _T("open"), _T("http://gabest.org/"), NULL, NULL, SW_SHOWDEFAULT);
05449 }
05450
05451 void CMainFrame::OnHelpDocumentation()
05452 {
05453 ShellExecute(m_hWnd, _T("open"), _T("http://sourceforge.net/project/showfiles.php?group_id=82303&package_id=144472"), NULL, NULL, SW_SHOWDEFAULT);
05454 }
05455
05456 void CMainFrame::OnHelpDonate()
05457 {
05458 const TCHAR URL[] = _T("http://order.kagi.com/?N4A");
05459 if(CString(URL).Find(CString(_T("A4N")).MakeReverse()) >= 0)
05460 ShellExecute(m_hWnd, _T("open"), URL, NULL, NULL, SW_SHOWDEFAULT);
05461 }
05462
05464
05465
05466 void CMainFrame::SetDefaultWindowRect()
05467 {
05468 AppSettings& s = AfxGetAppSettings();
05469
05470 {
05471 CRect r1, r2;
05472 GetClientRect(&r1);
05473 m_wndView.GetClientRect(&r2);
05474
05475 CSize logosize = m_wndView.GetLogoSize();
05476 int _DEFCLIENTW = max(logosize.cx, DEFCLIENTW);
05477 int _DEFCLIENTH = max(logosize.cy, DEFCLIENTH);
05478
05479 DWORD style = GetStyle();
05480
05481 MENUBARINFO mbi;
05482 memset(&mbi, 0, sizeof(mbi));
05483 mbi.cbSize = sizeof(mbi);
05484 ::GetMenuBarInfo(m_hWnd, OBJID_MENU, 0, &mbi);
05485
05486 int w = _DEFCLIENTW + GetSystemMetrics((style&WS_CAPTION)?SM_CXSIZEFRAME:SM_CXFIXEDFRAME)*2
05487 + r1.Width() - r2.Width();
05488 int h = _DEFCLIENTH + GetSystemMetrics((style&WS_CAPTION)?SM_CYSIZEFRAME:SM_CYFIXEDFRAME)*2
05489 + (mbi.rcBar.bottom - mbi.rcBar.top)
05490 + r1.Height() - r2.Height()
05491 + 1;
05492
05493 if(style&WS_CAPTION) h += GetSystemMetrics(SM_CYCAPTION);
05494
05495 if(s.HasFixedWindowSize())
05496 {
05497 w = s.fixedWindowSize.cx;
05498 h = s.fixedWindowSize.cy;
05499 }
05500 else if(s.fRememberWindowSize)
05501 {
05502 w = s.rcLastWindowPos.Width();
05503 h = s.rcLastWindowPos.Height();
05504 }
05505
05506 MONITORINFO mi;
05507 mi.cbSize = sizeof(MONITORINFO);
05508 GetMonitorInfo(MonitorFromWindow(m_hWnd, MONITOR_DEFAULTTONEAREST), &mi);
05509
05510 int x = (mi.rcWork.left+mi.rcWork.right-w)/2;
05511 int y = (mi.rcWork.top+mi.rcWork.bottom-h)/2;
05512
05513 if(s.fRememberWindowPos)
05514 {
05515 CRect r = s.rcLastWindowPos;
05516
05517
05518 x = r.TopLeft().x;
05519 y = r.TopLeft().y;
05520 }
05521
05522 UINT lastWindowType = s.lastWindowType;
05523
05524 MoveWindow(x, y, w, h);
05525
05526 if(s.fRememberWindowSize && s.fRememberWindowPos)
05527 {
05528 WINDOWPLACEMENT wp;
05529 memset(&wp, 0, sizeof(wp));
05530 wp.length = sizeof(WINDOWPLACEMENT);
05531 if(lastWindowType == SIZE_MAXIMIZED)
05532 ShowWindow(SW_MAXIMIZE);
05533 else if(lastWindowType == SIZE_MINIMIZED)
05534 ShowWindow(SW_MINIMIZE);
05535 }
05536 }
05537
05538 if(s.fHideCaptionMenu)
05539 {
05540 ModifyStyle(WS_CAPTION, 0, SWP_NOZORDER);
05541 ::SetMenu(m_hWnd, NULL);
05542 SetWindowPos(NULL, 0, 0, 0, 0, SWP_FRAMECHANGED|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER);
05543 }
05544 }
05545
05546 void CMainFrame::RestoreDefaultWindowRect()
05547 {
05548 AppSettings& s = AfxGetAppSettings();
05549
05550 WINDOWPLACEMENT wp;
05551 GetWindowPlacement(&wp);
05552 if(!m_fFullScreen && wp.showCmd != SW_SHOWMAXIMIZED && wp.showCmd != SW_SHOWMINIMIZED
05553
05554 && !s.fRememberWindowSize)
05555 {
05556 CRect r1, r2;
05557 GetClientRect(&r1);
05558 m_wndView.GetClientRect(&r2);
05559
05560 CSize logosize = m_wndView.GetLogoSize();
05561 int _DEFCLIENTW = max(logosize.cx, DEFCLIENTW);
05562 int _DEFCLIENTH = max(logosize.cy, DEFCLIENTH);
05563
05564 DWORD style = GetStyle();
05565
05566 MENUBARINFO mbi;
05567 memset(&mbi, 0, sizeof(mbi));
05568 mbi.cbSize = sizeof(mbi);
05569 ::GetMenuBarInfo(m_hWnd, OBJID_MENU, 0, &mbi);
05570
05571 int w = _DEFCLIENTW + GetSystemMetrics((style&WS_CAPTION)?SM_CXSIZEFRAME:SM_CXFIXEDFRAME)*2
05572 + r1.Width() - r2.Width();
05573 int h = _DEFCLIENTH + GetSystemMetrics((style&WS_CAPTION)?SM_CYSIZEFRAME:SM_CYFIXEDFRAME)*2
05574 + (mbi.rcBar.bottom - mbi.rcBar.top)
05575 + r1.Height() - r2.Height()
05576 + 1;
05577
05578 if(style&WS_CAPTION) h += GetSystemMetrics(SM_CYCAPTION);
05579
05580 if(s.HasFixedWindowSize())
05581 {
05582 w = s.fixedWindowSize.cx;
05583 h = s.fixedWindowSize.cy;
05584 }
05585
05586 CRect r;
05587 GetWindowRect(r);
05588
05589 int x = r.CenterPoint().x - w/2;
05590 int y = r.CenterPoint().y - h/2;
05591
05592 if(s.fRememberWindowPos)
05593 {
05594 CRect r = s.rcLastWindowPos;
05595
05596 x = r.TopLeft().x;
05597 y = r.TopLeft().y;
05598 }
05599
05600 MoveWindow(x, y, w, h);
05601 }
05602 }
05603
05604 OAFilterState CMainFrame::GetMediaState()
05605 {
05606 OAFilterState ret = -1;
05607 if(m_iMediaLoadState == MLS_LOADED) pMC->GetState(0, &ret);
05608 return(ret);
05609 }
05610
05611 CSize CMainFrame::GetVideoSize()
05612 {
05613 bool fKeepAspectRatio = AfxGetAppSettings().fKeepAspectRatio;
05614 bool fCompMonDeskARDiff = AfxGetAppSettings().fCompMonDeskARDiff;
05615
05616 CSize ret(0,0);
05617 if(m_iMediaLoadState != MLS_LOADED || m_fAudioOnly)
05618 return ret;
05619
05620 CSize wh(0, 0), arxy(0, 0);
05621
05622 if(m_pCAP)
05623 {
05624 wh = m_pCAP->GetVideoSize(false);
05625 arxy = m_pCAP->GetVideoSize(fKeepAspectRatio);
05626 }
05627 else
05628 {
05629 pBV->GetVideoSize(&wh.cx, &wh.cy);
05630
05631 long arx = 0, ary = 0;
05632 CComQIPtr<IBasicVideo2> pBV2 = pBV;
05633 if(pBV2 && SUCCEEDED(pBV2->GetPreferredAspectRatio(&arx, &ary)) && arx > 0 && ary > 0)
05634 arxy.SetSize(arx, ary);
05635 }
05636
05637 CSize& ar = AfxGetAppSettings().AspectRatio;
05638 if(ar.cx && ar.cy) arxy = ar;
05639
05640 if(wh.cx <= 0 || wh.cy <= 0)
05641 return ret;
05642
05643
05644 DVD_VideoAttributes VATR;
05645 if(m_iPlaybackMode == PM_DVD && SUCCEEDED(pDVDI->GetCurrentVideoAttributes(&VATR)))
05646 arxy.SetSize(VATR.ulAspectX, VATR.ulAspectY);
05647
05648 ret = (!fKeepAspectRatio || arxy.cx <= 0 || arxy.cy <= 0)
05649 ? wh
05650 : CSize(MulDiv(wh.cy, arxy.cx, arxy.cy), wh.cy);
05651
05652 if(fCompMonDeskARDiff)
05653 if(HDC hDC = ::GetDC(0))
05654 {
05655 int _HORZSIZE = GetDeviceCaps(hDC, HORZSIZE);
05656 int _VERTSIZE = GetDeviceCaps(hDC, VERTSIZE);
05657 int _HORZRES = GetDeviceCaps(hDC, HORZRES);
05658 int _VERTRES = GetDeviceCaps(hDC, VERTRES);
05659
05660 if(_HORZSIZE > 0 && _VERTSIZE > 0 && _HORZRES > 0 && _VERTRES > 0)
05661 {
05662 double a = 1.0*_HORZSIZE/_VERTSIZE;
05663 double b = 1.0*_HORZRES/_VERTRES;
05664
05665 if(b < a)
05666 ret.cy = (DWORD)(1.0*ret.cy * a / b);
05667 else if(a < b)
05668 ret.cx = (DWORD)(1.0*ret.cx * b / a);
05669 }
05670
05671 ::ReleaseDC(0, hDC);
05672 }
05673
05674 return ret;
05675 }
05676
05677 void CMainFrame::ToggleFullscreen(bool fToNearest, bool fSwitchScreenResWhenHasTo)
05678 {
05679 CRect r;
05680
05681 DWORD dwRemove = 0, dwAdd = 0;
05682 DWORD dwRemoveEx = 0, dwAddEx = 0;
05683 HMENU hMenu;
05684
05685 if(!m_fFullScreen)
05686 {
05687 GetWindowRect(&m_lastWindowRect);
05688
05689 dispmode& dm = AfxGetAppSettings().dmFullscreenRes;
05690 m_dmBeforeFullscreen.fValid = false;
05691 if(dm.fValid && fSwitchScreenResWhenHasTo)
05692 {
05693 GetCurDispMode(m_dmBeforeFullscreen);
05694 SetDispMode(dm);
05695 }
05696
05697 MONITORINFO mi;
05698 mi.cbSize = sizeof(MONITORINFO);
05699 GetMonitorInfo(MonitorFromWindow(m_hWnd, MONITOR_DEFAULTTONEAREST), &mi);
05700
05701 dwRemove = WS_CAPTION|WS_THICKFRAME;
05702 if(fToNearest) r = mi.rcMonitor;
05703 else GetDesktopWindow()->GetWindowRect(&r);
05704 hMenu = NULL;
05705 }
05706 else
05707 {
05708 if(m_dmBeforeFullscreen.fValid)
05709 SetDispMode(m_dmBeforeFullscreen);
05710
05711 dwAdd = (AfxGetAppSettings().fHideCaptionMenu ? 0 : WS_CAPTION) | WS_THICKFRAME;
05712 r = m_lastWindowRect;
05713 hMenu = AfxGetAppSettings().fHideCaptionMenu ? NULL : m_hMenuDefault;
05714 }
05715
05716 m_lastMouseMove.x = m_lastMouseMove.y = -1;
05717
05718 bool fAudioOnly = m_fAudioOnly;
05719 m_fAudioOnly = true;
05720
05721 m_fFullScreen = !m_fFullScreen;
05722
05723 SetAlwaysOnTop(AfxGetAppSettings().iOnTop);
05724
05725 ModifyStyle(dwRemove, dwAdd, SWP_NOZORDER);
05726 ModifyStyleEx(dwRemoveEx, dwAddEx, SWP_NOZORDER);
05727 ::SetMenu(m_hWnd, hMenu);
05728 SetWindowPos(NULL, r.left, r.top, r.Width(), r.Height(), SWP_NOZORDER|SWP_NOSENDCHANGING );
05729
05730 if(m_fFullScreen)
05731 {
05732 m_fHideCursor = true;
05733 ShowControls(CS_NONE, false);
05734 }
05735 else
05736 {
05737 KillTimer(TIMER_FULLSCREENCONTROLBARHIDER);
05738 KillTimer(TIMER_FULLSCREENMOUSEHIDER);
05739 m_fHideCursor = false;
05740 ShowControls(AfxGetAppSettings().nCS);
05741 }
05742
05743 m_wndView.SetWindowPos(NULL, 0, 0, 0, 0, SWP_FRAMECHANGED|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER);
05744
05745 m_fAudioOnly = fAudioOnly;
05746
05747 MoveVideoWindow();
05748 }
05749
05750 void CMainFrame::MoveVideoWindow(bool fShowStats)
05751 {
05752 if(m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly && IsWindowVisible())
05753 {
05754 CRect wr;
05755 if(!m_fFullScreen)
05756 {
05757 m_wndView.GetClientRect(wr);
05758 if(!AfxGetAppSettings().fHideCaptionMenu)
05759 wr.DeflateRect(2, 2);
05760 }
05761 else
05762 {
05763 GetWindowRect(&wr);
05764
05765
05766 CRect r;
05767 m_wndView.GetWindowRect(&r);
05768 wr -= r.TopLeft();
05769 }
05770
05771 CRect vr = CRect(0,0,0,0);
05772
05773 OAFilterState fs = GetMediaState();
05774 if(fs == State_Paused || fs == State_Running || fs == State_Stopped && (m_fShockwaveGraph || m_fQuicktimeGraph))
05775 {
05776 CSize arxy = GetVideoSize();
05777
05778 int iDefaultVideoSize = AfxGetAppSettings().iDefaultVideoSize;
05779
05780 CSize ws =
05781 iDefaultVideoSize == DVS_HALF ? CSize(arxy.cx/2, arxy.cy/2) :
05782 iDefaultVideoSize == DVS_NORMAL ? arxy :
05783 iDefaultVideoSize == DVS_DOUBLE ? CSize(arxy.cx*2, arxy.cy*2) :
05784 wr.Size();
05785
05786 int w = ws.cx;
05787 int h = ws.cy;
05788
05789 if(!m_fShockwaveGraph)
05790 {
05791 if(iDefaultVideoSize == DVS_FROMINSIDE || iDefaultVideoSize == DVS_FROMOUTSIDE)
05792 {
05793 h = ws.cy;
05794 w = MulDiv(h, arxy.cx, arxy.cy);
05795
05796 if(iDefaultVideoSize == DVS_FROMINSIDE && w > ws.cx
05797 || iDefaultVideoSize == DVS_FROMOUTSIDE && w < ws.cx)
05798 {
05799 w = ws.cx;
05800 h = MulDiv(w, arxy.cy, arxy.cx);
05801 }
05802 }
05803 }
05804
05805 CSize size(
05806 (int)(m_ZoomX*w),
05807 (int)(m_ZoomY*h));
05808
05809 CPoint pos(
05810 (int)(m_PosX*(wr.Width()*3 - m_ZoomX*w) - wr.Width()),
05811 (int)(m_PosY*(wr.Height()*3 - m_ZoomY*h) - wr.Height()));
05812
05813
05814
05815
05816
05817
05818 vr = CRect(pos, size);
05819 }
05820
05821 wr |= CRect(0,0,0,0);
05822 vr |= CRect(0,0,0,0);
05823
05824 if(m_pCAP)
05825 {
05826 m_pCAP->SetPosition(wr, vr);
05827 }
05828 else
05829 {
05830 HRESULT hr;
05831 hr = pBV->SetDefaultSourcePosition();
05832 hr = pBV->SetDestinationPosition(vr.left, vr.top, vr.Width(), vr.Height());
05833 hr = pVW->SetWindowPosition(wr.left, wr.top, wr.Width(), wr.Height());
05834 }
05835
05836 m_wndView.SetVideoRect(wr);
05837
05838 if(fShowStats && vr.Height() > 0)
05839 {
05840 CString info;
05841 info.Format(_T("Pos %.2f %.2f, Zoom %.2f %.2f, AR %.2f"), m_PosX, m_PosY, m_ZoomX, m_ZoomY, (float)vr.Width()/vr.Height());
05842 SendStatusMessage(info, 3000);
05843 }
05844 }
05845 else
05846 {
05847 m_wndView.SetVideoRect();
05848 }
05849 }
05850
05851 void CMainFrame::ZoomVideoWindow(double scale)
05852 {
05853 if(m_iMediaLoadState != MLS_LOADED)
05854 return;
05855
05856 AppSettings& s = AfxGetAppSettings();
05857
05858 if(scale <= 0)
05859 {
05860 scale = s.iZoomLevel == 0 ? 0.5 : s.iZoomLevel == 2 ? 2.0 : 1.0;
05861 }
05862
05863 if(m_fFullScreen)
05864 {
05865 OnViewFullscreen();
05866 }
05867
05868 MINMAXINFO mmi;
05869 OnGetMinMaxInfo(&mmi);
05870
05871 CRect r;
05872 int w = 0, h = 0;
05873
05874 if(!m_fAudioOnly)
05875 {
05876 CSize arxy = GetVideoSize();
05877
05878 long lWidth = int(arxy.cx * scale + 0.5);
05879 long lHeight = int(arxy.cy * scale + 0.5);
05880
05881 DWORD style = GetStyle();
05882
05883 CRect r1, r2;
05884 GetClientRect(&r1);
05885 m_wndView.GetClientRect(&r2);
05886
05887 w = GetSystemMetrics((style&WS_CAPTION)?SM_CXSIZEFRAME:SM_CXFIXEDFRAME)*2
05888 + r1.Width() - r2.Width()
05889 + lWidth;
05890
05891 MENUBARINFO mbi;
05892 memset(&mbi, 0, sizeof(mbi));
05893 mbi.cbSize = sizeof(mbi);
05894 ::GetMenuBarInfo(m_hWnd, OBJID_MENU, 0, &mbi);
05895
05896 h = GetSystemMetrics((style&WS_CAPTION)?SM_CYSIZEFRAME:SM_CYFIXEDFRAME)*2
05897 + (mbi.rcBar.bottom - mbi.rcBar.top)
05898 + r1.Height() - r2.Height()
05899 + lHeight;
05900
05901 if(style&WS_CAPTION)
05902 {
05903 h += GetSystemMetrics(SM_CYCAPTION);
05904 w += 2; h += 2;
05905 w += 2; h += 3;
05906 }
05907
05908 GetWindowRect(r);
05909
05910 w = max(w, mmi.ptMinTrackSize.x);
05911 h = max(h, mmi.ptMinTrackSize.y);
05912 }
05913 else
05914 {
05915 GetWindowRect(r);
05916
05917 w = r.Width();
05918 h = mmi.ptMinTrackSize.y;
05919 }
05920
05921
05922 if(!s.fRememberWindowPos)
05923 {
05924 CPoint cp = r.CenterPoint();
05925 r.left = cp.x - w/2;
05926 r.top = cp.y - h/2;
05927 }
05928
05929 r.right = r.left + w;
05930 r.bottom = r.top + h;
05931
05932 MONITORINFO mi;
05933 mi.cbSize = sizeof(MONITORINFO);
05934 GetMonitorInfo(MonitorFromWindow(m_hWnd, MONITOR_DEFAULTTONEAREST), &mi);
05935 if(r.right > mi.rcWork.right) r.OffsetRect(mi.rcWork.right-r.right, 0);
05936 if(r.left < mi.rcWork.left) r.OffsetRect(mi.rcWork.left-r.left, 0);
05937 if(r.bottom > mi.rcWork.bottom) r.OffsetRect(0, mi.rcWork.bottom-r.bottom);
05938 if(r.top < mi.rcWork.top) r.OffsetRect(0, mi.rcWork.top-r.top);
05939
05940 if(m_fFullScreen || !s.HasFixedWindowSize())
05941 {
05942 MoveWindow(r);
05943 }
05944
05945
05946
05947 MoveVideoWindow();
05948 }
05949
05950 void CMainFrame::RepaintVideo()
05951 {
05952 if(m_pCAP) m_pCAP->Paint(false);
05953 }
05954
05955 void CMainFrame::SetBalance(int balance)
05956 {
05957 AfxGetAppSettings().nBalance = balance;
05958
05959 int sign = balance>0?-1:1;
05960 balance = max(100-abs(balance), 1);
05961 balance = (int)((log10(1.0*balance)-2)*5000*sign);
05962 balance = max(min(balance, 10000), -10000);
05963
05964 if(m_iMediaLoadState == MLS_LOADED)
05965 pBA->put_Balance(balance);
05966 }
05967
05968 void CMainFrame::SetupIViAudReg()
05969 {
05970 if(!AfxGetAppSettings().fAutoSpeakerConf) return;
05971
05972 DWORD spc = 0, defchnum = 0;
05973
05974 if(AfxGetAppSettings().fAutoSpeakerConf)
05975 {
05976 CComPtr<IDirectSound> pDS;
05977 if(SUCCEEDED(DirectSoundCreate(NULL, &pDS, NULL))
05978 && SUCCEEDED(pDS->SetCooperativeLevel(m_hWnd, DSSCL_NORMAL)))
05979 {
05980 if(SUCCEEDED(pDS->GetSpeakerConfig(&spc)))
05981 {
05982 switch(spc)
05983 {
05984 case DSSPEAKER_DIRECTOUT: defchnum = 6; break;
05985 case DSSPEAKER_HEADPHONE: defchnum = 2; break;
05986 case DSSPEAKER_MONO: defchnum = 1; break;
05987 case DSSPEAKER_QUAD: defchnum = 4; break;
05988 default:
05989 case DSSPEAKER_STEREO: defchnum = 2; break;
05990 case DSSPEAKER_SURROUND: defchnum = 2; break;
05991 case DSSPEAKER_5POINT1: defchnum = 5; break;
05992 case DSSPEAKER_7POINT1: defchnum = 5; break;
05993 }
05994 }
05995 }
05996 }
05997 else
05998 {
05999 defchnum = 2;
06000 }
06001
06002 CRegKey iviaud;
06003 if(ERROR_SUCCESS == iviaud.Create(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\InterVideo\\Common\\AudioDec")))
06004 {
06005 DWORD chnum = 0;
06006 if(FAILED(iviaud.QueryDWORDValue(_T("AUDIO"), chnum))) chnum = 0;
06007 if(chnum <= defchnum)
06008 iviaud.SetDWORDValue(_T("AUDIO"), defchnum);
06009 }
06010 }
06011
06012
06013
06014
06015
06016 void CMainFrame::OpenCreateGraphObject(OpenMediaData* pOMD)
06017 {
06018 pGB = NULL;
06019
06020 m_fCustomGraph = false;
06021 m_fRealMediaGraph = m_fShockwaveGraph = m_fQuicktimeGraph = false;
06022
06023 if(OpenFileData* p = dynamic_cast<OpenFileData*>(pOMD))
06024 {
06025 AppSettings& s = AfxGetAppSettings();
06026
06027 engine_t engine = s.Formats.GetEngine(p->fns.GetHead());
06028
06029 CStringA ct = GetContentType(p->fns.GetHead());
06030
06031 if(ct == "video/x-ms-asf")
06032 {
06033
06034 }
06035 else if(ct == "audio/x-pn-realaudio"
06036 || ct == "audio/x-pn-realaudio-plugin"
06037 || ct == "audio/x-realaudio-secure"
06038 || ct == "video/vnd.rn-realvideo-secure"
06039 || ct == "application/vnd.rn-realmedia"
06040 || ct.Find("vnd.rn-") >= 0
06041 || ct.Find("realaudio") >= 0
06042 || ct.Find("realvideo") >= 0)
06043 {
06044 engine = RealMedia;
06045 }
06046 else if(ct == "application/x-shockwave-flash")
06047 {
06048 engine = ShockWave;
06049 }
06050 else if(ct == "video/quicktime"
06051 || ct == "application/x-quicktimeplayer")
06052 {
06053 engine = QuickTime;
06054 }
06055
06056 HRESULT hr;
06057 CComPtr<IUnknown> pUnk;
06058
06059 if(engine == RealMedia)
06060 {
06061 if(!(pUnk = (IUnknown*)(INonDelegatingUnknown*)new CRealMediaGraph(m_wndView.m_hWnd, hr)))
06062 throw _T("Out of memory");
06063
06064 m_pCAP = CComQIPtr<ISubPicAllocatorPresenter>(pUnk);
06065
06066
06067
06068 if(SUCCEEDED(hr) && !!(pGB = CComQIPtr<IGraphBuilder>(pUnk)))
06069 m_fRealMediaGraph = true;
06070 }
06071 else if(engine == ShockWave)
06072 {
06073 if(!(pUnk = (IUnknown*)(INonDelegatingUnknown*)new CShockwaveGraph(m_wndView.m_hWnd, hr)))
06074 throw _T("Out of memory");
06075
06076 if(FAILED(hr) || !(pGB = CComQIPtr<IGraphBuilder>(pUnk)))
06077 throw _T("Can't create shockwave control");
06078
06079 m_fShockwaveGraph = true;
06080 }
06081 else if(engine == QuickTime)
06082 {
06083 if(!(pUnk = (IUnknown*)(INonDelegatingUnknown*)new CQuicktimeGraph(m_wndView.m_hWnd, hr)))
06084 throw _T("Out of memory");
06085
06086 m_pCAP = CComQIPtr<ISubPicAllocatorPresenter>(pUnk);
06087
06088
06089
06090 if(SUCCEEDED(hr) && !!(pGB = CComQIPtr<IGraphBuilder>(pUnk)))
06091 m_fQuicktimeGraph = true;
06092 }
06093
06094 m_fCustomGraph = m_fRealMediaGraph || m_fShockwaveGraph || m_fQuicktimeGraph;
06095 }
06096
06097 if(!m_fCustomGraph)
06098 {
06099 if(FAILED(pGB.CoCreateInstance(CLSID_FilterGraph)))
06100 {
06101 throw _T("Failed to create the filter graph object");
06102 }
06103 }
06104
06105 pMC = pGB; pME = pGB; pMS = pGB;
06106 pVW = pGB; pBV = pGB;
06107 pBA = pGB;
06108 pFS = pGB;
06109
06110 if(!(pMC && pME && pMS)
06111 || !(pVW && pBV)
06112 || !(pBA))
06113 {
06114 throw _T("Failed to query the needed interfaces for playback");
06115 }
06116
06117 if(FAILED(pME->SetNotifyWindow((OAHWND)m_hWnd, WM_GRAPHNOTIFY, 0)))
06118 {
06119 throw _T("Could not set target window for graph notification");
06120 }
06121
06122 m_pProv = (IUnknown*)new CKeyProvider();
06123
06124 if(CComQIPtr<IObjectWithSite> pObjectWithSite = pGB)
06125 pObjectWithSite->SetSite(m_pProv);
06126
06127 m_pCB = new CDSMChapterBag(NULL, NULL);
06128 }
06129
06130 void CMainFrame::OpenFile(OpenFileData* pOFD)
06131 {
06132 if(pOFD->fns.IsEmpty())
06133 throw _T("Invalid argument");
06134
06135 AppSettings& s = AfxGetAppSettings();
06136
06137 CGraphBuilderFile gb(pGB, m_wndView.m_hWnd);
06138
06139 bool fFirst = true;
06140
06141 POSITION pos = pOFD->fns.GetHeadPosition();
06142 while(pos)
06143 {
06144 CString fn = pOFD->fns.GetNext(pos);
06145
06146 fn.Trim();
06147 if(fn.IsEmpty() && !fFirst)
06148 break;
06149
06150 HRESULT hr = gb.Render(fn);
06151
06152 if(FAILED(hr))
06153 {
06154 if(fFirst)
06155 {
06156 if(s.fReportFailedPins && gb.GetDeadEnd(0))
06157 {
06158 CMediaTypesDlg(gb, this).DoModal();
06159
06160 if(gb.GetStreamCount() == 0)
06161 throw _T("Cannot render any of the streams");
06162 }
06163
06164 CString err;
06165
06166 switch(hr)
06167 {
06168 case E_ABORT: err = _T("Opening aborted"); break;
06169 case E_FAIL: case E_POINTER: default: err = _T("Failed to render the file"); break;
06170 case E_INVALIDARG: err = _T("Invalid file name"); break;
06171 case E_OUTOFMEMORY: err = _T("Out of memory"); break;
06172 case VFW_E_CANNOT_CONNECT: err = _T("Cannot connect the filters"); break;
06173 case VFW_E_CANNOT_LOAD_SOURCE_FILTER: err = _T("Cannot load any source filter"); break;
06174 case VFW_E_CANNOT_RENDER: err = _T("Cannot render the file"); break;
06175 case VFW_E_INVALID_FILE_FORMAT: err = _T("Invalid file format"); break;
06176 case VFW_E_NOT_FOUND: err = _T("File not found"); break;
06177 case VFW_E_UNKNOWN_FILE_TYPE: err = _T("Unknown file type"); break;
06178 case VFW_E_UNSUPPORTED_STREAM: err = _T("Unsupported stream"); break;
06179 }
06180
06181 throw err;
06182 }
06183 }
06184
06185 if(s.fKeepHistory)
06186 {
06187 CRecentFileList* pMRU = fFirst ? &s.MRU : &s.MRUDub;
06188 pMRU->ReadList();
06189 pMRU->Add(fn);
06190 pMRU->WriteList();
06191 }
06192
06193 if(fFirst)
06194 {
06195 pOFD->title = fn;
06196 }
06197
06198 fFirst = false;
06199
06200 if(m_fCustomGraph) break;
06201 }
06202
06203 if(s.fReportFailedPins && gb.GetDeadEnd(0))
06204 CMediaTypesDlg(gb, this).DoModal();
06205
06206 if(!m_fCustomGraph)
06207 gb.FindInterface(__uuidof(ISubPicAllocatorPresenter), (void**)&m_pCAP);
06208
06209 if(!(pAMOP = pGB))
06210 {
06211 BeginEnumFilters(pGB, pEF, pBF)
06212 if(pAMOP = pBF) break;
06213 EndEnumFilters
06214 }
06215
06216 if(FindFilter(__uuidof(CShoutcastSource), pGB))
06217 m_fUpdateInfoBar = true;
06218
06219 SetupChapters();
06220
06221 CComQIPtr<IKeyFrameInfo> pKFI;
06222 BeginEnumFilters(pGB, pEF, pBF)
06223 if(pKFI = pBF) break;
06224 EndEnumFilters
06225 UINT nKFs = 0, nKFsTmp = 0;
06226 if(pKFI && S_OK == pKFI->GetKeyFrameCount(nKFs) && nKFs > 0)
06227 {
06228 m_kfs.SetSize(nKFsTmp = nKFs);
06229 if(S_OK != pKFI->GetKeyFrames(&TIME_FORMAT_MEDIA_TIME, m_kfs.GetData(), nKFsTmp) || nKFsTmp != nKFs)
06230 m_kfs.SetSize(0);
06231 }
06232
06233 m_iPlaybackMode = PM_FILE;
06234 }
06235
06236 void CMainFrame::SetupChapters()
06237 {
06238 ASSERT(m_pCB);
06239
06240 m_pCB->ChapRemoveAll();
06241
06242 CInterfaceList<IBaseFilter> pBFs;
06243 BeginEnumFilters(pGB, pEF, pBF)
06244 pBFs.AddTail(pBF);
06245 EndEnumFilters
06246
06247 POSITION pos;
06248
06249 pos = pBFs.GetHeadPosition();
06250 while(pos && !m_pCB->ChapGetCount())
06251 {
06252 IBaseFilter* pBF = pBFs.GetNext(pos);
06253
06254 CComQIPtr<IDSMChapterBag> pCB = pBF;
06255 if(!pCB) continue;
06256
06257 for(DWORD i = 0, cnt = pCB->ChapGetCount(); i < cnt; i++)
06258 {
06259 REFERENCE_TIME rt;
06260 CComBSTR name;
06261 if(SUCCEEDED(pCB->ChapGet(i, &rt, &name)))
06262 m_pCB->ChapAppend(rt, name);
06263 }
06264 }
06265
06266 pos = pBFs.GetHeadPosition();
06267 while(pos && !m_pCB->ChapGetCount())
06268 {
06269 IBaseFilter* pBF = pBFs.GetNext(pos);
06270
06271 CComQIPtr<IChapterInfo> pCI = pBF;
06272 if(!pCI) continue;
06273
06274 CHAR iso6391[3];
06275 ::GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME, iso6391, 3);
06276 CStringA iso6392 = ISO6391To6392(iso6391);
06277 if(iso6392.GetLength() < 3) iso6392 = "eng";
06278
06279 UINT cnt = pCI->GetChapterCount(CHAPTER_ROOT_ID);
06280 for(UINT i = 1; i <= cnt; i++)
06281 {
06282 UINT cid = pCI->GetChapterId(CHAPTER_ROOT_ID, i);
06283
06284 ChapterElement ce;
06285 if(pCI->GetChapterInfo(cid, &ce))
06286 {
06287 char pl[3] = {iso6392[0], iso6392[1], iso6392[2]};
06288 char cc[] = " ";
06289 CComBSTR name;
06290 name.Attach(pCI->GetChapterStringInfo(cid, pl, cc));
06291 m_pCB->ChapAppend(ce.rtStart, name);
06292 }
06293 }
06294 }
06295
06296 pos = pBFs.GetHeadPosition();
06297 while(pos && !m_pCB->ChapGetCount())
06298 {
06299 IBaseFilter* pBF = pBFs.GetNext(pos);
06300
06301 CComQIPtr<IAMExtendedSeeking, &IID_IAMExtendedSeeking> pES = pBF;
06302 if(!pES) continue;
06303
06304 long MarkerCount = 0;
06305 if(SUCCEEDED(pES->get_MarkerCount(&MarkerCount)))
06306 {
06307 for(long i = 1; i <= MarkerCount; i++)
06308 {
06309 double MarkerTime = 0;
06310 if(SUCCEEDED(pES->GetMarkerTime(i, &MarkerTime)))
06311 {
06312 CStringW name;
06313 name.Format(L"Chapter %d", i);
06314
06315 CComBSTR bstr;
06316 if(S_OK == pES->GetMarkerName(i, &bstr))
06317 name = bstr;
06318
06319 m_pCB->ChapAppend(REFERENCE_TIME(MarkerTime*10000000), name);
06320 }
06321 }
06322 }
06323 }
06324
06325 pos = pBFs.GetHeadPosition();
06326 while(pos && !m_pCB->ChapGetCount())
06327 {
06328 IBaseFilter* pBF = pBFs.GetNext(pos);
06329
06330 if(GetCLSID(pBF) != CLSID_OggSplitter)
06331 continue;
06332
06333 BeginEnumPins(pBF, pEP, pPin)
06334 {
06335 if(m_pCB->ChapGetCount()) break;
06336
06337 if(CComQIPtr<IPropertyBag> pPB = pPin)
06338 {
06339 for(int i = 1; ; i++)
06340 {
06341 CStringW str;
06342 CComVariant var;
06343
06344 var.Clear();
06345 str.Format(L"CHAPTER%02d", i);
06346 if(S_OK != pPB->Read(str, &var, NULL))
06347 break;
06348
06349 int h, m, s, ms;
06350 WCHAR wc;
06351 if(7 != swscanf(CStringW(var), L"%d%c%d%c%d%c%d", &h, &wc, &m, &wc, &s, &wc, &ms))
06352 break;
06353
06354 CStringW name;
06355 name.Format(L"Chapter %d", i);
06356 var.Clear();
06357 str += L"NAME";
06358 if(S_OK == pPB->Read(str, &var, NULL))
06359 name = var;
06360
06361 m_pCB->ChapAppend(10000i64*(((h*60 + m)*60 + s)*1000 + ms), name);
06362 }
06363 }
06364 }
06365 EndEnumPins
06366 }
06367
06368 m_pCB->ChapSort();
06369 }
06370
06371 void CMainFrame::OpenDVD(OpenDVDData* pODD)
06372 {
06373 CGraphBuilderDVD gb(pGB, m_wndView.m_hWnd);
06374
06375 HRESULT hr = gb.Render(pODD->path, pODD->title);
06376
06377 AppSettings& s = AfxGetAppSettings();
06378
06379 if(hr == VFW_E_CANNOT_LOAD_SOURCE_FILTER)
06380 throw _T("Can't find DVD directory");
06381 else if(hr == VFW_E_CANNOT_RENDER)
06382 throw _T("Failed to render all pins of the DVD Navigator filter");
06383 else if(hr == VFW_S_PARTIAL_RENDER)
06384 {
06385 if(s.fReportFailedPins && gb.GetDeadEnd(0))
06386 CMediaTypesDlg(gb, this).DoModal();
06387
06388 throw _T("Failed to render some of the pins of the DVD Navigator filter");
06389 }
06390 else if(hr == E_NOINTERFACE)
06391 throw _T("Failed to query the needed interfaces for DVD playback");
06392 else if(FAILED(hr))
06393 throw _T("Can't create the DVD Navigator filter");
06394
06395 gb.FindInterface(__uuidof(ISubPicAllocatorPresenter), (void**)&m_pCAP);
06396 gb.FindInterface(__uuidof(IDvdControl2), (void**)&pDVDC);
06397 gb.FindInterface(__uuidof(IDvdInfo2), (void**)&pDVDI);
06398
06399 if(!pDVDC || !pDVDI)
06400 throw _T("Failed to query the needed interfaces for DVD playback");
06401
06402 if(s.idMenuLang)
06403 pDVDC->SelectDefaultMenuLanguage(s.idMenuLang);
06404 if(s.idAudioLang)
06405 pDVDC->SelectDefaultAudioLanguage(s.idAudioLang, DVD_AUD_EXT_NotSpecified);
06406 if(s.idSubtitlesLang)
06407 pDVDC->SelectDefaultSubpictureLanguage(s.idSubtitlesLang, DVD_SP_EXT_NotSpecified);
06408
06409 m_iDVDDomain = DVD_DOMAIN_Stop;
06410
06411 m_iPlaybackMode = PM_DVD;
06412 }
06413
06414 void CMainFrame::OpenCapture(OpenDeviceData* pODD)
06415 {
06416 CStringW vidfrname, audfrname;
06417 CComPtr<IBaseFilter> pVidCapTmp, pAudCapTmp;
06418
06419 m_VidDispName = pODD->DisplayName[0];
06420
06421 if(!m_VidDispName.IsEmpty())
06422 {
06423 if(!CreateFilter(m_VidDispName, &pVidCapTmp, vidfrname))
06424 throw _T("Can't create video capture filter");
06425 }
06426
06427 m_AudDispName = pODD->DisplayName[1];
06428
06429 if(!m_AudDispName.IsEmpty())
06430 {
06431 if(!CreateFilter(m_AudDispName, &pAudCapTmp, audfrname))
06432 throw _T("Can't create video capture filter");
06433 }
06434
06435 if(!pVidCapTmp && !pAudCapTmp)
06436 {
06437 throw _T("No capture filters");
06438 }
06439
06440 pCGB = NULL;
06441 pVidCap = NULL;
06442 pAudCap = NULL;
06443
06444 if(FAILED(pCGB.CoCreateInstance(CLSID_CaptureGraphBuilder2)))
06445 {
06446 throw _T("Can't create capture graph builder object");
06447 }
06448
06449 HRESULT hr;
06450
06451 pCGB->SetFiltergraph(pGB);
06452
06453 if(pVidCapTmp)
06454 {
06455 if(FAILED(hr = pGB->AddFilter(pVidCapTmp, vidfrname)))
06456 {
06457 throw _T("Can't add video capture filter to the graph");
06458 }
06459
06460 pVidCap = pVidCapTmp;
06461
06462 if(!pAudCapTmp)
06463 {
06464 if(FAILED(pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Interleaved, pVidCap, IID_IAMStreamConfig, (void **)&pAMVSCCap))
06465 && FAILED(pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, pVidCap, IID_IAMStreamConfig, (void **)&pAMVSCCap)))
06466 TRACE(_T("Warning: No IAMStreamConfig interface for vidcap capture"));
06467
06468 if(FAILED(pCGB->FindInterface(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Interleaved, pVidCap, IID_IAMStreamConfig, (void **)&pAMVSCPrev))
06469 && FAILED(pCGB->FindInterface(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, pVidCap, IID_IAMStreamConfig, (void **)&pAMVSCPrev)))
06470 TRACE(_T("Warning: No IAMStreamConfig interface for vidcap capture"));
06471
06472 if(FAILED(pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Audio, pVidCap, IID_IAMStreamConfig, (void **)&pAMASC))
06473 && FAILED(pCGB->FindInterface(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Audio, pVidCap, IID_IAMStreamConfig, (void **)&pAMASC)))
06474 {
06475 TRACE(_T("Warning: No IAMStreamConfig interface for vidcap"));
06476 }
06477 else
06478 {
06479 pAudCap = pVidCap;
06480 }
06481 }
06482 else
06483 {
06484 if(FAILED(pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, pVidCap, IID_IAMStreamConfig, (void **)&pAMVSCCap)))
06485 TRACE(_T("Warning: No IAMStreamConfig interface for vidcap capture"));
06486
06487 if(FAILED(pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, pVidCap, IID_IAMStreamConfig, (void **)&pAMVSCPrev)))
06488 TRACE(_T("Warning: No IAMStreamConfig interface for vidcap capture"));
06489 }
06490
06491 if(FAILED(pCGB->FindInterface(&LOOK_UPSTREAM_ONLY, NULL, pVidCap, IID_IAMCrossbar, (void**)&pAMXBar)))
06492 TRACE(_T("Warning: No IAMCrossbar interface was found\n"));
06493
06494 if(FAILED(pCGB->FindInterface(&LOOK_UPSTREAM_ONLY, NULL, pVidCap, IID_IAMTVTuner, (void**)&pAMTuner)))
06495 TRACE(_T("Warning: No IAMTVTuner interface was found\n"));
06496
06497
06498
06499
06500
06501
06502
06503
06504
06505
06506
06507
06508
06509
06510
06511
06512
06513 if(pAMTuner)
06514 {
06515 pAMTuner->put_CountryCode(AfxGetApp()->GetProfileInt(_T("Capture"), _T("Country"), 1));
06516
06517 int vchannel = pODD->vchannel;
06518 if(vchannel < 0) vchannel = AfxGetApp()->GetProfileInt(_T("Capture\\") + CString(m_VidDispName), _T("Channel"), -1);
06519 if(vchannel >= 0)
06520 {
06521 OAFilterState fs = State_Stopped;
06522 pMC->GetState(0, &fs);
06523 if(fs == State_Running) pMC->Pause();
06524 pAMTuner->put_Channel(vchannel, AMTUNER_SUBCHAN_DEFAULT, AMTUNER_SUBCHAN_DEFAULT);
06525 if(fs == State_Running) pMC->Run();
06526 }
06527 }
06528 }
06529
06530 if(pAudCapTmp)
06531 {
06532 if(FAILED(hr = pGB->AddFilter(pAudCapTmp, CStringW(audfrname))))
06533 {
06534 throw _T("Can't add audio capture filter to the graph");
06535 }
06536
06537 pAudCap = pAudCapTmp;
06538
06539 if(FAILED(pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Audio, pAudCap, IID_IAMStreamConfig, (void **)&pAMASC))
06540 && FAILED(pCGB->FindInterface(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Audio, pAudCap, IID_IAMStreamConfig, (void **)&pAMASC)))
06541 {
06542 TRACE(_T("Warning: No IAMStreamConfig interface for vidcap"));
06543 }
06544
06545
06546
06547
06548
06549
06550
06551
06552
06553
06554
06555
06556
06557
06558
06559
06560
06561
06562
06563 }
06564
06565 if(!(pVidCap || pAudCap))
06566 {
06567 throw _T("Couldn't open any device");
06568 }
06569
06570 pODD->title = _T("Live");
06571
06572 m_iPlaybackMode = PM_CAPTURE;
06573 }
06574
06575 void CMainFrame::OpenCustomizeGraph()
06576 {
06577 if(m_iPlaybackMode == PM_CAPTURE)
06578 return;
06579
06580 CleanGraph();
06581
06582 if(m_iPlaybackMode == PM_FILE)
06583 {
06584 if(m_pCAP)
06585 AddTextPassThruFilter();
06586 }
06587
06588 if(m_iPlaybackMode == PM_DVD)
06589 {
06590 BeginEnumFilters(pGB, pEF, pBF)
06591 {
06592 if(CComQIPtr<IDirectVobSub2> pDVS2 = pBF)
06593 {
06594
06595
06596
06597
06598 if(!m_pSubClock) m_pSubClock = new CSubClock;
06599 pDVS2->AdviseSubClock(m_pSubClock);
06600 }
06601 }
06602 EndEnumFilters
06603 }
06604
06605 BeginEnumFilters(pGB, pEF, pBF)
06606 {
06607 if(GetCLSID(pBF) == CLSID_OggSplitter)
06608 {
06609 if(CComQIPtr<IAMStreamSelect> pSS = pBF)
06610 {
06611 LCID idAudio = AfxGetAppSettings().idAudioLang;
06612 if(!idAudio) idAudio = GetUserDefaultLCID();
06613 LCID idSub = AfxGetAppSettings().idSubtitlesLang;
06614 if(!idSub) idSub = GetUserDefaultLCID();
06615
06616 DWORD cnt = 0;
06617 pSS->Count(&cnt);
06618 for(DWORD i = 0; i < cnt; i++)
06619 {
06620 AM_MEDIA_TYPE* pmt = NULL;
06621 DWORD dwFlags = 0;
06622 LCID lcid = 0;
06623 DWORD dwGroup = 0;
06624 WCHAR* pszName = NULL;
06625 if(SUCCEEDED(pSS->Info((long)i, &pmt, &dwFlags, &lcid, &dwGroup, &pszName, NULL, NULL)))
06626 {
06627 CStringW name(pszName), sound(L"Sound"), subtitle(L"Subtitle");
06628
06629 if(idAudio != -1 && (idAudio&0x3ff) == (lcid&0x3ff)
06630 && name.GetLength() > sound.GetLength()
06631 && !name.Left(sound.GetLength()).CompareNoCase(sound))
06632 {
06633 if(SUCCEEDED(pSS->Enable(i, AMSTREAMSELECTENABLE_ENABLE)))
06634 idAudio = -1;
06635 }
06636
06637 if(idSub != -1 && (idSub&0x3ff) == (lcid&0x3ff)
06638 && name.GetLength() > subtitle.GetLength()
06639 && !name.Left(subtitle.GetLength()).CompareNoCase(subtitle)
06640 && name.Mid(subtitle.GetLength()).Trim().CompareNoCase(L"off"))
06641 {
06642 if(SUCCEEDED(pSS->Enable(i, AMSTREAMSELECTENABLE_ENABLE)))
06643 idSub = -1;
06644 }
06645
06646 if(pmt) DeleteMediaType(pmt);
06647 if(pszName) CoTaskMemFree(pszName);
06648 }
06649 }
06650 }
06651 }
06652 }
06653 EndEnumFilters
06654
06655 CleanGraph();
06656 }
06657
06658 void CMainFrame::OpenSetupVideo()
06659 {
06660 m_fAudioOnly = true;
06661
06662 if(m_pCAP)
06663 {
06664 CSize vs = m_pCAP->GetVideoSize();
06665 m_fAudioOnly = (vs.cx <= 0 || vs.cy <= 0);
06666 }
06667 else
06668 {
06669 {
06670 long w = 0, h = 0;
06671
06672 if(CComQIPtr<IBasicVideo> pBV = pGB)
06673 {
06674 pBV->GetVideoSize(&w, &h);
06675 }
06676
06677 if(w > 0 && h > 0)
06678 {
06679 m_fAudioOnly = false;
06680 }
06681 }
06682
06683 if(m_fAudioOnly)
06684 {
06685 BeginEnumFilters(pGB, pEF, pBF)
06686 {
06687 long w = 0, h = 0;
06688
06689 if(CComQIPtr<IVideoWindow> pVW = pBF)
06690 {
06691 long lVisible;
06692 if(FAILED(pVW->get_Visible(&lVisible)))
06693 continue;
06694
06695 pVW->get_Width(&w);
06696 pVW->get_Height(&h);
06697 }
06698
06699 if(w > 0 && h > 0)
06700 {
06701 m_fAudioOnly = false;
06702 break;
06703 }
06704 }
06705 EndEnumFilters
06706 }
06707 }
06708
06709 if(m_fShockwaveGraph)
06710 {
06711 m_fAudioOnly = false;
06712 }
06713
06714 if(!m_pCAP)
06715 {
06716 pVW->put_Owner((OAHWND)m_wndView.m_hWnd);
06717 pVW->put_WindowStyle(WS_CHILD|WS_CLIPSIBLINGS|WS_CLIPCHILDREN);
06718 pVW->put_MessageDrain((OAHWND)m_hWnd);
06719
06720 for(CWnd* pWnd = m_wndView.GetWindow(GW_CHILD); pWnd; pWnd = pWnd->GetNextWindow())
06721 pWnd->EnableWindow(FALSE);
06722 }
06723 else
06724 {
06725 return;
06726
06727
06728
06729
06730
06731
06732
06733
06734
06735
06736
06737
06738
06739
06740
06741
06742
06743
06744
06745
06746
06747
06748
06749
06750
06751
06752
06753 }
06754 }
06755
06756 void CMainFrame::OpenSetupAudio()
06757 {
06758 pBA->put_Volume(m_wndToolBar.Volume);
06759
06760
06761 int balance = AfxGetAppSettings().nBalance;
06762 int sign = balance>0?-1:1;
06763 balance = max(100-abs(balance), 1);
06764 balance = (int)((log10(1.0*balance)-2)*5000*sign);
06765 balance = max(min(balance, 10000), -10000);
06766 pBA->put_Balance(balance);
06767 }
06768
06769
06770
06771
06772
06773
06774
06775 void CMainFrame::OpenSetupCaptureBar()
06776 {
06777 if(m_iPlaybackMode == PM_CAPTURE)
06778 {
06779 if(pVidCap && pAMVSCCap)
06780 {
06781 CComQIPtr<IAMVfwCaptureDialogs> pVfwCD = pVidCap;
06782
06783 if(!pAMXBar && pVfwCD)
06784 {
06785 m_wndCaptureBar.m_capdlg.SetupVideoControls(m_VidDispName, pAMVSCCap, pVfwCD);
06786 }
06787 else
06788 {
06789 m_wndCaptureBar.m_capdlg.SetupVideoControls(m_VidDispName, pAMVSCCap, pAMXBar, pAMTuner);
06790 }
06791 }
06792
06793 if(pAudCap && pAMASC)
06794 {
06795 CInterfaceArray<IAMAudioInputMixer> pAMAIM;
06796
06797 BeginEnumPins(pAudCap, pEP, pPin)
06798 {
06799 PIN_DIRECTION dir;
06800 if(FAILED(pPin->QueryDirection(&dir)) || dir != PINDIR_INPUT)
06801 continue;
06802
06803 if(CComQIPtr<IAMAudioInputMixer> pAIM = pPin)
06804 pAMAIM.Add(pAIM);
06805 }
06806 EndEnumPins
06807
06808 m_wndCaptureBar.m_capdlg.SetupAudioControls(m_AudDispName, pAMASC, pAMAIM);
06809 }
06810 }
06811
06812 BuildGraphVideoAudio(
06813 !!m_wndCaptureBar.m_capdlg.m_fVidPreview, false,
06814 !!m_wndCaptureBar.m_capdlg.m_fAudPreview, false);
06815 }
06816
06817 void CMainFrame::OpenSetupInfoBar()
06818 {
06819 if(m_iPlaybackMode == PM_FILE)
06820 {
06821 bool fEmpty = true;
06822 BeginEnumFilters(pGB, pEF, pBF)
06823 {
06824 if(CComQIPtr<IAMMediaContent, &IID_IAMMediaContent> pAMMC = pBF)
06825 {
06826 CComBSTR bstr;
06827 if(SUCCEEDED(pAMMC->get_Title(&bstr))) {m_wndInfoBar.SetLine(_T("Title"), bstr.m_str); if(bstr.Length()) fEmpty = false;}
06828 if(SUCCEEDED(pAMMC->get_AuthorName(&bstr))) {m_wndInfoBar.SetLine(_T("Author"), bstr.m_str); if(bstr.Length()) fEmpty = false;}
06829 if(SUCCEEDED(pAMMC->get_Copyright(&bstr))) {m_wndInfoBar.SetLine(_T("Copyright"), bstr.m_str); if(bstr.Length()) fEmpty = false;}
06830 if(SUCCEEDED(pAMMC->get_Rating(&bstr))) {m_wndInfoBar.SetLine(_T("Rating"), bstr.m_str); if(bstr.Length()) fEmpty = false;}
06831 if(SUCCEEDED(pAMMC->get_Description(&bstr))) {m_wndInfoBar.SetLine(_T("Description"), bstr.m_str); if(bstr.Length()) fEmpty = false;}
06832 if(!fEmpty)
06833 {
06834 RecalcLayout();
06835 break;
06836 }
06837 }
06838 }
06839 EndEnumFilters
06840 }
06841 else if(m_iPlaybackMode == PM_DVD)
06842 {
06843 CString info('-');
06844 m_wndInfoBar.SetLine(_T("Domain"), info);
06845 m_wndInfoBar.SetLine(_T("Location"), info);
06846 m_wndInfoBar.SetLine(_T("Video"), info);
06847 m_wndInfoBar.SetLine(_T("Audio"), info);
06848 m_wndInfoBar.SetLine(_T("Subtitles"), info);
06849 RecalcLayout();
06850 }
06851 }
06852
06853 void CMainFrame::OpenSetupStatsBar()
06854 {
06855 CString info('-');
06856
06857 BeginEnumFilters(pGB, pEF, pBF)
06858 {
06859 if(!pQP && (pQP = pBF))
06860 {
06861 m_wndStatsBar.SetLine(_T("Frame-rate"), info);
06862 m_wndStatsBar.SetLine(_T("Sync Offset"), info);
06863 m_wndStatsBar.SetLine(_T("Frames"), info);
06864 m_wndStatsBar.SetLine(_T("Jitter"), info);
06865 m_wndStatsBar.SetLine(_T("Buffers"), info);
06866 m_wndStatsBar.SetLine(_T("Bitrate"), info);
06867 RecalcLayout();
06868 }
06869
06870 if(!pBI && (pBI = pBF))
06871 {
06872 m_wndStatsBar.SetLine(_T("Buffers"), info);
06873 m_wndStatsBar.SetLine(_T("Bitrate"), info);
06874 RecalcLayout();
06875 }
06876 }
06877 EndEnumFilters
06878 }
06879
06880 void CMainFrame::OpenSetupStatusBar()
06881 {
06882 m_wndStatusBar.ShowTimer(true);
06883
06884
06885
06886 if(!m_fCustomGraph)
06887 {
06888 UINT id = IDB_NOAUDIO;
06889
06890 BeginEnumFilters(pGB, pEF, pBF)
06891 {
06892 CComQIPtr<IBasicAudio> pBA = pBF;
06893 if(!pBA) continue;
06894
06895 BeginEnumPins(pBF, pEP, pPin)
06896 {
06897 PIN_DIRECTION dir;
06898 CComPtr<IPin> pPinTo;
06899 if(S_OK == pPin->QueryDirection(&dir) && dir == PINDIR_INPUT
06900 && S_OK == pPin->ConnectedTo(&pPinTo) && pPinTo)
06901 {
06902 AM_MEDIA_TYPE mt;
06903 memset(&mt, 0, sizeof(mt));
06904 pPin->ConnectionMediaType(&mt);
06905
06906 if(mt.majortype == MEDIATYPE_Audio
06907 && mt.formattype == FORMAT_WaveFormatEx)
06908 {
06909 switch(((WAVEFORMATEX*)mt.pbFormat)->nChannels)
06910 {
06911 case 1: id = IDB_MONO; break;
06912 case 2: default: id = IDB_STEREO; break;
06913 }
06914 break;
06915 }
06916 else if(mt.majortype == MEDIATYPE_Midi)
06917 {
06918 id = NULL;
06919 break;
06920 }
06921 }
06922 }
06923 EndEnumPins
06924
06925 if(id != IDB_NOAUDIO)
06926 {
06927 break;
06928 }
06929 }
06930 EndEnumFilters
06931
06932 m_wndStatusBar.SetStatusBitmap(id);
06933 }
06934
06935
06936
06937 HICON hIcon = NULL;
06938
06939 if(m_iPlaybackMode == PM_FILE)
06940 {
06941 CString fn = m_wndPlaylistBar.GetCur();
06942 CString ext = fn.Mid(fn.ReverseFind('.')+1);
06943 hIcon = LoadIcon(ext, true);
06944 }
06945 else if(m_iPlaybackMode == PM_DVD)
06946 {
06947 hIcon = LoadIcon(_T(".ifo"), true);
06948 }
06949 else if(m_iPlaybackMode == PM_DVD)
06950 {
06951
06952 }
06953
06954 m_wndStatusBar.SetStatusTypeIcon(hIcon);
06955 }
06956
06957 void CMainFrame::OpenSetupWindowTitle(CString fn)
06958 {
06959 CString title(MAKEINTRESOURCE(IDR_MAINFRAME));
06960
06961 int i = AfxGetAppSettings().iTitleBarTextStyle;
06962
06963 if(!fn.IsEmpty() && (i == 0 || i == 1))
06964 {
06965 if(i == 1)
06966 {
06967 if(m_iPlaybackMode == PM_FILE)
06968 {
06969 fn.Replace('\\', '/');
06970 CString fn2 = fn.Mid(fn.ReverseFind('/')+1);
06971 if(!fn2.IsEmpty()) fn = fn2;
06972 }
06973 else if(m_iPlaybackMode == PM_DVD)
06974 {
06975 fn = _T("DVD");
06976 }
06977 else if(m_iPlaybackMode == PM_CAPTURE)
06978 {
06979 fn = _T("Live");
06980 }
06981 }
06982
06983 title = fn + _T(" - ") + title;
06984 }
06985
06986 SetWindowText(title);
06987 }
06988
06989 bool CMainFrame::OpenMediaPrivate(CAutoPtr<OpenMediaData> pOMD)
06990 {
06991 if(m_iMediaLoadState != MLS_CLOSED)
06992 {
06993 ASSERT(0);
06994 return(false);
06995 }
06996
06997 if(!dynamic_cast<OpenFileData*>(pOMD.m_p)
06998 && !dynamic_cast<OpenDVDData*>(pOMD.m_p)
06999 && !dynamic_cast<OpenDeviceData*>(pOMD.m_p))
07000 {
07001 ASSERT(0);
07002 return(false);
07003 }
07004
07005 if(OpenFileData* pOFD = dynamic_cast<OpenFileData*>(pOMD.m_p))
07006 {
07007 if(pOFD->fns.IsEmpty())
07008 return(false);
07009
07010 CString fn = pOFD->fns.GetHead();
07011
07012 int i = fn.Find(_T(":\\"));
07013 if(i > 0)
07014 {
07015 CString drive = fn.Left(i+2);
07016 UINT type = GetDriveType(drive);
07017 CList<CString> sl;
07018 if(type == DRIVE_REMOVABLE || type == DRIVE_CDROM && GetCDROMType(drive[0], sl) != CDROM_Audio)
07019 {
07020 int ret = IDRETRY;
07021 while(ret == IDRETRY)
07022 {
07023 WIN32_FIND_DATA findFileData;
07024 HANDLE h = FindFirstFile(fn, &findFileData);
07025 if(h != INVALID_HANDLE_VALUE)
07026 {
07027 FindClose(h);
07028 ret = IDOK;
07029 }
07030 else
07031 {
07032 CString msg;
07033 msg.Format(_T("%s was not found, please insert media containing this file."), fn);
07034 ret = AfxMessageBox(msg, MB_RETRYCANCEL);
07035 }
07036 }
07037
07038 if(ret != IDOK)
07039 return(false);
07040 }
07041 }
07042 }
07043
07044 m_iMediaLoadState = MLS_LOADING;
07045
07046
07047 PostMessage(WM_KICKIDLE);
07048
07049 CString err, aborted(_T("Aborted"));
07050
07051 m_fUpdateInfoBar = false;
07052
07053 try
07054 {
07055 if(m_fOpeningAborted) throw aborted;
07056
07057 OpenCreateGraphObject(pOMD);
07058 AddToRot(pGB, &m_dwRegister);
07059
07060 if(m_fOpeningAborted) throw aborted;
07061
07062 SetupIViAudReg();
07063
07064 if(m_fOpeningAborted) throw aborted;
07065
07066 if(OpenFileData* p = dynamic_cast<OpenFileData*>(pOMD.m_p))
07067 {
07068 OpenFile(p);
07069 }
07070 else if(OpenDVDData* p = dynamic_cast<OpenDVDData*>(pOMD.m_p))
07071 {
07072 OpenDVD(p);
07073 }
07074 else if(OpenDeviceData* p = dynamic_cast<OpenDeviceData*>(pOMD.m_p))
07075 {
07076 OpenCapture(p);
07077 }
07078 else
07079 {
07080 throw _T("Can't open, invalid input parameters");
07081 }
07082
07083 if(m_fOpeningAborted) throw aborted;
07084
07085 OpenCustomizeGraph();
07086
07087 if(m_fOpeningAborted) throw aborted;
07088
07089 OpenSetupVideo();
07090
07091 if(m_fOpeningAborted) throw aborted;
07092
07093 OpenSetupAudio();
07094
07095 if(m_fOpeningAborted) throw aborted;
07096
07097 if(m_pCAP && (!m_fAudioOnly || m_fRealMediaGraph))
07098 {
07099 POSITION pos = pOMD->subs.GetHeadPosition();
07100 while(pos) LoadSubtitle(pOMD->subs.GetNext(pos));
07101
07102 if(m_pSubStreams.GetCount() > 0)
07103 SetSubtitle(m_pSubStreams.GetHead());
07104 }
07105
07106 if(m_fOpeningAborted) throw aborted;
07107
07108 OpenSetupWindowTitle(pOMD->title);
07109
07110 if(::GetCurrentThreadId() == AfxGetApp()->m_nThreadID)
07111 {
07112 OnFilePostOpenmedia();
07113 }
07114 else
07115 {
07116 PostMessage(WM_COMMAND, ID_FILE_POST_OPENMEDIA);
07117 }
07118
07119 while(m_iMediaLoadState != MLS_LOADED
07120 && m_iMediaLoadState != MLS_CLOSING
07121 )
07122 {
07123 Sleep(50);
07124 }
07125
07126
07127
07128 PostMessage(WM_COMMAND, ID_PLAY_PAUSE);
07129
07130 if(!(AfxGetAppSettings().nCLSwitches&CLSW_OPEN))
07131 PostMessage(WM_COMMAND, ID_PLAY_PLAY);
07132
07133 AfxGetAppSettings().nCLSwitches &= ~CLSW_OPEN;
07134
07135 if(OpenFileData* p = dynamic_cast<OpenFileData*>(pOMD.m_p))
07136 {
07137 if(p->rtStart > 0)
07138 PostMessage(WM_RESUMEFROMSTATE, (WPARAM)PM_FILE, (LPARAM)(p->rtStart/10000));
07139 }
07140 else if(OpenDVDData* p = dynamic_cast<OpenDVDData*>(pOMD.m_p))
07141 {
07142 if(p->pDvdState)
07143 PostMessage(WM_RESUMEFROMSTATE, (WPARAM)PM_DVD, (LPARAM)(CComPtr<IDvdState>(p->pDvdState).Detach()));
07144 }
07145 else if(OpenDeviceData* p = dynamic_cast<OpenDeviceData*>(pOMD.m_p))
07146 {
07147 m_wndCaptureBar.m_capdlg.SetVideoInput(p->vinput);
07148 m_wndCaptureBar.m_capdlg.SetVideoChannel(p->vchannel);
07149 m_wndCaptureBar.m_capdlg.SetAudioInput(p->ainput);
07150 }
07151 }
07152 catch(LPCTSTR msg)
07153 {
07154 err = msg;
07155 }
07156 catch(CString msg)
07157 {
07158 err = msg;
07159 }
07160
07161 if(!err.IsEmpty())
07162 {
07163 CloseMediaPrivate();
07164 m_closingmsg = err;
07165
07166 OpenFileData* p = dynamic_cast<OpenFileData*>(pOMD.m_p);
07167 if(p && err != aborted)
07168 {
07169 m_wndPlaylistBar.SetCurValid(false);
07170 if(m_wndPlaylistBar.GetCount() > 1)
07171 {
07172 CPlaylistItem pli[2];
07173 m_wndPlaylistBar.GetCur(pli[0]);
07174 m_wndPlaylistBar.SetNext();
07175 m_wndPlaylistBar.GetCur(pli[1]);
07176 if(pli[0].m_id != pli[1].m_id)
07177 {
07178 CAutoPtr<OpenMediaData> p(m_wndPlaylistBar.GetCurOMD());
07179 if(p) OpenMediaPrivate(p);
07180 }
07181 }
07182 }
07183 }
07184 else
07185 {
07186 m_wndPlaylistBar.SetCurValid(true);
07187 }
07188
07189 PostMessage(WM_KICKIDLE);
07190
07191 return(err.IsEmpty());
07192 }
07193
07194 void CMainFrame::CloseMediaPrivate()
07195 {
07196 m_iMediaLoadState = MLS_CLOSING;
07197
07198 OnPlayStop();
07199
07200 m_iPlaybackMode = PM_NONE;
07201 m_iSpeedLevel = 0;
07202
07203 m_fLiveWM = false;
07204
07205 m_fEndOfStream = false;
07206
07207 m_rtDurationOverride = -1;
07208
07209 m_kfs.RemoveAll();
07210
07211 m_pCB = NULL;
07212
07213 RemoveFromRot(m_dwRegister);
07214
07215
07216
07217
07218 m_pCAP = NULL;
07219 m_shaderlabel.Empty();
07220
07221 pAMXBar.Release(); pAMTuner.Release(); pAMDF.Release();
07222 pAMVCCap.Release(); pAMVCPrev.Release(); pAMVSCCap.Release(); pAMVSCPrev.Release(); pAMASC.Release();
07223 pVidCap.Release(); pAudCap.Release();
07224 pCGB.Release();
07225 pVMR.Release();
07226 pDVDC.Release(); pDVDI.Release();
07227 pQP.Release(); pBI.Release(); pAMOP.Release(); pFS.Release();
07228 pMC.Release(); pME.Release(); pMS.Release();
07229 pVW.Release(); pBV.Release();
07230 pBA.Release();
07231 pGB.Release();
07232
07233 m_fRealMediaGraph = m_fShockwaveGraph = m_fQuicktimeGraph = false;
07234
07235 m_pSubClock = NULL;
07236
07237 m_pProv.Release();
07238
07239 {
07240 CAutoLock cAutoLock(&m_csSubLock);
07241 m_pSubStreams.RemoveAll();
07242 }
07243
07244 m_VidDispName.Empty();
07245 m_AudDispName.Empty();
07246
07247 m_closingmsg = _T("Closed");
07248
07249 AfxGetAppSettings().nCLSwitches &= CLSW_OPEN|CLSW_PLAY|CLSW_AFTERPLAYBACK_MASK|CLSW_NOFOCUS;
07250
07251 m_iMediaLoadState = MLS_CLOSED;
07252 }
07253
07254
07255
07256 void CMainFrame::SendNowPlayingToMSN()
07257 {
07258 if(!AfxGetAppSettings().fNotifyMSN)
07259 return;
07260
07261 CString title, author;
07262
07263 if(m_iMediaLoadState == MLS_LOADED)
07264 {
07265 m_wndInfoBar.GetLine(_T("Title"), title);
07266 m_wndInfoBar.GetLine(_T("Author"), author);
07267
07268 if(title.IsEmpty())
07269 {
07270 CPlaylistItem pli;
07271 m_wndPlaylistBar.GetCur(pli);
07272
07273 if(!pli.m_fns.IsEmpty())
07274 {
07275 CString label = !pli.m_label.IsEmpty() ? pli.m_label : pli.m_fns.GetHead();
07276
07277 if(m_iPlaybackMode == PM_FILE)
07278 {
07279 CString fn = label;
07280 if(fn.Find(_T("://")) >= 0) {int i = fn.Find('?'); if(i >= 0) fn = fn.Left(i);}
07281 CPath path(fn);
07282 path.StripPath();
07283 path.MakePretty();
07284 path.RemoveExtension();
07285 title = (LPCTSTR)path;
07286 author.Empty();
07287 }
07288 else if(m_iPlaybackMode == PM_CAPTURE)
07289 {
07290 title = label != pli.m_fns.GetHead() ? label : _T("Live");
07291 author.Empty();
07292 }
07293 else if(m_iPlaybackMode == PM_DVD)
07294 {
07295 title = _T("DVD");
07296 author.Empty();
07297 }
07298 }
07299 }
07300 }
07301
07302 CStringW buff;
07303 buff += L"\\0Music\\0";
07304 buff += title.IsEmpty() ? L"0" : L"1";
07305 buff += L"\\0";
07306 buff += author.IsEmpty() ? L"{0}" : L"{0} - {1}";
07307 buff += L"\\0";
07308 if(!author.IsEmpty()) {buff += CStringW(author) + L"\\0";}
07309 buff += CStringW(title) + L"\\0";
07310 buff += L"\\0\\0";
07311
07312 COPYDATASTRUCT data;
07313 data.dwData = 0x0547;
07314 data.lpData = (PVOID)(LPCWSTR)buff;
07315 data.cbData = buff.GetLength() * 2 + 2;
07316
07317 HWND hWnd = NULL;
07318 while(hWnd = ::FindWindowEx(NULL, hWnd, _T("MsnMsgrUIManager"), NULL))
07319 ::SendMessage(hWnd, WM_COPYDATA, (WPARAM)NULL, (LPARAM)&data);
07320 }
07321
07322
07323
07324 void CMainFrame::SetupOpenCDSubMenu()
07325 {
07326 CMenu* pSub = &m_opencds;
07327
07328 if(!IsMenu(pSub->m_hMenu)) pSub->CreatePopupMenu();
07329 else while(pSub->RemoveMenu(0, MF_BYPOSITION));
07330
07331 if(m_iMediaLoadState == MLS_LOADING) return;
07332
07333 if(AfxGetAppSettings().fHideCDROMsSubMenu) return;
07334
07335 UINT id = ID_FILE_OPEN_CD_START;
07336
07337 for(TCHAR drive = 'C'; drive <= 'Z'; drive++)
07338 {
07339 CString label = GetDriveLabel(drive), str;
07340
07341 CList<CString> files;
07342 switch(GetCDROMType(drive, files))
07343 {
07344 case CDROM_Audio:
07345 if(label.IsEmpty()) label = _T("Audio CD");
07346 str.Format(_T("%s (%c:)"), label, drive);
07347 break;
07348 case CDROM_VideoCD:
07349 if(label.IsEmpty()) label = _T("(S)VCD");
07350 str.Format(_T("%s (%c:)"), label, drive);
07351 break;
07352 case CDROM_DVDVideo:
07353 if(label.IsEmpty()) label = _T("DVD Video");
07354 str.Format(_T("%s (%c:)"), label, drive);
07355 break;
07356 default:
07357 break;
07358 }
07359
07360 if(!str.IsEmpty())
07361 pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, id++, str);
07362 }
07363 }
07364
07365 void CMainFrame::SetupFiltersSubMenu()
07366 {
07367 CMenu* pSub = &m_filters;
07368
07369 if(!IsMenu(pSub->m_hMenu)) pSub->CreatePopupMenu();
07370 else while(pSub->RemoveMenu(0, MF_BYPOSITION));
07371
07372 m_filterpopups.RemoveAll();
07373
07374 m_spparray.RemoveAll();
07375 m_ssarray.RemoveAll();
07376
07377 if(m_iMediaLoadState == MLS_LOADED)
07378 {
07379 UINT idf = 0;
07380 UINT ids = ID_FILTERS_SUBITEM_START;
07381 UINT idl = ID_FILTERSTREAMS_SUBITEM_START;
07382
07383 BeginEnumFilters(pGB, pEF, pBF)
07384 {
07385 CString name(GetFilterName(pBF));
07386 if(name.GetLength() >= 43) name = name.Left(40) + _T("...");
07387
07388 CLSID clsid = GetCLSID(pBF);
07389 if(clsid == CLSID_AVIDec)
07390 {
07391 CComPtr<IPin> pPin = GetFirstPin(pBF);
07392 AM_MEDIA_TYPE mt;
07393 if(pPin && SUCCEEDED(pPin->ConnectionMediaType(&mt)))
07394 {
07395 DWORD c = ((VIDEOINFOHEADER*)mt.pbFormat)->bmiHeader.biCompression;
07396 switch(c)
07397 {
07398 case BI_RGB: name += _T(" (RGB)"); break;
07399 case BI_RLE4: name += _T(" (RLE4)"); break;
07400 case BI_RLE8: name += _T(" (RLE8)"); break;
07401 case BI_BITFIELDS: name += _T(" (BITF)"); break;
07402 default: name.Format(_T("%s (%c%c%c%c)"),
07403 CString(name), (TCHAR)((c>>0)&0xff), (TCHAR)((c>>8)&0xff), (TCHAR)((c>>16)&0xff), (TCHAR)((c>>24)&0xff)); break;
07404 }
07405 }
07406 }
07407 else if(clsid == CLSID_ACMWrapper)
07408 {
07409 CComPtr<IPin> pPin = GetFirstPin(pBF);
07410 AM_MEDIA_TYPE mt;
07411 if(pPin && SUCCEEDED(pPin->ConnectionMediaType(&mt)))
07412 {
07413 WORD c = ((WAVEFORMATEX*)mt.pbFormat)->wFormatTag;
07414 name.Format(_T("%s (0x%04x)"), CString(name), (int)c);
07415 }
07416 }
07417 else if(clsid == __uuidof(CTextPassThruFilter) || clsid == __uuidof(CNullTextRenderer)
07418 || clsid == GUIDFromCString(_T("{48025243-2D39-11CE-875D-00608CB78066}")))
07419 {
07420
07421 continue;
07422 }
07423
07424 CAutoPtr<CMenu> pSubSub(new CMenu);
07425 pSubSub->CreatePopupMenu();
07426
07427 int nPPages = 0;
07428
07429 CComQIPtr<ISpecifyPropertyPages> pSPP = pBF;
07430 if(pSPP)
07431 {
07432 CAUUID caGUID;
07433 caGUID.pElems = NULL;
07434 if(SUCCEEDED(pSPP->GetPages(&caGUID)) && caGUID.cElems > 0)
07435 {
07436 m_spparray.Add(pSPP);
07437 pSubSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, ids, _T("&Properties..."));
07438
07439 if(caGUID.pElems) CoTaskMemFree(caGUID.pElems);
07440
07441 nPPages++;
07442 }
07443 }
07444
07445 BeginEnumPins(pBF, pEP, pPin)
07446 {
07447 CString name = GetPinName(pPin);
07448 name.Replace(_T("&"), _T("&&"));
07449
07450 if(pSPP = pPin)
07451 {
07452 CAUUID caGUID;
07453 caGUID.pElems = NULL;
07454 if(SUCCEEDED(pSPP->GetPages(&caGUID)) && caGUID.cElems > 0)
07455 {
07456 m_spparray.Add(pSPP);
07457 pSubSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, ids+nPPages, name + _T(" (pin) properties..."));
07458
07459 if(caGUID.pElems) CoTaskMemFree(caGUID.pElems);
07460
07461 nPPages++;
07462 }
07463 }
07464 }
07465 EndEnumPins
07466
07467 CComQIPtr<IAMStreamSelect> pSS = pBF;
07468 if(pSS)
07469 {
07470 DWORD nStreams = 0, flags, group, prevgroup = -1;
07471 LCID lcid;
07472 WCHAR* wname = NULL;
07473 CComPtr<IUnknown> pObj, pUnk;
07474
07475 pSS->Count(&nStreams);
07476
07477 if(nStreams > 0 && nPPages > 0) pSubSub->AppendMenu(MF_SEPARATOR|MF_ENABLED);
07478
07479 UINT idlstart = idl;
07480
07481 for(DWORD i = 0; i < nStreams; i++, pObj = NULL, pUnk = NULL)
07482 {
07483 m_ssarray.Add(pSS);
07484
07485 flags = group = 0;
07486 wname = NULL;
07487 pSS->Info(i, NULL, &flags, &lcid, &group, &wname, &pObj, &pUnk);
07488
07489 if(group != prevgroup && idl > idlstart)
07490 pSubSub->AppendMenu(MF_SEPARATOR|MF_ENABLED);
07491 prevgroup = group;
07492
07493 if(flags & AMSTREAMSELECTINFO_EXCLUSIVE)
07494 {
07495 }
07496 else if(flags & AMSTREAMSELECTINFO_ENABLED)
07497 {
07498 }
07499
07500 if(!wname)
07501 {
07502 CStringW stream(L"Unknown Stream");
07503 wname = (WCHAR*)CoTaskMemAlloc((stream.GetLength()+3+1)*sizeof(WCHAR));
07504 swprintf(wname, L"%s %d", stream, min(i+1,999));
07505 }
07506
07507 CString name(wname);
07508 name.Replace(_T("&"), _T("&&"));
07509
07510 pSubSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, idl++, name);
07511
07512 CoTaskMemFree(wname);
07513 }
07514
07515 if(nStreams == 0) pSS.Release();
07516 }
07517
07518 if(nPPages == 1 && !pSS)
07519 {
07520 pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, ids, name);
07521 }
07522 else
07523 {
07524 pSub->AppendMenu(MF_BYPOSITION|MF_STRING|MF_DISABLED|MF_GRAYED, idf, name);
07525
07526 if(nPPages > 0 || pSS)
07527 {
07528 MENUITEMINFO mii;
07529 mii.cbSize = sizeof(mii);
07530 mii.fMask = MIIM_STATE|MIIM_SUBMENU;
07531 mii.fType = MF_POPUP;
07532 mii.hSubMenu = pSubSub->m_hMenu;
07533 mii.fState = (pSPP || pSS) ? MF_ENABLED : (MF_DISABLED|MF_GRAYED);
07534 pSub->SetMenuItemInfo(idf, &mii, TRUE);
07535
07536 m_filterpopups.Add(pSubSub);
07537 }
07538 }
07539
07540 ids += nPPages;
07541 idf++;
07542 }
07543 EndEnumFilters
07544 }
07545 }
07546
07547 void CMainFrame::SetupAudioSwitcherSubMenu()
07548 {
07549 CMenu* pSub = &m_audios;
07550
07551 if(!IsMenu(pSub->m_hMenu)) pSub->CreatePopupMenu();
07552 else while(pSub->RemoveMenu(0, MF_BYPOSITION));
07553
07554 if(m_iMediaLoadState == MLS_LOADED)
07555 {
07556 UINT id = ID_AUDIO_SUBITEM_START;
07557
07558 CComQIPtr<IAMStreamSelect> pSS = FindFilter(__uuidof(CAudioSwitcherFilter), pGB);
07559 if(!pSS) pSS = FindFilter(L"{D3CD7858-971A-4838-ACEC-40CA5D529DC8}", pGB);
07560
07561 if(pSS)
07562 {
07563 DWORD cStreams = 0;
07564 if(SUCCEEDED(pSS->Count(&cStreams)) && cStreams > 0)
07565 {
07566 pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, id++, _T("&Options..."));
07567 pSub->AppendMenu(MF_SEPARATOR|MF_ENABLED);
07568
07569 for(int i = 0; i < (int)cStreams; i++)
07570 {
07571 WCHAR* pName = NULL;
07572 if(FAILED(pSS->Info(i, NULL, NULL, NULL, NULL, &pName, NULL, NULL)))
07573 break;
07574
07575 CString name(pName);
07576 name.Replace(_T("&"), _T("&&"));
07577
07578 pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, id++, name);
07579
07580 CoTaskMemFree(pName);
07581 }
07582 }
07583 }
07584 }
07585 }
07586
07587 void CMainFrame::SetupSubtitlesSubMenu()
07588 {
07589 CMenu* pSub = &m_subtitles;
07590
07591 if(!IsMenu(pSub->m_hMenu)) pSub->CreatePopupMenu();
07592 else while(pSub->RemoveMenu(0, MF_BYPOSITION));
07593
07594 if(m_iMediaLoadState != MLS_LOADED || m_fAudioOnly || !m_pCAP)
07595 return;
07596
07597 UINT id = ID_SUBTITLES_SUBITEM_START;
07598
07599 POSITION pos = m_pSubStreams.GetHeadPosition();
07600
07601 if(pos)
07602 {
07603 pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, id++, _T("&Options..."));
07604 pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, id++, _T("&Styles..."));
07605 pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, id++, _T("&Reload"));
07606 pSub->AppendMenu(MF_SEPARATOR);
07607
07608 pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, id++, _T("&Enable"));
07609 pSub->AppendMenu(MF_SEPARATOR);
07610 }
07611
07612 while(pos)
07613 {
07614 CComPtr<ISubStream> pSubStream = m_pSubStreams.GetNext(pos);
07615 if(!pSubStream) continue;
07616
07617 for(int i = 0, j = pSubStream->GetStreamCount(); i < j; i++)
07618 {
07619 WCHAR* pName = NULL;
07620 if(SUCCEEDED(pSubStream->GetStreamInfo(i, &pName, NULL)))
07621 {
07622 CString name(pName);
07623 name.Replace(_T("&"), _T("&&"));
07624
07625 pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, id++, name);
07626 CoTaskMemFree(pName);
07627 }
07628 else
07629 {
07630 pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, id++, _T("<Unknown>"));
07631 }
07632 }
07633
07634
07635 if(pos && m_pSubStreams.GetAt(pos))
07636 {
07637 CLSID cur, next;
07638 pSubStream->GetClassID(&cur);
07639 m_pSubStreams.GetAt(pos)->GetClassID(&next);
07640
07641 if(cur != next)
07642 pSub->AppendMenu(MF_SEPARATOR);
07643 }
07644 }
07645 }
07646
07647 void CMainFrame::SetupNavAudioSubMenu()
07648 {
07649 CMenu* pSub = &m_navaudio;
07650
07651 if(!IsMenu(pSub->m_hMenu)) pSub->CreatePopupMenu();
07652 else while(pSub->RemoveMenu(0, MF_BYPOSITION));
07653
07654 if(m_iMediaLoadState != MLS_LOADED) return;
07655
07656 UINT id = ID_NAVIGATE_AUDIO_SUBITEM_START;
07657
07658 if(m_iPlaybackMode == PM_FILE)
07659 {
07660 SetupNavStreamSelectSubMenu(pSub, id, 1);
07661 }
07662 else if(m_iPlaybackMode == PM_DVD)
07663 {
07664 ULONG ulStreamsAvailable, ulCurrentStream;
07665 if(FAILED(pDVDI->GetCurrentAudio(&ulStreamsAvailable, &ulCurrentStream)))
07666 return;
07667
07668 LCID DefLanguage;
07669 DVD_AUDIO_LANG_EXT ext;
07670 if(FAILED(pDVDI->GetDefaultAudioLanguage(&DefLanguage, &ext)))
07671 return;
07672
07673 for(ULONG i = 0; i < ulStreamsAvailable; i++)
07674 {
07675 LCID Language;
07676 if(FAILED(pDVDI->GetAudioLanguage(i, &Language)))
07677 continue;
07678
07679 UINT flags = MF_BYCOMMAND|MF_STRING|MF_ENABLED;
07680 if(Language == DefLanguage) flags |= MF_DEFAULT;
07681 if(i == ulCurrentStream) flags |= MF_CHECKED;
07682
07683 CString str(_T("Unknown"));
07684 if(Language)
07685 {
07686 int len = GetLocaleInfo(Language, LOCALE_SENGLANGUAGE, str.GetBuffer(256), 256);
07687 str.ReleaseBufferSetLength(max(len-1, 0));
07688 }
07689
07690 DVD_AudioAttributes ATR;
07691 if(SUCCEEDED(pDVDI->GetAudioAttributes(i, &ATR)))
07692 {
07693 switch(ATR.LanguageExtension)
07694 {
07695 case DVD_AUD_EXT_NotSpecified:
07696 default: break;
07697 case DVD_AUD_EXT_Captions: str += _T(" (Captions)"); break;
07698 case DVD_AUD_EXT_VisuallyImpaired: str += _T(" (Visually Impaired)"); break;
07699 case DVD_AUD_EXT_DirectorComments1: str += _T(" (Director Comments 1)"); break;
07700 case DVD_AUD_EXT_DirectorComments2: str += _T(" (Director Comments 2)"); break;
07701 }
07702 }
07703
07704 str.Replace(_T("&"), _T("&&"));
07705
07706 pSub->AppendMenu(flags, id++, str);
07707 }
07708 }
07709 }
07710
07711 void CMainFrame::SetupNavSubtitleSubMenu()
07712 {
07713 CMenu* pSub = &m_navsubtitle;
07714
07715 if(!IsMenu(pSub->m_hMenu)) pSub->CreatePopupMenu();
07716 else while(pSub->RemoveMenu(0, MF_BYPOSITION));
07717
07718 if(m_iMediaLoadState != MLS_LOADED) return;
07719
07720 UINT id = ID_NAVIGATE_SUBP_SUBITEM_START;
07721
07722 if(m_iPlaybackMode == PM_FILE)
07723 {
07724 SetupNavStreamSelectSubMenu(pSub, id, 2);
07725 }
07726 else if(m_iPlaybackMode == PM_DVD)
07727 {
07728 ULONG ulStreamsAvailable, ulCurrentStream;
07729 BOOL bIsDisabled;
07730 if(FAILED(pDVDI->GetCurrentSubpicture(&ulStreamsAvailable, &ulCurrentStream, &bIsDisabled))
07731 || ulStreamsAvailable == 0)
07732 return;
07733
07734 LCID DefLanguage;
07735 DVD_SUBPICTURE_LANG_EXT ext;
07736 if(FAILED(pDVDI->GetDefaultSubpictureLanguage(&DefLanguage, &ext)))
07737 return;
07738
07739 pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|(bIsDisabled?0:MF_CHECKED), id++, _T("Enabled"));
07740 pSub->AppendMenu(MF_BYCOMMAND|MF_SEPARATOR|MF_ENABLED);
07741
07742 for(ULONG i = 0; i < ulStreamsAvailable; i++)
07743 {
07744 LCID Language;
07745 if(FAILED(pDVDI->GetSubpictureLanguage(i, &Language)))
07746 continue;
07747
07748 UINT flags = MF_BYCOMMAND|MF_STRING|MF_ENABLED;
07749 if(Language == DefLanguage) flags |= MF_DEFAULT;
07750 if(i == ulCurrentStream) flags |= MF_CHECKED;
07751
07752 CString str(_T("Unknown"));
07753 if(Language)
07754 {
07755 int len = GetLocaleInfo(Language, LOCALE_SENGLANGUAGE, str.GetBuffer(256), 256);
07756 str.ReleaseBufferSetLength(max(len-1, 0));
07757 }
07758
07759 DVD_SubpictureAttributes ATR;
07760 if(SUCCEEDED(pDVDI->GetSubpictureAttributes(i, &ATR)))
07761 {
07762 switch(ATR.LanguageExtension)
07763 {
07764 case DVD_SP_EXT_NotSpecified:
07765 default: break;
07766 case DVD_SP_EXT_Caption_Normal: str += _T(""); break;
07767 case DVD_SP_EXT_Caption_Big: str += _T(" (Big)"); break;
07768 case DVD_SP_EXT_Caption_Children: str += _T(" (Children)"); break;
07769 case DVD_SP_EXT_CC_Normal: str += _T(" (CC)"); break;
07770 case DVD_SP_EXT_CC_Big: str += _T(" (CC Big)"); break;
07771 case DVD_SP_EXT_CC_Children: str += _T(" (CC Children)"); break;
07772 case DVD_SP_EXT_Forced: str += _T(" (Forced)"); break;
07773 case DVD_SP_EXT_DirectorComments_Normal: str += _T(" (Director Comments)"); break;
07774 case DVD_SP_EXT_DirectorComments_Big: str += _T(" (Director Comments, Big)"); break;
07775 case DVD_SP_EXT_DirectorComments_Children: str += _T(" (Director Comments, Children)"); break;
07776 }
07777 }
07778
07779 str.Replace(_T("&"), _T("&&"));
07780
07781 pSub->AppendMenu(flags, id++, str);
07782 }
07783 }
07784 }
07785
07786 void CMainFrame::SetupNavAngleSubMenu()
07787 {
07788 CMenu* pSub = &m_navangle;
07789
07790 if(!IsMenu(pSub->m_hMenu)) pSub->CreatePopupMenu();
07791 else while(pSub->RemoveMenu(0, MF_BYPOSITION));
07792
07793 if(m_iMediaLoadState != MLS_LOADED) return;
07794
07795 UINT id = ID_NAVIGATE_ANGLE_SUBITEM_START;
07796
07797 if(m_iPlaybackMode == PM_FILE)
07798 {
07799 SetupNavStreamSelectSubMenu(pSub, id, 0);
07800 }
07801 else if(m_iPlaybackMode == PM_DVD)
07802 {
07803 ULONG ulStreamsAvailable, ulCurrentStream;
07804 if(FAILED(pDVDI->GetCurrentAngle(&ulStreamsAvailable, &ulCurrentStream)))
07805 return;
07806
07807 if(ulStreamsAvailable < 2) return;
07808
07809 for(ULONG i = 0; i < ulStreamsAvailable; i++)
07810 {
07811 UINT flags = MF_BYCOMMAND|MF_STRING|MF_ENABLED;
07812 if(i == ulCurrentStream) flags |= MF_CHECKED;
07813
07814 CString str;
07815 str.Format(_T("Angle %d"), i+1);
07816
07817 pSub->AppendMenu(flags, id++, str);
07818 }
07819 }
07820 }
07821
07822 void CMainFrame::SetupNavChaptersSubMenu()
07823 {
07824 CMenu* pSub = &m_navchapters;
07825
07826 if(!IsMenu(pSub->m_hMenu)) pSub->CreatePopupMenu();
07827 else while(pSub->RemoveMenu(0, MF_BYPOSITION));
07828
07829 if(m_iMediaLoadState != MLS_LOADED)
07830 return;
07831
07832 UINT id = ID_NAVIGATE_CHAP_SUBITEM_START;
07833
07834 if(m_iPlaybackMode == PM_FILE)
07835 {
07836 SetupChapters();
07837
07838 REFERENCE_TIME rt = GetPos();
07839 DWORD j = m_pCB->ChapLookup(&rt, NULL);
07840
07841 for(DWORD i = 0; i < m_pCB->ChapGetCount(); i++, id++)
07842 {
07843 rt = 0;
07844 CComBSTR bstr;
07845 if(FAILED(m_pCB->ChapGet(i, &rt, &bstr)))
07846 continue;
07847
07848 int s = (int)((rt/10000000)%60);
07849 int m = (int)((rt/10000000/60)%60);
07850 int h = (int)((rt/10000000/60/60));
07851
07852 CString time;
07853 time.Format(_T("[%02d:%02d:%02d] "), h, m, s);
07854
07855 CString name = CString(bstr);
07856 name.Replace(_T("&"), _T("&&"));
07857 name.Replace(_T("\t"), _T(" "));
07858
07859 UINT flags = MF_BYCOMMAND|MF_STRING|MF_ENABLED;
07860 if(i == j) flags |= MF_CHECKED;
07861 if(id != ID_NAVIGATE_CHAP_SUBITEM_START && i == 0) pSub->AppendMenu(MF_SEPARATOR);
07862 pSub->AppendMenu(flags, id, name + '\t' + time);
07863 }
07864
07865 if(m_wndPlaylistBar.GetCount() > 1)
07866 {
07867 POSITION pos = m_wndPlaylistBar.m_pl.GetHeadPosition();
07868 while(pos)
07869 {
07870 UINT flags = MF_BYCOMMAND|MF_STRING|MF_ENABLED;
07871 if(pos == m_wndPlaylistBar.m_pl.GetPos()) flags |= MF_CHECKED;
07872 if(id != ID_NAVIGATE_CHAP_SUBITEM_START && pos == m_wndPlaylistBar.m_pl.GetHeadPosition())
07873 pSub->AppendMenu(MF_SEPARATOR);
07874 CPlaylistItem& pli = m_wndPlaylistBar.m_pl.GetNext(pos);
07875 CString name = pli.GetLabel();
07876 name.Replace(_T("&"), _T("&&"));
07877 pSub->AppendMenu(flags, id++, name);
07878 }
07879 }
07880 }
07881 else if(m_iPlaybackMode == PM_DVD)
07882 {
07883 ULONG ulNumOfVolumes, ulVolume;
07884 DVD_DISC_SIDE Side;
07885 ULONG ulNumOfTitles = 0;
07886 pDVDI->GetDVDVolumeInfo(&ulNumOfVolumes, &ulVolume, &Side, &ulNumOfTitles);
07887
07888 DVD_PLAYBACK_LOCATION2 Location;
07889 pDVDI->GetCurrentLocation(&Location);
07890
07891 ULONG ulNumOfChapters = 0;
07892 pDVDI->GetNumberOfChapters(Location.TitleNum, &ulNumOfChapters);
07893
07894 ULONG ulUOPs = 0;
07895 pDVDI->GetCurrentUOPS(&ulUOPs);
07896
07897 for(ULONG i = 1; i <= ulNumOfTitles; i++)
07898 {
07899 UINT flags = MF_BYCOMMAND|MF_STRING|MF_ENABLED;
07900 if(i == Location.TitleNum) flags |= MF_CHECKED;
07901 if(ulUOPs&UOP_FLAG_Play_Title) flags |= MF_DISABLED|MF_GRAYED;
07902
07903 CString str;
07904 str.Format(_T("Title %d"), i);
07905
07906 pSub->AppendMenu(flags, id++, str);
07907 }
07908
07909 for(ULONG i = 1; i <= ulNumOfChapters; i++)
07910 {
07911 UINT flags = MF_BYCOMMAND|MF_STRING|MF_ENABLED;
07912 if(i == Location.ChapterNum) flags |= MF_CHECKED;
07913 if(ulUOPs&UOP_FLAG_Play_Chapter) flags |= MF_DISABLED|MF_GRAYED;
07914 if(i == 1) flags |= MF_MENUBARBREAK;
07915
07916 CString str;
07917 str.Format(_T("Chapter %d"), i);
07918
07919 pSub->AppendMenu(flags, id++, str);
07920 }
07921 }
07922 }
07923
07924 void CMainFrame::SetupNavStreamSelectSubMenu(CMenu* pSub, UINT id, DWORD dwSelGroup)
07925 {
07926 UINT baseid = id;
07927
07928 CComQIPtr<IAMStreamSelect> pSS = FindFilter(CLSID_OggSplitter, pGB);
07929 if(!pSS) pSS = FindFilter(L"{55DA30FC-F16B-49fc-BAA5-AE59FC65F82D}", pGB);
07930 if(!pSS) return;
07931
07932 DWORD cStreams;
07933 if(FAILED(pSS->Count(&cStreams)))
07934 return;
07935
07936 DWORD dwPrevGroup = -1;
07937
07938 for(int i = 0, j = cStreams; i < j; i++)
07939 {
07940 DWORD dwFlags, dwGroup;
07941 LCID lcid;
07942 WCHAR* pszName = NULL;
07943
07944 if(FAILED(pSS->Info(i, NULL, &dwFlags, &lcid, &dwGroup, &pszName, NULL, NULL))
07945 || !pszName)
07946 continue;
07947
07948 CStringW name(pszName);
07949 name.MakeLower();
07950
07951 if(pszName) CoTaskMemFree(pszName);
07952
07953 if(dwGroup != dwSelGroup)
07954 continue;
07955
07956 if(dwPrevGroup != -1 && dwPrevGroup != dwGroup)
07957 pSub->AppendMenu(MF_SEPARATOR);
07958 dwPrevGroup = dwGroup;
07959
07960 CString str;
07961
07962 if(name.Find(L" off") >= 0)
07963 {
07964 str = _T("Disabled");
07965 }
07966 else if(lcid == 0)
07967 {
07968 str.Format(_T("Unknown %d"), id - baseid);
07969 }
07970 else
07971 {
07972 int len = GetLocaleInfo(lcid, LOCALE_SENGLANGUAGE, str.GetBuffer(64), 64);
07973 str.ReleaseBufferSetLength(max(len-1, 0));
07974 }
07975
07976 UINT flags = MF_BYCOMMAND|MF_STRING|MF_ENABLED;
07977 if(dwFlags) flags |= MF_CHECKED;
07978
07979 str.Replace(_T("&"), _T("&&"));
07980 pSub->AppendMenu(flags, id++, str);
07981 }
07982 }
07983
07984 void CMainFrame::OnNavStreamSelectSubMenu(UINT id, DWORD dwSelGroup)
07985 {
07986 CComQIPtr<IAMStreamSelect> pSS = FindFilter(CLSID_OggSplitter, pGB);
07987 if(!pSS) pSS = FindFilter(L"{55DA30FC-F16B-49fc-BAA5-AE59FC65F82D}", pGB);
07988 if(!pSS) return;
07989
07990 DWORD cStreams;
07991 if(FAILED(pSS->Count(&cStreams)))
07992 return;
07993
07994 for(int i = 0, j = cStreams; i < j; i++)
07995 {
07996 DWORD dwFlags, dwGroup;
07997 LCID lcid;
07998 WCHAR* pszName = NULL;
07999
08000 if(FAILED(pSS->Info(i, NULL, &dwFlags, &lcid, &dwGroup, &pszName, NULL, NULL))
08001 || !pszName)
08002 continue;
08003
08004 if(pszName) CoTaskMemFree(pszName);
08005
08006 if(dwGroup != dwSelGroup)
08007 continue;
08008
08009 if(id == 0)
08010 {
08011 pSS->Enable(i, AMSTREAMSELECTENABLE_ENABLE);
08012 break;
08013 }
08014
08015 id--;
08016 }
08017 }
08018
08019 void CMainFrame::SetupFavoritesSubMenu()
08020 {
08021 CMenu* pSub = &m_favorites;
08022
08023 if(!IsMenu(pSub->m_hMenu)) pSub->CreatePopupMenu();
08024 else while(pSub->RemoveMenu(0, MF_BYPOSITION));
08025
08026 AppSettings& s = AfxGetAppSettings();
08027
08028 pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, ID_FAVORITES_ADD, _T("&Add to Favorites..."));
08029 pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, ID_FAVORITES_ORGANIZE, _T("&Organize Favorites..."));
08030
08031 int nLastGroupStart = pSub->GetMenuItemCount();
08032
08033 UINT id = ID_FAVORITES_FILE_START;
08034
08035 CList<CString> sl;
08036 AfxGetAppSettings().GetFav(FAV_FILE, sl);
08037
08038 POSITION pos = sl.GetHeadPosition();
08039 while(pos)
08040 {
08041 UINT flags = MF_BYCOMMAND|MF_STRING|MF_ENABLED;
08042
08043 CString str = sl.GetNext(pos);
08044 str.Replace(_T("&"), _T("&&"));
08045 str.Replace(_T("\t"), _T(" "));
08046
08047 CList<CString> sl;
08048 Explode(str, sl, ';', 2);
08049
08050 str = sl.RemoveHead();
08051
08052 if(!sl.IsEmpty())
08053 {
08054 REFERENCE_TIME rt = 0;
08055 if(1 == _stscanf(sl.GetHead(), _T("%I64d"), &rt) && rt > 0)
08056 {
08057 DVD_HMSF_TIMECODE hmsf = RT2HMSF(rt, 0);
08058 str.Format(_T("%s\t[%02d:%02d:%02d]"), CString(str), hmsf.bHours, hmsf.bMinutes, hmsf.bSeconds);
08059 }
08060 }
08061
08062 if(!str.IsEmpty())
08063 pSub->AppendMenu(flags, id, str);
08064
08065 id++;
08066 }
08067
08068 if(id > ID_FAVORITES_FILE_START)
08069 pSub->InsertMenu(nLastGroupStart, MF_SEPARATOR|MF_ENABLED|MF_BYPOSITION);
08070
08071 nLastGroupStart = pSub->GetMenuItemCount();
08072
08073 id = ID_FAVORITES_DVD_START;
08074
08075 AfxGetAppSettings().GetFav(FAV_DVD, sl);
08076
08077 pos = sl.GetHeadPosition();
08078 while(pos)
08079 {
08080 UINT flags = MF_BYCOMMAND|MF_STRING|MF_ENABLED;
08081
08082 CString str = sl.GetNext(pos);
08083 str.Replace(_T("&"), _T("&&"));
08084
08085 CList<CString> sl;
08086 Explode(str, sl, ';', 2);
08087
08088 str = sl.RemoveHead();
08089
08090 if(!sl.IsEmpty())
08091 {
08092
08093 }
08094
08095 if(!str.IsEmpty())
08096 pSub->AppendMenu(flags, id, str);
08097
08098 id++;
08099 }
08100
08101 if(id > ID_FAVORITES_DVD_START)
08102 pSub->InsertMenu(nLastGroupStart, MF_SEPARATOR|MF_ENABLED|MF_BYPOSITION);
08103
08104 nLastGroupStart = pSub->GetMenuItemCount();
08105
08106 id = ID_FAVORITES_DEVICE_START;
08107
08108 AfxGetAppSettings().GetFav(FAV_DEVICE, sl);
08109
08110 pos = sl.GetHeadPosition();
08111 while(pos)
08112 {
08113 UINT flags = MF_BYCOMMAND|MF_STRING|MF_ENABLED;
08114
08115 CString str = sl.GetNext(pos);
08116 str.Replace(_T("&"), _T("&&"));
08117
08118 CList<CString> sl;
08119 Explode(str, sl, ';', 2);
08120
08121 str = sl.RemoveHead();
08122
08123 if(!str.IsEmpty())
08124 pSub->AppendMenu(flags, id, str);
08125
08126 id++;
08127 }
08128 }
08129
08130 void CMainFrame::SetupShadersSubMenu()
08131 {
08132 CMenu* pSub = &m_shaders;
08133
08134 if(!IsMenu(pSub->m_hMenu)) pSub->CreatePopupMenu();
08135 else while(pSub->RemoveMenu(0, MF_BYPOSITION));
08136
08137 CWinApp* pApp = AfxGetApp();
08138
08139 pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, ID_SHADERS_START, ResStr(IDS_SHADER_EDIT));
08140
08141 UINT id = ID_SHADERS_START+1;
08142
08143 for(int i = 0; ; i++)
08144 {
08145 CString str;
08146 str.Format(_T("%d"), i);
08147 str = pApp->GetProfileString(_T("Shaders"), str);
08148
08149 CList<CString> sl;
08150 CString label = Explode(str, sl, '|');
08151 if(label.IsEmpty()) break;
08152
08153 UINT flags = MF_BYCOMMAND|MF_STRING|MF_ENABLED;
08154
08155 if(i == 0)
08156 {
08157 pSub->AppendMenu(MF_SEPARATOR);
08158 pSub->AppendMenu(flags, id++, ResStr(IDS_SHADER_OFF));
08159 }
08160
08161 label.Replace(_T("&"), _T("&&"));
08162 pSub->AppendMenu(flags, id++, label);
08163 }
08164 }
08165
08167
08168 void CMainFrame::ShowControls(int nCS, bool fSave)
08169 {
08170 int nCSprev = AfxGetAppSettings().nCS;
08171 int hbefore = 0, hafter = 0;
08172
08173 m_pLastBar = NULL;
08174
08175 POSITION pos = m_bars.GetHeadPosition();
08176 for(int i = 1; pos; i <<= 1)
08177 {
08178 CControlBar* pNext = m_bars.GetNext(pos);
08179 ShowControlBar(pNext, !!(nCS&i), TRUE);
08180 if(nCS&i) m_pLastBar = pNext;
08181
08182 CSize s = pNext->CalcFixedLayout(FALSE, TRUE);
08183 if(nCSprev&i) hbefore += s.cy;
08184 if(nCS&i) hafter += s.cy;
08185 }
08186
08187 WINDOWPLACEMENT wp;
08188 wp.length = sizeof(wp);
08189 GetWindowPlacement(&wp);
08190
08191 if(wp.showCmd != SW_SHOWMAXIMIZED && !m_fFullScreen)
08192 {
08193 CRect r;
08194 GetWindowRect(r);
08195 MoveWindow(r.left, r.top, r.Width(), r.Height()+(hafter-hbefore));
08196 }
08197
08198 if(fSave)
08199 AfxGetAppSettings().nCS = nCS;
08200
08201 RecalcLayout();
08202 }
08203
08204 void CMainFrame::SetAlwaysOnTop(int i)
08205 {
08206 AfxGetAppSettings().iOnTop = i;
08207
08208 if(!m_fFullScreen)
08209 {
08210 const CWnd* pInsertAfter = NULL;
08211
08212 if(i == 0)
08213 pInsertAfter = &wndNoTopMost;
08214 else if(i == 1)
08215 pInsertAfter = &wndTopMost;
08216 else
08217 pInsertAfter = GetMediaState() == State_Running ? &wndTopMost : &wndNoTopMost;
08218
08219 SetWindowPos(pInsertAfter, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
08220 }
08221 else if(!(GetWindowLong(m_hWnd, GWL_EXSTYLE)&WS_EX_TOPMOST))
08222 {
08223 SetWindowPos(&wndTopMost, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
08224 }
08225 }
08226
08227 void CMainFrame::AddTextPassThruFilter()
08228 {
08229 BeginEnumFilters(pGB, pEF, pBF)
08230 {
08231 if(!IsSplitter(pBF)) continue;
08232
08233 BeginEnumPins(pBF, pEP, pPin)
08234 {
08235 CComPtr<IPin> pPinTo;
08236 AM_MEDIA_TYPE mt;
08237 if(FAILED(pPin->ConnectedTo(&pPinTo)) || !pPinTo
08238 || FAILED(pPin->ConnectionMediaType(&mt))
08239 || mt.majortype != MEDIATYPE_Text && mt.majortype != MEDIATYPE_Subtitle)
08240 continue;
08241
08242 CComQIPtr<IBaseFilter> pTPTF = new CTextPassThruFilter(this);
08243 CStringW name;
08244 name.Format(L"TextPassThru%08x", pTPTF);
08245 if(FAILED(pGB->AddFilter(pTPTF, name)))
08246 continue;
08247
08248 HRESULT hr;
08249
08250 hr = pPinTo->Disconnect();
08251 hr = pPin->Disconnect();
08252
08253 if(FAILED(hr = pGB->ConnectDirect(pPin, GetFirstPin(pTPTF, PINDIR_INPUT), NULL))
08254 || FAILED(hr = pGB->ConnectDirect(GetFirstPin(pTPTF, PINDIR_OUTPUT), pPinTo, NULL)))
08255 hr = pGB->ConnectDirect(pPin, pPinTo, NULL);
08256 else
08257 m_pSubStreams.AddTail(CComQIPtr<ISubStream>(pTPTF));
08258 }
08259 EndEnumPins
08260 }
08261 EndEnumFilters
08262 }
08263
08264 bool CMainFrame::LoadSubtitle(CString fn)
08265 {
08266 CComPtr<ISubStream> pSubStream;
08267
08268
08269 try
08270 {
08271 if(!pSubStream)
08272 {
08273 CAutoPtr<CVobSubFile> pVSF(new CVobSubFile(&m_csSubLock));
08274 if(pVSF && pVSF->Open(fn) && pVSF->GetStreamCount() > 0)
08275 pSubStream = pVSF.Detach();
08276 }
08277
08278 if(!pSubStream)
08279 {
08280 CAutoPtr<CRenderedTextSubtitle> pRTS(new CRenderedTextSubtitle(&m_csSubLock));
08281 if(pRTS && pRTS->Open(fn, DEFAULT_CHARSET) && pRTS->GetStreamCount() > 0)
08282 pSubStream = pRTS.Detach();
08283 }
08284 }
08285 catch(CException* e)
08286 {
08287 e->Delete();
08288 }
08289
08290 if(pSubStream)
08291 {
08292 m_pSubStreams.AddTail(pSubStream);
08293 }
08294
08295 return(!!pSubStream);
08296 }
08297
08298 void CMainFrame::UpdateSubtitle(bool fApplyDefStyle)
08299 {
08300 if(!m_pCAP) return;
08301
08302 int i = m_iSubtitleSel;
08303
08304 POSITION pos = m_pSubStreams.GetHeadPosition();
08305 while(pos && i >= 0)
08306 {
08307 CComPtr<ISubStream> pSubStream = m_pSubStreams.GetNext(pos);
08308
08309 if(i < pSubStream->GetStreamCount())
08310 {
08311 CAutoLock cAutoLock(&m_csSubLock);
08312 pSubStream->SetStream(i);
08313 SetSubtitle(pSubStream, fApplyDefStyle);
08314 return;
08315 }
08316
08317 i -= pSubStream->GetStreamCount();
08318 }
08319
08320 m_pCAP->SetSubPicProvider(NULL);
08321 }
08322
08323 void CMainFrame::SetSubtitle(ISubStream* pSubStream, bool fApplyDefStyle)
08324 {
08325 AppSettings& s = AfxGetAppSettings();
08326
08327 if(pSubStream)
08328 {
08329 CLSID clsid;
08330 pSubStream->GetClassID(&clsid);
08331
08332 if(clsid == __uuidof(CVobSubFile))
08333 {
08334 CVobSubFile* pVSF = (CVobSubFile*)(ISubStream*)pSubStream;
08335
08336 if(fApplyDefStyle)
08337 {
08338 pVSF->SetAlignment(s.fOverridePlacement, s.nHorPos, s.nVerPos, 1, 1);
08339 }
08340 }
08341 if(clsid == __uuidof(CVobSubStream))
08342 {
08343 CVobSubStream* pVSS = (CVobSubStream*)(ISubStream*)pSubStream;
08344
08345 if(fApplyDefStyle)
08346 {
08347 pVSS->SetAlignment(s.fOverridePlacement, s.nHorPos, s.nVerPos, 1, 1);
08348 }
08349 }
08350 else if(clsid == __uuidof(CRenderedTextSubtitle))
08351 {
08352 CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)pSubStream;
08353
08354 STSStyle style;
08355
08356 if(fApplyDefStyle || pRTS->m_fUsingAutoGeneratedDefaultStyle)
08357 {
08358 style = s.subdefstyle;
08359
08360 if(s.fOverridePlacement)
08361 {
08362 style.scrAlignment = 2;
08363 int w = pRTS->m_dstScreenSize.cx;
08364 int h = pRTS->m_dstScreenSize.cy;
08365 int mw = w - style.marginRect.left - style.marginRect.right;
08366 style.marginRect.bottom = h - MulDiv(h, s.nVerPos, 100);
08367 style.marginRect.left = MulDiv(w, s.nHorPos, 100) - mw/2;
08368 style.marginRect.right = w - (style.marginRect.left + mw);
08369 }
08370
08371 pRTS->SetDefaultStyle(style);
08372 }
08373
08374 if(pRTS->GetDefaultStyle(style) && style.relativeTo == 2)
08375 {
08376 style.relativeTo = s.subdefstyle.relativeTo;
08377 pRTS->SetDefaultStyle(style);
08378 }
08379
08380 pRTS->Deinit();
08381 }
08382 }
08383
08384 if(!fApplyDefStyle)
08385 {
08386 m_iSubtitleSel = -1;
08387
08388 if(pSubStream)
08389 {
08390
08391 int i = 0;
08392
08393 POSITION pos = m_pSubStreams.GetHeadPosition();
08394 while(pos)
08395 {
08396 CComPtr<ISubStream> pSubStream2 = m_pSubStreams.GetNext(pos);
08397
08398 if(pSubStream == pSubStream2)
08399 {
08400 m_iSubtitleSel = i + pSubStream2->GetStream();
08401 break;
08402 }
08403
08404 i += pSubStream2->GetStreamCount();
08405 }
08406
08407 }
08408 }
08409
08410 m_nSubtitleId = (DWORD_PTR)pSubStream;
08411
08412 if(m_pCAP)
08413 {
08414 m_pCAP->SetSubPicProvider(CComQIPtr<ISubPicProvider>(pSubStream));
08415 m_wndSubresyncBar.SetSubtitle(pSubStream, m_pCAP->GetFPS());
08416 }
08417 }
08418
08419 void CMainFrame::ReplaceSubtitle(ISubStream* pSubStreamOld, ISubStream* pSubStreamNew)
08420 {
08421 POSITION pos = m_pSubStreams.GetHeadPosition();
08422 while(pos)
08423 {
08424 POSITION cur = pos;
08425 if(pSubStreamOld == m_pSubStreams.GetNext(pos))
08426 {
08427 m_pSubStreams.SetAt(cur, pSubStreamNew);
08428 UpdateSubtitle();
08429 break;
08430 }
08431 }
08432 }
08433
08434 void CMainFrame::InvalidateSubtitle(DWORD_PTR nSubtitleId, REFERENCE_TIME rtInvalidate)
08435 {
08436 if(m_pCAP)
08437 {
08438 if(nSubtitleId == -1 || nSubtitleId == m_nSubtitleId)
08439 m_pCAP->Invalidate(rtInvalidate);
08440 }
08441 }
08442
08443 void CMainFrame::ReloadSubtitle()
08444 {
08445 POSITION pos = m_pSubStreams.GetHeadPosition();
08446 while(pos) m_pSubStreams.GetNext(pos)->Reload();
08447 UpdateSubtitle();
08448 }
08449
08450 REFERENCE_TIME CMainFrame::GetPos()
08451 {
08452 return(m_iMediaLoadState == MLS_LOADED ? m_wndSeekBar.GetPos() : 0);
08453 }
08454
08455 REFERENCE_TIME CMainFrame::GetDur()
08456 {
08457 __int64 start, stop;
08458 m_wndSeekBar.GetRange(start, stop);
08459 return(m_iMediaLoadState == MLS_LOADED ? stop : 0);
08460 }
08461
08462 void CMainFrame::SeekTo(REFERENCE_TIME rtPos, bool fSeekToKeyFrame)
08463 {
08464 OAFilterState fs = GetMediaState();
08465
08466 if(rtPos < 0) rtPos = 0;
08467
08468 if(m_iPlaybackMode == PM_FILE)
08469 {
08470 if(fs == State_Stopped)
08471 SendMessage(WM_COMMAND, ID_PLAY_PAUSE);
08472
08473 HRESULT hr;
08474
08475 if(fSeekToKeyFrame)
08476 {
08477 if(!m_kfs.IsEmpty())
08478 {
08479 int i = rangebsearch(rtPos, m_kfs);
08480 if(i >= 0 && i < m_kfs.GetCount())
08481 rtPos = m_kfs[i];
08482 }
08483 }
08484
08485 hr = pMS->SetPositions(&rtPos, AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning);
08486 }
08487 else if(m_iPlaybackMode == PM_DVD && m_iDVDDomain == DVD_DOMAIN_Title)
08488 {
08489 if(fs != State_Running)
08490 SendMessage(WM_COMMAND, ID_PLAY_PLAY);
08491
08492 DVD_HMSF_TIMECODE tc = RT2HMSF(rtPos);
08493 pDVDC->PlayAtTime(&tc, DVD_CMD_FLAG_Block|DVD_CMD_FLAG_Flush, NULL);
08494
08495
08496
08497 }
08498 else if(m_iPlaybackMode == PM_CAPTURE)
08499 {
08500 TRACE(_T("Warning (CMainFrame::SeekTo): Trying to seek in capture mode"));
08501 }
08502 }
08503
08504 void CMainFrame::CleanGraph()
08505 {
08506 if(!pGB) return;
08507
08508 BeginEnumFilters(pGB, pEF, pBF)
08509 {
08510 CComQIPtr<IAMFilterMiscFlags> pAMMF(pBF);
08511 if(pAMMF && (pAMMF->GetMiscFlags()&AM_FILTER_MISC_FLAGS_IS_SOURCE))
08512 continue;
08513
08514
08515
08516 if(pBF == pVidCap || pBF == pAudCap)
08517 continue;
08518
08519 if(CComQIPtr<IFileSourceFilter>(pBF))
08520 continue;
08521
08522 int nIn, nOut, nInC, nOutC;
08523 if(CountPins(pBF, nIn, nOut, nInC, nOutC) > 0 && (nInC+nOutC) == 0)
08524 {
08525 TRACE(CStringW(L"Removing: ") + GetFilterName(pBF) + '\n');
08526
08527 pGB->RemoveFilter(pBF);
08528 pEF->Reset();
08529 }
08530 }
08531 EndEnumFilters
08532 }
08533
08534 #define AUDIOBUFFERLEN 500
08535
08536 static void SetLatency(IBaseFilter* pBF, int cbBuffer)
08537 {
08538 BeginEnumPins(pBF, pEP, pPin)
08539 {
08540 if(CComQIPtr<IAMBufferNegotiation> pAMBN = pPin)
08541 {
08542 ALLOCATOR_PROPERTIES ap;
08543 ap.cbAlign = -1;
08544 ap.cbBuffer = cbBuffer;
08545 ap.cbPrefix = -1;
08546 ap.cBuffers = -1;
08547 pAMBN->SuggestAllocatorProperties(&ap);
08548 }
08549 }
08550 EndEnumPins
08551 }
08552
08553 HRESULT CMainFrame::BuildCapture(IPin* pPin, IBaseFilter* pBF[3], const GUID& majortype, AM_MEDIA_TYPE* pmt)
08554 {
08555 IBaseFilter* pBuff = pBF[0];
08556 IBaseFilter* pEnc = pBF[1];
08557 IBaseFilter* pMux = pBF[2];
08558
08559 if(!pPin || !pMux) return E_FAIL;
08560
08561 CString err;
08562
08563 HRESULT hr = S_OK;
08564
08565 AddFilterToGraph(pGB, pMux, L"Multiplexer");
08566
08567 IUnknown* pPrev = pPin;
08568
08569 CStringW prefix, prefixl;
08570 if(majortype == MEDIATYPE_Video) prefix = L"Video ";
08571 else if(majortype == MEDIATYPE_Audio) prefix = L"Audio ";
08572 prefixl = prefix;
08573 prefixl.MakeLower();
08574
08575 if(pBuff)
08576 {
08577 hr = pGB->AddFilter(pBuff, prefix + L"Buffer");
08578 if(FAILED(hr))
08579 {
08580 err = _T("Can't add ") + CString(prefixl) + _T("buffer filter");
08581 AfxMessageBox(err);
08582 return hr;
08583 }
08584
08585 hr = pCGB->RenderStream(NULL, &majortype, pPrev, NULL, pBuff);
08586 if(FAILED(hr))
08587 {
08588 err = _T("Error connecting the ") + CString(prefixl) + _T("buffer filter");
08589 AfxMessageBox(err);
08590 return(hr);
08591 }
08592
08593 pPrev = pBuff;
08594 }
08595
08596 if(pEnc)
08597 {
08598 hr = pGB->AddFilter(pEnc, prefix + L"Encoder");
08599 if(FAILED(hr))
08600 {
08601 err = _T("Can't add ") + CString(prefixl) + _T("encoder filter");
08602 AfxMessageBox(err);
08603 return hr;
08604 }
08605
08606 hr = pCGB->RenderStream(NULL, &majortype, pPrev, NULL, pEnc);
08607 if(FAILED(hr))
08608 {
08609 err = _T("Error connecting the ") + CString(prefixl) + _T("encoder filter");
08610 AfxMessageBox(err);
08611 return(hr);
08612 }
08613
08614 pPrev = pEnc;
08615
08616 if(CComQIPtr<IAMStreamConfig> pAMSC = GetFirstPin(pEnc, PINDIR_OUTPUT))
08617 {
08618 if(pmt->majortype == majortype)
08619 {
08620 hr = pAMSC->SetFormat(pmt);
08621 if(FAILED(hr))
08622 {
08623 err = _T("Can't set compression format on the ") + CString(prefixl) + _T("encoder filter");
08624 AfxMessageBox(err);
08625 return(hr);
08626 }
08627 }
08628 }
08629
08630 }
08631
08632
08633 {
08634 hr = pCGB->RenderStream(NULL, &majortype, pPrev, NULL, pMux);
08635 if(FAILED(hr))
08636 {
08637 err = _T("Error connecting ") + CString(prefixl) + _T(" to the muliplexer filter");
08638 AfxMessageBox(err);
08639 return(hr);
08640 }
08641 }
08642
08643 CleanGraph();
08644
08645 return S_OK;
08646 }
08647
08648 bool CMainFrame::BuildToCapturePreviewPin(
08649 IBaseFilter* pVidCap, IPin** ppVidCapPin, IPin** ppVidPrevPin,
08650 IBaseFilter* pAudCap, IPin** ppAudCapPin, IPin** ppAudPrevPin)
08651 {
08652 HRESULT hr;
08653
08654 *ppVidCapPin = *ppVidPrevPin = NULL;
08655 *ppAudCapPin = *ppAudPrevPin = NULL;
08656
08657 CComPtr<IPin> pDVAudPin;
08658
08659 if(pVidCap)
08660 {
08661 CComPtr<IPin> pPin;
08662 if(!pAudCap
08663 && SUCCEEDED(pCGB->FindPin(pVidCap, PINDIR_OUTPUT, &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Interleaved, TRUE, 0, &pPin)))
08664 {
08665 CComPtr<IBaseFilter> pDVSplitter;
08666 hr = pDVSplitter.CoCreateInstance(CLSID_DVSplitter);
08667 hr = pGB->AddFilter(pDVSplitter, L"DV Splitter");
08668
08669 hr = pCGB->RenderStream(NULL, &MEDIATYPE_Interleaved, pPin, NULL, pDVSplitter);
08670
08671 pPin = NULL;
08672 hr = pCGB->FindPin(pDVSplitter, PINDIR_OUTPUT, NULL, &MEDIATYPE_Video, TRUE, 0, &pPin);
08673 hr = pCGB->FindPin(pDVSplitter, PINDIR_OUTPUT, NULL, &MEDIATYPE_Audio, TRUE, 0, &pDVAudPin);
08674
08675 CComPtr<IBaseFilter> pDVDec;
08676 hr = pDVDec.CoCreateInstance(CLSID_DVVideoCodec);
08677 hr = pGB->AddFilter(pDVDec, L"DV Video Decoder");
08678
08679 hr = pCGB->RenderStream(NULL, &MEDIATYPE_Video, pPin, NULL, pDVDec);
08680
08681 pPin = NULL;
08682 hr = pCGB->FindPin(pDVDec, PINDIR_OUTPUT, NULL, &MEDIATYPE_Video, TRUE, 0, &pPin);
08683 }
08684 else if(SUCCEEDED(pCGB->FindPin(pVidCap, PINDIR_OUTPUT, &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, TRUE, 0, &pPin)))
08685 {
08686 }
08687 else
08688 {
08689 AfxMessageBox(_T("No video capture pin found"));
08690 return(false);
08691 }
08692
08693 CComPtr<IBaseFilter> pSmartTee;
08694 hr = pSmartTee.CoCreateInstance(CLSID_SmartTee);
08695 hr = pGB->AddFilter(pSmartTee, L"Smart Tee (video)");
08696
08697 hr = pCGB->RenderStream(NULL, &MEDIATYPE_Video, pPin, NULL, pSmartTee);
08698
08699 hr = pSmartTee->FindPin(L"Preview", ppVidPrevPin);
08700 hr = pSmartTee->FindPin(L"Capture", ppVidCapPin);
08701 }
08702
08703 if(pAudCap || pDVAudPin)
08704 {
08705 CComPtr<IPin> pPin;
08706 if(pDVAudPin)
08707 {
08708 pPin = pDVAudPin;
08709 }
08710 else if(SUCCEEDED(pCGB->FindPin(pAudCap, PINDIR_OUTPUT, &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Audio, TRUE, 0, &pPin)))
08711 {
08712 }
08713 else
08714 {
08715 AfxMessageBox(_T("No audio capture pin found"));
08716 return(false);
08717 }
08718
08719 CComPtr<IBaseFilter> pSmartTee;
08720 hr = pSmartTee.CoCreateInstance(CLSID_SmartTee);
08721 hr = pGB->AddFilter(pSmartTee, L"Smart Tee (audio)");
08722
08723 hr = pCGB->RenderStream(NULL, &MEDIATYPE_Audio, pPin, NULL, pSmartTee);
08724
08725 hr = pSmartTee->FindPin(L"Preview", ppAudPrevPin);
08726 hr = pSmartTee->FindPin(L"Capture", ppAudCapPin);
08727 }
08728
08729 return(true);
08730 }
08731
08732 bool CMainFrame::BuildGraphVideoAudio(bool fVPreview, bool fVCapture, bool fAPreview, bool fACapture)
08733 {
08734 if(!pCGB) return(false);
08735
08736 SaveMediaState;
08737
08738 HRESULT hr;
08739
08740 NukeDownstream(pVidCap, pGB);
08741 NukeDownstream(pAudCap, pGB);
08742
08743 CleanGraph();
08744
08745 if(pAMVSCCap) hr = pAMVSCCap->SetFormat(&m_wndCaptureBar.m_capdlg.m_mtv);
08746 if(pAMVSCPrev) hr = pAMVSCPrev->SetFormat(&m_wndCaptureBar.m_capdlg.m_mtv);
08747 if(pAMASC) hr = pAMASC->SetFormat(&m_wndCaptureBar.m_capdlg.m_mta);
08748
08749 CComPtr<IBaseFilter> pVidBuffer = m_wndCaptureBar.m_capdlg.m_pVidBuffer;
08750 CComPtr<IBaseFilter> pAudBuffer = m_wndCaptureBar.m_capdlg.m_pAudBuffer;
08751 CComPtr<IBaseFilter> pVidEnc = m_wndCaptureBar.m_capdlg.m_pVidEnc;
08752 CComPtr<IBaseFilter> pAudEnc = m_wndCaptureBar.m_capdlg.m_pAudEnc;
08753 CComPtr<IBaseFilter> pMux = m_wndCaptureBar.m_capdlg.m_pMux;
08754 CComPtr<IBaseFilter> pDst = m_wndCaptureBar.m_capdlg.m_pDst;
08755 CComPtr<IBaseFilter> pAudMux = m_wndCaptureBar.m_capdlg.m_pAudMux;
08756 CComPtr<IBaseFilter> pAudDst = m_wndCaptureBar.m_capdlg.m_pAudDst;
08757
08758 bool fFileOutput = (pMux && pDst) || (pAudMux && pAudDst);
08759 bool fCapture = (fVCapture || fACapture);
08760
08761 if(pAudCap)
08762 {
08763 AM_MEDIA_TYPE* pmt = &m_wndCaptureBar.m_capdlg.m_mta;
08764 int ms = (fACapture && fFileOutput && m_wndCaptureBar.m_capdlg.m_fAudOutput) ? AUDIOBUFFERLEN : 60;
08765 if(pMux != pAudMux && fACapture) SetLatency(pAudCap, -1);
08766 else if(pmt->pbFormat) SetLatency(pAudCap, ((WAVEFORMATEX*)pmt->pbFormat)->nAvgBytesPerSec * ms / 1000);
08767 }
08768
08769 CComPtr<IPin> pVidCapPin, pVidPrevPin, pAudCapPin, pAudPrevPin;
08770 BuildToCapturePreviewPin(pVidCap, &pVidCapPin, &pVidPrevPin, pAudCap, &pAudCapPin, &pAudPrevPin);
08771
08772 CGraphBuilderCapture gb(pGB, m_wndView.m_hWnd);
08773
08774
08775 {
08776 bool fVidPrev = pVidPrevPin && fVPreview;
08777 bool fVidCap = pVidCapPin && fVCapture && fFileOutput && m_wndCaptureBar.m_capdlg.m_fVidOutput;
08778
08779 if(fVidPrev && !fVidCap && pVidCapPin)
08780 {
08781 pVidPrevPin = pVidCapPin;
08782 pVidCapPin = NULL;
08783 }
08784
08785 if(fVidPrev)
08786 {
08787 m_pCAP = NULL;
08788 gb.Render(pVidPrevPin);
08789 gb.FindInterface(__uuidof(ISubPicAllocatorPresenter), (void**)&m_pCAP);
08790 }
08791
08792 if(fVidCap)
08793 {
08794 IBaseFilter* pBF[3] = {pVidBuffer, pVidEnc, pMux};
08795 HRESULT hr = BuildCapture(pVidCapPin, pBF, MEDIATYPE_Video, &m_wndCaptureBar.m_capdlg.m_mtcv);
08796 }
08797
08798 pAMDF = NULL;
08799 pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, pVidCap, IID_IAMDroppedFrames, (void**)&pAMDF);
08800 }
08801
08802
08803 {
08804 bool fAudPrev = pAudPrevPin && fAPreview;
08805 bool fAudCap = pAudCapPin && fACapture && fFileOutput && m_wndCaptureBar.m_capdlg.m_fAudOutput;
08806
08807 if(fAudPrev)
08808 {
08809 gb.Render(fAudCap ? pAudPrevPin : pAudCapPin);
08810 }
08811
08812 if(fAudCap)
08813 {
08814 IBaseFilter* pBF[3] = {pAudBuffer, pAudEnc, pAudMux ? pAudMux : pMux};
08815 HRESULT hr = BuildCapture(pAudCapPin, pBF, MEDIATYPE_Audio, &m_wndCaptureBar.m_capdlg.m_mtca);
08816 }
08817 }
08818
08819 if((pVidCap || pAudCap) && fCapture && fFileOutput)
08820 {
08821 if(pMux != pDst)
08822 {
08823 hr = pGB->AddFilter(pDst, L"File Writer V/A");
08824 hr = pCGB->RenderStream(NULL, NULL, pMux, NULL, pDst);
08825 }
08826
08827 if(CComQIPtr<IConfigAviMux> pCAM = pMux)
08828 {
08829 int nIn, nOut, nInC, nOutC;
08830 CountPins(pMux, nIn, nOut, nInC, nOutC);
08831 pCAM->SetMasterStream(nInC-1);
08832
08833 pCAM->SetOutputCompatibilityIndex(FALSE);
08834 }
08835
08836 if(CComQIPtr<IConfigInterleaving> pCI = pMux)
08837 {
08838
08839 if(FAILED(pCI->put_Mode(INTERLEAVE_NONE_BUFFERED)))
08840 pCI->put_Mode(INTERLEAVE_NONE);
08841
08842 REFERENCE_TIME rtInterleave = 10000i64*AUDIOBUFFERLEN, rtPreroll = 0;
08843 pCI->put_Interleaving(&rtInterleave, &rtPreroll);
08844 }
08845
08846 if(pMux != pAudMux && pAudMux != pAudDst)
08847 {
08848 hr = pGB->AddFilter(pAudDst, L"File Writer A");
08849 hr = pCGB->RenderStream(NULL, NULL, pAudMux, NULL, pAudDst);
08850 }
08851 }
08852
08853 REFERENCE_TIME stop = MAX_TIME;
08854 hr = pCGB->ControlStream(&PIN_CATEGORY_CAPTURE, NULL, NULL, NULL, &stop, 0, 0);
08855
08856 CleanGraph();
08857
08858 OpenSetupVideo();
08859 OpenSetupStatsBar();
08860 OpenSetupStatusBar();
08861
08862 RestoreMediaState;
08863
08864 return(true);
08865 }
08866
08867 bool CMainFrame::StartCapture()
08868 {
08869 if(!pCGB || m_fCapturing) return(false);
08870
08871 if(!m_wndCaptureBar.m_capdlg.m_pMux && !m_wndCaptureBar.m_capdlg.m_pDst) return(false);
08872
08873 HRESULT hr;
08874
08875 ::SetPriorityClass(::GetCurrentProcess(), HIGH_PRIORITY_CLASS);
08876
08877
08878
08879
08880 BuildGraphVideoAudio(
08881 !!m_wndCaptureBar.m_capdlg.m_fVidPreview, true,
08882 !!m_wndCaptureBar.m_capdlg.m_fAudPreview, true);
08883
08884 hr = pME->CancelDefaultHandling(EC_REPAINT);
08885
08886 SendMessage(WM_COMMAND, ID_PLAY_PLAY);
08887
08888 m_fCapturing = true;
08889
08890 return(true);
08891 }
08892
08893 bool CMainFrame::StopCapture()
08894 {
08895 if(!pCGB || !m_fCapturing) return(false);
08896
08897 if(!m_wndCaptureBar.m_capdlg.m_pMux && !m_wndCaptureBar.m_capdlg.m_pDst) return(false);
08898
08899 HRESULT hr;
08900
08901 m_wndStatusBar.SetStatusMessage(_T("Completing..."));
08902
08903 m_fCapturing = false;
08904
08905 BuildGraphVideoAudio(
08906 !!m_wndCaptureBar.m_capdlg.m_fVidPreview, false,
08907 !!m_wndCaptureBar.m_capdlg.m_fAudPreview, false);
08908
08909 hr = pME->RestoreDefaultHandling(EC_REPAINT);
08910
08911 ::SetPriorityClass(::GetCurrentProcess(), AfxGetAppSettings().priority);
08912
08913 m_rtDurationOverride = -1;
08914
08915 return(true);
08916 }
08917
08918
08919
08920 void CMainFrame::ShowOptions(int idPage)
08921 {
08922 AppSettings& s = AfxGetAppSettings();
08923
08924 CPPageSheet options(ResStr(IDS_OPTIONS_CAPTION), pGB, this, idPage);
08925
08926 if(options.DoModal() == IDOK)
08927 {
08928 if(!m_fFullScreen)
08929 SetAlwaysOnTop(s.iOnTop);
08930
08931 m_wndView.LoadLogo();
08932
08933 s.UpdateData(true);
08934 }
08935 }
08936
08937 void CMainFrame::StartWebServer(int nPort)
08938 {
08939 if(!m_pWebServer)
08940 m_pWebServer.Attach(new CWebServer(this, nPort));
08941 }
08942
08943 void CMainFrame::StopWebServer()
08944 {
08945 if(m_pWebServer)
08946 m_pWebServer.Free();
08947 }
08948
08949 CString CMainFrame::GetStatusMessage()
08950 {
08951 CString str;
08952 m_wndStatusBar.m_status.GetWindowText(str);
08953 return str;
08954 }
08955
08956 void CMainFrame::SendStatusMessage(CString msg, int nTimeOut)
08957 {
08958 KillTimer(TIMER_STATUSERASER);
08959
08960 m_playingmsg.Empty();
08961 if(nTimeOut <= 0) return;
08962
08963 m_playingmsg = msg;
08964 SetTimer(TIMER_STATUSERASER, nTimeOut, NULL);
08965 }
08966
08967 void CMainFrame::OpenCurPlaylistItem(REFERENCE_TIME rtStart)
08968 {
08969 if(m_wndPlaylistBar.GetCount() == 0)
08970 return;
08971
08972 CPlaylistItem pli;
08973 if(!m_wndPlaylistBar.GetCur(pli)) m_wndPlaylistBar.SetFirst();
08974 if(!m_wndPlaylistBar.GetCur(pli)) return;
08975
08976 CAutoPtr<OpenMediaData> p(m_wndPlaylistBar.GetCurOMD(rtStart));
08977 if(p) OpenMedia(p);
08978 }
08979
08980 void CMainFrame::AddCurDevToPlaylist()
08981 {
08982 if(m_iPlaybackMode == PM_CAPTURE)
08983 {
08984 m_wndPlaylistBar.Append(
08985 m_VidDispName,
08986 m_AudDispName,
08987 m_wndCaptureBar.m_capdlg.GetVideoInput(),
08988 m_wndCaptureBar.m_capdlg.GetVideoChannel(),
08989 m_wndCaptureBar.m_capdlg.GetAudioInput()
08990 );
08991 }
08992 }
08993
08994 static int s_fOpenedThruThread = false;
08995
08996 void CMainFrame::OpenMedia(CAutoPtr<OpenMediaData> pOMD)
08997 {
08998
08999 if(OpenDeviceData* p = dynamic_cast<OpenDeviceData*>(pOMD.m_p))
09000 {
09001 if(m_iMediaLoadState == MLS_LOADED && pAMTuner
09002 && m_VidDispName == p->DisplayName[0] && m_AudDispName == p->DisplayName[1])
09003 {
09004 m_wndCaptureBar.m_capdlg.SetVideoInput(p->vinput);
09005 m_wndCaptureBar.m_capdlg.SetVideoChannel(p->vchannel);
09006 m_wndCaptureBar.m_capdlg.SetAudioInput(p->ainput);
09007 SendNowPlayingToMSN();
09008 return;
09009 }
09010 }
09011
09012 if(m_iMediaLoadState != MLS_CLOSED)
09013 CloseMedia();
09014
09015 AppSettings& s = AfxGetAppSettings();
09016
09017 bool fUseThread = true;
09018
09019 if(OpenFileData* p = dynamic_cast<OpenFileData*>(pOMD.m_p))
09020 {
09021 if(p->fns.GetCount() > 0)
09022 {
09023 engine_t e = s.Formats.GetEngine(p->fns.GetHead());
09024 fUseThread = e == DirectShow ;
09025 }
09026 }
09027 else if(OpenDeviceData* p = dynamic_cast<OpenDeviceData*>(pOMD.m_p))
09028 {
09029 fUseThread = false;
09030 }
09031
09032 if(m_pGraphThread && fUseThread
09033 && AfxGetAppSettings().fEnableWorkerThreadForOpening)
09034 {
09035 m_pGraphThread->PostThreadMessage(CGraphThread::TM_OPEN, 0, (LPARAM)pOMD.Detach());
09036 s_fOpenedThruThread = true;
09037 }
09038 else
09039 {
09040 OpenMediaPrivate(pOMD);
09041 s_fOpenedThruThread = false;
09042 }
09043 }
09044
09045 void CMainFrame::CloseMedia()
09046 {
09047 if(m_iMediaLoadState == MLS_CLOSING)
09048 {
09049 TRACE(_T("WARNING: CMainFrame::CloseMedia() called twice or more\n"));
09050 return;
09051 }
09052
09053 int nTimeWaited = 0;
09054
09055 while(m_iMediaLoadState == MLS_LOADING)
09056 {
09057 m_fOpeningAborted = true;
09058
09059 if(pGB) pGB->Abort();
09060
09061 if(nTimeWaited > 5*1000 && m_pGraphThread)
09062 {
09063 MessageBeep(MB_ICONEXCLAMATION);
09064 TRACE(_T("CRITICAL ERROR: !!! Must kill opener thread !!!"));
09065 TerminateThread(m_pGraphThread->m_hThread, -1);
09066 m_pGraphThread = (CGraphThread*)AfxBeginThread(RUNTIME_CLASS(CGraphThread));
09067 s_fOpenedThruThread = false;
09068 break;
09069 }
09070
09071 Sleep(50);
09072
09073 nTimeWaited += 50;
09074 }
09075
09076 m_fOpeningAborted = false;
09077
09078 m_closingmsg.Empty();
09079
09080 m_iMediaLoadState = MLS_CLOSING;
09081
09082 OnFilePostClosemedia();
09083
09084 if(m_pGraphThread && s_fOpenedThruThread)
09085 {
09086 CAMEvent e;
09087 m_pGraphThread->PostThreadMessage(CGraphThread::TM_CLOSE, 0, (LPARAM)&e);
09088 e.Wait();
09089 }
09090 else
09091 {
09092 CloseMediaPrivate();
09093 }
09094
09095 UnloadExternalObjects();
09096 }
09097
09098
09099
09100
09101
09102 IMPLEMENT_DYNCREATE(CGraphThread, CWinThread)
09103
09104 BOOL CGraphThread::InitInstance()
09105 {
09106 AfxSocketInit();
09107 return SUCCEEDED(CoInitialize(0)) ? TRUE : FALSE;
09108 }
09109
09110 int CGraphThread::ExitInstance()
09111 {
09112 CoUninitialize();
09113 return __super::ExitInstance();
09114 }
09115
09116 BEGIN_MESSAGE_MAP(CGraphThread, CWinThread)
09117 ON_THREAD_MESSAGE(TM_EXIT, OnExit)
09118 ON_THREAD_MESSAGE(TM_OPEN, OnOpen)
09119 ON_THREAD_MESSAGE(TM_CLOSE, OnClose)
09120 END_MESSAGE_MAP()
09121
09122 void CGraphThread::OnExit(WPARAM wParam, LPARAM lParam)
09123 {
09124 PostQuitMessage(0);
09125 if(CAMEvent* e = (CAMEvent*)lParam) e->Set();
09126 }
09127
09128 void CGraphThread::OnOpen(WPARAM wParam, LPARAM lParam)
09129 {
09130 if(m_pMainFrame)
09131 {
09132 CAutoPtr<OpenMediaData> pOMD((OpenMediaData*)lParam);
09133 m_pMainFrame->OpenMediaPrivate(pOMD);
09134 }
09135 }
09136
09137 void CGraphThread::OnClose(WPARAM wParam, LPARAM lParam)
09138 {
09139 if(m_pMainFrame) m_pMainFrame->CloseMediaPrivate();
09140 if(CAMEvent* e = (CAMEvent*)lParam) e->Set();
09141 }
09142
09143