2 * Copyright (C) 2003-2006 Gabest
3 * http://www.gabest.org
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with GNU Make; see the file COPYING. If not, write to
17 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18 * http://www.gnu.org/copyleft/gpl.html
22 // MainFrm.cpp : implementation of the CMainFrame class
38 #include "OpenFileDlg.h"
42 #include "PnSPresetsDlg.h"
43 #include "MediaTypesDlg.h"
44 #include "SaveTextFileDialog.h"
45 #include "SaveThumbnailsDialog.h"
46 #include "FavoriteAddDlg.h"
47 #include "FavoriteOrganizeDlg.h"
48 #include "ConvertDlg.h"
49 #include "ShaderCombineDlg.h"
60 #include "..\..\..\include\moreuuids.h"
64 #include "..\..\DSUtil\DSUtil.h"
65 #include "FGManager.h"
67 #include "textpassthrufilter.h"
68 #include "..\..\filters\filters.h"
69 #include "..\..\filters\PinInfoWnd.h"
71 #include "DX7AllocatorPresenter.h"
72 #include "DX9AllocatorPresenter.h"
74 #include "..\..\subtitles\SSF.h"
76 #define DEFCLIENTW 292
77 #define DEFCLIENTH 200
79 static UINT s_uTaskbarRestart
= RegisterWindowMessage(TEXT("TaskbarCreated"));
80 static UINT WM_NOTIFYICON
= RegisterWindowMessage(TEXT("MYWM_NOTIFYICON"));
82 #include "..\..\filters\transform\vsfilter\IDirectVobSub.h"
84 class CSubClock
: public CUnknown
, public ISubClock
86 STDMETHODIMP
NonDelegatingQueryInterface(REFIID riid
, void** ppv
)
90 CUnknown::NonDelegatingQueryInterface(riid
, ppv
);
96 CSubClock() : CUnknown(NAME("CSubClock"), NULL
) {m_rt
= 0;}
101 STDMETHODIMP
SetTime(REFERENCE_TIME rt
) {m_rt
= rt
; return S_OK
;}
102 STDMETHODIMP_(REFERENCE_TIME
) GetTime() {return(m_rt
);}
107 #define SaveMediaState \
108 OAFilterState __fs = GetMediaState(); \
110 REFERENCE_TIME __rt = 0; \
111 if(m_iMediaLoadState == MLS_LOADED) __rt = GetPos(); \
113 if(__fs != State_Stopped) \
114 SendMessage(WM_COMMAND, ID_PLAY_STOP); \
117 #define RestoreMediaState \
118 if(m_iMediaLoadState == MLS_LOADED) \
122 if(__fs == State_Stopped) \
123 SendMessage(WM_COMMAND, ID_PLAY_STOP); \
124 else if(__fs == State_Paused) \
125 SendMessage(WM_COMMAND, ID_PLAY_PAUSE); \
126 else if(__fs == State_Running) \
127 SendMessage(WM_COMMAND, ID_PLAY_PLAY); \
132 #define new DEBUG_NEW
134 static char THIS_FILE[] = __FILE__;
137 /////////////////////////////////////////////////////////////////////////////
140 IMPLEMENT_DYNAMIC(CMainFrame
, CFrameWnd
)
142 BEGIN_MESSAGE_MAP(CMainFrame
, CFrameWnd
)
147 ON_REGISTERED_MESSAGE(s_uTaskbarRestart
, OnTaskBarRestart
)
148 ON_REGISTERED_MESSAGE(WM_NOTIFYICON
, OnNotifyIcon
)
151 ON_WM_GETMINMAXINFO()
156 ON_MESSAGE_VOID(WM_DISPLAYCHANGE
, OnDisplayChange
)
160 ON_MESSAGE(WM_APPCOMMAND
, OnAppCommand
)
164 ON_MESSAGE(WM_GRAPHNOTIFY
, OnGraphNotify
)
165 ON_MESSAGE(WM_REARRANGERENDERLESS
, OnRepaintRenderLess
)
166 ON_MESSAGE(WM_RESUMEFROMSTATE
, OnResumeFromState
)
170 ON_WM_LBUTTONDBLCLK()
173 ON_WM_MBUTTONDBLCLK()
176 ON_WM_RBUTTONDBLCLK()
177 ON_MESSAGE(WM_XBUTTONDOWN
, OnXButtonDown
)
178 ON_MESSAGE(WM_XBUTTONUP
, OnXButtonUp
)
179 ON_MESSAGE(WM_XBUTTONDBLCLK
, OnXButtonDblClk
)
188 ON_WM_INITMENUPOPUP()
190 ON_COMMAND(ID_MENU_PLAYER_SHORT
, OnMenuPlayerShort
)
191 ON_COMMAND(ID_MENU_PLAYER_LONG
, OnMenuPlayerLong
)
192 ON_COMMAND(ID_MENU_FILTERS
, OnMenuFilters
)
194 ON_UPDATE_COMMAND_UI(IDC_PLAYERSTATUS
, OnUpdatePlayerStatus
)
196 ON_COMMAND(ID_FILE_POST_OPENMEDIA
, OnFilePostOpenmedia
)
197 ON_UPDATE_COMMAND_UI(ID_FILE_POST_OPENMEDIA
, OnUpdateFilePostOpenmedia
)
198 ON_COMMAND(ID_FILE_POST_CLOSEMEDIA
, OnFilePostClosemedia
)
199 ON_UPDATE_COMMAND_UI(ID_FILE_POST_CLOSEMEDIA
, OnUpdateFilePostClosemedia
)
201 ON_COMMAND(ID_BOSS
, OnBossKey
)
203 ON_COMMAND_RANGE(ID_STREAM_AUDIO_NEXT
, ID_STREAM_AUDIO_PREV
, OnStreamAudio
)
204 ON_COMMAND_RANGE(ID_STREAM_SUB_NEXT
, ID_STREAM_SUB_PREV
, OnStreamSub
)
205 ON_COMMAND(ID_STREAM_SUB_ONOFF
, OnStreamSubOnOff
)
206 ON_COMMAND_RANGE(ID_OGM_AUDIO_NEXT
, ID_OGM_AUDIO_PREV
, OnOgmAudio
)
207 ON_COMMAND_RANGE(ID_OGM_SUB_NEXT
, ID_OGM_SUB_PREV
, OnOgmSub
)
208 ON_COMMAND_RANGE(ID_DVD_ANGLE_NEXT
, ID_DVD_ANGLE_PREV
, OnDvdAngle
)
209 ON_COMMAND_RANGE(ID_DVD_AUDIO_NEXT
, ID_DVD_AUDIO_PREV
, OnDvdAudio
)
210 ON_COMMAND_RANGE(ID_DVD_SUB_NEXT
, ID_DVD_SUB_PREV
, OnDvdSub
)
211 ON_COMMAND(ID_DVD_SUB_ONOFF
, OnDvdSubOnOff
)
214 ON_COMMAND(ID_FILE_OPENQUICK
, OnFileOpenQuick
)
215 ON_UPDATE_COMMAND_UI(ID_FILE_OPENMEDIA
, OnUpdateFileOpen
)
216 ON_COMMAND(ID_FILE_OPENMEDIA
, OnFileOpenmedia
)
217 ON_UPDATE_COMMAND_UI(ID_FILE_OPENMEDIA
, OnUpdateFileOpen
)
219 ON_COMMAND(ID_FILE_OPENDVD
, OnFileOpendvd
)
220 ON_UPDATE_COMMAND_UI(ID_FILE_OPENDVD
, OnUpdateFileOpen
)
221 ON_COMMAND(ID_FILE_OPENDEVICE
, OnFileOpendevice
)
222 ON_UPDATE_COMMAND_UI(ID_FILE_OPENDEVICE
, OnUpdateFileOpen
)
223 ON_COMMAND_RANGE(ID_FILE_OPEN_CD_START
, ID_FILE_OPEN_CD_END
, OnFileOpenCD
)
224 ON_UPDATE_COMMAND_UI_RANGE(ID_FILE_OPEN_CD_START
, ID_FILE_OPEN_CD_END
, OnUpdateFileOpen
)
226 ON_COMMAND(ID_FILE_SAVE_COPY
, OnFileSaveAs
)
227 ON_UPDATE_COMMAND_UI(ID_FILE_SAVE_COPY
, OnUpdateFileSaveAs
)
228 ON_COMMAND(ID_FILE_SAVE_IMAGE
, OnFileSaveImage
)
229 ON_UPDATE_COMMAND_UI(ID_FILE_SAVE_IMAGE
, OnUpdateFileSaveImage
)
230 ON_COMMAND(ID_FILE_SAVE_IMAGE_AUTO
, OnFileSaveImageAuto
)
231 ON_UPDATE_COMMAND_UI(ID_FILE_SAVE_IMAGE_AUTO
, OnUpdateFileSaveImage
)
232 ON_COMMAND(ID_FILE_SAVE_THUMBNAILS
, OnFileSaveThumbnails
)
233 ON_UPDATE_COMMAND_UI(ID_FILE_SAVE_THUMBNAILS
, OnUpdateFileSaveThumbnails
)
234 ON_COMMAND(ID_FILE_CONVERT
, OnFileConvert
)
235 ON_UPDATE_COMMAND_UI(ID_FILE_CONVERT
, OnUpdateFileConvert
)
236 ON_COMMAND(ID_FILE_LOAD_SUBTITLE
, OnFileLoadsubtitle
)
237 ON_UPDATE_COMMAND_UI(ID_FILE_LOAD_SUBTITLE
, OnUpdateFileLoadsubtitle
)
238 ON_COMMAND(ID_FILE_SAVE_SUBTITLE
, OnFileSavesubtitle
)
239 ON_UPDATE_COMMAND_UI(ID_FILE_SAVE_SUBTITLE
, OnUpdateFileSavesubtitle
)
240 ON_COMMAND(ID_FILE_ISDB_SEARCH
, OnFileISDBSearch
)
241 ON_UPDATE_COMMAND_UI(ID_FILE_ISDB_SEARCH
, OnUpdateFileISDBSearch
)
242 ON_COMMAND(ID_FILE_ISDB_UPLOAD
, OnFileISDBUpload
)
243 ON_UPDATE_COMMAND_UI(ID_FILE_ISDB_UPLOAD
, OnUpdateFileISDBUpload
)
244 ON_COMMAND(ID_FILE_ISDB_DOWNLOAD
, OnFileISDBDownload
)
245 ON_UPDATE_COMMAND_UI(ID_FILE_ISDB_DOWNLOAD
, OnUpdateFileISDBDownload
)
246 ON_COMMAND(ID_FILE_PROPERTIES
, OnFileProperties
)
247 ON_UPDATE_COMMAND_UI(ID_FILE_PROPERTIES
, OnUpdateFileProperties
)
248 ON_COMMAND(ID_FILE_CLOSEPLAYLIST
, OnFileClosePlaylist
)
249 ON_COMMAND(ID_FILE_CLOSEMEDIA
, OnFileCloseMedia
)
250 ON_UPDATE_COMMAND_UI(ID_FILE_CLOSEMEDIA
, OnUpdateFileClose
)
252 ON_COMMAND(ID_VIEW_CAPTIONMENU
, OnViewCaptionmenu
)
253 ON_UPDATE_COMMAND_UI(ID_VIEW_CAPTIONMENU
, OnUpdateViewCaptionmenu
)
254 ON_COMMAND_RANGE(ID_VIEW_SEEKER
, ID_VIEW_STATUS
, OnViewControlBar
)
255 ON_UPDATE_COMMAND_UI_RANGE(ID_VIEW_SEEKER
, ID_VIEW_STATUS
, OnUpdateViewControlBar
)
256 ON_COMMAND(ID_VIEW_SUBRESYNC
, OnViewSubresync
)
257 ON_UPDATE_COMMAND_UI(ID_VIEW_SUBRESYNC
, OnUpdateViewSubresync
)
258 ON_COMMAND(ID_VIEW_PLAYLIST
, OnViewPlaylist
)
259 ON_UPDATE_COMMAND_UI(ID_VIEW_PLAYLIST
, OnUpdateViewPlaylist
)
260 ON_COMMAND(ID_VIEW_CAPTURE
, OnViewCapture
)
261 ON_UPDATE_COMMAND_UI(ID_VIEW_CAPTURE
, OnUpdateViewCapture
)
262 ON_COMMAND(ID_VIEW_SHADEREDITOR
, OnViewShaderEditor
)
263 ON_UPDATE_COMMAND_UI(ID_VIEW_SHADEREDITOR
, OnUpdateViewShaderEditor
)
264 ON_COMMAND(ID_VIEW_PRESETS_MINIMAL
, OnViewMinimal
)
265 ON_UPDATE_COMMAND_UI(ID_VIEW_PRESETS_MINIMAL
, OnUpdateViewMinimal
)
266 ON_COMMAND(ID_VIEW_PRESETS_COMPACT
, OnViewCompact
)
267 ON_UPDATE_COMMAND_UI(ID_VIEW_PRESETS_COMPACT
, OnUpdateViewCompact
)
268 ON_COMMAND(ID_VIEW_PRESETS_NORMAL
, OnViewNormal
)
269 ON_UPDATE_COMMAND_UI(ID_VIEW_PRESETS_NORMAL
, OnUpdateViewNormal
)
270 ON_COMMAND(ID_VIEW_FULLSCREEN
, OnViewFullscreen
)
271 ON_COMMAND(ID_VIEW_FULLSCREEN_SECONDARY
, OnViewFullscreenSecondary
)
272 ON_UPDATE_COMMAND_UI(ID_VIEW_FULLSCREEN
, OnUpdateViewFullscreen
)
273 ON_COMMAND_RANGE(ID_VIEW_ZOOM_50
, ID_VIEW_ZOOM_200
, OnViewZoom
)
274 ON_UPDATE_COMMAND_UI_RANGE(ID_VIEW_ZOOM_50
, ID_VIEW_ZOOM_200
, OnUpdateViewZoom
)
275 ON_COMMAND(ID_VIEW_ZOOM_AUTOFIT
, OnViewZoomAutoFit
)
276 ON_UPDATE_COMMAND_UI(ID_VIEW_ZOOM_AUTOFIT
, OnUpdateViewZoom
)
277 ON_COMMAND_RANGE(ID_VIEW_VF_HALF
, ID_VIEW_VF_FROMOUTSIDE
, OnViewDefaultVideoFrame
)
278 ON_UPDATE_COMMAND_UI_RANGE(ID_VIEW_VF_HALF
, ID_VIEW_VF_FROMOUTSIDE
, OnUpdateViewDefaultVideoFrame
)
279 ON_COMMAND(ID_VIEW_VF_KEEPASPECTRATIO
, OnViewKeepaspectratio
)
280 ON_UPDATE_COMMAND_UI(ID_VIEW_VF_KEEPASPECTRATIO
, OnUpdateViewKeepaspectratio
)
281 ON_COMMAND(ID_VIEW_VF_COMPMONDESKARDIFF
, OnViewCompMonDeskARDiff
)
282 ON_UPDATE_COMMAND_UI(ID_VIEW_VF_COMPMONDESKARDIFF
, OnUpdateViewCompMonDeskARDiff
)
283 ON_COMMAND_RANGE(ID_VIEW_RESET
, ID_PANSCAN_CENTER
, OnViewPanNScan
)
284 ON_UPDATE_COMMAND_UI_RANGE(ID_VIEW_RESET
, ID_PANSCAN_CENTER
, OnUpdateViewPanNScan
)
285 ON_COMMAND_RANGE(ID_PANNSCAN_PRESETS_START
, ID_PANNSCAN_PRESETS_END
, OnViewPanNScanPresets
)
286 ON_UPDATE_COMMAND_UI_RANGE(ID_PANNSCAN_PRESETS_START
, ID_PANNSCAN_PRESETS_END
, OnUpdateViewPanNScanPresets
)
287 ON_COMMAND_RANGE(ID_PANSCAN_ROTATEXP
, ID_PANSCAN_ROTATEZM
, OnViewRotate
)
288 ON_UPDATE_COMMAND_UI_RANGE(ID_PANSCAN_ROTATEXP
, ID_PANSCAN_ROTATEZM
, OnUpdateViewRotate
)
289 ON_COMMAND_RANGE(ID_ASPECTRATIO_START
, ID_ASPECTRATIO_END
, OnViewAspectRatio
)
290 ON_UPDATE_COMMAND_UI_RANGE(ID_ASPECTRATIO_START
, ID_ASPECTRATIO_END
, OnUpdateViewAspectRatio
)
291 ON_COMMAND(ID_ASPECTRATIO_NEXT
, OnViewAspectRatioNext
)
292 ON_COMMAND_RANGE(ID_ONTOP_NEVER
, ID_ONTOP_WHILEPLAYING
, OnViewOntop
)
293 ON_UPDATE_COMMAND_UI_RANGE(ID_ONTOP_NEVER
, ID_ONTOP_WHILEPLAYING
, OnUpdateViewOntop
)
294 ON_COMMAND(ID_VIEW_OPTIONS
, OnViewOptions
)
296 ON_COMMAND_RANGE(ID_SUB_DELAY_DOWN
, ID_SUB_DELAY_UP
, OnSubtitleDelay
)
298 ON_COMMAND(ID_PLAY_PLAY
, OnPlayPlay
)
299 ON_COMMAND(ID_PLAY_PAUSE
, OnPlayPause
)
300 ON_COMMAND(ID_PLAY_PLAYPAUSE
, OnPlayPlaypause
)
301 ON_COMMAND(ID_PLAY_STOP
, OnPlayStop
)
302 ON_UPDATE_COMMAND_UI(ID_PLAY_PLAY
, OnUpdatePlayPauseStop
)
303 ON_UPDATE_COMMAND_UI(ID_PLAY_PAUSE
, OnUpdatePlayPauseStop
)
304 ON_UPDATE_COMMAND_UI(ID_PLAY_PLAYPAUSE
, OnUpdatePlayPauseStop
)
305 ON_UPDATE_COMMAND_UI(ID_PLAY_STOP
, OnUpdatePlayPauseStop
)
306 ON_COMMAND_RANGE(ID_PLAY_FRAMESTEP
, ID_PLAY_FRAMESTEPCANCEL
, OnPlayFramestep
)
307 ON_UPDATE_COMMAND_UI_RANGE(ID_PLAY_FRAMESTEP
, ID_PLAY_FRAMESTEPCANCEL
, OnUpdatePlayFramestep
)
308 ON_COMMAND_RANGE(ID_PLAY_SEEKBACKWARDSMALL
, ID_PLAY_SEEKFORWARDLARGE
, OnPlaySeek
)
309 ON_COMMAND_RANGE(ID_PLAY_SEEKKEYBACKWARD
, ID_PLAY_SEEKKEYFORWARD
, OnPlaySeekKey
)
310 ON_UPDATE_COMMAND_UI_RANGE(ID_PLAY_SEEKBACKWARDSMALL
, ID_PLAY_SEEKFORWARDLARGE
, OnUpdatePlaySeek
)
311 ON_UPDATE_COMMAND_UI_RANGE(ID_PLAY_SEEKKEYBACKWARD
, ID_PLAY_SEEKKEYFORWARD
, OnUpdatePlaySeek
)
312 ON_COMMAND(ID_PLAY_GOTO
, OnPlayGoto
)
313 ON_UPDATE_COMMAND_UI(ID_PLAY_GOTO
, OnUpdateGoto
)
314 ON_COMMAND_RANGE(ID_PLAY_DECRATE
, ID_PLAY_INCRATE
, OnPlayChangeRate
)
315 ON_UPDATE_COMMAND_UI_RANGE(ID_PLAY_DECRATE
, ID_PLAY_INCRATE
, OnUpdatePlayChangeRate
)
316 ON_COMMAND(ID_PLAY_RESETRATE
, OnPlayResetRate
)
317 ON_UPDATE_COMMAND_UI(ID_PLAY_RESETRATE
, OnUpdatePlayResetRate
)
318 ON_COMMAND_RANGE(ID_PLAY_INCAUDDELAY
, ID_PLAY_DECAUDDELAY
, OnPlayChangeAudDelay
)
319 ON_UPDATE_COMMAND_UI_RANGE(ID_PLAY_INCAUDDELAY
, ID_PLAY_DECAUDDELAY
, OnUpdatePlayChangeAudDelay
)
320 ON_COMMAND_RANGE(ID_FILTERS_SUBITEM_START
, ID_FILTERS_SUBITEM_END
, OnPlayFilters
)
321 ON_UPDATE_COMMAND_UI_RANGE(ID_FILTERS_SUBITEM_START
, ID_FILTERS_SUBITEM_END
, OnUpdatePlayFilters
)
322 ON_COMMAND_RANGE(ID_SHADERS_START
, ID_SHADERS_END
, OnPlayShaders
)
323 ON_UPDATE_COMMAND_UI_RANGE(ID_SHADERS_START
, ID_SHADERS_END
, OnUpdatePlayShaders
)
324 ON_COMMAND_RANGE(ID_AUDIO_SUBITEM_START
, ID_AUDIO_SUBITEM_END
, OnPlayAudio
)
325 ON_UPDATE_COMMAND_UI_RANGE(ID_AUDIO_SUBITEM_START
, ID_AUDIO_SUBITEM_END
, OnUpdatePlayAudio
)
326 ON_COMMAND_RANGE(ID_SUBTITLES_SUBITEM_START
, ID_SUBTITLES_SUBITEM_END
, OnPlaySubtitles
)
327 ON_UPDATE_COMMAND_UI_RANGE(ID_SUBTITLES_SUBITEM_START
, ID_SUBTITLES_SUBITEM_END
, OnUpdatePlaySubtitles
)
328 ON_COMMAND_RANGE(ID_FILTERSTREAMS_SUBITEM_START
, ID_FILTERSTREAMS_SUBITEM_END
, OnPlayLanguage
)
329 ON_UPDATE_COMMAND_UI_RANGE(ID_FILTERSTREAMS_SUBITEM_START
, ID_FILTERSTREAMS_SUBITEM_END
, OnUpdatePlayLanguage
)
330 ON_COMMAND_RANGE(ID_VOLUME_UP
, ID_VOLUME_MUTE
, OnPlayVolume
)
331 ON_COMMAND_RANGE(ID_VOLUME_BOOST_INC
, ID_VOLUME_BOOST_MAX
, OnPlayVolumeBoost
)
332 ON_UPDATE_COMMAND_UI_RANGE(ID_VOLUME_BOOST_INC
, ID_VOLUME_BOOST_MAX
, OnUpdatePlayVolumeBoost
)
333 ON_COMMAND_RANGE(ID_AFTERPLAYBACK_CLOSE
, ID_AFTERPLAYBACK_DONOTHING
, OnAfterplayback
)
334 ON_UPDATE_COMMAND_UI_RANGE(ID_AFTERPLAYBACK_CLOSE
, ID_AFTERPLAYBACK_DONOTHING
, OnUpdateAfterplayback
)
336 ON_COMMAND_RANGE(ID_NAVIGATE_SKIPBACK
, ID_NAVIGATE_SKIPFORWARD
, OnNavigateSkip
)
337 ON_UPDATE_COMMAND_UI_RANGE(ID_NAVIGATE_SKIPBACK
, ID_NAVIGATE_SKIPFORWARD
, OnUpdateNavigateSkip
)
338 ON_COMMAND_RANGE(ID_NAVIGATE_SKIPBACKPLITEM
, ID_NAVIGATE_SKIPFORWARDPLITEM
, OnNavigateSkipPlaylistItem
)
339 ON_UPDATE_COMMAND_UI_RANGE(ID_NAVIGATE_SKIPBACKPLITEM
, ID_NAVIGATE_SKIPFORWARDPLITEM
, OnUpdateNavigateSkipPlaylistItem
)
340 ON_COMMAND_RANGE(ID_NAVIGATE_TITLEMENU
, ID_NAVIGATE_CHAPTERMENU
, OnNavigateMenu
)
341 ON_UPDATE_COMMAND_UI_RANGE(ID_NAVIGATE_TITLEMENU
, ID_NAVIGATE_CHAPTERMENU
, OnUpdateNavigateMenu
)
342 ON_COMMAND_RANGE(ID_NAVIGATE_AUDIO_SUBITEM_START
, ID_NAVIGATE_AUDIO_SUBITEM_END
, OnNavigateAudio
)
343 ON_COMMAND_RANGE(ID_NAVIGATE_SUBP_SUBITEM_START
, ID_NAVIGATE_SUBP_SUBITEM_END
, OnNavigateSubpic
)
344 ON_COMMAND_RANGE(ID_NAVIGATE_ANGLE_SUBITEM_START
, ID_NAVIGATE_ANGLE_SUBITEM_END
, OnNavigateAngle
)
345 ON_COMMAND_RANGE(ID_NAVIGATE_CHAP_SUBITEM_START
, ID_NAVIGATE_CHAP_SUBITEM_END
, OnNavigateChapters
)
346 ON_COMMAND_RANGE(ID_NAVIGATE_MENU_LEFT
, ID_NAVIGATE_MENU_LEAVE
, OnNavigateMenuItem
)
347 ON_UPDATE_COMMAND_UI_RANGE(ID_NAVIGATE_MENU_LEFT
, ID_NAVIGATE_MENU_LEAVE
, OnUpdateNavigateMenuItem
)
349 ON_COMMAND(ID_FAVORITES_ADD
, OnFavoritesAdd
)
350 ON_UPDATE_COMMAND_UI(ID_FAVORITES_ADD
, OnUpdateFavoritesAdd
)
351 ON_COMMAND(ID_FAVORITES_ORGANIZE
, OnFavoritesOrganize
)
352 ON_UPDATE_COMMAND_UI(ID_FAVORITES_ORGANIZE
, OnUpdateFavoritesOrganize
)
353 ON_COMMAND_RANGE(ID_FAVORITES_FILE_START
, ID_FAVORITES_FILE_END
, OnFavoritesFile
)
354 ON_UPDATE_COMMAND_UI_RANGE(ID_FAVORITES_FILE_START
, ID_FAVORITES_FILE_END
, OnUpdateFavoritesFile
)
355 ON_COMMAND_RANGE(ID_FAVORITES_DVD_START
, ID_FAVORITES_DVD_END
, OnFavoritesDVD
)
356 ON_UPDATE_COMMAND_UI_RANGE(ID_FAVORITES_DVD_START
, ID_FAVORITES_DVD_END
, OnUpdateFavoritesDVD
)
357 ON_COMMAND_RANGE(ID_FAVORITES_DEVICE_START
, ID_FAVORITES_DEVICE_END
, OnFavoritesDevice
)
358 ON_UPDATE_COMMAND_UI_RANGE(ID_FAVORITES_DEVICE_START
, ID_FAVORITES_DEVICE_END
, OnUpdateFavoritesDevice
)
360 ON_COMMAND(ID_HELP_HOMEPAGE
, OnHelpHomepage
)
361 ON_COMMAND(ID_HELP_DOCUMENTATION
, OnHelpDocumentation
)
365 /////////////////////////////////////////////////////////////////////////////
366 // CMainFrame construction/destruction
368 #pragma warning(disable : 4355)
370 CMainFrame::CMainFrame() :
372 m_iMediaLoadState(MLS_CLOSED
),
373 m_iPlaybackMode(PM_NONE
),
375 m_rtDurationOverride(-1),
376 m_fFullScreen(false),
377 m_fHideCursor(false),
378 m_lastMouseMove(-1, -1),
382 m_ZoomX(1), m_ZoomY(1), m_PosX(0.5), m_PosY(0.5),
383 m_AngleX(0), m_AngleY(0), m_AngleZ(0),
384 m_fCustomGraph(false),
385 m_fRealMediaGraph(false), m_fShockwaveGraph(false), m_fQuicktimeGraph(false),
386 m_fFrameSteppingActive(false),
387 m_fEndOfStream(false),
390 m_fOpeningAborted(false),
392 m_fileDropTarget(this),
397 CMainFrame::~CMainFrame()
399 // m_owner.DestroyWindow();
402 int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct
)
404 if(__super::OnCreate(lpCreateStruct
) == -1)
407 m_popup
.LoadMenu(IDR_POPUP
);
408 m_popupmain
.LoadMenu(IDR_POPUPMAIN
);
410 GetMenu()->ModifyMenu(ID_FAVORITES
, MF_BYCOMMAND
|MF_STRING
, IDR_MAINFRAME
, ResStr(IDS_FAVORITES_POPUP
));
412 // create a view to occupy the client area of the frame
413 if(!m_wndView
.Create(NULL
, NULL
, AFX_WS_DEFAULT_VIEW
,
414 CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST
, NULL
))
416 TRACE0("Failed to create view window\n");
422 if(!m_wndStatusBar
.Create(this)
423 || !m_wndStatsBar
.Create(this)
424 || !m_wndInfoBar
.Create(this)
425 || !m_wndToolBar
.Create(this)
426 || !m_wndSeekBar
.Create(this))
428 TRACE0("Failed to create all control bars\n");
429 return -1; // fail to create
432 m_bars
.AddTail(&m_wndSeekBar
);
433 m_bars
.AddTail(&m_wndToolBar
);
434 m_bars
.AddTail(&m_wndInfoBar
);
435 m_bars
.AddTail(&m_wndStatsBar
);
436 m_bars
.AddTail(&m_wndStatusBar
);
438 m_wndSeekBar
.Enable(false);
442 EnableDocking(CBRS_ALIGN_ANY
);
444 m_dockingbars
.RemoveAll();
446 m_wndSubresyncBar
.Create(this, &m_csSubLock
);
447 m_wndSubresyncBar
.SetBarStyle(m_wndSubresyncBar
.GetBarStyle() | CBRS_TOOLTIPS
| CBRS_FLYBY
| CBRS_SIZE_DYNAMIC
);
448 m_wndSubresyncBar
.EnableDocking(CBRS_ALIGN_ANY
);
449 m_wndSubresyncBar
.SetHeight(200);
450 LoadControlBar(&m_wndSubresyncBar
, AFX_IDW_DOCKBAR_TOP
);
452 m_wndPlaylistBar
.Create(this);
453 m_wndPlaylistBar
.SetBarStyle(m_wndPlaylistBar
.GetBarStyle() | CBRS_TOOLTIPS
| CBRS_FLYBY
| CBRS_SIZE_DYNAMIC
);
454 m_wndPlaylistBar
.EnableDocking(CBRS_ALIGN_ANY
);
455 m_wndPlaylistBar
.SetHeight(100);
456 LoadControlBar(&m_wndPlaylistBar
, AFX_IDW_DOCKBAR_BOTTOM
);
457 m_wndPlaylistBar
.LoadPlaylist();
459 m_wndCaptureBar
.Create(this);
460 m_wndCaptureBar
.SetBarStyle(m_wndCaptureBar
.GetBarStyle() | CBRS_TOOLTIPS
| CBRS_FLYBY
| CBRS_SIZE_DYNAMIC
);
461 m_wndCaptureBar
.EnableDocking(CBRS_ALIGN_LEFT
|CBRS_ALIGN_RIGHT
);
462 LoadControlBar(&m_wndCaptureBar
, AFX_IDW_DOCKBAR_LEFT
);
464 m_wndShaderEditorBar
.Create(this);
465 m_wndShaderEditorBar
.SetBarStyle(m_wndShaderEditorBar
.GetBarStyle() | CBRS_TOOLTIPS
| CBRS_FLYBY
| CBRS_SIZE_DYNAMIC
);
466 m_wndShaderEditorBar
.EnableDocking(CBRS_ALIGN_ANY
);
467 LoadControlBar(&m_wndShaderEditorBar
, AFX_IDW_DOCKBAR_TOP
);
469 m_fileDropTarget
.Register(this);
471 GetDesktopWindow()->GetWindowRect(&m_rcDesktop
);
473 AppSettings
& s
= AfxGetAppSettings();
477 SetAlwaysOnTop(s
.iOnTop
);
479 ShowTrayIcon(s
.fTrayIcon
);
483 m_pGraphThread
= (CGraphThread
*)AfxBeginThread(RUNTIME_CLASS(CGraphThread
));
486 m_pGraphThread
->SetMainFrame(this);
488 if(s
.fEnableWebServer
)
489 StartWebServer(s
.nWebServerPort
);
492 CString strList
= AfxGetAppSettings().strShaderList
;
496 strRes
= strList
.Tokenize (_T("|"), curPos
);
497 while (strRes
!= _T(""))
499 m_shaderlabels
.AddTail (strRes
);
500 strRes
= strList
.Tokenize(_T("|"),curPos
);
508 void CMainFrame::OnDestroy()
512 m_fileDropTarget
.Revoke();
517 m_pGraphThread
->PostThreadMessage(CGraphThread::TM_EXIT
, 0, (LPARAM
)&e
);
520 TRACE(_T("ERROR: Must call TerminateThread() on CMainFrame::m_pGraphThread->m_hThread\n"));
521 TerminateThread(m_pGraphThread
->m_hThread
, -1);
525 __super::OnDestroy();
528 void CMainFrame::OnClose()
532 CString strList
= "";
534 pos
= m_shaderlabels
.GetHeadPosition();
537 strList
+= m_shaderlabels
.GetAt (pos
) + "|";
538 m_dockingbars
.GetNext(pos
);
540 AfxGetAppSettings().strShaderList
= strList
;
543 m_wndPlaylistBar
.SavePlaylist();
554 DROPEFFECT
CMainFrame::OnDragEnter(COleDataObject
* pDataObject
, DWORD dwKeyState
, CPoint point
)
556 return DROPEFFECT_NONE
;
558 DROPEFFECT
CMainFrame::OnDragOver(COleDataObject
* pDataObject
, DWORD dwKeyState
, CPoint point
)
560 UINT CF_URL
= RegisterClipboardFormat(_T("UniformResourceLocator"));
561 return pDataObject
->IsDataAvailable(CF_URL
) ? DROPEFFECT_COPY
: DROPEFFECT_NONE
;
563 BOOL
CMainFrame::OnDrop(COleDataObject
* pDataObject
, DROPEFFECT dropEffect
, CPoint point
)
565 UINT CF_URL
= RegisterClipboardFormat(_T("UniformResourceLocator"));
567 BOOL bResult
= FALSE
;
569 if(pDataObject
->IsDataAvailable(CF_URL
))
571 FORMATETC fmt
= {CF_URL
, NULL
, DVASPECT_CONTENT
, -1, TYMED_HGLOBAL
};
572 if(HGLOBAL hGlobal
= pDataObject
->GetGlobalData(CF_URL
, &fmt
))
574 LPCSTR pText
= (LPCSTR
)GlobalLock(hGlobal
);
575 if(AfxIsValidString(pText
))
579 SetForegroundWindow();
581 CAtlList
<CString
> sl
;
582 sl
.AddTail(CString(url
));
584 if(m_wndPlaylistBar
.IsWindowVisible())
586 m_wndPlaylistBar
.Append(sl
, true);
590 m_wndPlaylistBar
.Open(sl
, true);
591 OpenCurPlaylistItem();
594 GlobalUnlock(hGlobal
);
602 DROPEFFECT
CMainFrame::OnDropEx(COleDataObject
* pDataObject
, DROPEFFECT dropDefault
, DROPEFFECT dropList
, CPoint point
)
604 return (DROPEFFECT
)-1;
606 void CMainFrame::OnDragLeave()
609 DROPEFFECT
CMainFrame::OnDragScroll(DWORD dwKeyState
, CPoint point
)
611 return DROPEFFECT_NONE
;
614 void CMainFrame::LoadControlBar(CControlBar
* pBar
, UINT defDockBarID
)
619 pBar
->GetWindowText(str
);
620 if(str
.IsEmpty()) return;
621 CString section
= _T("ToolBars\\") + str
;
623 CWinApp
* pApp
= AfxGetApp();
625 UINT nID
= pApp
->GetProfileInt(section
, _T("DockState"), defDockBarID
);
627 if(nID
!= AFX_IDW_DOCKBAR_FLOAT
)
629 DockControlBar(pBar
, nID
);
633 pApp
->GetProfileInt(section
, _T("Visible"), FALSE
)
634 && pBar
!= &m_wndSubresyncBar
635 && pBar
!= &m_wndCaptureBar
636 && pBar
!= &m_wndShaderEditorBar
640 if(CSizingControlBar
* pSCB
= dynamic_cast<CSizingControlBar
*>(pBar
))
642 pSCB
->LoadState(section
+ _T("\\State"));
643 m_dockingbars
.AddTail(pSCB
);
647 void CMainFrame::RestoreFloatingControlBars()
649 CWinApp
* pApp
= AfxGetApp();
654 POSITION pos
= m_dockingbars
.GetHeadPosition();
657 CSizingControlBar
* pBar
= m_dockingbars
.GetNext(pos
);
660 pBar
->GetWindowText(str
);
661 if(str
.IsEmpty()) return;
662 CString section
= _T("ToolBars\\") + str
;
664 if(pApp
->GetProfileInt(section
, _T("DockState"), AFX_IDW_DOCKBAR_FLOAT
) == AFX_IDW_DOCKBAR_FLOAT
)
667 p
.x
= pApp
->GetProfileInt(section
, _T("DockPosX"), 100);
668 p
.y
= pApp
->GetProfileInt(section
, _T("DockPosY"), 100);
669 if(p
.x
< m_rcDesktop
.left
) p
.x
= m_rcDesktop
.left
;
670 if(p
.y
< m_rcDesktop
.top
) p
.y
= m_rcDesktop
.top
;
671 if(p
.x
>= m_rcDesktop
.right
) p
.x
= m_rcDesktop
.right
-1;
672 if(p
.y
>= m_rcDesktop
.bottom
) p
.y
= m_rcDesktop
.bottom
-1;
673 FloatControlBar(pBar
, p
);
678 void CMainFrame::SaveControlBars()
680 CWinApp
* pApp
= AfxGetApp();
682 POSITION pos
= m_dockingbars
.GetHeadPosition();
685 CSizingControlBar
* pBar
= m_dockingbars
.GetNext(pos
);
688 pBar
->GetWindowText(str
);
689 if(str
.IsEmpty()) return;
690 CString section
= _T("ToolBars\\") + str
;
692 pApp
->WriteProfileInt(section
, _T("Visible"), pBar
->IsWindowVisible());
694 if(CSizingControlBar
* pSCB
= dynamic_cast<CSizingControlBar
*>(pBar
))
696 pSCB
->SaveState(section
+ _T("\\State"));
699 UINT nID
= pBar
->GetParent()->GetDlgCtrlID();
701 if(nID
== AFX_IDW_DOCKBAR_FLOAT
)
704 pBar
->GetParent()->GetParent()->GetWindowRect(r
);
705 pApp
->WriteProfileInt(section
, _T("DockPosX"), r
.left
);
706 pApp
->WriteProfileInt(section
, _T("DockPosY"), r
.top
);
709 pApp
->WriteProfileInt(section
, _T("DockState"), nID
);
713 LRESULT
CMainFrame::OnTaskBarRestart(WPARAM
, LPARAM
)
716 ShowTrayIcon(AfxGetAppSettings().fTrayIcon
);
721 LRESULT
CMainFrame::OnNotifyIcon(WPARAM wParam
, LPARAM lParam
)
723 if((UINT
)wParam
!= IDR_MAINFRAME
)
731 SetForegroundWindow();
734 case WM_LBUTTONDBLCLK
:
735 PostMessage(WM_COMMAND
, ID_FILE_OPENMEDIA
);
742 SetForegroundWindow();
743 m_popupmain
.GetSubMenu(0)->TrackPopupMenu(TPM_RIGHTBUTTON
|TPM_NOANIMATION
, p
.x
, p
.y
, this);
744 PostMessage(WM_NULL
);
763 void CMainFrame::ShowTrayIcon(bool fShow
)
765 BOOL bWasVisible
= ShowWindow(SW_HIDE
);
768 ZeroMemory(&tnid
, sizeof(NOTIFYICONDATA
));
769 tnid
.cbSize
= sizeof(NOTIFYICONDATA
);
771 tnid
.uID
= IDR_MAINFRAME
;
777 tnid
.hIcon
= (HICON
)LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME
), IMAGE_ICON
, 16, 16, LR_DEFAULTCOLOR
);
778 tnid
.uFlags
= NIF_MESSAGE
|NIF_ICON
|NIF_TIP
;
779 tnid
.uCallbackMessage
= WM_NOTIFYICON
;
780 lstrcpyn(tnid
.szTip
, TEXT("Media Player Classic"), sizeof(tnid
.szTip
));
781 Shell_NotifyIcon(NIM_ADD
, &tnid
);
790 Shell_NotifyIcon(NIM_DELETE
, &tnid
);
800 void CMainFrame::SetTrayTip(CString str
)
803 tnid
.cbSize
= sizeof(NOTIFYICONDATA
);
805 tnid
.uID
= IDR_MAINFRAME
;
806 tnid
.uFlags
= NIF_TIP
;
807 lstrcpyn(tnid
.szTip
, str
, sizeof(tnid
.szTip
));
808 Shell_NotifyIcon(NIM_MODIFY
, &tnid
);
811 BOOL
CMainFrame::PreCreateWindow(CREATESTRUCT
& cs
)
813 if(!__super::PreCreateWindow(cs
))
816 cs
.dwExStyle
&= ~WS_EX_CLIENTEDGE
;
817 cs
.lpszClass
= MPC_WND_CLASS_NAME
; //AfxRegisterWndClass(0);
822 BOOL
CMainFrame::PreTranslateMessage(MSG
* pMsg
)
824 if(pMsg
->message
== WM_KEYDOWN
)
826 /* if(m_fShockwaveGraph
827 && (pMsg->wParam == VK_LEFT || pMsg->wParam == VK_RIGHT
828 || pMsg->wParam == VK_UP || pMsg->wParam == VK_DOWN))
831 if(pMsg
->wParam
== VK_ESCAPE
&& m_iMediaLoadState
== MLS_LOADED
&& m_fFullScreen
)
834 PostMessage(WM_COMMAND
, ID_PLAY_PAUSE
);
837 else if(pMsg
->wParam
== VK_ESCAPE
&& (IsCaptionMenuHidden()))
839 PostMessage(WM_COMMAND
, ID_VIEW_CAPTIONMENU
);
842 else if(pMsg
->wParam
== VK_LEFT
&& pAMTuner
)
844 PostMessage(WM_COMMAND
, ID_NAVIGATE_SKIPBACK
);
847 else if(pMsg
->wParam
== VK_RIGHT
&& pAMTuner
)
849 PostMessage(WM_COMMAND
, ID_NAVIGATE_SKIPFORWARD
);
854 return __super::PreTranslateMessage(pMsg
);
857 void CMainFrame::RecalcLayout(BOOL bNotify
)
859 __super::RecalcLayout(bNotify
);
864 memset(&mmi
, 0, sizeof(mmi
));
865 SendMessage(WM_GETMINMAXINFO
, 0, (LPARAM
)&mmi
);
866 r
|= CRect(r
.TopLeft(), CSize(r
.Width(), mmi
.ptMinTrackSize
.y
));
870 /////////////////////////////////////////////////////////////////////////////
871 // CMainFrame diagnostics
874 void CMainFrame::AssertValid() const
876 __super::AssertValid();
879 void CMainFrame::Dump(CDumpContext
& dc
) const
886 /////////////////////////////////////////////////////////////////////////////
887 // CMainFrame message handlers
888 void CMainFrame::OnSetFocus(CWnd
* pOldWnd
)
890 SetAlwaysOnTop(AfxGetAppSettings().iOnTop
);
892 // forward focus to the view window
893 if(IsWindow(m_wndView
.m_hWnd
))
894 m_wndView
.SetFocus();
897 BOOL
CMainFrame::OnCmdMsg(UINT nID
, int nCode
, void* pExtra
, AFX_CMDHANDLERINFO
* pHandlerInfo
)
899 // let the view have first crack at the command
900 if(m_wndView
.OnCmdMsg(nID
, nCode
, pExtra
, pHandlerInfo
))
903 POSITION pos
= m_bars
.GetHeadPosition();
906 if(m_bars
.GetNext(pos
)->OnCmdMsg(nID
, nCode
, pExtra
, pHandlerInfo
))
910 pos
= m_dockingbars
.GetHeadPosition();
913 if(m_dockingbars
.GetNext(pos
)->OnCmdMsg(nID
, nCode
, pExtra
, pHandlerInfo
))
917 // otherwise, do default handling
918 return __super::OnCmdMsg(nID
, nCode
, pExtra
, pHandlerInfo
);
921 void CMainFrame::OnGetMinMaxInfo(MINMAXINFO
* lpMMI
)
923 DWORD style
= GetStyle();
926 memset(&mbi
, 0, sizeof(mbi
));
927 mbi
.cbSize
= sizeof(mbi
);
928 ::GetMenuBarInfo(m_hWnd
, OBJID_MENU
, 0, &mbi
);
930 lpMMI
->ptMinTrackSize
.x
= 0;
931 if(!IsCaptionMenuHidden())
933 lpMMI
->ptMinTrackSize
.x
= 10;
935 for(int i
= 0; ::GetMenuItemRect(m_hWnd
, mbi
.hMenu
, i
, &r
); i
++)
936 lpMMI
->ptMinTrackSize
.x
+= r
.Width();
937 lpMMI
->ptMinTrackSize
.x
= max(DEFCLIENTW
, lpMMI
->ptMinTrackSize
.x
);
939 if(style
&WS_THICKFRAME
) lpMMI
->ptMinTrackSize
.x
+= GetSystemMetrics((style
&WS_CAPTION
)?SM_CXSIZEFRAME
:SM_CXFIXEDFRAME
)*2;
941 memset(&mbi
, 0, sizeof(mbi
));
942 mbi
.cbSize
= sizeof(mbi
);
943 ::GetMenuBarInfo(m_hWnd
, OBJID_MENU
, 0, &mbi
);
945 lpMMI
->ptMinTrackSize
.y
= 0;
946 if(style
&WS_CAPTION
) lpMMI
->ptMinTrackSize
.y
+= GetSystemMetrics(SM_CYCAPTION
);
947 if(style
&WS_THICKFRAME
) lpMMI
->ptMinTrackSize
.y
+= GetSystemMetrics((style
&WS_CAPTION
)?SM_CYSIZEFRAME
:SM_CYFIXEDFRAME
)*2;
948 lpMMI
->ptMinTrackSize
.y
+= (mbi
.rcBar
.bottom
- mbi
.rcBar
.top
);
949 if(!AfxGetAppSettings().fHideCaptionMenu
) lpMMI
->ptMinTrackSize
.y
+= 3;
951 POSITION pos
= m_bars
.GetHeadPosition();
954 CControlBar
* pCB
= m_bars
.GetNext(pos
);
955 if(!IsWindow(pCB
->m_hWnd
) || !pCB
->IsVisible()) continue;
957 lpMMI
->ptMinTrackSize
.y
+= pCB
->CalcFixedLayout(TRUE
, TRUE
).cy
;
960 pos
= m_dockingbars
.GetHeadPosition();
963 CSizingControlBar
* pCB
= m_dockingbars
.GetNext(pos
);
964 if(IsWindow(pCB
->m_hWnd
) && pCB
->IsWindowVisible() && !pCB
->IsFloating())
965 lpMMI
->ptMinTrackSize
.y
+= pCB
->CalcFixedLayout(TRUE
, TRUE
).cy
-2;
968 __super::OnGetMinMaxInfo(lpMMI
);
971 void CMainFrame::OnMove(int x
, int y
)
973 __super::OnMove(x
, y
);
978 GetWindowPlacement(&wp
);
979 if(!m_fFullScreen
&& wp
.flags
!= WPF_RESTORETOMAXIMIZED
&& wp
.showCmd
!= SW_SHOWMINIMIZED
)
980 GetWindowRect(AfxGetAppSettings().rcLastWindowPos
);
983 void CMainFrame::OnMoving(UINT fwSide
, LPRECT pRect
)
985 __super::OnMoving(fwSide
, pRect
);
987 if(AfxGetAppSettings().fSnapToDesktopEdges
)
989 const CPoint
threshold(3, 3);
991 CRect r0
= m_rcDesktop
;
992 CRect r1
= r0
+ threshold
;
993 CRect r2
= r0
- threshold
;
996 CSize ws
= CRect(wr
).Size();
998 if(wr
.left
< r1
.left
&& wr
.left
> r2
.left
)
999 wr
.right
= (wr
.left
= r0
.left
) + ws
.cx
;
1001 if(wr
.top
< r1
.top
&& wr
.top
> r2
.top
)
1002 wr
.bottom
= (wr
.top
= r0
.top
) + ws
.cy
;
1004 if(wr
.right
< r1
.right
&& wr
.right
> r2
.right
)
1005 wr
.left
= (wr
.right
= r0
.right
) - ws
.cx
;
1007 if(wr
.bottom
< r1
.bottom
&& wr
.bottom
> r2
.bottom
)
1008 wr
.top
= (wr
.bottom
= r0
.bottom
) - ws
.cy
;
1012 void CMainFrame::OnSize(UINT nType
, int cx
, int cy
)
1014 __super::OnSize(nType
, cx
, cy
);
1016 if(nType
== SIZE_RESTORED
&& m_fTrayIcon
)
1018 ShowWindow(SW_SHOW
);
1023 AppSettings
& s
= AfxGetAppSettings();
1024 if(nType
!= SIZE_MAXIMIZED
&& nType
!= SIZE_MINIMIZED
)
1025 GetWindowRect(s
.rcLastWindowPos
);
1026 s
.lastWindowType
= nType
;
1030 void CMainFrame::OnSizing(UINT fwSide
, LPRECT pRect
)
1032 __super::OnSizing(fwSide
, pRect
);
1034 AppSettings
& s
= AfxGetAppSettings();
1036 bool fCtrl
= !!(GetAsyncKeyState(VK_CONTROL
)&0x80000000);
1038 if(m_iMediaLoadState
!= MLS_LOADED
|| m_fFullScreen
1039 || s
.iDefaultVideoSize
== DVS_STRETCH
1040 || (fCtrl
^ s
.fFreeWindowResizing
))
1043 CSize
wsize(pRect
->right
- pRect
->left
, pRect
->bottom
- pRect
->top
);
1044 CSize vsize
= GetVideoSize();
1047 if(!vsize
.cx
|| !vsize
.cy
)
1052 DWORD style
= GetStyle();
1055 memset(&mbi
, 0, sizeof(mbi
));
1056 mbi
.cbSize
= sizeof(mbi
);
1057 ::GetMenuBarInfo(m_hWnd
, OBJID_MENU
, 0, &mbi
);
1059 fsize
.cx
+= GetSystemMetrics((style
&WS_CAPTION
)?SM_CXSIZEFRAME
:SM_CXFIXEDFRAME
)*2;
1061 if(style
&WS_CAPTION
) fsize
.cy
+= GetSystemMetrics(SM_CYCAPTION
);
1062 if(style
&WS_THICKFRAME
) fsize
.cy
+= GetSystemMetrics((style
&WS_CAPTION
)?SM_CYSIZEFRAME
:SM_CYFIXEDFRAME
)*2;
1063 fsize
.cy
+= mbi
.rcBar
.bottom
- mbi
.rcBar
.top
;
1064 if(!AfxGetAppSettings().fHideCaptionMenu
) fsize
.cy
+= 3;
1066 POSITION pos
= m_bars
.GetHeadPosition();
1069 CControlBar
* pCB
= m_bars
.GetNext(pos
);
1070 if(IsWindow(pCB
->m_hWnd
) && pCB
->IsVisible())
1071 fsize
.cy
+= pCB
->CalcFixedLayout(TRUE
, TRUE
).cy
;
1074 pos
= m_dockingbars
.GetHeadPosition();
1077 CSizingControlBar
* pCB
= m_dockingbars
.GetNext(pos
);
1079 if(IsWindow(pCB
->m_hWnd
) && pCB
->IsWindowVisible())
1081 if(pCB
->IsHorzDocked()) fsize
.cy
+= pCB
->CalcFixedLayout(TRUE
, TRUE
).cy
-2;
1082 else if(pCB
->IsVertDocked()) fsize
.cx
+= pCB
->CalcFixedLayout(TRUE
, FALSE
).cx
;
1089 bool fWider
= wsize
.cy
< wsize
.cx
;
1092 wsize
.cy
* vsize
.cx
/ vsize
.cy
,
1093 wsize
.cx
* vsize
.cy
/ vsize
.cx
);
1097 if(fwSide
== WMSZ_TOP
|| fwSide
== WMSZ_BOTTOM
|| !fWider
&& (fwSide
== WMSZ_TOPRIGHT
|| fwSide
== WMSZ_BOTTOMRIGHT
))
1099 pRect
->right
= pRect
->left
+ wsize
.cx
;
1101 else if(fwSide
== WMSZ_LEFT
|| fwSide
== WMSZ_RIGHT
|| fWider
&& (fwSide
== WMSZ_BOTTOMLEFT
|| fwSide
== WMSZ_BOTTOMRIGHT
))
1103 pRect
->bottom
= pRect
->top
+ wsize
.cy
;
1105 else if(!fWider
&& (fwSide
== WMSZ_TOPLEFT
|| fwSide
== WMSZ_BOTTOMLEFT
))
1107 pRect
->left
= pRect
->right
- wsize
.cx
;
1109 else if(fWider
&& (fwSide
== WMSZ_TOPLEFT
|| fwSide
== WMSZ_TOPRIGHT
))
1111 pRect
->top
= pRect
->bottom
- wsize
.cy
;
1115 void CMainFrame::OnDisplayChange() // untested, not sure if it's working...
1117 TRACE(_T("*** CMainFrame::OnDisplayChange()\n"));
1119 if(m_iMediaLoadState == MLS_LOADED && m_pCAP)
1120 m_pCAP->OnDisplayChange();
1123 GetDesktopWindow()->GetWindowRect(&m_rcDesktop
);
1128 void CMainFrame::OnSysCommand(UINT nID
, LPARAM lParam
)
1130 if( (GetMediaState() == State_Running
) && (((nID
& 0xFFF0) == SC_SCREENSAVE
) || ((nID
& 0xFFF0) == SC_MONITORPOWER
)) )
1132 TRACE(_T("SC_SCREENSAVE, nID = %d, lParam = %d\n"), nID
, lParam
);
1135 else if((nID
& 0xFFF0) == SC_MINIMIZE
&& m_fTrayIcon
)
1137 ShowWindow(SW_HIDE
);
1141 __super::OnSysCommand(nID
, lParam
);
1144 void CMainFrame::OnActivateApp(BOOL bActive
, DWORD dwThreadID
)
1146 __super::OnActivateApp(bActive
, dwThreadID
);
1149 mi
.cbSize
= sizeof(MONITORINFO
);
1150 GetMonitorInfo(MonitorFromWindow(m_hWnd
, MONITOR_DEFAULTTONEAREST
), &mi
);
1152 if(!bActive
&& (mi
.dwFlags
&MONITORINFOF_PRIMARY
) && m_fFullScreen
&& m_iMediaLoadState
== MLS_LOADED
)
1154 bool fExitFullscreen
= true;
1156 if(CWnd
* pWnd
= GetForegroundWindow())
1158 HMONITOR hMonitor1
= MonitorFromWindow(m_hWnd
, MONITOR_DEFAULTTONEAREST
);
1159 HMONITOR hMonitor2
= MonitorFromWindow(pWnd
->m_hWnd
, MONITOR_DEFAULTTONEAREST
);
1160 if(hMonitor1
&& hMonitor2
&& hMonitor1
!= hMonitor2
) fExitFullscreen
= false;
1163 pWnd
->GetWindowText(title
);
1167 if(GetVersion()&0x80000000)
1169 module
.ReleaseBufferSetLength(GetWindowModuleFileName(pWnd
->m_hWnd
, module
.GetBuffer(MAX_PATH
), MAX_PATH
));
1174 GetWindowThreadProcessId(pWnd
->m_hWnd
, &pid
);
1176 if(HANDLE hProcess
= OpenProcess(PROCESS_QUERY_INFORMATION
| PROCESS_VM_READ
, FALSE
, pid
))
1181 if(EnumProcessModules(hProcess
, &hMod
, sizeof(hMod
), &cbNeeded
))
1183 module
.ReleaseBufferSetLength(GetModuleFileNameEx(hProcess
, hMod
, module
.GetBuffer(MAX_PATH
), MAX_PATH
));
1186 CloseHandle(hProcess
);
1192 module
= (LPCTSTR
)p
;
1196 str
.Format(_T("Focus lost to: %s - %s"), module
, title
);
1197 SendStatusMessage(str
, 5000);
1200 if(fExitFullscreen
) OnViewFullscreen();
1204 LRESULT
CMainFrame::OnAppCommand(WPARAM wParam
, LPARAM lParam
)
1206 UINT cmd
= GET_APPCOMMAND_LPARAM(lParam
);
1207 UINT uDevice
= GET_DEVICE_LPARAM(lParam
);
1208 UINT dwKeys
= GET_KEYSTATE_LPARAM(lParam
);
1210 if(uDevice
!= FAPPCOMMAND_OEM
)
1212 AppSettings
& s
= AfxGetAppSettings();
1216 POSITION pos
= s
.wmcmds
.GetHeadPosition();
1219 wmcmd
& wc
= s
.wmcmds
.GetNext(pos
);
1220 if(wc
.appcmd
== cmd
&& TRUE
== SendMessage(WM_COMMAND
, wc
.cmd
))
1224 if(fRet
) return TRUE
;
1230 void CMainFrame::OnTimer(UINT nIDEvent
)
1232 if(nIDEvent
== TIMER_STREAMPOSPOLLER
&& m_iMediaLoadState
== MLS_LOADED
)
1234 REFERENCE_TIME rtNow
= 0, rtDur
= 0;
1236 if(m_iPlaybackMode
== PM_FILE
)
1238 pMS
->GetCurrentPosition(&rtNow
);
1239 pMS
->GetDuration(&rtDur
);
1241 if(m_rtDurationOverride
>= 0) rtDur
= m_rtDurationOverride
;
1243 m_wndSeekBar
.Enable(rtDur
> 0);
1244 m_wndSeekBar
.SetRange(0, rtDur
);
1245 m_wndSeekBar
.SetPos(rtNow
);
1247 else if(m_iPlaybackMode
== PM_CAPTURE
)
1249 if(m_fCapturing
&& m_wndCaptureBar
.m_capdlg
.m_pMux
)
1251 CComQIPtr
<IMediaSeeking
> pMuxMS
= m_wndCaptureBar
.m_capdlg
.m_pMux
;
1252 if(!pMuxMS
|| FAILED(pMuxMS
->GetCurrentPosition(&rtNow
))) rtNow
= 0;
1255 if(m_rtDurationOverride
>= 0) rtDur
= m_rtDurationOverride
;
1257 m_wndSeekBar
.Enable(false);
1258 m_wndSeekBar
.SetRange(0, rtDur
);
1259 m_wndSeekBar
.SetPos(rtNow
);
1263 if(rtNow > 10000i64*1000*60*60*3)
1265 m_wndCaptureBar.m_capdlg.OnRecord();
1271 if(m_pCAP
&& m_iPlaybackMode
!= PM_FILE
) m_pCAP
->SetTime(/*rtNow*/m_wndSeekBar
.GetPos());
1273 else if(nIDEvent
== TIMER_STREAMPOSPOLLER2
&& m_iMediaLoadState
== MLS_LOADED
)
1275 __int64 start
, stop
, pos
;
1276 m_wndSeekBar
.GetRange(start
, stop
);
1277 pos
= m_wndSeekBar
.GetPosReal();
1280 pMS
->GetTimeFormat(&tf
);
1282 if(m_iPlaybackMode
== PM_CAPTURE
&& !m_fCapturing
)
1284 CString str
= _T("Live");
1286 long lChannel
= 0, lVivSub
= 0, lAudSub
= 0;
1288 && m_wndCaptureBar
.m_capdlg
.IsTunerActive()
1289 && SUCCEEDED(pAMTuner
->get_Channel(&lChannel
, &lVivSub
, &lAudSub
)))
1292 ch
.Format(_T(" (ch%d)"), lChannel
);
1296 m_wndStatusBar
.SetStatusTimer(str
);
1300 m_wndStatusBar
.SetStatusTimer(pos
, stop
, !!m_wndSubresyncBar
.IsWindowVisible(), &tf
);
1303 m_wndSubresyncBar
.SetTime(pos
);
1305 if(m_pCAP
&& GetMediaState() == State_Paused
) m_pCAP
->Paint(true);
1307 else if(nIDEvent
== TIMER_FULLSCREENCONTROLBARHIDER
)
1314 bool fCursorOutside
= !r
.PtInRect(p
);
1316 CWnd
* pWnd
= WindowFromPoint(p
);
1317 if(pWnd
&& (m_wndView
== *pWnd
|| m_wndView
.IsChild(pWnd
) || fCursorOutside
))
1319 if(AfxGetAppSettings().nShowBarsWhenFullScreenTimeOut
>= 0)
1320 ShowControls(CS_NONE
, false);
1323 else if(nIDEvent
== TIMER_FULLSCREENMOUSEHIDER
)
1330 bool fCursorOutside
= !r
.PtInRect(p
);
1332 CWnd
* pWnd
= WindowFromPoint(p
);
1333 if(pWnd
&& (m_wndView
== *pWnd
|| m_wndView
.IsChild(pWnd
) || fCursorOutside
))
1335 m_fHideCursor
= true;
1339 else if(nIDEvent
== TIMER_STATS
)
1344 if(m_iSpeedLevel
>= -11 && m_iSpeedLevel
<= 3 && m_iSpeedLevel
!= -4)
1346 CString speeds
[] = {_T("1/8"),_T("1/4"),_T("1/2"),_T("1"),_T("2"),_T("4"),_T("8")};
1347 rate
= speeds
[(m_iSpeedLevel
>= -3 ? m_iSpeedLevel
: (-m_iSpeedLevel
- 8)) + 3];
1348 if(m_iSpeedLevel
< -4) rate
= _T("-") + rate
;
1349 if(!rate
.IsEmpty()) rate
= _T("(") + rate
+ _T("X)");
1355 pQP
->get_AvgFrameRate(&val
);
1356 info
.Format(_T("%d.%02d %s"), val
/100, val
%100, rate
);
1357 m_wndStatsBar
.SetLine(_T("Frame-rate"), info
);
1360 pQP
->get_AvgSyncOffset(&avg
);
1361 pQP
->get_DevSyncOffset(&dev
);
1362 info
.Format(_T("avg: %d ms, dev: %d ms"), avg
, dev
);
1363 m_wndStatsBar
.SetLine(_T("Sync Offset"), info
);
1366 pQP
->get_FramesDrawn(&drawn
);
1367 pQP
->get_FramesDroppedInRenderer(&dropped
);
1368 info
.Format(_T("drawn: %d, dropped: %d"), drawn
, dropped
);
1369 m_wndStatsBar
.SetLine(_T("Frames"), info
);
1371 pQP
->get_Jitter(&val
);
1372 info
.Format(_T("%d ms"), val
);
1373 m_wndStatsBar
.SetLine(_T("Jitter"), info
);
1378 CAtlList
<CString
> sl
;
1380 for(int i
= 0, j
= pBI
->GetCount(); i
< j
; i
++)
1383 if(S_OK
== pBI
->GetStatus(i
, samples
, size
))
1386 str
.Format(_T("[%d]: %03d/%d KB"), i
, samples
, size
/ 1024);
1394 str
.Format(_T("%s (p%d)"), Implode(sl
, ' '), pBI
->GetPriority());
1396 m_wndStatsBar
.SetLine(_T("Buffers"), str
);
1400 CInterfaceList
<IBitRateInfo
> pBRIs
;
1402 BeginEnumFilters(pGB
, pEF
, pBF
)
1404 BeginEnumPins(pBF
, pEP
, pPin
)
1406 if(CComQIPtr
<IBitRateInfo
> pBRI
= pPin
)
1408 pBRIs
.AddTail(pBRI
);
1413 if(!pBRIs
.IsEmpty())
1415 CAtlList
<CString
> sl
;
1417 POSITION pos
= pBRIs
.GetHeadPosition();
1418 for(int i
= 0; pos
; i
++)
1420 IBitRateInfo
* pBRI
= pBRIs
.GetNext(pos
);
1422 DWORD cur
= pBRI
->GetCurrentBitRate() / 1000;
1423 DWORD avg
= pBRI
->GetAverageBitRate() / 1000;
1425 if(avg
== 0) continue;
1428 if(cur
!= avg
) str
.Format(_T("[%d]: %d/%d Kb/s"), i
, avg
, cur
);
1429 else str
.Format(_T("[%d]: %d Kb/s"), i
, avg
);
1435 m_wndStatsBar
.SetLine(_T("Bitrate"), Implode(sl
, ' ') + _T(" (avg/cur)"));
1443 if(m_iPlaybackMode
== PM_FILE
)
1448 if(m_iPlaybackMode
== PM_DVD
) // we also use this timer to update the info panel for dvd playback
1450 ULONG ulAvailable
, ulCurrent
;
1454 CString
Location('-');
1456 DVD_PLAYBACK_LOCATION2 loc
;
1457 ULONG ulNumOfVolumes
, ulVolume
;
1459 ULONG ulNumOfTitles
;
1460 ULONG ulNumOfChapters
;
1462 if(SUCCEEDED(pDVDI
->GetCurrentLocation(&loc
))
1463 && SUCCEEDED(pDVDI
->GetNumberOfChapters(loc
.TitleNum
, &ulNumOfChapters
))
1464 && SUCCEEDED(pDVDI
->GetDVDVolumeInfo(&ulNumOfVolumes
, &ulVolume
, &Side
, &ulNumOfTitles
)))
1466 Location
.Format(_T("Volume: %02d/%02d, Title: %02d/%02d, Chapter: %02d/%02d"),
1467 ulVolume
, ulNumOfVolumes
,
1468 loc
.TitleNum
, ulNumOfTitles
,
1469 loc
.ChapterNum
, ulNumOfChapters
);
1472 m_wndInfoBar
.SetLine(ResStr(IDS_INFOBAR_LOCATION
), Location
);
1478 DVD_VideoAttributes VATR
;
1480 if(SUCCEEDED(pDVDI
->GetCurrentAngle(&ulAvailable
, &ulCurrent
))
1481 && SUCCEEDED(pDVDI
->GetCurrentVideoAttributes(&VATR
)))
1483 Video
.Format(_T("Angle: %02d/%02d, %dx%d %dHz %d:%d"),
1484 ulAvailable
, ulCurrent
,
1485 VATR
.ulSourceResolutionX
, VATR
.ulSourceResolutionY
, VATR
.ulFrameRate
,
1486 VATR
.ulAspectX
, VATR
.ulAspectY
);
1489 m_wndInfoBar
.SetLine(ResStr(IDS_INFOBAR_VIDEO
), Video
);
1495 DVD_AudioAttributes AATR
;
1497 if(SUCCEEDED(pDVDI
->GetCurrentAudio(&ulAvailable
, &ulCurrent
))
1498 && SUCCEEDED(pDVDI
->GetAudioAttributes(ulCurrent
, &AATR
)))
1501 int len
= GetLocaleInfo(AATR
.Language
, LOCALE_SENGLANGUAGE
, lang
.GetBuffer(64), 64);
1502 lang
.ReleaseBufferSetLength(max(len
-1, 0));
1504 switch(AATR
.LanguageExtension
)
1506 case DVD_AUD_EXT_NotSpecified
:
1508 case DVD_AUD_EXT_Captions
: lang
+= _T(" (Captions)"); break;
1509 case DVD_AUD_EXT_VisuallyImpaired
: lang
+= _T(" (Visually Impaired)"); break;
1510 case DVD_AUD_EXT_DirectorComments1
: lang
+= _T(" (Director Comments 1)"); break;
1511 case DVD_AUD_EXT_DirectorComments2
: lang
+= _T(" (Director Comments 2)"); break;
1515 switch(AATR
.AudioFormat
)
1517 case DVD_AudioFormat_AC3
: format
= _T("AC3"); break;
1518 case DVD_AudioFormat_MPEG1
:
1519 case DVD_AudioFormat_MPEG1_DRC
: format
= _T("MPEG1"); break;
1520 case DVD_AudioFormat_MPEG2
:
1521 case DVD_AudioFormat_MPEG2_DRC
: format
= _T("MPEG2"); break;
1522 case DVD_AudioFormat_LPCM
: format
= _T("LPCM"); break;
1523 case DVD_AudioFormat_DTS
: format
= _T("DTS"); break;
1524 case DVD_AudioFormat_SDDS
: format
= _T("SDDS"); break;
1525 case DVD_AudioFormat_Other
:
1526 default: format
= _T("Unknown format"); break;
1529 Audio
.Format(_T("%s, %s %dHz %dbits %d channel(s)"),
1534 AATR
.bNumberOfChannels
);
1536 m_wndStatusBar
.SetStatusBitmap(
1537 AATR
.bNumberOfChannels
== 1 ? IDB_MONO
1538 : AATR
.bNumberOfChannels
>= 2 ? IDB_STEREO
1542 m_wndInfoBar
.SetLine(ResStr(IDS_INFOBAR_AUDIO
), Audio
);
1546 CString
Subtitles('-');
1549 DVD_SubpictureAttributes SATR
;
1551 if(SUCCEEDED(pDVDI
->GetCurrentSubpicture(&ulAvailable
, &ulCurrent
, &bIsDisabled
))
1552 && SUCCEEDED(pDVDI
->GetSubpictureAttributes(ulCurrent
, &SATR
)))
1555 int len
= GetLocaleInfo(SATR
.Language
, LOCALE_SENGLANGUAGE
, lang
.GetBuffer(64), 64);
1556 lang
.ReleaseBufferSetLength(max(len
-1, 0));
1558 switch(SATR
.LanguageExtension
)
1560 case DVD_SP_EXT_NotSpecified
:
1562 case DVD_SP_EXT_Caption_Normal
: lang
+= _T(""); break;
1563 case DVD_SP_EXT_Caption_Big
: lang
+= _T(" (Big)"); break;
1564 case DVD_SP_EXT_Caption_Children
: lang
+= _T(" (Children)"); break;
1565 case DVD_SP_EXT_CC_Normal
: lang
+= _T(" (CC)"); break;
1566 case DVD_SP_EXT_CC_Big
: lang
+= _T(" (CC Big)"); break;
1567 case DVD_SP_EXT_CC_Children
: lang
+= _T(" (CC Children)"); break;
1568 case DVD_SP_EXT_Forced
: lang
+= _T(" (Forced)"); break;
1569 case DVD_SP_EXT_DirectorComments_Normal
: lang
+= _T(" (Director Comments)"); break;
1570 case DVD_SP_EXT_DirectorComments_Big
: lang
+= _T(" (Director Comments, Big)"); break;
1571 case DVD_SP_EXT_DirectorComments_Children
: lang
+= _T(" (Director Comments, Children)"); break;
1574 if(bIsDisabled
) lang
= _T("-");
1576 Subtitles
.Format(_T("%s"),
1580 m_wndInfoBar
.SetLine(ResStr(IDS_INFOBAR_SUBTITLES
), Subtitles
);
1583 if(GetMediaState() == State_Running
)
1585 UINT fSaverActive
= 0;
1586 if(SystemParametersInfo(SPI_GETSCREENSAVEACTIVE
, 0, (PVOID
)&fSaverActive
, 0))
1588 SystemParametersInfo(SPI_SETSCREENSAVEACTIVE
, 0, 0, SPIF_SENDWININICHANGE
); // this might not be needed at all...
1589 SystemParametersInfo(SPI_SETSCREENSAVEACTIVE
, fSaverActive
, 0, SPIF_SENDWININICHANGE
);
1593 if(SystemParametersInfo(SPI_GETPOWEROFFACTIVE
, 0, (PVOID
)&fSaverActive
, 0))
1595 SystemParametersInfo(SPI_SETPOWEROFFACTIVE
, 0, 0, SPIF_SENDWININICHANGE
); // this might not be needed at all...
1596 SystemParametersInfo(SPI_SETPOWEROFFACTIVE
, fSaverActive
, 0, SPIF_SENDWININICHANGE
);
1600 else if(nIDEvent
== TIMER_STATUSERASER
)
1602 KillTimer(TIMER_STATUSERASER
);
1603 m_playingmsg
.Empty();
1606 __super::OnTimer(nIDEvent
);
1609 static bool SetShutdownPrivilege()
1612 TOKEN_PRIVILEGES tkp
;
1614 // Get a token for this process.
1616 if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
, &hToken
))
1619 // Get the LUID for the shutdown privilege.
1621 LookupPrivilegeValue(NULL
, SE_SHUTDOWN_NAME
, &tkp
.Privileges
[0].Luid
);
1623 tkp
.PrivilegeCount
= 1; // one privilege to set
1624 tkp
.Privileges
[0].Attributes
= SE_PRIVILEGE_ENABLED
;
1626 // Get the shutdown privilege for this process.
1628 AdjustTokenPrivileges(hToken
, FALSE
, &tkp
, 0, (PTOKEN_PRIVILEGES
)NULL
, 0);
1630 if(GetLastError() != ERROR_SUCCESS
)
1636 bool CMainFrame::DoAfterPlaybackEvent()
1638 AppSettings
& s
= AfxGetAppSettings();
1642 if(s
.nCLSwitches
&CLSW_CLOSE
)
1647 if(s
.nCLSwitches
&CLSW_STANDBY
)
1649 SetShutdownPrivilege();
1650 SetSystemPowerState(TRUE
, TRUE
);
1651 fExit
= true; // TODO: unless the app closes, it will call standby or hibernate once again forever, how to avoid that?
1653 else if(s
.nCLSwitches
&CLSW_HIBERNATE
)
1655 SetShutdownPrivilege();
1656 SetSystemPowerState(FALSE
, TRUE
);
1657 fExit
= true; // TODO: unless the app closes, it will call standby or hibernate once again forever, how to avoid that?
1659 else if(s
.nCLSwitches
&CLSW_SHUTDOWN
)
1661 SetShutdownPrivilege();
1662 ExitWindowsEx(EWX_SHUTDOWN
|EWX_POWEROFF
|EWX_FORCEIFHUNG
, 0);
1665 else if(s
.nCLSwitches
&CLSW_LOGOFF
)
1667 SetShutdownPrivilege();
1668 ExitWindowsEx(EWX_LOGOFF
|EWX_FORCEIFHUNG
, 0);
1672 if(!fExit
) return false;
1674 SendMessage(WM_COMMAND
, ID_FILE_EXIT
);
1680 // our WM_GRAPHNOTIFY handler
1683 LRESULT
CMainFrame::OnGraphNotify(WPARAM wParam
, LPARAM lParam
)
1687 LONG evCode
, evParam1
, evParam2
;
1688 while(pME
&& SUCCEEDED(pME
->GetEvent(&evCode
, (LONG_PTR
*)&evParam1
, (LONG_PTR
*)&evParam2
, 0)))
1694 if(EC_BG_ERROR
== evCode
)
1696 str
= CString((char*)evParam1
);
1700 hr
= pME
->FreeEventParams(evCode
, evParam1
, evParam2
);
1702 if(EC_COMPLETE
== evCode
)
1704 AppSettings
& s
= AfxGetAppSettings();
1706 if(m_wndPlaylistBar
.GetCount() <= 1)
1710 if(DoAfterPlaybackEvent()) return hr
;
1712 if(s
.fLoopForever
|| m_nLoops
< s
.nLoops
)
1714 if(GetMediaState() == State_Stopped
)
1716 SendMessage(WM_COMMAND
, ID_PLAY_PLAY
);
1721 pMS
->SetPositions(&pos
, AM_SEEKING_AbsolutePositioning
, NULL
, AM_SEEKING_NoPositioning
);
1723 if(GetMediaState() == State_Paused
)
1725 SendMessage(WM_COMMAND
, ID_PLAY_PLAY
);
1731 if(s
.fRewind
) SendMessage(WM_COMMAND
, ID_PLAY_STOP
);
1732 else m_fEndOfStream
= true;
1733 SendMessage(WM_COMMAND
, ID_PLAY_PAUSE
);
1735 if(m_fFullScreen
&& s
.fExitFullScreenAtTheEnd
)
1739 else if(m_wndPlaylistBar
.GetCount() > 1)
1741 if(m_wndPlaylistBar
.IsAtEnd())
1743 if(DoAfterPlaybackEvent()) return hr
;
1748 if(s
.fLoopForever
|| m_nLoops
< s
.nLoops
)
1750 int nLoops
= m_nLoops
;
1751 PostMessage(WM_COMMAND
, ID_NAVIGATE_SKIPFORWARD
);
1756 if(m_fFullScreen
&& s
.fExitFullScreenAtTheEnd
)
1761 AfxGetAppSettings().nCLSwitches
|= CLSW_OPEN
; // HACK
1762 PostMessage(WM_COMMAND
, ID_NAVIGATE_SKIPFORWARD
);
1766 m_fEndOfStream
= true;
1767 PostMessage(WM_COMMAND
, ID_PLAY_PAUSE
);
1772 else if(EC_ERRORABORT
== evCode
)
1774 TRACE(_T("EC_ERRORABORT, hr = %08x\n"), (HRESULT
)evParam1
);
1775 // SendMessage(WM_COMMAND, ID_FILE_CLOSEMEDIA);
1776 // m_closingmsg = _com_error((HRESULT)evParam1).ErrorMessage();
1778 else if(EC_REPAINT
== evCode
)
1780 TRACE(_T("EC_REPAINT\n"));
1782 else if(EC_BUFFERING_DATA
== evCode
)
1784 TRACE(_T("EC_BUFFERING_DATA, %d, %d\n"), (HRESULT
)evParam1
, evParam2
);
1786 m_fBuffering
= ((HRESULT
)evParam1
!= S_OK
);
1788 else if(EC_STEP_COMPLETE
== evCode
)
1790 if(m_fFrameSteppingActive
)
1792 m_fFrameSteppingActive
= false;
1793 pBA
->put_Volume(m_VolumeBeforeFrameStepping
);
1796 else if(EC_DEVICE_LOST
== evCode
)
1798 CComQIPtr
<IBaseFilter
> pBF
;
1799 if(m_iPlaybackMode
== PM_CAPTURE
1800 && (!pVidCap
&& pVidCap
== (pBF
= (IUnknown
*)evParam1
)
1801 || !pAudCap
&& pAudCap
== (pBF
= (IUnknown
*)evParam1
))
1804 SendMessage(WM_COMMAND
, ID_FILE_CLOSEMEDIA
);
1807 else if(EC_DVD_TITLE_CHANGE
== evCode
)
1809 if(m_iPlaybackMode
== PM_FILE
)
1813 else if(m_iPlaybackMode
== PM_DVD
)
1815 m_iDVDTitle
= (DWORD
)evParam1
;
1817 if(m_iDVDDomain
== DVD_DOMAIN_Title
)
1820 Domain
.Format(_T("Title %d"), m_iDVDTitle
);
1821 m_wndInfoBar
.SetLine(ResStr(IDS_INFOBAR_DOMAIN
), Domain
);
1825 else if(EC_DVD_DOMAIN_CHANGE
== evCode
)
1827 m_iDVDDomain
= (DVD_DOMAIN
)evParam1
;
1829 CString
Domain('-');
1831 switch(m_iDVDDomain
)
1833 case DVD_DOMAIN_FirstPlay
: Domain
= _T("First Play"); break;
1834 case DVD_DOMAIN_VideoManagerMenu
: Domain
= _T("Video Manager Menu"); break;
1835 case DVD_DOMAIN_VideoTitleSetMenu
: Domain
= _T("Video Title Set Menu"); break;
1836 case DVD_DOMAIN_Title
: Domain
.Format(_T("Title %d"), m_iDVDTitle
); break;
1837 case DVD_DOMAIN_Stop
: Domain
= _T("Stop"); break;
1838 default: Domain
= _T("-"); break;
1841 m_wndInfoBar
.SetLine(ResStr(IDS_INFOBAR_DOMAIN
), Domain
);
1843 MoveVideoWindow(); // AR might have changed
1845 else if(EC_DVD_CURRENT_HMSF_TIME
== evCode
)
1847 double fps
= evParam2
== DVD_TC_FLAG_25fps
? 25.0
1848 : evParam2
== DVD_TC_FLAG_30fps
? 30.0
1849 : evParam2
== DVD_TC_FLAG_DropFrame
? 29.97
1852 REFERENCE_TIME rtDur
= 0;
1854 DVD_HMSF_TIMECODE tcDur
;
1856 if(SUCCEEDED(pDVDI
->GetTotalTitleTime(&tcDur
, &ulFlags
)))
1857 rtDur
= HMSF2RT(tcDur
, fps
);
1859 m_wndSeekBar
.Enable(rtDur
> 0);
1860 m_wndSeekBar
.SetRange(0, rtDur
);
1862 REFERENCE_TIME rtNow
= HMSF2RT(*((DVD_HMSF_TIMECODE
*)&evParam1
), fps
);
1864 m_wndSeekBar
.SetPos(rtNow
);
1866 if(m_pSubClock
) m_pSubClock
->SetTime(rtNow
);
1868 else if(EC_DVD_ERROR
== evCode
)
1870 TRACE(_T("EC_DVD_ERROR %d %d\n"), evParam1
, evParam2
);
1876 case DVD_ERROR_Unexpected
: default: err
= _T("DVD: Unexpected error"); break;
1877 case DVD_ERROR_CopyProtectFail
: err
= _T("DVD: Copy-Protect Fail"); break;
1878 case DVD_ERROR_InvalidDVD1_0Disc
: err
= _T("DVD: Invalid DVD 1.x Disc"); break;
1879 case DVD_ERROR_InvalidDiscRegion
: err
= _T("DVD: Invalid Disc Region"); break;
1880 case DVD_ERROR_LowParentalLevel
: err
= _T("DVD: Low Parental Level"); break;
1881 case DVD_ERROR_MacrovisionFail
: err
= _T("DVD: Macrovision Fail"); break;
1882 case DVD_ERROR_IncompatibleSystemAndDecoderRegions
: err
= _T("DVD: Incompatible System And Decoder Regions"); break;
1883 case DVD_ERROR_IncompatibleDiscAndDecoderRegions
: err
= _T("DVD: Incompatible Disc And Decoder Regions"); break;
1886 SendMessage(WM_COMMAND
, ID_FILE_CLOSEMEDIA
);
1890 else if(EC_DVD_WARNING
== evCode
)
1892 TRACE(_T("EC_DVD_WARNING %d %d\n"), evParam1
, evParam2
);
1894 else if(EC_VIDEO_SIZE_CHANGED
== evCode
)
1896 TRACE(_T("EC_VIDEO_SIZE_CHANGED %dx%d\n"), CSize(evParam1
));
1899 wp
.length
= sizeof(wp
);
1900 GetWindowPlacement(&wp
);
1902 CSize
size(evParam1
);
1903 m_fAudioOnly
= (size
.cx
<= 0 || size
.cy
<= 0);
1905 if(AfxGetAppSettings().fRememberZoomLevel
1906 && !(m_fFullScreen
|| wp
.showCmd
== SW_SHOWMAXIMIZED
|| wp
.showCmd
== SW_SHOWMINIMIZED
))
1915 if(m_iMediaLoadState
== MLS_LOADED
1916 && !m_fAudioOnly
&& (AfxGetAppSettings().nCLSwitches
&CLSW_FULLSCREEN
))
1918 PostMessage(WM_COMMAND
, ID_VIEW_FULLSCREEN
);
1919 AfxGetAppSettings().nCLSwitches
&= ~CLSW_FULLSCREEN
;
1922 else if(EC_LENGTH_CHANGED
== evCode
)
1925 pMS
->GetDuration(&rtDur
);
1926 m_wndPlaylistBar
.SetCurTime(rtDur
);
1928 else if(!m_fCustomGraph
)
1930 TRACE(_T("evCode: %d\n"), evCode
);
1932 else if(EC_BG_AUDIO_CHANGED
== evCode
)
1934 int nAudioChannels
= evParam1
;
1936 m_wndStatusBar
.SetStatusBitmap(nAudioChannels
== 1 ? IDB_MONO
1937 : nAudioChannels
>= 2 ? IDB_STEREO
1940 else if(EC_BG_ERROR
== evCode
)
1942 SendMessage(WM_COMMAND
, ID_FILE_CLOSEMEDIA
);
1943 m_closingmsg
= !str
.IsEmpty() ? str
: _T("Unspecified graph error");
1944 m_wndPlaylistBar
.SetCurValid(false);
1952 LRESULT
CMainFrame::OnRepaintRenderLess(WPARAM wParam
, LPARAM lParam
)
1958 LRESULT
CMainFrame::OnResumeFromState(WPARAM wParam
, LPARAM lParam
)
1960 int iPlaybackMode
= (int)wParam
;
1962 if(iPlaybackMode
== PM_FILE
)
1964 SeekTo(10000i64
*int(lParam
));
1966 else if(iPlaybackMode
== PM_DVD
)
1968 CComPtr
<IDvdState
> pDvdState
;
1969 pDvdState
.Attach((IDvdState
*)lParam
);
1970 if(pDVDC
) pDVDC
->SetState(pDvdState
, DVD_CMD_FLAG_Block
, NULL
);
1972 else if(iPlaybackMode
== PM_CAPTURE
)
1985 BOOL
CMainFrame::OnButton(UINT id
, UINT nFlags
, CPoint point
)
1990 m_wndView
.GetClientRect(r
);
1991 m_wndView
.MapWindowPoints(this, &r
);
1993 if(id
!= wmcmd::WDOWN
&& id
!= wmcmd::WUP
&& !r
.PtInRect(point
)) return FALSE
;
1997 AppSettings
& s
= AfxGetAppSettings();
1998 POSITION pos
= s
.wmcmds
.GetHeadPosition();
2001 wmcmd
& wc
= s
.wmcmds
.GetNext(pos
);
2004 SendMessage(WM_COMMAND
, wc
.cmd
);
2012 static bool s_fLDown
= false;
2014 void CMainFrame::OnLButtonDown(UINT nFlags
, CPoint point
)
2018 bool fClicked
= false;
2020 if(m_iPlaybackMode
== PM_DVD
)
2022 CPoint p
= point
- m_wndView
.GetVideoRect().TopLeft();
2024 if(SUCCEEDED(pDVDC
->ActivateAtPosition(p
))
2025 || m_iDVDDomain
== DVD_DOMAIN_VideoManagerMenu
2026 || m_iDVDDomain
== DVD_DOMAIN_VideoTitleSetMenu
)
2032 bool fLeftMouseBtnUnassigned
= true;
2033 AppSettings
& s
= AfxGetAppSettings();
2034 POSITION pos
= s
.wmcmds
.GetHeadPosition();
2035 while(pos
&& fLeftMouseBtnUnassigned
)
2036 if(s
.wmcmds
.GetNext(pos
).mouse
== wmcmd::LDOWN
)
2037 fLeftMouseBtnUnassigned
= false;
2039 if(!m_fFullScreen
&& (IsCaptionMenuHidden() || fLeftMouseBtnUnassigned
))
2041 PostMessage(WM_NCLBUTTONDOWN
, HTCAPTION
, MAKELPARAM(point
.x
, point
.y
));
2046 if(OnButton(wmcmd::LDOWN
, nFlags
, point
))
2051 __super::OnLButtonDown(nFlags
, point
);
2054 void CMainFrame::OnLButtonUp(UINT nFlags
, CPoint point
)
2056 if(!OnButton(wmcmd::LUP
, nFlags
, point
))
2057 __super::OnLButtonUp(nFlags
, point
);
2060 void CMainFrame::OnLButtonDblClk(UINT nFlags
, CPoint point
)
2064 SendMessage(WM_LBUTTONDOWN
, nFlags
, MAKELPARAM(point
.x
, point
.y
));
2067 if(!OnButton(wmcmd::LDBLCLK
, nFlags
, point
))
2068 __super::OnLButtonDblClk(nFlags
, point
);
2071 void CMainFrame::OnMButtonDown(UINT nFlags
, CPoint point
)
2073 SendMessage(WM_CANCELMODE
);
2074 if(!OnButton(wmcmd::MDOWN
, nFlags
, point
))
2075 __super::OnMButtonDown(nFlags
, point
);
2078 void CMainFrame::OnMButtonUp(UINT nFlags
, CPoint point
)
2080 if(!OnButton(wmcmd::MUP
, nFlags
, point
))
2081 __super::OnMButtonUp(nFlags
, point
);
2084 void CMainFrame::OnMButtonDblClk(UINT nFlags
, CPoint point
)
2086 SendMessage(WM_MBUTTONDOWN
, nFlags
, MAKELPARAM(point
.x
, point
.y
));
2087 if(!OnButton(wmcmd::MDBLCLK
, nFlags
, point
))
2088 __super::OnMButtonDblClk(nFlags
, point
);
2091 void CMainFrame::OnRButtonDown(UINT nFlags
, CPoint point
)
2093 if(!OnButton(wmcmd::RDOWN
, nFlags
, point
))
2094 __super::OnRButtonDown(nFlags
, point
);
2097 void CMainFrame::OnRButtonUp(UINT nFlags
, CPoint point
)
2099 if(!OnButton(wmcmd::RUP
, nFlags
, point
))
2100 __super::OnRButtonUp(nFlags
, point
);
2103 void CMainFrame::OnRButtonDblClk(UINT nFlags
, CPoint point
)
2105 SendMessage(WM_RBUTTONDOWN
, nFlags
, MAKELPARAM(point
.x
, point
.y
));
2106 if(!OnButton(wmcmd::RDBLCLK
, nFlags
, point
))
2107 __super::OnRButtonDblClk(nFlags
, point
);
2110 LRESULT
CMainFrame::OnXButtonDown(WPARAM wParam
, LPARAM lParam
)
2112 SendMessage(WM_CANCELMODE
);
2113 UINT fwButton
= GET_XBUTTON_WPARAM(wParam
);
2114 return OnButton(fwButton
== XBUTTON1
? wmcmd::X1DOWN
: fwButton
== XBUTTON2
? wmcmd::X2DOWN
: wmcmd::NONE
,
2115 GET_KEYSTATE_WPARAM(wParam
), CPoint(lParam
));
2118 LRESULT
CMainFrame::OnXButtonUp(WPARAM wParam
, LPARAM lParam
)
2120 UINT fwButton
= GET_XBUTTON_WPARAM(wParam
);
2121 return OnButton(fwButton
== XBUTTON1
? wmcmd::X1UP
: fwButton
== XBUTTON2
? wmcmd::X2UP
: wmcmd::NONE
,
2122 GET_KEYSTATE_WPARAM(wParam
), CPoint(lParam
));
2125 LRESULT
CMainFrame::OnXButtonDblClk(WPARAM wParam
, LPARAM lParam
)
2127 SendMessage(WM_XBUTTONDOWN
, wParam
, lParam
);
2128 UINT fwButton
= GET_XBUTTON_WPARAM(wParam
);
2129 return OnButton(fwButton
== XBUTTON1
? wmcmd::X1DBLCLK
: fwButton
== XBUTTON2
? wmcmd::X2DBLCLK
: wmcmd::NONE
,
2130 GET_KEYSTATE_WPARAM(wParam
), CPoint(lParam
));
2133 BOOL
CMainFrame::OnMouseWheel(UINT nFlags
, short zDelta
, CPoint point
)
2135 ScreenToClient(&point
);
2138 zDelta
> 0 ? OnButton(wmcmd::WUP
, nFlags
, point
) :
2139 zDelta
< 0 ? OnButton(wmcmd::WDOWN
, nFlags
, point
) :
2145 void CMainFrame::OnMouseMove(UINT nFlags
, CPoint point
)
2147 if(m_iPlaybackMode
== PM_DVD
)
2149 CPoint vp
= point
- m_wndView
.GetVideoRect().TopLeft();
2150 pDVDC
->SelectAtPosition(vp
);
2153 CSize diff
= m_lastMouseMove
- point
;
2155 if(m_fFullScreen
&& (abs(diff
.cx
)+abs(diff
.cy
)) >= 1)
2157 int nTimeOut
= AfxGetAppSettings().nShowBarsWhenFullScreenTimeOut
;
2161 m_fHideCursor
= false;
2162 if(AfxGetAppSettings().fShowBarsWhenFullScreen
)
2163 ShowControls(AfxGetAppSettings().nCS
);
2165 KillTimer(TIMER_FULLSCREENCONTROLBARHIDER
);
2166 SetTimer(TIMER_FULLSCREENMOUSEHIDER
, 2000, NULL
);
2168 else if(nTimeOut
== 0)
2174 POSITION pos
= m_bars
.GetHeadPosition();
2175 for(int i
= 1; pos
; i
<<= 1)
2177 CControlBar
* pNext
= m_bars
.GetNext(pos
);
2178 CSize s
= pNext
->CalcFixedLayout(FALSE
, TRUE
);
2179 if(AfxGetAppSettings().nCS
&i
) r
.top
-= s
.cy
;
2182 // HACK: the controls would cover the menu too early hiding some buttons
2183 if(m_iPlaybackMode
== PM_DVD
2184 && (m_iDVDDomain
== DVD_DOMAIN_VideoManagerMenu
2185 || m_iDVDDomain
== DVD_DOMAIN_VideoTitleSetMenu
))
2186 r
.top
= r
.bottom
- 10;
2188 m_fHideCursor
= false;
2190 if(r
.PtInRect(point
))
2192 if(AfxGetAppSettings().fShowBarsWhenFullScreen
)
2193 ShowControls(AfxGetAppSettings().nCS
);
2197 if(AfxGetAppSettings().fShowBarsWhenFullScreen
)
2198 ShowControls(CS_NONE
, false);
2201 SetTimer(TIMER_FULLSCREENMOUSEHIDER
, 2000, NULL
);
2205 m_fHideCursor
= false;
2206 if(AfxGetAppSettings().fShowBarsWhenFullScreen
)
2207 ShowControls(AfxGetAppSettings().nCS
);
2209 SetTimer(TIMER_FULLSCREENCONTROLBARHIDER
, nTimeOut
*1000, NULL
);
2210 SetTimer(TIMER_FULLSCREENMOUSEHIDER
, max(nTimeOut
*1000, 2000), NULL
);
2214 m_lastMouseMove
= point
;
2216 __super::OnMouseMove(nFlags
, point
);
2219 LRESULT
CMainFrame::OnNcHitTest(CPoint point
)
2221 LRESULT nHitTest
= __super::OnNcHitTest(point
);
2222 return ((IsCaptionMenuHidden()) && nHitTest
== HTCLIENT
) ? HTCAPTION
: nHitTest
;
2225 void CMainFrame::OnHScroll(UINT nSBCode
, UINT nPos
, CScrollBar
* pScrollBar
)
2227 if(pScrollBar
->IsKindOf(RUNTIME_CLASS(CVolumeCtrl
)))
2231 else if(pScrollBar
->IsKindOf(RUNTIME_CLASS(CPlayerSeekBar
)) && m_iMediaLoadState
== MLS_LOADED
)
2233 SeekTo(m_wndSeekBar
.GetPos(), !!(::GetKeyState(VK_SHIFT
)&0x8000));
2236 __super::OnHScroll(nSBCode
, nPos
, pScrollBar
);
2239 void CMainFrame::OnInitMenu(CMenu
* pMenu
)
2241 __super::OnInitMenu(pMenu
);
2244 mii
.cbSize
= sizeof(mii
);
2246 for(UINT i
= 0, j
= pMenu
->GetMenuItemCount(); i
< j
; i
++)
2249 pMenu
->GetMenuString(i
, str
, MF_BYPOSITION
);
2251 CMenu
* pSubMenu
= NULL
;
2253 if(str
== ResStr(IDS_FAVORITES_POPUP
))
2255 SetupFavoritesSubMenu();
2256 pSubMenu
= &m_favorites
;
2261 mii
.fMask
= MIIM_STATE
|MIIM_SUBMENU
;
2262 mii
.fType
= MF_POPUP
;
2263 mii
.hSubMenu
= pSubMenu
->m_hMenu
;
2264 mii
.fState
= (pSubMenu
->GetMenuItemCount() > 0 ? MF_ENABLED
: (MF_DISABLED
|MF_GRAYED
));
2265 pMenu
->SetMenuItemInfo(i
, &mii
, TRUE
);
2270 void CMainFrame::OnInitMenuPopup(CMenu
* pPopupMenu
, UINT nIndex
, BOOL bSysMenu
)
2272 __super::OnInitMenuPopup(pPopupMenu
, nIndex
, bSysMenu
);
2274 static CAtlStringMap
<UINT
> transl
;
2276 if(transl
.IsEmpty())
2278 transl
[_T("Navigate")] = IDS_NAVIGATE_POPUP
;
2279 transl
[_T("Open Disc")] = IDS_OPENCDROM_POPUP
;
2280 transl
[_T("Filters")] = IDS_FILTERS_POPUP
;
2281 transl
[_T("Audio")] = IDS_AUDIO_POPUP
;
2282 transl
[_T("Subtitles")] = IDS_SUBTITLES_POPUP
;
2283 transl
[_T("Audio Language")] = IDS_AUDIOLANGUAGE_POPUP
;
2284 transl
[_T("Subtitle Language")] = IDS_SUBTITLELANGUAGE_POPUP
;
2285 transl
[_T("Video Angle")] = IDS_VIDEOANGLE_POPUP
;
2286 transl
[_T("Jump To...")] = IDS_JUMPTO_POPUP
;
2287 transl
[_T("Favorites")] = IDS_FAVORITES_POPUP
;
2288 transl
[_T("Shaders")] = IDS_SHADER_POPUP
;
2289 transl
[_T("Video Frame")] = IDS_VIDEOFRAME_POPUP
;
2290 transl
[_T("PanScan")] = IDS_PANSCAN_POPUP
;
2291 transl
[_T("Aspect Ratio")] = IDS_ASPECTRATIO_POPUP
;
2292 transl
[_T("Zoom")] = IDS_ZOOM_POPUP
;
2296 mii
.cbSize
= sizeof(mii
);
2298 for(UINT i
= 0, j
= pPopupMenu
->GetMenuItemCount(); i
< j
; i
++)
2301 pPopupMenu
->GetMenuString(i
, str
, MF_BYPOSITION
);
2303 CString lookupstr
= str
;
2304 lookupstr
.Remove('&');
2306 CMenu
* pSubMenu
= NULL
;
2309 if(transl
.Lookup(lookupstr
, id
))
2312 // pPopupMenu->ModifyMenu(i, MF_BYPOSITION|MF_STRING, 0, str);
2314 mii
.cbSize
= sizeof(mii
);
2315 mii
.fMask
= MIIM_STRING
;
2316 mii
.dwTypeData
= (LPTSTR
)(LPCTSTR
)str
;
2317 pPopupMenu
->SetMenuItemInfo(i
, &mii
, TRUE
);
2320 if(str
== ResStr(IDS_NAVIGATE_POPUP
))
2322 UINT fState
= (m_iMediaLoadState
== MLS_LOADED
2323 && (1/*m_iPlaybackMode == PM_DVD *//*|| (m_iPlaybackMode == PM_FILE && m_PlayList.GetCount() > 0)*/))
2325 : (MF_DISABLED
|MF_GRAYED
);
2327 pPopupMenu
->EnableMenuItem(i
, MF_BYPOSITION
|fState
);
2329 else if(str
== ResStr(IDS_VIDEOFRAME_POPUP
)
2330 || str
== ResStr(IDS_PANSCAN_POPUP
)
2331 || str
== ResStr(IDS_ASPECTRATIO_POPUP
)
2332 || str
== ResStr(IDS_ZOOM_POPUP
))
2334 UINT fState
= (m_iMediaLoadState
== MLS_LOADED
&& !m_fAudioOnly
)
2336 : (MF_DISABLED
|MF_GRAYED
);
2338 pPopupMenu
->EnableMenuItem(i
, MF_BYPOSITION
|fState
);
2340 else if(str
== ResStr(IDS_OPENCDROM_POPUP
))
2342 SetupOpenCDSubMenu();
2343 pSubMenu
= &m_opencds
;
2345 else if(str
== ResStr(IDS_FILTERS_POPUP
))
2347 SetupFiltersSubMenu();
2348 pSubMenu
= &m_filters
;
2350 else if(str
== ResStr(IDS_AUDIO_POPUP
))
2352 SetupAudioSwitcherSubMenu();
2353 pSubMenu
= &m_audios
;
2355 else if(str
== ResStr(IDS_SUBTITLES_POPUP
))
2357 SetupSubtitlesSubMenu();
2358 pSubMenu
= &m_subtitles
;
2360 else if(str
== ResStr(IDS_AUDIOLANGUAGE_POPUP
))
2362 SetupNavAudioSubMenu();
2363 pSubMenu
= &m_navaudio
;
2365 else if(str
== ResStr(IDS_SUBTITLELANGUAGE_POPUP
))
2367 SetupNavSubtitleSubMenu();
2368 pSubMenu
= &m_navsubtitle
;
2370 else if(str
== ResStr(IDS_VIDEOANGLE_POPUP
))
2372 SetupNavAngleSubMenu();
2373 pSubMenu
= &m_navangle
;
2375 else if(str
== ResStr(IDS_JUMPTO_POPUP
))
2377 SetupNavChaptersSubMenu();
2378 pSubMenu
= &m_navchapters
;
2380 else if(str
== ResStr(IDS_FAVORITES_POPUP
))
2382 SetupFavoritesSubMenu();
2383 pSubMenu
= &m_favorites
;
2385 else if(str
== ResStr(IDS_SHADER_POPUP
))
2387 SetupShadersSubMenu();
2388 pSubMenu
= &m_shaders
;
2393 mii
.fMask
= MIIM_STATE
|MIIM_SUBMENU
;
2394 mii
.fType
= MF_POPUP
;
2395 mii
.hSubMenu
= pSubMenu
->m_hMenu
;
2396 mii
.fState
= (pSubMenu
->GetMenuItemCount() > 0 ? MF_ENABLED
: (MF_DISABLED
|MF_GRAYED
));
2397 pPopupMenu
->SetMenuItemInfo(i
, &mii
, TRUE
);
2403 for(UINT i
= 0, j
= pPopupMenu
->GetMenuItemCount(); i
< j
; i
++)
2405 UINT nID
= pPopupMenu
->GetMenuItemID(i
);
2406 if(nID
== ID_SEPARATOR
|| nID
== -1
2407 || nID
>= ID_FAVORITES_FILE_START
&& nID
<= ID_FAVORITES_FILE_END
2408 || nID
>= ID_NAVIGATE_CHAP_SUBITEM_START
&& nID
<= ID_NAVIGATE_CHAP_SUBITEM_END
)
2412 pPopupMenu
->GetMenuString(i
, str
, MF_BYPOSITION
);
2413 int k
= str
.Find('\t');
2414 if(k
> 0) str
= str
.Left(k
);
2416 CString key
= CPPageAccelTbl::MakeAccelShortcutLabel(nID
);
2417 if(!key
.IsEmpty()) str
+= _T("\t") + key
;
2419 if(key
.IsEmpty() && i
< 0) continue;
2421 // BUG(?): this disables menu item update ui calls for some reason...
2422 // pPopupMenu->ModifyMenu(i, MF_BYPOSITION|MF_STRING, nID, str);
2426 mii
.cbSize
= sizeof(mii
);
2427 mii
.fMask
= MIIM_STRING
;
2428 mii
.dwTypeData
= (LPTSTR
)(LPCTSTR
)str
;
2429 pPopupMenu
->SetMenuItemInfo(i
, &mii
, TRUE
);
2435 bool fPnSPresets
= false;
2437 for(UINT i
= 0, j
= pPopupMenu
->GetMenuItemCount(); i
< j
; i
++)
2439 UINT nID
= pPopupMenu
->GetMenuItemID(i
);
2441 if(nID
>= ID_PANNSCAN_PRESETS_START
&& nID
< ID_PANNSCAN_PRESETS_END
)
2445 nID
= pPopupMenu
->GetMenuItemID(i
);
2446 pPopupMenu
->DeleteMenu(i
, MF_BYPOSITION
);
2449 while(i
< j
&& nID
>= ID_PANNSCAN_PRESETS_START
&& nID
< ID_PANNSCAN_PRESETS_END
);
2451 nID
= pPopupMenu
->GetMenuItemID(i
);
2454 if(nID
== ID_VIEW_RESET
)
2462 AppSettings
& s
= AfxGetAppSettings();
2463 int i
= 0, j
= s
.m_pnspresets
.GetCount();
2467 CString label
= s
.m_pnspresets
[i
].Tokenize(_T(","), k
);
2468 pPopupMenu
->InsertMenu(ID_VIEW_RESET
, MF_BYCOMMAND
, ID_PANNSCAN_PRESETS_START
+i
, label
);
2472 pPopupMenu
->InsertMenu(ID_VIEW_RESET
, MF_BYCOMMAND
, ID_PANNSCAN_PRESETS_START
+i
, ResStr(IDS_PANSCAN_EDIT
));
2473 pPopupMenu
->InsertMenu(ID_VIEW_RESET
, MF_BYCOMMAND
|MF_SEPARATOR
);
2478 BOOL
CMainFrame::OnMenu(CMenu
* pMenu
)
2480 if(!pMenu
) return FALSE
;
2482 KillTimer(TIMER_FULLSCREENMOUSEHIDER
);
2483 m_fHideCursor
= false;
2486 GetCursorPos(&point
);
2488 pMenu
->TrackPopupMenu(TPM_RIGHTBUTTON
|TPM_NOANIMATION
, point
.x
+1, point
.y
+1, this);
2493 void CMainFrame::OnMenuPlayerShort()
2495 if(IsCaptionMenuHidden())
2497 OnMenu(m_popupmain
.GetSubMenu(0));
2501 OnMenu(m_popup
.GetSubMenu(0));
2505 void CMainFrame::OnMenuPlayerLong()
2507 OnMenu(m_popupmain
.GetSubMenu(0));
2510 void CMainFrame::OnMenuFilters()
2512 SetupFiltersSubMenu();
2516 void CMainFrame::OnUpdatePlayerStatus(CCmdUI
* pCmdUI
)
2518 if(m_iMediaLoadState
== MLS_LOADING
)
2520 pCmdUI
->SetText(ResStr(IDS_CONTROLS_OPENING
));
2522 else if(m_iMediaLoadState
== MLS_LOADED
)
2526 if(!m_playingmsg
.IsEmpty())
2530 else if(m_fCapturing
)
2532 msg
= ResStr(IDS_CONTROLS_CAPTURING
);
2537 pAMDF
->GetNumDropped(&lDropped
);
2538 long lNotDropped
= 0;
2539 pAMDF
->GetNumNotDropped(&lNotDropped
);
2541 if((lDropped
+ lNotDropped
) > 0)
2544 str
.Format(_T(", Total: %d, Dropped: %d"), lDropped
+ lNotDropped
, lDropped
);
2550 if(SUCCEEDED(pCGB
->FindPin(m_wndCaptureBar
.m_capdlg
.m_pDst
, PINDIR_INPUT
, NULL
, NULL
, FALSE
, 0, &pPin
)))
2553 if(CComQIPtr
<IStream
> pStream
= pPin
)
2555 pStream
->Commit(STGC_DEFAULT
);
2557 WIN32_FIND_DATA findFileData
;
2558 HANDLE h
= FindFirstFile(m_wndCaptureBar
.m_capdlg
.m_file
, &findFileData
);
2559 if(h
!= INVALID_HANDLE_VALUE
)
2561 size
= ((LONGLONG
)findFileData
.nFileSizeHigh
<< 32) | findFileData
.nFileSizeLow
;
2564 if(size
< 1024i64
*1024)
2565 str
.Format(_T(", Size: %I64dKB"), size
/1024);
2566 else //if(size < 1024i64*1024*1024)
2567 str
.Format(_T(", Size: %I64dMB"), size
/1024/1024);
2574 ULARGE_INTEGER FreeBytesAvailable
, TotalNumberOfBytes
, TotalNumberOfFreeBytes
;
2575 if(GetDiskFreeSpaceEx(
2576 m_wndCaptureBar
.m_capdlg
.m_file
.Left(m_wndCaptureBar
.m_capdlg
.m_file
.ReverseFind('\\')+1),
2577 &FreeBytesAvailable
, &TotalNumberOfBytes
, &TotalNumberOfFreeBytes
))
2580 if(FreeBytesAvailable
.QuadPart
< 1024i64
*1024)
2581 str
.Format(_T(", Free: %I64dKB"), FreeBytesAvailable
.QuadPart
/1024);
2582 else //if(FreeBytesAvailable.QuadPart < 1024i64*1024*1024)
2583 str
.Format(_T(", Free: %I64dMB"), FreeBytesAvailable
.QuadPart
/1024/1024);
2587 if(m_wndCaptureBar
.m_capdlg
.m_pMux
)
2590 CComQIPtr
<IMediaSeeking
> pMuxMS
= m_wndCaptureBar
.m_capdlg
.m_pMux
;
2591 if(pMuxMS
&& SUCCEEDED(pMuxMS
->GetCurrentPosition(&pos
)) && pos
> 0)
2593 double bytepersec
= 10000000.0 * size
/ pos
;
2595 m_rtDurationOverride
= __int64(10000000.0 * (FreeBytesAvailable
.QuadPart
+size
) / bytepersec
);
2599 if(m_wndCaptureBar
.m_capdlg
.m_pVidBuffer
2600 || m_wndCaptureBar
.m_capdlg
.m_pAudBuffer
)
2602 int nFreeVidBuffers
= 0, nFreeAudBuffers
= 0;
2603 if(CComQIPtr
<IBufferFilter
> pVB
= m_wndCaptureBar
.m_capdlg
.m_pVidBuffer
)
2604 nFreeVidBuffers
= pVB
->GetFreeBuffers();
2605 if(CComQIPtr
<IBufferFilter
> pAB
= m_wndCaptureBar
.m_capdlg
.m_pAudBuffer
)
2606 nFreeAudBuffers
= pAB
->GetFreeBuffers();
2609 str
.Format(_T(", Free V/A Buffers: %03d/%03d"), nFreeVidBuffers
, nFreeAudBuffers
);
2614 else if(m_fBuffering
)
2616 BeginEnumFilters(pGB
, pEF
, pBF
)
2618 if(CComQIPtr
<IAMNetworkStatus
, &IID_IAMNetworkStatus
> pAMNS
= pBF
)
2620 long BufferingProgress
= 0;
2621 if(SUCCEEDED(pAMNS
->get_BufferingProgress(&BufferingProgress
)) && BufferingProgress
> 0)
2623 msg
.Format(ResStr(IDS_CONTROLS_BUFFERING
), BufferingProgress
);
2625 __int64 start
= 0, stop
= 0;
2626 m_wndSeekBar
.GetRange(start
, stop
);
2627 m_fLiveWM
= (stop
== start
);
2636 __int64 t
= 0, c
= 0;
2637 if(SUCCEEDED(pAMOP
->QueryProgress(&t
, &c
)) && t
> 0 && c
< t
)
2638 msg
.Format(ResStr(IDS_CONTROLS_BUFFERING
), c
*100/t
);
2640 if(m_fUpdateInfoBar
)
2644 OAFilterState fs
= GetMediaState();
2646 !msg
.IsEmpty() ? msg
:
2647 fs
== State_Stopped
? ResStr(IDS_CONTROLS_STOPPED
) :
2648 (fs
== State_Paused
|| m_fFrameSteppingActive
) ? ResStr(IDS_CONTROLS_PAUSED
) :
2649 fs
== State_Running
? ResStr(IDS_CONTROLS_PLAYING
) :
2652 else if(m_iMediaLoadState
== MLS_CLOSING
)
2654 pCmdUI
->SetText(ResStr(IDS_CONTROLS_CLOSING
));
2658 pCmdUI
->SetText(m_closingmsg
);
2662 void CMainFrame::OnFilePostOpenmedia()
2666 OpenSetupStatsBar();
2668 OpenSetupStatusBar();
2670 // OpenSetupToolBar();
2672 OpenSetupCaptureBar();
2675 pMS
->GetDuration(&rtDur
);
2676 m_wndPlaylistBar
.SetCurTime(rtDur
);
2678 if(m_iPlaybackMode
== PM_CAPTURE
)
2680 ShowControlBar(&m_wndSubresyncBar
, FALSE
, TRUE
);
2681 // ShowControlBar(&m_wndPlaylistBar, FALSE, TRUE);
2682 // ShowControlBar(&m_wndCaptureBar, TRUE, TRUE);
2685 if(m_pCAP
) m_pCAP
->SetSubtitleDelay(0);
2686 m_iMediaLoadState
= MLS_LOADED
;
2688 // IMPORTANT: must not call any windowing msgs before
2689 // this point, it will deadlock when OpenMediaPrivate is
2690 // still running and the renderer window was created on
2691 // the same worker-thread
2695 wp
.length
= sizeof(wp
);
2696 GetWindowPlacement(&wp
);
2698 // restore magnification
2699 if(IsWindowVisible() && AfxGetAppSettings().fRememberZoomLevel
2700 && !(m_fFullScreen
|| wp
.showCmd
== SW_SHOWMAXIMIZED
|| wp
.showCmd
== SW_SHOWMINIMIZED
))
2706 if(!m_fAudioOnly
&& (AfxGetAppSettings().nCLSwitches
&CLSW_FULLSCREEN
))
2708 SendMessage(WM_COMMAND
, ID_VIEW_FULLSCREEN
);
2709 AfxGetAppSettings().nCLSwitches
&= ~CLSW_FULLSCREEN
;
2712 SendNowPlayingToMSN();
2713 SendNowPlayingTomIRC();
2716 void CMainFrame::OnUpdateFilePostOpenmedia(CCmdUI
* pCmdUI
)
2718 pCmdUI
->Enable(m_iMediaLoadState
== MLS_LOADING
);
2721 void CMainFrame::OnFilePostClosemedia()
2723 m_wndView
.SetVideoRect();
2724 m_wndSeekBar
.Enable(false);
2725 m_wndSeekBar
.SetPos(0);
2726 m_wndInfoBar
.RemoveAllLines();
2727 m_wndStatsBar
.RemoveAllLines();
2728 m_wndStatusBar
.Clear();
2729 m_wndStatusBar
.ShowTimer(false);
2731 if(IsWindow(m_wndSubresyncBar
.m_hWnd
))
2733 ShowControlBar(&m_wndSubresyncBar
, FALSE
, TRUE
);
2737 if(IsWindow(m_wndCaptureBar
.m_hWnd
))
2739 ShowControlBar(&m_wndCaptureBar
, FALSE
, TRUE
);
2740 m_wndCaptureBar
.m_capdlg
.SetupVideoControls(_T(""), NULL
, NULL
, NULL
);
2741 m_wndCaptureBar
.m_capdlg
.SetupAudioControls(_T(""), NULL
, CInterfaceArray
<IAMAudioInputMixer
>());
2746 SetWindowText(ResStr(IDR_MAINFRAME
));
2748 SetAlwaysOnTop(AfxGetAppSettings().iOnTop
);
2750 // this will prevent any further UI updates on the dynamically added menu items
2751 SetupFiltersSubMenu();
2752 SetupAudioSwitcherSubMenu();
2753 SetupSubtitlesSubMenu();
2754 SetupNavAudioSubMenu();
2755 SetupNavSubtitleSubMenu();
2756 SetupNavAngleSubMenu();
2757 SetupNavChaptersSubMenu();
2758 SetupFavoritesSubMenu();
2760 SendNowPlayingToMSN();
2763 void CMainFrame::OnUpdateFilePostClosemedia(CCmdUI
* pCmdUI
)
2765 pCmdUI
->Enable(!!m_hWnd
&& m_iMediaLoadState
== MLS_CLOSING
);
2768 void CMainFrame::OnBossKey()
2770 SendMessage(WM_COMMAND
, ID_PLAY_PAUSE
);
2771 if(m_fFullScreen
) SendMessage(WM_COMMAND
, ID_VIEW_FULLSCREEN
);
2772 SendMessage(WM_SYSCOMMAND
, SC_MINIMIZE
, -1);
2775 void CMainFrame::OnStreamAudio(UINT nID
)
2777 nID
-= ID_STREAM_AUDIO_NEXT
;
2779 if(m_iMediaLoadState
!= MLS_LOADED
) return;
2781 CComQIPtr
<IAMStreamSelect
> pSS
= FindFilter(__uuidof(CAudioSwitcherFilter
), pGB
);
2782 if(!pSS
) pSS
= FindFilter(L
"{D3CD7858-971A-4838-ACEC-40CA5D529DC8}", pGB
); // morgan's switcher
2785 if(pSS
&& SUCCEEDED(pSS
->Count(&cStreams
)) && cStreams
> 1)
2787 for(int i
= 0; i
< (int)cStreams
; i
++)
2789 AM_MEDIA_TYPE
* pmt
= NULL
;
2793 WCHAR
* pszName
= NULL
;
2794 if(FAILED(pSS
->Info(i
, &pmt
, &dwFlags
, &lcid
, &dwGroup
, &pszName
, NULL
, NULL
)))
2796 if(pmt
) DeleteMediaType(pmt
);
2797 if(pszName
) CoTaskMemFree(pszName
);
2799 if(dwFlags
&(AMSTREAMSELECTINFO_ENABLED
|AMSTREAMSELECTINFO_EXCLUSIVE
))
2801 pSS
->Enable((i
+(nID
==0?1:cStreams
-1))%cStreams
, AMSTREAMSELECTENABLE_ENABLE
);
2806 else if(m_iPlaybackMode
== PM_FILE
) SendMessage(WM_COMMAND
, ID_OGM_AUDIO_NEXT
+nID
);
2807 else if(m_iPlaybackMode
== PM_DVD
) SendMessage(WM_COMMAND
, ID_DVD_AUDIO_NEXT
+nID
);
2810 void CMainFrame::OnStreamSub(UINT nID
)
2812 nID
-= ID_STREAM_SUB_NEXT
;
2814 if(m_iMediaLoadState
!= MLS_LOADED
) return;
2817 POSITION pos
= m_pSubStreams
.GetHeadPosition();
2818 while(pos
) cnt
+= m_pSubStreams
.GetNext(pos
)->GetStreamCount();
2822 int i
= ((m_iSubtitleSel
&0x7fffffff)+(nID
==0?1:cnt
-1))%cnt
;
2823 m_iSubtitleSel
= i
| (m_iSubtitleSel
&0x80000000);
2827 else if(m_iPlaybackMode
== PM_FILE
) SendMessage(WM_COMMAND
, ID_OGM_SUB_NEXT
+nID
);
2828 else if(m_iPlaybackMode
== PM_DVD
) SendMessage(WM_COMMAND
, ID_DVD_SUB_NEXT
+nID
);
2831 void CMainFrame::OnStreamSubOnOff()
2833 if(m_iMediaLoadState
!= MLS_LOADED
) return;
2836 POSITION pos
= m_pSubStreams
.GetHeadPosition();
2837 while(pos
) cnt
+= m_pSubStreams
.GetNext(pos
)->GetStreamCount();
2841 m_iSubtitleSel
^= 0x80000000;
2845 else if(m_iPlaybackMode
== PM_DVD
) SendMessage(WM_COMMAND
, ID_DVD_SUB_ONOFF
);
2848 void CMainFrame::OnOgmAudio(UINT nID
)
2850 nID
-= ID_OGM_AUDIO_NEXT
;
2852 if(m_iMediaLoadState
!= MLS_LOADED
) return;
2854 CComQIPtr
<IAMStreamSelect
> pSS
= FindFilter(CLSID_OggSplitter
, pGB
);
2855 if(!pSS
) pSS
= FindFilter(L
"{55DA30FC-F16B-49fc-BAA5-AE59FC65F82D}", pGB
);
2858 CAtlArray
<int> snds
;
2862 if(SUCCEEDED(pSS
->Count(&cStreams
)) && cStreams
> 1)
2864 for(int i
= 0; i
< (int)cStreams
; i
++)
2866 AM_MEDIA_TYPE
* pmt
= NULL
;
2870 WCHAR
* pszName
= NULL
;
2871 if(FAILED(pSS
->Info(i
, &pmt
, &dwFlags
, &lcid
, &dwGroup
, &pszName
, NULL
, NULL
)))
2876 if(dwFlags
&(AMSTREAMSELECTINFO_ENABLED
|AMSTREAMSELECTINFO_EXCLUSIVE
))
2877 iSel
= snds
.GetCount();
2881 if(pmt
) DeleteMediaType(pmt
);
2882 if(pszName
) CoTaskMemFree(pszName
);
2886 int cnt
= snds
.GetCount();
2887 if(cnt
> 1 && iSel
>= 0)
2888 pSS
->Enable(snds
[(iSel
+(nID
==0?1:cnt
-1))%cnt
], AMSTREAMSELECTENABLE_ENABLE
);
2892 void CMainFrame::OnOgmSub(UINT nID
)
2894 nID
-= ID_OGM_SUB_NEXT
;
2896 if(m_iMediaLoadState
!= MLS_LOADED
) return;
2898 CComQIPtr
<IAMStreamSelect
> pSS
= FindFilter(CLSID_OggSplitter
, pGB
);
2899 if(!pSS
) pSS
= FindFilter(L
"{55DA30FC-F16B-49fc-BAA5-AE59FC65F82D}", pGB
);
2902 CAtlArray
<int> subs
;
2906 if(SUCCEEDED(pSS
->Count(&cStreams
)) && cStreams
> 1)
2908 for(int i
= 0; i
< (int)cStreams
; i
++)
2910 AM_MEDIA_TYPE
* pmt
= NULL
;
2914 WCHAR
* pszName
= NULL
;
2915 if(FAILED(pSS
->Info(i
, &pmt
, &dwFlags
, &lcid
, &dwGroup
, &pszName
, NULL
, NULL
)))
2920 if(dwFlags
&(AMSTREAMSELECTINFO_ENABLED
|AMSTREAMSELECTINFO_EXCLUSIVE
))
2921 iSel
= subs
.GetCount();
2925 if(pmt
) DeleteMediaType(pmt
);
2926 if(pszName
) CoTaskMemFree(pszName
);
2930 int cnt
= subs
.GetCount();
2931 if(cnt
> 1 && iSel
>= 0)
2932 pSS
->Enable(subs
[(iSel
+(nID
==0?1:cnt
-1))%cnt
], AMSTREAMSELECTENABLE_ENABLE
);
2936 void CMainFrame::OnDvdAngle(UINT nID
)
2938 nID
-= ID_DVD_ANGLE_NEXT
;
2940 if(m_iMediaLoadState
!= MLS_LOADED
) return;
2944 ULONG ulAnglesAvailable
, ulCurrentAngle
;
2945 if(SUCCEEDED(pDVDI
->GetCurrentAngle(&ulAnglesAvailable
, &ulCurrentAngle
)) && ulAnglesAvailable
> 1)
2947 ulCurrentAngle
+= nID
==0 ? 1 : ulAnglesAvailable
-1;
2948 if(ulCurrentAngle
> ulAnglesAvailable
) ulCurrentAngle
= 1;
2949 else if(ulCurrentAngle
< 1) ulCurrentAngle
= ulAnglesAvailable
;
2950 pDVDC
->SelectAngle(ulCurrentAngle
, DVD_CMD_FLAG_Block
, NULL
);
2955 void CMainFrame::OnDvdAudio(UINT nID
)
2957 nID
-= ID_DVD_AUDIO_NEXT
;
2959 if(m_iMediaLoadState
!= MLS_LOADED
) return;
2963 ULONG nStreamsAvailable
, nCurrentStream
;
2964 if(SUCCEEDED(pDVDI
->GetCurrentAudio(&nStreamsAvailable
, &nCurrentStream
)) && nStreamsAvailable
> 1)
2965 pDVDC
->SelectAudioStream((nCurrentStream
+(nID
==0?1:nStreamsAvailable
-1))%nStreamsAvailable
, DVD_CMD_FLAG_Block
, NULL
);
2969 void CMainFrame::OnDvdSub(UINT nID
)
2971 nID
-= ID_DVD_SUB_NEXT
;
2973 if(m_iMediaLoadState
!= MLS_LOADED
) return;
2977 ULONG ulStreamsAvailable
, ulCurrentStream
;
2979 if(SUCCEEDED(pDVDI
->GetCurrentSubpicture(&ulStreamsAvailable
, &ulCurrentStream
, &bIsDisabled
))
2980 && ulStreamsAvailable
> 1)
2982 pDVDC
->SelectSubpictureStream(
2983 (ulCurrentStream
+(nID
==0?1:ulStreamsAvailable
-1))%ulStreamsAvailable
,
2984 DVD_CMD_FLAG_Block
, NULL
);
2989 void CMainFrame::OnDvdSubOnOff()
2991 if(m_iMediaLoadState
!= MLS_LOADED
) return;
2995 ULONG ulStreamsAvailable
, ulCurrentStream
;
2997 if(SUCCEEDED(pDVDI
->GetCurrentSubpicture(&ulStreamsAvailable
, &ulCurrentStream
, &bIsDisabled
)))
2999 pDVDC
->SetSubpictureState(bIsDisabled
, DVD_CMD_FLAG_Block
, NULL
);
3005 // menu item handlers
3010 void CMainFrame::OnFileOpenQuick()
3012 if(m_iMediaLoadState
== MLS_LOADING
|| !IsWindow(m_wndPlaylistBar
)) return;
3015 CAtlArray
<CString
> mask
;
3016 AfxGetAppSettings().Formats
.GetFilter(filter
, mask
);
3018 COpenFileDlg
fd(mask
, true, NULL
, NULL
,
3019 OFN_EXPLORER
|OFN_ENABLESIZING
|OFN_HIDEREADONLY
|OFN_ALLOWMULTISELECT
|OFN_ENABLEINCLUDENOTIFY
,
3021 if(fd
.DoModal() != IDOK
) return;
3023 CAtlList
<CString
> fns
;
3025 POSITION pos
= fd
.GetStartPosition();
3026 while(pos
) fns
.AddTail(fd
.GetNextPathName(pos
));
3028 bool fMultipleFiles
= false;
3030 if(fns
.GetCount() > 1
3031 || fns
.GetCount() == 1
3032 && (fns
.GetHead()[fns
.GetHead().GetLength()-1] == '\\'
3033 || fns
.GetHead()[fns
.GetHead().GetLength()-1] == '*'))
3035 fMultipleFiles
= true;
3038 SendMessage(WM_COMMAND
, ID_FILE_CLOSEMEDIA
);
3040 ShowWindow(SW_SHOW
);
3041 SetForegroundWindow();
3043 m_wndPlaylistBar
.Open(fns
, fMultipleFiles
);
3045 if(m_wndPlaylistBar
.GetCount() == 1 && m_wndPlaylistBar
.IsWindowVisible() && !m_wndPlaylistBar
.IsFloating())
3047 ShowControlBar(&m_wndPlaylistBar
, FALSE
, TRUE
);
3050 OpenCurPlaylistItem();
3053 void CMainFrame::OnFileOpenmedia()
3055 if(m_iMediaLoadState
== MLS_LOADING
|| !IsWindow(m_wndPlaylistBar
)) return;
3058 if(dlg
.DoModal() != IDOK
|| dlg
.m_fns
.GetCount() == 0) return;
3060 if(dlg
.m_fAppendPlaylist
)
3062 m_wndPlaylistBar
.Append(dlg
.m_fns
, dlg
.m_fMultipleFiles
);
3066 SendMessage(WM_COMMAND
, ID_FILE_CLOSEMEDIA
);
3068 ShowWindow(SW_SHOW
);
3069 SetForegroundWindow();
3071 m_wndPlaylistBar
.Open(dlg
.m_fns
, dlg
.m_fMultipleFiles
);
3073 if(m_wndPlaylistBar
.GetCount() == 1 && m_wndPlaylistBar
.IsWindowVisible() && !m_wndPlaylistBar
.IsFloating())
3075 ShowControlBar(&m_wndPlaylistBar
, FALSE
, TRUE
);
3078 OpenCurPlaylistItem();
3081 void CMainFrame::OnUpdateFileOpen(CCmdUI
* pCmdUI
)
3083 pCmdUI
->Enable(m_iMediaLoadState
!= MLS_LOADING
);
3086 BOOL
CMainFrame::OnCopyData(CWnd
* pWnd
, COPYDATASTRUCT
* pCDS
)
3088 if(m_iMediaLoadState
== MLS_LOADING
|| !IsWindow(m_wndPlaylistBar
))
3091 if(pCDS
->dwData
!= 0x6ABE51 || pCDS
->cbData
< sizeof(DWORD
))
3094 DWORD len
= *((DWORD
*)pCDS
->lpData
);
3095 TCHAR
* pBuff
= (TCHAR
*)((DWORD
*)pCDS
->lpData
+ 1);
3096 TCHAR
* pBuffEnd
= (TCHAR
*)((BYTE
*)pBuff
+ pCDS
->cbData
- sizeof(DWORD
));
3098 CAtlList
<CString
> cmdln
;
3103 while(pBuff
< pBuffEnd
&& *pBuff
) str
+= *pBuff
++;
3108 AppSettings
& s
= AfxGetAppSettings();
3110 s
.ParseCommandLine(cmdln
);
3112 POSITION pos
= s
.slFilters
.GetHeadPosition();
3115 CString fullpath
= MakeFullPath(s
.slFilters
.GetNext(pos
));
3117 CPath
tmp(fullpath
);
3118 tmp
.RemoveFileSpec();
3122 WIN32_FIND_DATA fd
= {0};
3123 HANDLE hFind
= FindFirstFile(fullpath
, &fd
);
3124 if(hFind
!= INVALID_HANDLE_VALUE
)
3128 if(fd
.dwFileAttributes
&FILE_ATTRIBUTE_DIRECTORY
) continue;
3130 CFilterMapper2
fm2(false);
3131 fm2
.Register(path
+ fd
.cFileName
);
3132 while(!fm2
.m_filters
.IsEmpty())
3134 if(FilterOverride
* f
= fm2
.m_filters
.RemoveTail())
3136 f
->fTemporary
= true;
3138 bool fFound
= false;
3140 POSITION pos2
= s
.filters
.GetHeadPosition();
3143 FilterOverride
* f2
= s
.filters
.GetNext(pos2
);
3144 if(f2
->type
== FilterOverride::EXTERNAL
&& !f2
->path
.CompareNoCase(f
->path
))
3153 CAutoPtr
<FilterOverride
> p(f
);
3154 s
.filters
.AddHead(p
);
3159 while(FindNextFile(hFind
, &fd
));
3165 bool fSetForegroundWindow
= false;
3167 if((s
.nCLSwitches
&CLSW_DVD
) && !s
.slFiles
.IsEmpty())
3169 SendMessage(WM_COMMAND
, ID_FILE_CLOSEMEDIA
);
3170 fSetForegroundWindow
= true;
3172 CAutoPtr
<OpenDVDData
> p(new OpenDVDData());
3173 if(p
) {p
->path
= s
.slFiles
.GetHead(); p
->subs
.AddTailList(&s
.slSubs
);}
3176 else if(s
.nCLSwitches
&CLSW_CD
)
3178 SendMessage(WM_COMMAND
, ID_FILE_CLOSEMEDIA
);
3179 fSetForegroundWindow
= true;
3181 CAtlList
<CString
> sl
;
3183 if(!s
.slFiles
.IsEmpty())
3185 GetCDROMType(s
.slFiles
.GetHead()[0], sl
);
3190 dir
.ReleaseBufferSetLength(GetCurrentDirectory(MAX_PATH
, dir
.GetBuffer(MAX_PATH
)));
3192 GetCDROMType(dir
[0], sl
);
3194 for(TCHAR drive
= 'C'; sl
.IsEmpty() && drive
<= 'Z'; drive
++)
3196 GetCDROMType(drive
, sl
);
3200 m_wndPlaylistBar
.Open(sl
, true);
3201 OpenCurPlaylistItem();
3203 else if(!s
.slFiles
.IsEmpty())
3205 bool fMulti
= s
.slFiles
.GetCount() > 1;
3207 CAtlList
<CString
> sl
;
3208 sl
.AddTailList(&s
.slFiles
);
3209 if(!fMulti
) sl
.AddTailList(&s
.slDubs
);
3211 if((s
.nCLSwitches
&CLSW_ADD
) && m_wndPlaylistBar
.GetCount() > 0)
3213 m_wndPlaylistBar
.Append(sl
, fMulti
, &s
.slSubs
);
3215 if(s
.nCLSwitches
&(CLSW_OPEN
|CLSW_PLAY
))
3217 m_wndPlaylistBar
.SetLast();
3218 OpenCurPlaylistItem();
3223 SendMessage(WM_COMMAND
, ID_FILE_CLOSEMEDIA
);
3224 fSetForegroundWindow
= true;
3226 m_wndPlaylistBar
.Open(sl
, fMulti
, &s
.slSubs
);
3227 OpenCurPlaylistItem((s
.nCLSwitches
&CLSW_STARTVALID
) ? s
.rtStart
: 0);
3229 s
.nCLSwitches
&= ~CLSW_STARTVALID
;
3235 s
.nCLSwitches
= CLSW_NONE
;
3238 if(fSetForegroundWindow
&& !(s
.nCLSwitches
&CLSW_NOFOCUS
))
3239 SetForegroundWindow();
3241 s
.nCLSwitches
&= ~CLSW_NOFOCUS
;
3246 void CMainFrame::OnFileOpendvd()
3248 if(m_iMediaLoadState
== MLS_LOADING
) return;
3250 SendMessage(WM_COMMAND
, ID_FILE_CLOSEMEDIA
);
3251 SetForegroundWindow();
3253 ShowWindow(SW_SHOW
);
3255 CAutoPtr
<OpenDVDData
> p(new OpenDVDData());
3258 AppSettings
& s
= AfxGetAppSettings();
3259 if(s
.fUseDVDPath
&& !s
.sDVDPath
.IsEmpty())
3261 p
->path
= s
.sDVDPath
;
3262 p
->path
.Replace('/', '\\');
3263 if(p
->path
[p
->path
.GetLength()-1] != '\\') p
->path
+= '\\';
3269 void CMainFrame::OnFileOpendevice()
3271 if(m_iMediaLoadState
== MLS_LOADING
) return;
3273 COpenCapDeviceDlg capdlg
;
3274 if(capdlg
.DoModal() != IDOK
)
3277 SendMessage(WM_COMMAND
, ID_FILE_CLOSEMEDIA
);
3278 SetForegroundWindow();
3280 ShowWindow(SW_SHOW
);
3282 m_wndPlaylistBar
.Empty();
3284 CAutoPtr
<OpenDeviceData
> p(new OpenDeviceData());
3285 if(p
) {p
->DisplayName
[0] = capdlg
.m_vidstr
; p
->DisplayName
[1] = capdlg
.m_audstr
;}
3289 void CMainFrame::OnFileOpenCD(UINT nID
)
3291 nID
-= ID_FILE_OPEN_CD_START
;
3294 for(TCHAR drive
= 'C'; drive
<= 'Z'; drive
++)
3296 CAtlList
<CString
> sl
;
3298 switch(GetCDROMType(drive
, sl
))
3302 case CDROM_DVDVideo
:
3311 SendMessage(WM_COMMAND
, ID_FILE_CLOSEMEDIA
);
3312 SetForegroundWindow();
3314 ShowWindow(SW_SHOW
);
3316 m_wndPlaylistBar
.Open(sl
, true);
3317 OpenCurPlaylistItem();
3324 void CMainFrame::OnDropFiles(HDROP hDropInfo
)
3326 SetForegroundWindow();
3328 if(m_wndPlaylistBar
.IsWindowVisible())
3330 m_wndPlaylistBar
.OnDropFiles(hDropInfo
);
3334 CAtlList
<CString
> sl
;
3336 UINT nFiles
= ::DragQueryFile(hDropInfo
, (UINT
)-1, NULL
, 0);
3338 for(UINT iFile
= 0; iFile
< nFiles
; iFile
++)
3341 fn
.ReleaseBuffer(::DragQueryFile(hDropInfo
, iFile
, fn
.GetBuffer(MAX_PATH
), MAX_PATH
));
3345 ::DragFinish(hDropInfo
);
3347 if(sl
.IsEmpty()) return;
3349 if(sl
.GetCount() == 1 && m_iMediaLoadState
== MLS_LOADED
&& m_pCAP
)
3351 if(LoadSubtitle(sl
.GetHead()))
3353 SetSubtitle(m_pSubStreams
.GetTail());
3354 CPath
p(sl
.GetHead());
3356 SendStatusMessage(CString((LPCTSTR
)p
) + _T(" loaded successfully"), 3000);
3361 m_wndPlaylistBar
.Open(sl
, true);
3362 OpenCurPlaylistItem();
3365 void CMainFrame::OnFileSaveAs()
3367 CString ext
, in
= m_wndPlaylistBar
.GetCur(), out
= in
;
3369 if(out
.Find(_T("://")) < 0)
3371 ext
= CString(CPath(out
).GetExtension()).MakeLower();
3372 if(ext
== _T(".cda")) out
= out
.Left(out
.GetLength()-4) + _T(".wav");
3373 else if(ext
== _T(".ifo")) out
= out
.Left(out
.GetLength()-4) + _T(".vob");
3380 CFileDialog
fd(FALSE
, 0, out
,
3381 OFN_EXPLORER
|OFN_ENABLESIZING
|OFN_HIDEREADONLY
|OFN_OVERWRITEPROMPT
|OFN_PATHMUSTEXIST
,
3382 _T("All files (*.*)|*.*||"), this, 0);
3383 if(fd
.DoModal() != IDOK
|| !in
.CompareNoCase(fd
.GetPathName())) return;
3385 CPath
p(fd
.GetPathName());
3386 if(!ext
.IsEmpty()) p
.AddExtension(ext
);
3388 OAFilterState fs
= State_Stopped
;
3389 pMC
->GetState(0, &fs
);
3390 if(fs
== State_Running
) pMC
->Pause();
3392 CSaveDlg
dlg(in
, p
);
3395 if(fs
== State_Running
) pMC
->Run();
3398 void CMainFrame::OnUpdateFileSaveAs(CCmdUI
* pCmdUI
)
3400 if(m_iMediaLoadState
!= MLS_LOADED
|| m_iPlaybackMode
!= PM_FILE
)
3402 pCmdUI
->Enable(FALSE
);
3406 CString fn
= m_wndPlaylistBar
.GetCur();
3407 CString ext
= fn
.Mid(fn
.ReverseFind('.')+1).MakeLower();
3409 int i
= fn
.Find(_T("://"));
3412 CString protocol
= fn
.Left(i
).MakeLower();
3413 if(protocol
!= _T("http"))
3415 pCmdUI
->Enable(FALSE
);
3420 if((GetVersion()&0x80000000) && (ext
== _T("cda") || ext
== _T("ifo")))
3422 pCmdUI
->Enable(FALSE
);
3426 pCmdUI
->Enable(TRUE
);
3429 bool CMainFrame::GetDIB(BYTE
** ppData
, long& size
, bool fSilent
)
3431 if(!ppData
) return false;
3436 bool fNeedsToPause
= !m_pCAP
;
3437 if(fNeedsToPause
) fNeedsToPause
= !IsVMR7InGraph(pGB
);
3438 if(fNeedsToPause
) fNeedsToPause
= !IsVMR9InGraph(pGB
);
3440 OAFilterState fs
= GetMediaState();
3442 if(!(m_iMediaLoadState
== MLS_LOADED
&& !m_fAudioOnly
&& (fs
== State_Paused
|| fs
== State_Running
)))
3445 if(fs
== State_Running
&& fNeedsToPause
)
3448 GetMediaState(); // wait for completion of the pause command
3458 hr
= m_pCAP
->GetDIB(NULL
, (DWORD
*)&size
);
3461 OnPlayPause();GetMediaState(); // Pause and retry to support ffdshow queueing.
3463 while(FAILED(hr
) && retry
< 20)
3465 hr
= m_pCAP
->GetDIB(*ppData
, (DWORD
*)&size
);
3466 if(SUCCEEDED(hr
)) break;
3471 {errmsg
.Format(_T("GetDIB failed, hr = %08x"), hr
); break;}
3474 if(!(*ppData
= new BYTE
[size
])) return false;
3476 hr
= m_pCAP
->GetDIB(*ppData
, (DWORD
*)&size
);
3477 if(FAILED(hr
)) {errmsg
.Format(_T("GetDIB failed, hr = %08x"), hr
); break;}
3481 hr
= pBV
->GetCurrentImage(&size
, NULL
);
3482 if(FAILED(hr
) || size
== 0) {errmsg
.Format(_T("GetCurrentImage failed, hr = %08x"), hr
); break;}
3484 if(!(*ppData
= new BYTE
[size
])) return false;
3486 hr
= pBV
->GetCurrentImage(&size
, (long*)*ppData
);
3487 if(FAILED(hr
)) {errmsg
.Format(_T("GetCurrentImage failed, hr = %08x"), hr
); break;}
3494 if(!errmsg
.IsEmpty())
3496 AfxMessageBox(errmsg
, MB_OK
);
3500 if(fs
== State_Running
&& GetMediaState() != State_Running
)
3507 if(*ppData
) {ASSERT(0); delete [] *ppData
; *ppData
= NULL
;} // huh?
3517 void CMainFrame::SaveDIB(LPCTSTR fn
, BYTE
* pData
, long size
)
3519 CString ext
= CString(CPath(fn
).GetExtension()).MakeLower();
3521 if(ext
== _T(".bmp"))
3523 if(FILE* f
= _tfopen(fn
, _T("wb")))
3525 BITMAPINFO
* bi
= (BITMAPINFO
*)pData
;
3527 BITMAPFILEHEADER bfh
;
3529 bfh
.bfOffBits
= sizeof(bfh
) + sizeof(bi
->bmiHeader
);
3530 bfh
.bfSize
= sizeof(bfh
) + size
;
3531 bfh
.bfReserved1
= bfh
.bfReserved2
= 0;
3533 if(bi
->bmiHeader
.biBitCount
<= 8)
3535 if(bi
->bmiHeader
.biClrUsed
) bfh
.bfOffBits
+= bi
->bmiHeader
.biClrUsed
* sizeof(bi
->bmiColors
[0]);
3536 else bfh
.bfOffBits
+= (1 << bi
->bmiHeader
.biBitCount
) * sizeof(bi
->bmiColors
[0]);
3539 fwrite(&bfh
, 1, sizeof(bfh
), f
);
3540 fwrite(pData
, 1, size
, f
);
3546 AfxMessageBox(_T("Cannot create file"), MB_OK
);
3549 else if(ext
== _T(".png"))
3551 DWORD bmpsize
= size
;
3552 LPBITMAPINFOHEADER pdib
;
3553 LPBITMAPFILEHEADER pbmfh
;
3558 BITMAPINFO
* bi
= (BITMAPINFO
*)pData
;
3560 BITMAPFILEHEADER bfh
;
3562 bfh
.bfOffBits
= sizeof(bfh
) + sizeof(bi
->bmiHeader
);
3563 bfh
.bfSize
= sizeof(bfh
) + size
;
3564 bfh
.bfReserved1
= bfh
.bfReserved2
= 0;
3566 if(bi
->bmiHeader
.biBitCount
<= 8)
3568 if(bi
->bmiHeader
.biClrUsed
) bfh
.bfOffBits
+= bi
->bmiHeader
.biClrUsed
* sizeof(bi
->bmiColors
[0]);
3569 else bfh
.bfOffBits
+= (1 << bi
->bmiHeader
.biBitCount
) * sizeof(bi
->bmiColors
[0]);
3571 pbmfh
= (LPBITMAPFILEHEADER
)&bfh
;
3572 pbits
= &pData
[pbmfh
->bfOffBits
-sizeof(bfh
)];
3573 pdib
= (LPBITMAPINFOHEADER
)pData
;
3574 pngdib
= pngdib_d2p_init();
3575 pngdib_d2p_set_dib(pngdib
,pdib
,bmpsize
,pbits
,0);
3576 pngdib_d2p_set_png_filename(pngdib
, fn
);
3577 pngdib_d2p_set_gamma_label(pngdib
, 1, PNGDIB_DEFAULT_FILE_GAMMA
);
3578 ret
= pngdib_d2p_run(pngdib
);
3579 pngdib_done(pngdib
);
3582 err_str
.Format(_T("%s\n%s (%d)"), "Cannot create file", pngdib_get_error_msg(pngdib
), ret
);
3583 AfxMessageBox(err_str
, MB_OK
);
3586 else if(ext
== _T(".jpg"))
3588 CJpegEncoderFile(fn
).Encode(pData
);
3593 if(CDC
* pDC
= m_wndStatusBar
.m_status
.GetDC())
3596 m_wndStatusBar
.m_status
.GetClientRect(r
);
3597 p
.CompactPath(pDC
->m_hDC
, r
.Width());
3598 m_wndStatusBar
.m_status
.ReleaseDC(pDC
);
3601 SendStatusMessage((LPCTSTR
)p
, 3000);
3604 void CMainFrame::SaveImage(LPCTSTR fn
)
3609 if(GetDIB(&pData
, size
))
3611 SaveDIB(fn
, pData
, size
);
3616 void CMainFrame::SaveThumbnails(LPCTSTR fn
)
3618 if(!pMC
|| !pMS
|| m_iPlaybackMode
!= PM_FILE
/*&& m_iPlaybackMode != PM_DVD*/)
3621 REFERENCE_TIME rtPos
= GetPos();
3622 REFERENCE_TIME rtDur
= GetDur();
3626 AfxMessageBox(_T("Cannot create thumbnails for files with no duration"));
3631 GetMediaState(); // wait for completion of the pause command
3635 CSize video
, wh(0, 0), arxy(0, 0);
3639 wh
= m_pCAP
->GetVideoSize(false);
3640 arxy
= m_pCAP
->GetVideoSize(true);
3644 pBV
->GetVideoSize(&wh
.cx
, &wh
.cy
);
3646 long arx
= 0, ary
= 0;
3647 CComQIPtr
<IBasicVideo2
> pBV2
= pBV
;
3648 if(pBV2
&& SUCCEEDED(pBV2
->GetPreferredAspectRatio(&arx
, &ary
)) && arx
> 0 && ary
> 0)
3649 arxy
.SetSize(arx
, ary
);
3652 if(wh
.cx
<= 0 || wh
.cy
<= 0)
3654 AfxMessageBox(_T("Failed to get video frame size"));
3658 // with the overlay mixer IBasicVideo2 won't tell the new AR when changed dynamically
3659 DVD_VideoAttributes VATR
;
3660 if(m_iPlaybackMode
== PM_DVD
&& SUCCEEDED(pDVDI
->GetCurrentVideoAttributes(&VATR
)))
3661 arxy
.SetSize(VATR
.ulAspectX
, VATR
.ulAspectY
);
3663 video
= (arxy
.cx
<= 0 || arxy
.cy
<= 0) ? wh
: CSize(MulDiv(wh
.cy
, arxy
.cx
, arxy
.cy
), wh
.cy
);
3667 AppSettings
& s
= AfxGetAppSettings();
3669 int cols
= max(1, min(8, s
.ThumbCols
));
3670 int rows
= max(1, min(8, s
.ThumbRows
));
3673 int infoheight
= 70;
3674 int width
= max(256, min(2048, s
.ThumbWidth
));
3675 int height
= width
* video
.cy
/ video
.cx
* rows
/ cols
+ infoheight
;
3677 int dibsize
= sizeof(BITMAPINFOHEADER
) + width
*height
*4;
3679 CAutoVectorPtr
<BYTE
> dib
;
3680 if(!dib
.Allocate(dibsize
))
3682 AfxMessageBox(_T("Out of memory, go buy some more!"));
3686 BITMAPINFOHEADER
* bih
= (BITMAPINFOHEADER
*)(BYTE
*)dib
;
3687 memset(bih
, 0, sizeof(BITMAPINFOHEADER
));
3688 bih
->biSize
= sizeof(BITMAPINFOHEADER
);
3689 bih
->biWidth
= width
;
3690 bih
->biHeight
= height
;
3692 bih
->biBitCount
= 32;
3693 bih
->biCompression
= BI_RGB
;
3694 bih
->biSizeImage
= width
*height
*4;
3695 memsetd(bih
+ 1, 0xffffff, bih
->biSizeImage
);
3701 spd
.pitch
= -width
*4;
3702 spd
.bits
= (BYTE
*)(bih
+ 1) + (width
*4)*(height
-1);
3705 BYTE
* p
= (BYTE
*)spd
.bits
;
3706 for(int y
= 0; y
< spd
.h
; y
++, p
+= spd
.pitch
)
3707 for(int x
= 0; x
< spd
.w
; x
++)
3708 ((DWORD
*)p
)[x
] = 0x010101 * (0xe0 + 0x08*y
/spd
.h
+ 0x18*(spd
.w
-x
)/spd
.w
);
3714 for(int i
= 1, pics
= cols
*rows
; i
<= pics
; i
++)
3716 REFERENCE_TIME rt
= rtDur
* i
/ (pics
+1);
3717 DVD_HMSF_TIMECODE hmsf
= RT2HMSF(rt
, 25);
3721 m_VolumeBeforeFrameStepping
= m_wndToolBar
.Volume
;
3722 pBA
->put_Volume(-10000);
3724 HRESULT hr
= pFS
? pFS
->Step(1, NULL
) : E_FAIL
;
3728 pBA
->put_Volume(m_VolumeBeforeFrameStepping
);
3729 AfxMessageBox(_T("Cannot frame step, try a different video renderer."));
3733 HANDLE hGraphEvent
= NULL
;
3734 pME
->GetEventHandle((OAEVENT
*)&hGraphEvent
);
3736 while(hGraphEvent
&& WaitForSingleObject(hGraphEvent
, INFINITE
) == WAIT_OBJECT_0
)
3738 LONG evCode
= 0, evParam1
, evParam2
;
3739 while(SUCCEEDED(pME
->GetEvent(&evCode
, (LONG_PTR
*)&evParam1
, (LONG_PTR
*)&evParam2
, 0)))
3741 pME
->FreeEventParams(evCode
, evParam1
, evParam2
);
3742 if(EC_STEP_COMPLETE
== evCode
) hGraphEvent
= NULL
;
3746 pBA
->put_Volume(m_VolumeBeforeFrameStepping
);
3748 int col
= (i
-1)%cols
;
3749 int row
= (i
-1)/cols
;
3751 CSize
s((width
-margin
*2)/cols
, (height
-margin
*2-infoheight
)/rows
);
3752 CPoint
p(margin
+col
*s
.cx
, margin
+row
*s
.cy
+infoheight
);
3754 r
.DeflateRect(margin
, margin
);
3756 CRenderedTextSubtitle
rts(&csSubLock
);
3757 rts
.CreateDefaultStyle(0);
3758 rts
.m_dstScreenSize
.SetSize(width
, height
);
3759 STSStyle
* style
= new STSStyle();
3760 style
->marginRect
.SetRectEmpty();
3761 rts
.AddStyle(_T("thumbs"), style
);
3764 str
.Format(L
"{\\an7\\1c&Hffffff&\\4a&Hb0&\\bord1\\shad4\\be1}{\\p1}m %d %d l %d %d %d %d %d %d{\\p}",
3765 r
.left
, r
.top
, r
.right
, r
.top
, r
.right
, r
.bottom
, r
.left
, r
.bottom
);
3766 rts
.Add(str
, true, 0, 1, _T("thumbs"));
3767 str
.Format(L
"{\\an3\\1c&Hffffff&\\3c&H000000&\\alpha&H80&\\fs16\\b1\\bord2\\shad0\\pos(%d,%d)}%02d:%02d:%02d",
3768 r
.right
-5, r
.bottom
-3, hmsf
.bHours
, hmsf
.bMinutes
, hmsf
.bSeconds
);
3769 rts
.Add(str
, true, 1, 2, _T("thumbs"));
3771 rts
.Render(spd
, 0, 25, bbox
);
3775 if(!GetDIB(&pData
, size
)) return;
3777 BITMAPINFO
* bi
= (BITMAPINFO
*)pData
;
3779 if(bi
->bmiHeader
.biBitCount
!= 32)
3783 str
.Format(_T("Invalid image format, cannot create thumbnails out of %d bpp dibs."), bi
->bmiHeader
.biBitCount
);
3788 int sw
= bi
->bmiHeader
.biWidth
;
3789 int sh
= abs(bi
->bmiHeader
.biHeight
);
3791 const BYTE
* src
= pData
+ sizeof(bi
->bmiHeader
);
3792 if(bi
->bmiHeader
.biHeight
>= 0) {src
+= sp
*(sh
-1); sp
= -sp
;}
3797 BYTE
* dst
= (BYTE
*)spd
.bits
+ spd
.pitch
*r
.top
+ r
.left
*4;
3799 for(DWORD h
= r
.bottom
- r
.top
, y
= 0, yd
= (sh
<<8)/h
; h
> 0; y
+= yd
, h
--)
3804 DWORD
* s0
= (DWORD
*)(src
+ yi
*sp
);
3805 DWORD
* s1
= (DWORD
*)(src
+ yi
*sp
+ sp
);
3806 DWORD
* d
= (DWORD
*)dst
;
3808 for(DWORD w
= r
.right
- r
.left
, x
= 0, xd
= (sw
<<8)/w
; w
> 0; x
+= xd
, w
--)
3814 DWORD c1
= s0
[xi
+1];
3816 DWORD c3
= s1
[xi
+1];
3818 c0
= ((c0
&0xff00ff) + ((((c1
&0xff00ff) - (c0
&0xff00ff)) * xf
) >> 8)) & 0xff00ff
3819 | ((c0
&0x00ff00) + ((((c1
&0x00ff00) - (c0
&0x00ff00)) * xf
) >> 8)) & 0x00ff00;
3821 c2
= ((c2
&0xff00ff) + ((((c3
&0xff00ff) - (c2
&0xff00ff)) * xf
) >> 8)) & 0xff00ff
3822 | ((c2
&0x00ff00) + ((((c3
&0x00ff00) - (c2
&0x00ff00)) * xf
) >> 8)) & 0x00ff00;
3824 c0
= ((c0
&0xff00ff) + ((((c2
&0xff00ff) - (c0
&0xff00ff)) * yf
) >> 8)) & 0xff00ff
3825 | ((c0
&0x00ff00) + ((((c2
&0x00ff00) - (c0
&0x00ff00)) * yf
) >> 8)) & 0x00ff00;
3833 rts
.Render(spd
, 10000, 25, bbox
);
3839 CRenderedTextSubtitle
rts(&csSubLock
);
3840 rts
.CreateDefaultStyle(0);
3841 rts
.m_dstScreenSize
.SetSize(width
, height
);
3842 STSStyle
* style
= new STSStyle();
3843 style
->marginRect
.SetRect(margin
*2, margin
*2, margin
*2, height
-infoheight
-margin
);
3844 rts
.AddStyle(_T("thumbs"), style
);
3847 str
.Format(L
"{\\an9\\fs%d\\b1\\bord0\\shad0\\1c&Hffffff&}%s", infoheight
-10, width
>= 550 ? L
"Media Player Classic" : L
"MPC");
3849 rts
.Add(str
, true, 0, 1, _T("thumbs"), _T(""), _T(""), CRect(0,0,0,0), -1);
3851 DVD_HMSF_TIMECODE hmsf
= RT2HMSF(rtDur
, 25);
3853 CPath
path(m_wndPlaylistBar
.GetCur());
3855 CStringW fn
= (LPCTSTR
)path
;
3858 WIN32_FIND_DATA wfd
;
3859 HANDLE hFind
= FindFirstFile(m_wndPlaylistBar
.GetCur(), &wfd
);
3860 if(hFind
!= INVALID_HANDLE_VALUE
)
3864 __int64 size
= (__int64(wfd
.nFileSizeHigh
)<<32)|wfd
.nFileSizeLow
;
3865 __int64 shortsize
= size
;
3866 CStringW measure
= _T("B");
3867 if(shortsize
> 10240) shortsize
/= 1024, measure
= L
"KB";
3868 if(shortsize
> 10240) shortsize
/= 1024, measure
= L
"MB";
3869 if(shortsize
> 10240) shortsize
/= 1024, measure
= L
"GB";
3870 fs
.Format(L
"File Size: %I64d%s (%I64d bytes)\\N", shortsize
, measure
, size
);
3874 if(arxy
.cx
> 0 && arxy
.cy
> 0 && arxy
.cx
!= wh
.cx
&& arxy
.cy
!= wh
.cy
)
3875 ar
.Format(L
"(%d:%d)", arxy
.cx
, arxy
.cy
);
3877 str
.Format(L
"{\\an7\\1c&H000000&\\fs16\\b0\\bord0\\shad0}File Name: %s\\N%sResolution: %dx%d %s\\NDuration: %02d:%02d:%02d",
3878 fn
, fs
, wh
.cx
, wh
.cy
, ar
, hmsf
.bHours
, hmsf
.bMinutes
, hmsf
.bSeconds
);
3879 rts
.Add(str
, true, 0, 1, _T("thumbs"));
3881 rts
.Render(spd
, 0, 25, bbox
);
3884 SaveDIB(fn
, (BYTE
*)dib
, dibsize
);
3889 static CString
MakeSnapshotFileName(LPCTSTR prefix
)
3891 CTime t
= CTime::GetCurrentTime();
3893 fn
.Format(_T("%s%s%s"), prefix
, t
.Format(_T("%Y%m%d%H%M%S")), AfxGetAppSettings().SnapShotExt
);
3897 BOOL
CMainFrame::IsRendererCompatibleWithSaveImage()
3900 AppSettings
& s
= AfxGetAppSettings();
3902 if(m_fRealMediaGraph
) {
3903 if(s
.iRMVideoRendererType
== VIDRNDT_RM_DEFAULT
) {
3904 AfxMessageBox(_T("The 'Save Image' and 'Save Thumbnails' functions do not work with the default video renderer for RealMedia.\nSelect one of the DirectX renderers for RealMedia in MPC's output options and reopen the file."));
3908 if(m_fQuicktimeGraph
) {
3909 if(s
.iQTVideoRendererType
== VIDRNDT_QT_DEFAULT
) {
3910 AfxMessageBox(_T("The 'Save Image and 'Save Thumbnails' functions do not work with the default video renderer for QuickTime.\nSelect one of the DirectX renderers for QuickTime in MPC's output options and reopen the file."));
3914 if(m_fShockwaveGraph
) {
3915 AfxMessageBox(_T("The 'Save Image' and 'Save Thumbnails' functions do not work for Shockwave files."));
3918 if(s
.iDSVideoRendererType
== VIDRNDT_DS_OVERLAYMIXER
) {
3919 AfxMessageBox(_T("The 'Save Image' and 'Save Thumbnails' functions do not work with the Overlay Mixer video renderer.\nChange the video renderer in MPC's output options and reopen the file."));
3928 void CMainFrame::OnFileSaveImage()
3930 AppSettings
& s
= AfxGetAppSettings();
3932 /* Check if a compatible renderer is being used */
3933 if(!IsRendererCompatibleWithSaveImage()) {
3937 CPath
psrc(s
.SnapShotPath
);
3938 psrc
.Combine(s
.SnapShotPath
, MakeSnapshotFileName(_T("snapshot")));
3940 CFileDialog
fd(FALSE
, 0, (LPCTSTR
)psrc
,
3941 OFN_EXPLORER
|OFN_ENABLESIZING
|OFN_HIDEREADONLY
|OFN_OVERWRITEPROMPT
|OFN_PATHMUSTEXIST
,
3942 _T("Bitmaps (*.bmp)|*.bmp|Jpeg (*.jpg)|*.jpg|Png (*.png)|*.png||"), this, 0);
3944 if(s
.SnapShotExt
== _T(".bmp")) fd
.m_pOFN
->nFilterIndex
= 1;
3945 else if(s
.SnapShotExt
== _T(".jpg")) fd
.m_pOFN
->nFilterIndex
= 2;
3946 else if(s
.SnapShotExt
== _T(".png")) fd
.m_pOFN
->nFilterIndex
= 3;
3948 if(fd
.DoModal() != IDOK
) return;
3950 if(fd
.m_pOFN
->nFilterIndex
== 1) s
.SnapShotExt
= _T(".bmp");
3951 else if(fd
.m_pOFN
->nFilterIndex
== 2) s
.SnapShotExt
= _T(".jpg");
3952 else if(fd
.m_pOFN
->nFilterIndex
= 3) s
.SnapShotExt
= _T(".png");
3954 CPath
pdst(fd
.GetPathName());
3955 if(pdst
.GetExtension().MakeLower() != s
.SnapShotExt
) pdst
= CPath((LPCTSTR
)pdst
+ s
.SnapShotExt
);
3956 CString path
= (LPCTSTR
)pdst
;
3957 pdst
.RemoveFileSpec();
3958 s
.SnapShotPath
= (LPCTSTR
)pdst
;
3963 void CMainFrame::OnFileSaveImageAuto()
3965 AppSettings
& s
= AfxGetAppSettings();
3967 /* Check if a compatible renderer is being used */
3968 if(!IsRendererCompatibleWithSaveImage()) {
3973 fn
.Format(_T("%s\\%s"), AfxGetAppSettings().SnapShotPath
, MakeSnapshotFileName(_T("snapshot")));
3977 void CMainFrame::OnUpdateFileSaveImage(CCmdUI
* pCmdUI
)
3979 OAFilterState fs
= GetMediaState();
3980 pCmdUI
->Enable(m_iMediaLoadState
== MLS_LOADED
&& !m_fAudioOnly
&& (fs
== State_Paused
|| fs
== State_Running
));
3983 void CMainFrame::OnFileSaveThumbnails()
3985 AppSettings
& s
= AfxGetAppSettings();
3987 /* Check if a compatible renderer is being used */
3988 if(!IsRendererCompatibleWithSaveImage()) {
3992 CPath
psrc(s
.SnapShotPath
);
3993 psrc
.Combine(s
.SnapShotPath
, MakeSnapshotFileName(_T("thumbs")));
3995 CSaveThumbnailsDialog
fd(
3996 s
.ThumbRows
, s
.ThumbCols
, s
.ThumbWidth
,
3998 _T("Bitmaps (*.bmp)|*.bmp|Jpeg (*.jpg)|*.jpg|Png (*.png)|*.png||"), this);
4000 if(s
.SnapShotExt
== _T(".bmp")) fd
.m_pOFN
->nFilterIndex
= 1;
4001 else if(s
.SnapShotExt
== _T(".jpg")) fd
.m_pOFN
->nFilterIndex
= 2;
4002 else if(s
.SnapShotExt
== _T(".png")) fd
.m_pOFN
->nFilterIndex
= 3;
4004 if(fd
.DoModal() != IDOK
) return;
4006 if(fd
.m_pOFN
->nFilterIndex
== 1) s
.SnapShotExt
= _T(".bmp");
4007 else if(fd
.m_pOFN
->nFilterIndex
== 2) s
.SnapShotExt
= _T(".jpg");
4008 else if(fd
.m_pOFN
->nFilterIndex
= 3) s
.SnapShotExt
= _T(".png");
4010 s
.ThumbRows
= fd
.m_rows
;
4011 s
.ThumbCols
= fd
.m_cols
;
4012 s
.ThumbWidth
= fd
.m_width
;
4014 CPath
pdst(fd
.GetPathName());
4015 if(pdst
.GetExtension().MakeLower() != s
.SnapShotExt
) pdst
= CPath((LPCTSTR
)pdst
+ s
.SnapShotExt
);
4016 CString path
= (LPCTSTR
)pdst
;
4017 pdst
.RemoveFileSpec();
4018 s
.SnapShotPath
= (LPCTSTR
)pdst
;
4020 SaveThumbnails(path
);
4023 void CMainFrame::OnUpdateFileSaveThumbnails(CCmdUI
* pCmdUI
)
4025 OAFilterState fs
= GetMediaState();
4026 pCmdUI
->Enable(m_iMediaLoadState
== MLS_LOADED
&& !m_fAudioOnly
&& (m_iPlaybackMode
== PM_FILE
/*|| m_iPlaybackMode == PM_DVD*/));
4029 void CMainFrame::OnFileConvert()
4031 CConvertDlg().DoModal();
4034 void CMainFrame::OnUpdateFileConvert(CCmdUI
* pCmdUI
)
4036 // TODO: Add your command update UI handler code here
4039 void CMainFrame::OnFileLoadsubtitle()
4044 AfxMessageBox(_T("To load subtitles you have change the video renderer and reopen the file.\n")
4045 _T("- DirectShow: VMR7/VMR9(renderless) or Haali Video Renderer\n")
4046 _T("- RealMedia: Special renderer for RealMedia, or open it through DirectShow\n")
4047 _T("- Quicktime: DX7 or DX9 renderer for QuickTime\n")
4052 static TCHAR BASED_CODE szFilter
[] =
4053 _T(".srt .sub .ssa .ass .smi .psb .txt .idx .usf .xss .ssf|")
4054 _T("*.srt;*.sub;*.ssa;*.ass;*smi;*.psb;*.txt;*.idx;*.usf;*.xss;*.ssf|")
4055 _T("All files (*.*)|")
4058 CFileDialog
fd(TRUE
, NULL
, NULL
,
4059 OFN_EXPLORER
| OFN_ENABLESIZING
| OFN_HIDEREADONLY
,
4062 if(fd
.DoModal() != IDOK
) return;
4064 if(LoadSubtitle(fd
.GetPathName()))
4065 SetSubtitle(m_pSubStreams
.GetTail());
4068 void CMainFrame::OnUpdateFileLoadsubtitle(CCmdUI
*pCmdUI
)
4073 pCmdUI
->Enable(m_iMediaLoadState
== MLS_LOADED
&& /*m_pCAP &&*/ !m_fAudioOnly
);
4077 void CMainFrame::OnFileSavesubtitle()
4079 int i
= m_iSubtitleSel
;
4081 POSITION pos
= m_pSubStreams
.GetHeadPosition();
4082 while(pos
&& i
>= 0)
4084 CComPtr
<ISubStream
> pSubStream
= m_pSubStreams
.GetNext(pos
);
4086 if(i
< pSubStream
->GetStreamCount())
4089 if(FAILED(pSubStream
->GetClassID(&clsid
)))
4092 if(clsid
== __uuidof(CVobSubFile
))
4094 CVobSubFile
* pVSF
= (CVobSubFile
*)(ISubStream
*)pSubStream
;
4096 CFileDialog
fd(FALSE
, NULL
, NULL
,
4097 OFN_EXPLORER
|OFN_ENABLESIZING
|OFN_HIDEREADONLY
|OFN_OVERWRITEPROMPT
|OFN_PATHMUSTEXIST
,
4098 _T("VobSub (*.idx, *.sub)|*.idx;*.sub||"), this, 0);
4100 if(fd
.DoModal() == IDOK
)
4102 CAutoLock
cAutoLock(&m_csSubLock
);
4103 pVSF
->Save(fd
.GetPathName());
4108 else if(clsid
== __uuidof(CRenderedTextSubtitle
))
4110 CRenderedTextSubtitle
* pRTS
= (CRenderedTextSubtitle
*)(ISubStream
*)pSubStream
;
4113 filter
+= _T("Subripper (*.srt)|*.srt|");
4114 filter
+= _T("Microdvd (*.sub)|*.sub|");
4115 filter
+= _T("Sami (*.smi)|*.smi|");
4116 filter
+= _T("Psb (*.psb)|*.psb|");
4117 filter
+= _T("Sub Station Alpha (*.ssa)|*.ssa|");
4118 filter
+= _T("Advanced Sub Station Alpha (*.ass)|*.ass|");
4121 CSaveTextFileDialog
fd(pRTS
->m_encoding
, NULL
, NULL
, filter
, this);
4123 if(fd
.DoModal() == IDOK
)
4125 CAutoLock
cAutoLock(&m_csSubLock
);
4126 pRTS
->SaveAs(fd
.GetPathName(), (exttype
)(fd
.m_ofn
.nFilterIndex
-1), m_pCAP
->GetFPS(), fd
.GetEncoding());
4133 i
-= pSubStream
->GetStreamCount();
4137 void CMainFrame::OnUpdateFileSavesubtitle(CCmdUI
* pCmdUI
)
4139 pCmdUI
->Enable(m_iSubtitleSel
>= 0);
4144 #include "SubtitleDlDlg.h"
4147 void CMainFrame::OnFileISDBSearch()
4149 CStringA url
= "http://" + AfxGetAppSettings().ISDb
+ "/index.php?";
4150 CStringA args
= makeargs(m_wndPlaylistBar
.m_pl
);
4151 ShellExecute(m_hWnd
, _T("open"), CString(url
+args
), NULL
, NULL
, SW_SHOWDEFAULT
);
4154 void CMainFrame::OnUpdateFileISDBSearch(CCmdUI
*pCmdUI
)
4156 pCmdUI
->Enable(TRUE
);
4159 void CMainFrame::OnFileISDBUpload()
4161 CStringA url
= "http://" + AfxGetAppSettings().ISDb
+ "/ul.php?";
4162 CStringA args
= makeargs(m_wndPlaylistBar
.m_pl
);
4163 ShellExecute(m_hWnd
, _T("open"), CString(url
+args
), NULL
, NULL
, SW_SHOWDEFAULT
);
4166 void CMainFrame::OnUpdateFileISDBUpload(CCmdUI
*pCmdUI
)
4168 pCmdUI
->Enable(m_wndPlaylistBar
.GetCount() > 0);
4171 void CMainFrame::OnFileISDBDownload()
4174 if(!hash(m_wndPlaylistBar
.GetCur(), fh
))
4180 // TODO: put this on a worker thread
4182 CStringA url
= "http://" + AfxGetAppSettings().ISDb
+ "/index.php?";
4184 args
.Format("player=mpc&name[0]=%s&size[0]=%016I64x&hash[0]=%016I64x",
4185 UrlEncode(CStringA(fh
.name
)), fh
.size
, fh
.hash
);
4189 CInternetSession is
;
4192 if(!OpenUrl(is
, CString(url
+args
), str
))
4199 CList
<isdb_movie
> movies
;
4203 CAtlList
<CStringA
> sl
;
4204 Explode(str
, sl
, '\n');
4206 POSITION pos
= sl
.GetHeadPosition();
4209 str
= sl
.GetNext(pos
);
4211 CStringA param
= str
.Left(max(0, str
.Find('=')));
4212 CStringA value
= str
.Mid(str
.Find('=')+1);
4214 if(param
== "ticket") ticket
= value
;
4215 else if(param
== "movie") {m
.reset(); Explode(value
, m
.titles
, '|');}
4216 else if(param
== "subtitle") {s
.reset(); s
.id
= atoi(value
);}
4217 else if(param
== "name") s
.name
= value
;
4218 else if(param
== "discs") s
.discs
= atoi(value
);
4219 else if(param
== "disc_no") s
.disc_no
= atoi(value
);
4220 else if(param
== "format") s
.format
= value
;
4221 else if(param
== "iso639_2") s
.iso639_2
= value
;
4222 else if(param
== "language") s
.language
= value
;
4223 else if(param
== "nick") s
.nick
= value
;
4224 else if(param
== "email") s
.email
= value
;
4225 else if(param
== "" && value
== "endsubtitle") {m
.subs
.AddTail(s
);}
4226 else if(param
== "" && value
== "endmovie") {movies
.AddTail(m
);}
4227 else if(param
== "" && value
== "end") break;
4230 CSubtitleDlDlg
dlg(movies
, this);
4231 if(IDOK
== dlg
.DoModal())
4233 if(dlg
.m_fReplaceSubs
)
4234 m_pSubStreams
.RemoveAll();
4236 CComPtr
<ISubStream
> pSubStreamToSet
;
4238 POSITION pos
= dlg
.m_selsubs
.GetHeadPosition();
4241 isdb_subtitle
& s
= dlg
.m_selsubs
.GetNext(pos
);
4243 CStringA url
= "http://" + AfxGetAppSettings().ISDb
+ "/dl.php?";
4245 args
.Format("id=%d&ticket=%s", s
.id
, UrlEncode(ticket
));
4247 if(OpenUrl(is
, CString(url
+args
), str
))
4249 CAutoPtr
<CRenderedTextSubtitle
> pRTS(new CRenderedTextSubtitle(&m_csSubLock
));
4250 if(pRTS
&& pRTS
->Open((BYTE
*)(LPCSTR
)str
, str
.GetLength(), DEFAULT_CHARSET
, CString(s
.name
)) && pRTS
->GetStreamCount() > 0)
4252 CComPtr
<ISubStream
> pSubStream
= pRTS
.Detach();
4253 m_pSubStreams
.AddTail(pSubStream
);
4254 if(!pSubStreamToSet
) pSubStreamToSet
= pSubStream
;
4260 SetSubtitle(pSubStreamToSet
);
4263 catch(CInternetException
* ie
)
4270 void CMainFrame::OnUpdateFileISDBDownload(CCmdUI
*pCmdUI
)
4272 pCmdUI
->Enable(m_iMediaLoadState
== MLS_LOADED
&& m_pCAP
&& !m_fAudioOnly
);
4275 void CMainFrame::OnFileProperties()
4277 CPPageFileInfoSheet
m_fileinfo(m_wndPlaylistBar
.GetCur(), this);
4278 m_fileinfo
.DoModal();
4281 void CMainFrame::OnUpdateFileProperties(CCmdUI
* pCmdUI
)
4283 pCmdUI
->Enable(m_iMediaLoadState
== MLS_LOADED
&& m_iPlaybackMode
== PM_FILE
);
4286 void CMainFrame::OnFileCloseMedia()
4291 void CMainFrame::OnFileClosePlaylist()
4293 SendMessage(WM_COMMAND
, ID_FILE_CLOSEMEDIA
);
4294 RestoreDefaultWindowRect();
4297 void CMainFrame::OnUpdateFileClose(CCmdUI
* pCmdUI
)
4299 pCmdUI
->Enable(m_iMediaLoadState
== MLS_LOADED
|| m_iMediaLoadState
== MLS_LOADING
);
4304 void CMainFrame::OnViewCaptionmenu()
4306 bool fHideCaptionMenu
= AfxGetAppSettings().fHideCaptionMenu
;
4308 AfxGetAppSettings().fHideCaptionMenu
= !fHideCaptionMenu
;
4310 if(m_fFullScreen
) return;
4312 DWORD dwRemove
= 0, dwAdd
= 0;
4315 if(!fHideCaptionMenu
)
4317 dwRemove
= WS_CAPTION
;
4323 hMenu
= m_hMenuDefault
;
4326 ModifyStyle(dwRemove
, dwAdd
, SWP_NOZORDER
);
4327 ::SetMenu(m_hWnd
, hMenu
);
4328 SetWindowPos(NULL
, 0, 0, 0, 0, SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOZORDER
);
4333 void CMainFrame::OnUpdateViewCaptionmenu(CCmdUI
* pCmdUI
)
4335 pCmdUI
->SetCheck(!AfxGetAppSettings().fHideCaptionMenu
);
4338 void CMainFrame::OnViewControlBar(UINT nID
)
4340 nID
-= ID_VIEW_SEEKER
;
4341 ShowControls(AfxGetAppSettings().nCS
^ (1<<nID
));
4344 void CMainFrame::OnUpdateViewControlBar(CCmdUI
* pCmdUI
)
4346 UINT nID
= pCmdUI
->m_nID
- ID_VIEW_SEEKER
;
4347 pCmdUI
->SetCheck(!!(AfxGetAppSettings().nCS
& (1<<nID
)));
4350 void CMainFrame::OnViewSubresync()
4352 ShowControlBar(&m_wndSubresyncBar
, !m_wndSubresyncBar
.IsWindowVisible(), TRUE
);
4355 void CMainFrame::OnUpdateViewSubresync(CCmdUI
* pCmdUI
)
4357 pCmdUI
->SetCheck(m_wndSubresyncBar
.IsWindowVisible());
4358 pCmdUI
->Enable(m_pCAP
&& m_iSubtitleSel
>= 0);
4361 void CMainFrame::OnViewPlaylist()
4363 ShowControlBar(&m_wndPlaylistBar
, !m_wndPlaylistBar
.IsWindowVisible(), TRUE
);
4366 void CMainFrame::OnUpdateViewPlaylist(CCmdUI
* pCmdUI
)
4368 pCmdUI
->SetCheck(m_wndPlaylistBar
.IsWindowVisible());
4369 pCmdUI
->Enable(m_iMediaLoadState
== MLS_CLOSED
&& m_iMediaLoadState
!= MLS_LOADED
4370 || m_iMediaLoadState
== MLS_LOADED
/*&& (m_iPlaybackMode == PM_FILE || m_iPlaybackMode == PM_CAPTURE)*/);
4373 void CMainFrame::OnViewCapture()
4375 ShowControlBar(&m_wndCaptureBar
, !m_wndCaptureBar
.IsWindowVisible(), TRUE
);
4378 void CMainFrame::OnUpdateViewCapture(CCmdUI
* pCmdUI
)
4380 pCmdUI
->SetCheck(m_wndCaptureBar
.IsWindowVisible());
4381 pCmdUI
->Enable(m_iMediaLoadState
== MLS_LOADED
&& m_iPlaybackMode
== PM_CAPTURE
);
4384 void CMainFrame::OnViewShaderEditor()
4386 ShowControlBar(&m_wndShaderEditorBar
, !m_wndShaderEditorBar
.IsWindowVisible(), TRUE
);
4389 void CMainFrame::OnUpdateViewShaderEditor(CCmdUI
* pCmdUI
)
4391 pCmdUI
->SetCheck(m_wndShaderEditorBar
.IsWindowVisible());
4392 pCmdUI
->Enable(TRUE
);
4395 void CMainFrame::OnViewMinimal()
4397 if(!AfxGetAppSettings().fHideCaptionMenu
)
4398 SendMessage(WM_COMMAND
, ID_VIEW_CAPTIONMENU
);
4402 void CMainFrame::OnUpdateViewMinimal(CCmdUI
* pCmdUI
)
4406 void CMainFrame::OnViewCompact()
4408 if(AfxGetAppSettings().fHideCaptionMenu
)
4409 SendMessage(WM_COMMAND
, ID_VIEW_CAPTIONMENU
);
4410 ShowControls(CS_TOOLBAR
);
4413 void CMainFrame::OnUpdateViewCompact(CCmdUI
* pCmdUI
)
4417 void CMainFrame::OnViewNormal()
4419 if(AfxGetAppSettings().fHideCaptionMenu
)
4420 SendMessage(WM_COMMAND
, ID_VIEW_CAPTIONMENU
);
4421 ShowControls(CS_SEEKBAR
|CS_TOOLBAR
|CS_STATUSBAR
|CS_INFOBAR
);
4424 void CMainFrame::OnUpdateViewNormal(CCmdUI
* pCmdUI
)
4428 void CMainFrame::OnViewFullscreen()
4430 ToggleFullscreen(true, true);
4433 void CMainFrame::OnViewFullscreenSecondary()
4435 ToggleFullscreen(true, false);
4438 void CMainFrame::OnUpdateViewFullscreen(CCmdUI
* pCmdUI
)
4440 pCmdUI
->Enable(m_iMediaLoadState
== MLS_LOADED
&& !m_fAudioOnly
|| m_fFullScreen
);
4441 pCmdUI
->SetCheck(m_fFullScreen
);
4444 void CMainFrame::OnViewZoom(UINT nID
)
4446 ZoomVideoWindow(nID
== ID_VIEW_ZOOM_50
? 0.5 : nID
== ID_VIEW_ZOOM_200
? 2.0 : 1.0);
4449 void CMainFrame::OnUpdateViewZoom(CCmdUI
* pCmdUI
)
4451 pCmdUI
->Enable(m_iMediaLoadState
== MLS_LOADED
&& !m_fAudioOnly
);
4454 void CMainFrame::OnViewZoomAutoFit()
4456 ZoomVideoWindow(GetZoomAutoFitScale());
4459 void CMainFrame::OnViewDefaultVideoFrame(UINT nID
)
4461 AfxGetAppSettings().iDefaultVideoSize
= nID
- ID_VIEW_VF_HALF
;
4462 m_ZoomX
= m_ZoomY
= 1;
4463 m_PosX
= m_PosY
= 0.5;
4467 void CMainFrame::OnUpdateViewDefaultVideoFrame(CCmdUI
* pCmdUI
)
4469 pCmdUI
->Enable(m_iMediaLoadState
== MLS_LOADED
&& !m_fAudioOnly
);
4470 pCmdUI
->SetRadio(AfxGetAppSettings().iDefaultVideoSize
== (pCmdUI
->m_nID
- ID_VIEW_VF_HALF
));
4473 void CMainFrame::OnViewKeepaspectratio()
4475 AfxGetAppSettings().fKeepAspectRatio
= !AfxGetAppSettings().fKeepAspectRatio
;
4479 void CMainFrame::OnUpdateViewKeepaspectratio(CCmdUI
* pCmdUI
)
4481 pCmdUI
->Enable(m_iMediaLoadState
== MLS_LOADED
&& !m_fAudioOnly
);
4482 pCmdUI
->SetCheck(AfxGetAppSettings().fKeepAspectRatio
);
4485 void CMainFrame::OnViewCompMonDeskARDiff()
4487 AfxGetAppSettings().fCompMonDeskARDiff
= !AfxGetAppSettings().fCompMonDeskARDiff
;
4491 void CMainFrame::OnUpdateViewCompMonDeskARDiff(CCmdUI
* pCmdUI
)
4493 pCmdUI
->Enable(m_iMediaLoadState
== MLS_LOADED
&& !m_fAudioOnly
);
4494 pCmdUI
->SetCheck(AfxGetAppSettings().fCompMonDeskARDiff
);
4497 void CMainFrame::OnViewPanNScan(UINT nID
)
4499 if(m_iMediaLoadState
!= MLS_LOADED
) return;
4506 case ID_VIEW_RESET
: m_ZoomX
= m_ZoomY
= 1.0; m_PosX
= m_PosY
= 0.5; m_AngleX
= m_AngleY
= m_AngleZ
= 0; break;
4507 case ID_VIEW_INCSIZE
: x
= y
= 1; break;
4508 case ID_VIEW_DECSIZE
: x
= y
= -1; break;
4509 case ID_VIEW_INCWIDTH
: x
= 1; break;
4510 case ID_VIEW_DECWIDTH
: x
= -1; break;
4511 case ID_VIEW_INCHEIGHT
: y
= 1; break;
4512 case ID_VIEW_DECHEIGHT
: y
= -1; break;
4513 case ID_PANSCAN_CENTER
: m_PosX
= m_PosY
= 0.5; break;
4514 case ID_PANSCAN_MOVELEFT
: dx
= -1; break;
4515 case ID_PANSCAN_MOVERIGHT
: dx
= 1; break;
4516 case ID_PANSCAN_MOVEUP
: dy
= -1; break;
4517 case ID_PANSCAN_MOVEDOWN
: dy
= 1; break;
4518 case ID_PANSCAN_MOVEUPLEFT
: dx
= dy
= -1; break;
4519 case ID_PANSCAN_MOVEUPRIGHT
: dx
= 1; dy
= -1; break;
4520 case ID_PANSCAN_MOVEDOWNLEFT
: dx
= -1; dy
= 1; break;
4521 case ID_PANSCAN_MOVEDOWNRIGHT
: dx
= dy
= 1; break;
4525 if(x
> 0 && m_ZoomX
< 3) m_ZoomX
*= 1.02;
4526 if(x
< 0 && m_ZoomX
> 0.2) m_ZoomX
/= 1.02;
4527 if(y
> 0 && m_ZoomY
< 3) m_ZoomY
*= 1.02;
4528 if(y
< 0 && m_ZoomY
> 0.2) m_ZoomY
/= 1.02;
4530 if(dx
< 0 && m_PosX
> 0) m_PosX
= max(m_PosX
- 0.005*m_ZoomX
, 0);
4531 if(dx
> 0 && m_PosX
< 1) m_PosX
= min(m_PosX
+ 0.005*m_ZoomX
, 1);
4532 if(dy
< 0 && m_PosY
> 0) m_PosY
= max(m_PosY
- 0.005*m_ZoomY
, 0);
4533 if(dy
> 0 && m_PosY
< 1) m_PosY
= min(m_PosY
+ 0.005*m_ZoomY
, 1);
4535 MoveVideoWindow(true);
4538 void CMainFrame::OnUpdateViewPanNScan(CCmdUI
* pCmdUI
)
4540 pCmdUI
->Enable(m_iMediaLoadState
== MLS_LOADED
&& !m_fAudioOnly
);
4543 void CMainFrame::OnViewPanNScanPresets(UINT nID
)
4545 if(m_iMediaLoadState
!= MLS_LOADED
) return;
4547 AppSettings
& s
= AfxGetAppSettings();
4549 nID
-= ID_PANNSCAN_PRESETS_START
;
4551 if(nID
== s
.m_pnspresets
.GetCount())
4554 dlg
.m_pnspresets
.Copy(s
.m_pnspresets
);
4555 if(dlg
.DoModal() == IDOK
)
4557 s
.m_pnspresets
.Copy(dlg
.m_pnspresets
);
4568 CString str
= s
.m_pnspresets
[nID
];
4571 for(CString token
= str
.Tokenize(_T(","), i
); !token
.IsEmpty(); token
= str
.Tokenize(_T(","), i
), j
++)
4574 if(_stscanf(token
, _T("%f"), &f
) != 1) continue;
4579 case 1: m_PosX
= f
; break;
4580 case 2: m_PosY
= f
; break;
4581 case 3: m_ZoomX
= f
; break;
4582 case 4: m_ZoomY
= f
; break;
4589 m_PosX
= min(max(m_PosX
, 0), 1);
4590 m_PosY
= min(max(m_PosY
, 0), 1);
4591 m_ZoomX
= min(max(m_ZoomX
, 0.2), 3);
4592 m_ZoomY
= min(max(m_ZoomY
, 0.2), 3);
4594 MoveVideoWindow(true);
4597 void CMainFrame::OnUpdateViewPanNScanPresets(CCmdUI
* pCmdUI
)
4599 int nID
= pCmdUI
->m_nID
- ID_PANNSCAN_PRESETS_START
;
4600 AppSettings
& s
= AfxGetAppSettings();
4601 pCmdUI
->Enable(m_iMediaLoadState
== MLS_LOADED
&& !m_fAudioOnly
&& nID
>= 0 && nID
<= s
.m_pnspresets
.GetCount());
4604 void CMainFrame::OnViewRotate(UINT nID
)
4610 case ID_PANSCAN_ROTATEXP
: m_AngleX
+= 2; break;
4611 case ID_PANSCAN_ROTATEXM
: m_AngleX
-= 2; break;
4612 case ID_PANSCAN_ROTATEYP
: m_AngleY
+= 2; break;
4613 case ID_PANSCAN_ROTATEYM
: m_AngleY
-= 2; break;
4614 case ID_PANSCAN_ROTATEZP
: m_AngleZ
+= 2; break;
4615 case ID_PANSCAN_ROTATEZM
: m_AngleZ
-= 2; break;
4619 m_pCAP
->SetVideoAngle(Vector(DegToRad(m_AngleX
), DegToRad(m_AngleY
), DegToRad(m_AngleZ
)));
4622 info
.Format(_T("x: %d, y: %d, z: %d"), m_AngleX
, m_AngleY
, m_AngleZ
);
4623 SendStatusMessage(info
, 3000);
4626 void CMainFrame::OnUpdateViewRotate(CCmdUI
* pCmdUI
)
4628 pCmdUI
->Enable(m_iMediaLoadState
== MLS_LOADED
&& !m_fAudioOnly
&& m_pCAP
);
4632 const static SIZE s_ar
[] = {{0,0}, {4,3}, {5,4}, {16,9}};
4634 void CMainFrame::OnViewAspectRatio(UINT nID
)
4636 CSize
& ar
= AfxGetAppSettings().AspectRatio
;
4638 ar
= s_ar
[nID
- ID_ASPECTRATIO_START
];
4641 if(ar
.cx
&& ar
.cy
) info
.Format(_T("Aspect Ratio: %d:%d"), ar
.cx
, ar
.cy
);
4642 else info
.Format(_T("Aspect Ratio: Default"));
4643 SendStatusMessage(info
, 3000);
4648 void CMainFrame::OnUpdateViewAspectRatio(CCmdUI
* pCmdUI
)
4650 pCmdUI
->SetRadio(AfxGetAppSettings().AspectRatio
== s_ar
[pCmdUI
->m_nID
- ID_ASPECTRATIO_START
]);
4651 pCmdUI
->Enable(m_iMediaLoadState
== MLS_LOADED
&& !m_fAudioOnly
);
4654 void CMainFrame::OnViewAspectRatioNext()
4656 CSize
& ar
= AfxGetAppSettings().AspectRatio
;
4658 UINT nID
= ID_ASPECTRATIO_START
;
4660 for(int i
= 0; i
< countof(s_ar
); i
++)
4664 nID
+= (i
+ 1) % countof(s_ar
);
4669 OnViewAspectRatio(nID
);
4672 void CMainFrame::OnViewOntop(UINT nID
)
4674 nID
-= ID_ONTOP_NEVER
;
4675 if(AfxGetAppSettings().iOnTop
== nID
)
4677 SetAlwaysOnTop(nID
);
4680 void CMainFrame::OnUpdateViewOntop(CCmdUI
* pCmdUI
)
4682 pCmdUI
->SetRadio(AfxGetAppSettings().iOnTop
== (pCmdUI
->m_nID
- ID_ONTOP_NEVER
));
4685 void CMainFrame::OnViewOptions()
4692 void CMainFrame::OnPlayPlay()
4694 if(m_iMediaLoadState
== MLS_LOADED
)
4696 if(GetMediaState() == State_Stopped
) m_iSpeedLevel
= 0;
4698 if(m_iPlaybackMode
== PM_FILE
)
4700 if(m_fEndOfStream
) SendMessage(WM_COMMAND
, ID_PLAY_STOP
);
4703 else if(m_iPlaybackMode
== PM_DVD
)
4706 if(m_iSpeedLevel
!= -4 && m_iSpeedLevel
!= 0)
4707 dRate
= pow(2.0, m_iSpeedLevel
>= -3 ? m_iSpeedLevel
: (-m_iSpeedLevel
- 8));
4709 pDVDC
->PlayForwards(dRate
, DVD_CMD_FLAG_Block
, NULL
);
4710 pDVDC
->Pause(FALSE
);
4713 else if(m_iPlaybackMode
== PM_CAPTURE
)
4715 pMC
->Stop(); // audio preview won't be in sync if we run it from paused state
4719 SetTimer(TIMER_STREAMPOSPOLLER
, 40, NULL
);
4720 SetTimer(TIMER_STREAMPOSPOLLER2
, 500, NULL
);
4721 SetTimer(TIMER_STATS
, 1000, NULL
);
4723 if(m_fFrameSteppingActive
) // FIXME
4725 m_fFrameSteppingActive
= false;
4726 pBA
->put_Volume(m_VolumeBeforeFrameStepping
);
4729 SetAlwaysOnTop(AfxGetAppSettings().iOnTop
);
4735 void CMainFrame::OnPlayPauseI()
4737 if(m_iMediaLoadState
== MLS_LOADED
)
4739 SetAlwaysOnTop(AfxGetAppSettings().iOnTop
);
4741 if(m_iPlaybackMode
== PM_FILE
)
4745 else if(m_iPlaybackMode
== PM_DVD
)
4749 else if(m_iPlaybackMode
== PM_CAPTURE
)
4754 SetTimer(TIMER_STREAMPOSPOLLER
, 40, NULL
);
4755 SetTimer(TIMER_STREAMPOSPOLLER2
, 500, NULL
);
4756 SetTimer(TIMER_STATS
, 1000, NULL
);
4762 void CMainFrame::OnPlayPause()
4764 // Support ffdshow queueing.
4765 // To avoid black out on pause, we have to lock g_ffdshowReceive to synchronize with ReceiveMine.
4766 if(queueu_ffdshow_support
)
4768 CAutoLock
lck(&g_ffdshowReceive
);
4769 return OnPlayPauseI();
4774 void CMainFrame::OnPlayPlaypause()
4776 OAFilterState fs
= GetMediaState();
4777 if(fs
== State_Running
) SendMessage(WM_COMMAND
, ID_PLAY_PAUSE
);
4778 else if(fs
== State_Stopped
|| fs
== State_Paused
) SendMessage(WM_COMMAND
, ID_PLAY_PLAY
);
4781 void CMainFrame::OnPlayStop()
4783 if(m_iMediaLoadState
== MLS_LOADED
)
4785 if(m_iPlaybackMode
== PM_FILE
)
4788 pMS
->SetPositions(&pos
, AM_SEEKING_AbsolutePositioning
, NULL
, AM_SEEKING_NoPositioning
);
4791 // BUG: after pause or stop the netshow url source filter won't continue
4792 // on the next play command, unless we cheat it by setting the file name again.
4794 // Note: WMPx may be using some undocumented interface to restart streaming.
4796 BeginEnumFilters(pGB
, pEF
, pBF
)
4798 CComQIPtr
<IAMNetworkStatus
, &IID_IAMNetworkStatus
> pAMNS
= pBF
;
4799 CComQIPtr
<IFileSourceFilter
> pFSF
= pBF
;
4804 if(SUCCEEDED(pFSF
->GetCurFile(&pFN
, &mt
)) && pFN
&& *pFN
)
4806 pFSF
->Load(pFN
, NULL
);
4814 else if(m_iPlaybackMode
== PM_DVD
)
4816 pDVDC
->SetOption(DVD_ResetOnStop
, TRUE
);
4818 pDVDC
->SetOption(DVD_ResetOnStop
, FALSE
);
4820 else if(m_iPlaybackMode
== PM_CAPTURE
)
4827 if(m_fFrameSteppingActive
) // FIXME
4829 m_fFrameSteppingActive
= false;
4830 pBA
->put_Volume(m_VolumeBeforeFrameStepping
);
4833 m_fEndOfStream
= false;
4840 KillTimer(TIMER_STREAMPOSPOLLER2
);
4841 KillTimer(TIMER_STREAMPOSPOLLER
);
4842 KillTimer(TIMER_STATS
);
4846 if(m_iMediaLoadState
== MLS_LOADED
)
4848 __int64 start
, stop
;
4849 m_wndSeekBar
.GetRange(start
, stop
);
4851 pMS
->GetTimeFormat(&tf
);
4852 m_wndStatusBar
.SetStatusTimer(m_wndSeekBar
.GetPosReal(), stop
, !!m_wndSubresyncBar
.IsWindowVisible(), &tf
);
4854 SetAlwaysOnTop(AfxGetAppSettings().iOnTop
);
4859 void CMainFrame::OnUpdatePlayPauseStop(CCmdUI
* pCmdUI
)
4861 OAFilterState fs
= m_fFrameSteppingActive
? State_Paused
: GetMediaState();
4863 pCmdUI
->SetCheck(fs
== State_Running
&& pCmdUI
->m_nID
== ID_PLAY_PLAY
4864 || fs
== State_Paused
&& pCmdUI
->m_nID
== ID_PLAY_PAUSE
4865 || fs
== State_Stopped
&& pCmdUI
->m_nID
== ID_PLAY_STOP
4866 || (fs
== State_Paused
|| fs
== State_Running
) && pCmdUI
->m_nID
== ID_PLAY_PLAYPAUSE
);
4868 bool fEnable
= false;
4872 if(m_iPlaybackMode
== PM_FILE
|| m_iPlaybackMode
== PM_CAPTURE
)
4876 if(fs
== State_Stopped
&& pCmdUI
->m_nID
== ID_PLAY_PAUSE
&& m_fRealMediaGraph
) fEnable
= false; // can't go into paused state from stopped with rm
4877 else if(m_fCapturing
) fEnable
= false;
4878 else if(m_fLiveWM
&& pCmdUI
->m_nID
== ID_PLAY_PAUSE
) fEnable
= false;
4880 else if(m_iPlaybackMode
== PM_DVD
)
4882 fEnable
= m_iDVDDomain
!= DVD_DOMAIN_VideoManagerMenu
4883 && m_iDVDDomain
!= DVD_DOMAIN_VideoTitleSetMenu
;
4885 if(fs
== State_Stopped
&& pCmdUI
->m_nID
== ID_PLAY_PAUSE
) fEnable
= false;
4889 pCmdUI
->Enable(fEnable
);
4892 void CMainFrame::OnPlayFramestep(UINT nID
)
4896 if(pFS
&& m_fQuicktimeGraph
)
4898 if(GetMediaState() != State_Paused
&& !queueu_ffdshow_support
)
4899 SendMessage(WM_COMMAND
, ID_PLAY_PAUSE
);
4901 pFS
->Step(nID
== ID_PLAY_FRAMESTEP
? 1 : -1, NULL
);
4903 else if(pFS
&& nID
== ID_PLAY_FRAMESTEP
)
4905 if(GetMediaState() != State_Paused
)
4906 SendMessage(WM_COMMAND
, ID_PLAY_PAUSE
);
4908 m_fFrameSteppingActive
= true;
4910 m_VolumeBeforeFrameStepping
= m_wndToolBar
.Volume
;
4911 pBA
->put_Volume(-10000);
4915 else if(S_OK
== pMS
->IsFormatSupported(&TIME_FORMAT_FRAME
))
4917 if(GetMediaState() != State_Paused
)
4918 SendMessage(WM_COMMAND
, ID_PLAY_PAUSE
);
4920 pMS
->SetTimeFormat(&TIME_FORMAT_FRAME
);
4921 pMS
->GetCurrentPosition(&rt
);
4922 if(nID
== ID_PLAY_FRAMESTEP
) rt
++;
4923 else if(nID
== ID_PLAY_FRAMESTEPCANCEL
) rt
--;
4924 pMS
->SetPositions(&rt
, AM_SEEKING_AbsolutePositioning
, NULL
, AM_SEEKING_NoPositioning
);
4925 pMS
->SetTimeFormat(&TIME_FORMAT_MEDIA_TIME
);
4929 void CMainFrame::OnUpdatePlayFramestep(CCmdUI
* pCmdUI
)
4931 bool fEnable
= false;
4933 if(m_iMediaLoadState
== MLS_LOADED
&& !m_fAudioOnly
4934 && (m_iPlaybackMode
!= PM_DVD
|| m_iDVDDomain
== DVD_DOMAIN_Title
)
4935 && m_iPlaybackMode
!= PM_CAPTURE
4938 REFTIME AvgTimePerFrame
= 0;
4939 if(S_OK
== pMS
->IsFormatSupported(&TIME_FORMAT_FRAME
)
4940 || pCmdUI
->m_nID
== ID_PLAY_FRAMESTEP
&& pFS
&& pFS
->CanStep(0, NULL
) == S_OK
4941 || m_fQuicktimeGraph
&& pFS
)
4947 pCmdUI
->Enable(fEnable
);
4950 void CMainFrame::OnPlaySeek(UINT nID
)
4952 AppSettings
& s
= AfxGetAppSettings();
4955 nID
== ID_PLAY_SEEKBACKWARDSMALL
? -10000i64
*s
.nJumpDistS
:
4956 nID
== ID_PLAY_SEEKFORWARDSMALL
? +10000i64
*s
.nJumpDistS
:
4957 nID
== ID_PLAY_SEEKBACKWARDMED
? -10000i64
*s
.nJumpDistM
:
4958 nID
== ID_PLAY_SEEKFORWARDMED
? +10000i64
*s
.nJumpDistM
:
4959 nID
== ID_PLAY_SEEKBACKWARDLARGE
? -10000i64
*s
.nJumpDistL
:
4960 nID
== ID_PLAY_SEEKFORWARDLARGE
? +10000i64
*s
.nJumpDistL
:
4965 // HACK: the custom graph should support frame based seeking instead
4966 if(m_fShockwaveGraph
) dt
/= 10000i64
*100;
4968 SeekTo(m_wndSeekBar
.GetPos() + dt
);
4971 static int rangebsearch(REFERENCE_TIME val
, CAtlArray
<REFERENCE_TIME
>& rta
)
4973 int i
= 0, j
= rta
.GetCount() - 1, ret
= -1;
4975 if(j
>= 0 && val
>= rta
[j
]) return(j
);
4979 int mid
= (i
+ j
) >> 1;
4980 REFERENCE_TIME midt
= rta
[mid
];
4981 if(val
== midt
) {ret
= mid
; break;}
4982 else if(val
< midt
) {ret
= -1; if(j
== mid
) mid
--; j
= mid
;}
4983 else if(val
> midt
) {ret
= mid
; if(i
== mid
) mid
++; i
= mid
;}
4989 void CMainFrame::OnPlaySeekKey(UINT nID
)
4991 if(m_kfs
.GetCount() > 0)
4995 if(GetMediaState() == State_Stopped
)
4996 SendMessage(WM_COMMAND
, ID_PLAY_PAUSE
);
4998 REFERENCE_TIME rtCurrent
, rtDur
;
4999 hr
= pMS
->GetCurrentPosition(&rtCurrent
);
5000 hr
= pMS
->GetDuration(&rtDur
);
5003 int i
= rangebsearch(rtCurrent
, m_kfs
);
5004 if(i
> 0) dec
= (UINT
)max(min(rtCurrent
- m_kfs
[i
-1], 10000000), 0);
5007 nID
== ID_PLAY_SEEKKEYBACKWARD
? max(rtCurrent
- dec
, 0) :
5008 nID
== ID_PLAY_SEEKKEYFORWARD
? rtCurrent
: 0;
5010 i
= rangebsearch(rtCurrent
, m_kfs
);
5012 if(nID
== ID_PLAY_SEEKKEYBACKWARD
)
5013 rtCurrent
= m_kfs
[max(i
, 0)];
5014 else if(nID
== ID_PLAY_SEEKKEYFORWARD
&& i
< m_kfs
.GetCount()-1)
5015 rtCurrent
= m_kfs
[i
+1];
5019 // HACK: if d3d or something changes fpu control word the values of
5020 // m_kfs may be different now (if it was asked again), adding a little
5021 // to the seek position eliminates this error usually.
5025 hr
= pMS
->SetPositions(
5026 &rtCurrent
, AM_SEEKING_AbsolutePositioning
|AM_SEEKING_SeekToKeyFrame
,
5027 NULL
, AM_SEEKING_NoPositioning
);
5031 void CMainFrame::OnUpdatePlaySeek(CCmdUI
* pCmdUI
)
5033 bool fEnable
= false;
5035 OAFilterState fs
= GetMediaState();
5037 if(m_iMediaLoadState
== MLS_LOADED
&& (fs
== State_Paused
|| fs
== State_Running
))
5040 if(m_iPlaybackMode
== PM_DVD
&& (m_iDVDDomain
!= DVD_DOMAIN_Title
|| fs
!= State_Running
)) fEnable
= false;
5041 else if(m_iPlaybackMode
== PM_CAPTURE
) fEnable
= false;
5044 pCmdUI
->Enable(fEnable
);
5047 void CMainFrame::OnPlayGoto()
5049 if(m_iMediaLoadState
!= MLS_LOADED
)
5053 if(FAILED(pBV
->get_AvgTimePerFrame(&atpf
)) || atpf
< 0)
5057 BeginEnumFilters(pGB
, pEF
, pBF
)
5061 BeginEnumPins(pBF
, pEP
, pPin
)
5066 pPin
->ConnectionMediaType(&mt
);
5068 if(mt
.majortype
== MEDIATYPE_Video
&& mt
.formattype
== FORMAT_VideoInfo
)
5070 atpf
= (REFTIME
)((VIDEOINFOHEADER
*)mt
.pbFormat
)->AvgTimePerFrame
/ 10000000i64
;
5072 else if(mt
.majortype
== MEDIATYPE_Video
&& mt
.formattype
== FORMAT_VideoInfo2
)
5074 atpf
= (REFTIME
)((VIDEOINFOHEADER2
*)mt
.pbFormat
)->AvgTimePerFrame
/ 10000000i64
;
5082 CGoToDlg
dlg((int)(m_wndSeekBar
.GetPos()/10000), atpf
> 0 ? (float)(1.0/atpf
) : 0);
5083 if(IDOK
!= dlg
.DoModal() || dlg
.m_time
< 0) return;
5085 SeekTo(10000i64
* dlg
.m_time
);
5088 void CMainFrame::OnUpdateGoto(CCmdUI
* pCmdUI
)
5090 bool fEnable
= false;
5092 if(m_iMediaLoadState
== MLS_LOADED
)
5095 if(m_iPlaybackMode
== PM_DVD
&& m_iDVDDomain
!= DVD_DOMAIN_Title
) fEnable
= false;
5096 else if(m_iPlaybackMode
== PM_CAPTURE
) fEnable
= false;
5099 pCmdUI
->Enable(fEnable
);
5102 void CMainFrame::OnPlayChangeRate(UINT nID
)
5104 if(m_iMediaLoadState
!= MLS_LOADED
)
5107 if(m_iPlaybackMode
== PM_CAPTURE
)
5109 if(GetMediaState() != State_Running
)
5110 SendMessage(WM_COMMAND
, ID_PLAY_PLAY
);
5112 long lChannelMin
= 0, lChannelMax
= 0;
5113 pAMTuner
->ChannelMinMax(&lChannelMin
, &lChannelMax
);
5114 long lChannel
= 0, lVivSub
= 0, lAudSub
= 0;
5115 pAMTuner
->get_Channel(&lChannel
, &lVivSub
, &lAudSub
);
5117 long lFreqOrg
= 0, lFreqNew
= -1;
5118 pAMTuner
->get_VideoFrequency(&lFreqOrg
);
5120 // long lSignalStrength;
5123 if(nID
== ID_PLAY_DECRATE
) lChannel
--;
5124 else if(nID
== ID_PLAY_INCRATE
) lChannel
++;
5126 // if(lChannel < lChannelMin) lChannel = lChannelMax;
5127 // if(lChannel > lChannelMax) lChannel = lChannelMin;
5129 if(lChannel
< lChannelMin
|| lChannel
> lChannelMax
)
5132 if(FAILED(pAMTuner
->put_Channel(lChannel
, AMTUNER_SUBCHAN_DEFAULT
, AMTUNER_SUBCHAN_DEFAULT
)))
5136 pAMTuner
->AutoTune(lChannel
, &flFoundSignal
);
5138 pAMTuner
->get_VideoFrequency(&lFreqNew
);
5141 /* SUCCEEDED(pAMTuner->SignalPresent(&lSignalStrength))
5142 && (lSignalStrength != AMTUNER_SIGNALPRESENT || lFreqNew == lFreqOrg));*/
5149 if(nID
== ID_PLAY_INCRATE
) iNewSpeedLevel
= m_iSpeedLevel
+1;
5150 else if(nID
== ID_PLAY_DECRATE
) iNewSpeedLevel
= m_iSpeedLevel
-1;
5153 HRESULT hr
= E_FAIL
;
5155 if(iNewSpeedLevel
== -4)
5157 if(GetMediaState() != State_Paused
)
5158 SendMessage(WM_COMMAND
, ID_PLAY_PAUSE
);
5160 if(GetMediaState() == State_Paused
) hr
= S_OK
;
5164 double dRate
= pow(2.0, iNewSpeedLevel
>= -3 ? iNewSpeedLevel
: (-iNewSpeedLevel
- 8));
5165 if(fabs(dRate
- 1.0) < 0.01) dRate
= 1.0;
5167 if(GetMediaState() != State_Running
)
5168 SendMessage(WM_COMMAND
, ID_PLAY_PLAY
);
5170 if(m_iPlaybackMode
== PM_FILE
)
5172 hr
= pMS
->SetRate(dRate
);
5174 else if(m_iPlaybackMode
== PM_DVD
)
5176 if(iNewSpeedLevel
>= -3)
5177 hr
= pDVDC
->PlayForwards(dRate
, DVD_CMD_FLAG_Block
, NULL
);
5179 hr
= pDVDC
->PlayBackwards(dRate
, DVD_CMD_FLAG_Block
, NULL
);
5184 m_iSpeedLevel
= iNewSpeedLevel
;
5188 void CMainFrame::OnUpdatePlayChangeRate(CCmdUI
* pCmdUI
)
5190 bool fEnable
= false;
5192 if(m_iMediaLoadState
== MLS_LOADED
)
5194 bool fInc
= pCmdUI
->m_nID
== ID_PLAY_INCRATE
;
5197 if(fInc
&& m_iSpeedLevel
>= 3) fEnable
= false;
5198 else if(!fInc
&& m_iPlaybackMode
== PM_FILE
&& m_iSpeedLevel
<= -4) fEnable
= false;
5199 else if(!fInc
&& m_iPlaybackMode
== PM_DVD
&& m_iSpeedLevel
<= -11) fEnable
= false;
5200 else if(m_iPlaybackMode
== PM_DVD
&& m_iDVDDomain
!= DVD_DOMAIN_Title
) fEnable
= false;
5201 else if(m_fRealMediaGraph
|| m_fShockwaveGraph
) fEnable
= false;
5202 else if(m_iPlaybackMode
== PM_CAPTURE
&& (!m_wndCaptureBar
.m_capdlg
.IsTunerActive() || m_fCapturing
)) fEnable
= false;
5203 else if(m_fLiveWM
) fEnable
= false;
5206 pCmdUI
->Enable(fEnable
);
5209 void CMainFrame::OnPlayResetRate()
5211 if(m_iMediaLoadState
!= MLS_LOADED
)
5214 HRESULT hr
= E_FAIL
;
5216 if(GetMediaState() != State_Running
)
5217 SendMessage(WM_COMMAND
, ID_PLAY_PLAY
);
5219 if(m_iPlaybackMode
== PM_FILE
)
5221 hr
= pMS
->SetRate(1.0);
5223 else if(m_iPlaybackMode
== PM_DVD
)
5225 hr
= pDVDC
->PlayForwards(1.0, DVD_CMD_FLAG_Block
, NULL
);
5232 void CMainFrame::OnUpdatePlayResetRate(CCmdUI
* pCmdUI
)
5234 pCmdUI
->Enable(m_iMediaLoadState
== MLS_LOADED
);
5237 void CMainFrame::SetSubtitleDelay(int delay_ms
)
5240 m_pCAP
->SetSubtitleDelay(delay_ms
);
5244 void CMainFrame::OnPlayChangeAudDelay(UINT nID
)
5246 if(CComQIPtr
<IAudioSwitcherFilter
> pASF
= FindFilter(__uuidof(CAudioSwitcherFilter
), pGB
))
5248 REFERENCE_TIME rtShift
= pASF
->GetAudioTimeShift();
5250 nID
== ID_PLAY_INCAUDDELAY
? 100000 :
5251 nID
== ID_PLAY_DECAUDDELAY
? -100000 :
5253 pASF
->SetAudioTimeShift(rtShift
);
5256 str
.Format(_T("Audio Delay: %I64dms"), rtShift
/10000);
5257 SendStatusMessage(str
, 3000);
5261 void CMainFrame::OnUpdatePlayChangeAudDelay(CCmdUI
* pCmdUI
)
5263 pCmdUI
->Enable(!!pGB
/*&& !!FindFilter(__uuidof(CAudioSwitcherFilter), pGB)*/);
5266 #include "ComPropertySheet.h"
5268 void CMainFrame::OnPlayFilters(UINT nID
)
5270 // ShowPPage(m_spparray[nID - ID_FILTERS_SUBITEM_START], m_hWnd);
5272 CComPtr
<IUnknown
> pUnk
= m_pparray
[nID
- ID_FILTERS_SUBITEM_START
];
5274 CComPropertySheet
ps(ResStr(IDS_PROPSHEET_PROPERTIES
), this);
5276 if(CComQIPtr
<ISpecifyPropertyPages
> pSPP
= pUnk
)
5281 if(CComQIPtr
<IBaseFilter
> pBF
= pUnk
)
5284 CComPtr
<IPropertyPage
> pPP
= new CInternalPropertyPageTempl
<CPinInfoWnd
>(NULL
, &hr
);
5285 ps
.AddPage(pPP
, pBF
);
5288 if(ps
.GetPageCount() > 0)
5291 OpenSetupStatusBar();
5295 void CMainFrame::OnUpdatePlayFilters(CCmdUI
* pCmdUI
)
5297 pCmdUI
->Enable(!m_fCapturing
);
5300 void CMainFrame::OnPlayShaders(UINT nID
)
5302 if(nID
== ID_SHADERS_START
+2)
5304 ShowControlBar(&m_wndShaderEditorBar
, TRUE
, TRUE
);
5310 if(nID
== ID_SHADERS_START
)
5312 m_shaderlabels
.RemoveAll();
5314 else if(nID
== ID_SHADERS_START
+1)
5316 if(IDOK
!= CShaderCombineDlg(m_shaderlabels
, this).DoModal())
5319 else if(nID
>= ID_SHADERS_START
+3)
5322 memset(&mii
, 0, sizeof(mii
));
5323 mii
.cbSize
= sizeof(mii
);
5324 mii
.fMask
= MIIM_DATA
;
5325 m_shaders
.GetMenuItemInfo(nID
, &mii
);
5327 m_shaderlabels
.RemoveAll();
5328 m_shaderlabels
.AddTail(((const AppSettings::Shader
*)mii
.dwItemData
)->label
);
5334 void CMainFrame::OnUpdatePlayShaders(CCmdUI
* pCmdUI
)
5336 if(pCmdUI
->m_nID
>= ID_SHADERS_START
)
5338 pCmdUI
->Enable(!!m_pCAP
);
5340 if(pCmdUI
->m_nID
== ID_SHADERS_START
)
5342 pCmdUI
->SetRadio(m_shaderlabels
.IsEmpty());
5344 else if(pCmdUI
->m_nID
== ID_SHADERS_START
+1)
5346 pCmdUI
->SetRadio(m_shaderlabels
.GetCount() > 1);
5348 else if(pCmdUI
->m_nID
== ID_SHADERS_START
+2)
5350 pCmdUI
->Enable(TRUE
);
5355 memset(&mii
, 0, sizeof(mii
));
5356 mii
.cbSize
= sizeof(mii
);
5357 mii
.fMask
= MIIM_DATA
;
5358 m_shaders
.GetMenuItemInfo(pCmdUI
->m_nID
, &mii
);
5360 pCmdUI
->SetRadio(m_shaderlabels
.GetCount() == 1
5361 && m_shaderlabels
.GetHead() == ((AppSettings::Shader
*)mii
.dwItemData
)->label
);
5366 void CMainFrame::OnPlayAudio(UINT nID
)
5368 int i
= (int)nID
- (1 + ID_AUDIO_SUBITEM_START
);
5370 CComQIPtr
<IAMStreamSelect
> pSS
= FindFilter(__uuidof(CAudioSwitcherFilter
), pGB
);
5371 if(!pSS
) pSS
= FindFilter(L
"{D3CD7858-971A-4838-ACEC-40CA5D529DC8}", pGB
);
5375 ShowOptions(CPPageAudioSwitcher::IDD
);
5377 else if(i
>= 0 && pSS
)
5379 pSS
->Enable(i
, AMSTREAMSELECTENABLE_ENABLE
);
5383 void CMainFrame::OnUpdatePlayAudio(CCmdUI
* pCmdUI
)
5385 UINT nID
= pCmdUI
->m_nID
;
5386 int i
= (int)nID
- (1 + ID_AUDIO_SUBITEM_START
);
5388 CComQIPtr
<IAMStreamSelect
> pSS
= FindFilter(__uuidof(CAudioSwitcherFilter
), pGB
);
5389 if(!pSS
) pSS
= FindFilter(L
"{D3CD7858-971A-4838-ACEC-40CA5D529DC8}", pGB
);
5395 else*/ if(i
>= 0 && pSS
)
5399 if(SUCCEEDED(pSS
->Info(i
, NULL
, &flags
, NULL
, NULL
, NULL
, NULL
, NULL
)))
5401 if(flags
&AMSTREAMSELECTINFO_EXCLUSIVE
) pCmdUI
->SetRadio(TRUE
);
5402 else if(flags
&AMSTREAMSELECTINFO_ENABLED
) pCmdUI
->SetCheck(TRUE
);
5403 else pCmdUI
->SetCheck(FALSE
);
5407 pCmdUI
->Enable(FALSE
);
5412 void CMainFrame::OnPlaySubtitles(UINT nID
)
5414 int i
= (int)nID
- (4 + ID_SUBTITLES_SUBITEM_START
);
5418 ShowOptions(CPPageSubtitles::IDD
);
5422 int i
= m_iSubtitleSel
;
5424 POSITION pos
= m_pSubStreams
.GetHeadPosition();
5425 while(pos
&& i
>= 0)
5427 CComPtr
<ISubStream
> pSubStream
= m_pSubStreams
.GetNext(pos
);
5429 if(i
< pSubStream
->GetStreamCount())
5432 if(FAILED(pSubStream
->GetClassID(&clsid
)))
5435 if(clsid
== __uuidof(CRenderedTextSubtitle
))
5437 CRenderedTextSubtitle
* pRTS
= (CRenderedTextSubtitle
*)(ISubStream
*)pSubStream
;
5439 CAutoPtrArray
<CPPageSubStyle
> pages
;
5440 CAtlArray
<STSStyle
*> styles
;
5442 POSITION pos
= pRTS
->m_styles
.GetStartPosition();
5443 for(int i
= 0; pos
; i
++)
5447 pRTS
->m_styles
.GetNextAssoc(pos
, key
, val
);
5449 CAutoPtr
<CPPageSubStyle
> page(new CPPageSubStyle());
5450 page
->InitStyle(key
, *val
);
5455 CPropertySheet
dlg(_T("Styles..."), this);
5456 for(int i
= 0; i
< (int)pages
.GetCount(); i
++)
5457 dlg
.AddPage(pages
[i
]);
5459 if(dlg
.DoModal() == IDOK
)
5461 for(int j
= 0; j
< (int)pages
.GetCount(); j
++)
5462 pages
[j
]->GetStyle(*styles
[j
]);
5463 UpdateSubtitle(false);
5470 i
-= pSubStream
->GetStreamCount();
5479 if(m_iSubtitleSel
== -1) m_iSubtitleSel
= 0;
5480 else m_iSubtitleSel
^= (1<<31);
5489 AfxGetAppSettings().fEnableSubtitles
= !(m_iSubtitleSel
& 0x80000000);
5492 void CMainFrame::OnUpdatePlaySubtitles(CCmdUI
* pCmdUI
)
5494 UINT nID
= pCmdUI
->m_nID
;
5495 int i
= (int)nID
- (4 + ID_SUBTITLES_SUBITEM_START
);
5497 pCmdUI
->Enable(m_pCAP
&& !m_fAudioOnly
);
5501 pCmdUI
->Enable(FALSE
);
5503 int i
= m_iSubtitleSel
;
5505 POSITION pos
= m_pSubStreams
.GetHeadPosition();
5506 while(pos
&& i
>= 0)
5508 CComPtr
<ISubStream
> pSubStream
= m_pSubStreams
.GetNext(pos
);
5510 if(i
< pSubStream
->GetStreamCount())
5513 if(FAILED(pSubStream
->GetClassID(&clsid
)))
5516 if(clsid
== __uuidof(CRenderedTextSubtitle
))
5518 pCmdUI
->Enable(TRUE
);
5523 i
-= pSubStream
->GetStreamCount();
5528 pCmdUI
->SetCheck(m_iSubtitleSel
>= 0);
5532 pCmdUI
->SetRadio(i
== abs(m_iSubtitleSel
));
5536 void CMainFrame::OnPlayLanguage(UINT nID
)
5538 nID
-= ID_FILTERSTREAMS_SUBITEM_START
;
5539 CComPtr
<IAMStreamSelect
> pAMSS
= m_ssarray
[nID
];
5541 while(i
> 0 && pAMSS
== m_ssarray
[i
-1]) i
--;
5542 if(FAILED(pAMSS
->Enable(nID
-i
, AMSTREAMSELECTENABLE_ENABLE
)))
5545 OpenSetupStatusBar();
5548 void CMainFrame::OnUpdatePlayLanguage(CCmdUI
* pCmdUI
)
5550 UINT nID
= pCmdUI
->m_nID
;
5551 nID
-= ID_FILTERSTREAMS_SUBITEM_START
;
5552 CComPtr
<IAMStreamSelect
> pAMSS
= m_ssarray
[nID
];
5554 while(i
> 0 && pAMSS
== m_ssarray
[i
-1]) i
--;
5556 pAMSS
->Info(nID
-i
, NULL
, &flags
, NULL
, NULL
, NULL
, NULL
, NULL
);
5557 if(flags
&AMSTREAMSELECTINFO_EXCLUSIVE
) pCmdUI
->SetRadio(TRUE
);
5558 else if(flags
&AMSTREAMSELECTINFO_ENABLED
) pCmdUI
->SetCheck(TRUE
);
5559 else pCmdUI
->SetCheck(FALSE
);
5562 void CMainFrame::OnPlayVolume(UINT nID
)
5564 if(m_iMediaLoadState
== MLS_LOADED
)
5566 pBA
->put_Volume(m_wndToolBar
.Volume
);
5570 void CMainFrame::OnPlayVolumeBoost(UINT nID
)
5572 AppSettings
& s
= AfxGetAppSettings();
5574 int i
= (int)(50.0f
*log10(s
.AudioBoost
));
5578 case ID_VOLUME_BOOST_INC
: i
= min(i
+10, 100); break;
5579 case ID_VOLUME_BOOST_DEC
: i
= max(i
-10, 0); break;
5580 case ID_VOLUME_BOOST_MIN
: i
= 0; break;
5581 case ID_VOLUME_BOOST_MAX
: i
= 100; break;
5584 s
.AudioBoost
= pow(10.0f
, (float)i
/50);
5586 if(CComQIPtr
<IAudioSwitcherFilter
> pASF
= FindFilter(__uuidof(CAudioSwitcherFilter
), pGB
))
5588 bool fNormalize
, fNormalizeRecover
;
5590 pASF
->GetNormalizeBoost(fNormalize
, fNormalizeRecover
, boost
);
5591 pASF
->SetNormalizeBoost(fNormalize
, fNormalizeRecover
, s
.AudioBoost
);
5595 void CMainFrame::OnUpdatePlayVolumeBoost(CCmdUI
* pCmdUI
)
5600 void CMainFrame::OnAfterplayback(UINT nID
)
5602 AppSettings
& s
= AfxGetAppSettings();
5604 s
.nCLSwitches
&= ~CLSW_AFTERPLAYBACK_MASK
;
5608 case ID_AFTERPLAYBACK_CLOSE
: s
.nCLSwitches
|= CLSW_CLOSE
; break;
5609 case ID_AFTERPLAYBACK_STANDBY
: s
.nCLSwitches
|= CLSW_STANDBY
; break;
5610 case ID_AFTERPLAYBACK_HIBERNATE
: s
.nCLSwitches
|= CLSW_HIBERNATE
; break;
5611 case ID_AFTERPLAYBACK_SHUTDOWN
: s
.nCLSwitches
|= CLSW_SHUTDOWN
; break;
5612 case ID_AFTERPLAYBACK_LOGOFF
: s
.nCLSwitches
|= CLSW_LOGOFF
; break;
5616 void CMainFrame::OnUpdateAfterplayback(CCmdUI
* pCmdUI
)
5618 AppSettings
& s
= AfxGetAppSettings();
5620 bool fChecked
= false;
5622 switch(pCmdUI
->m_nID
)
5624 case ID_AFTERPLAYBACK_CLOSE
: fChecked
= !!(s
.nCLSwitches
& CLSW_CLOSE
); break;
5625 case ID_AFTERPLAYBACK_STANDBY
: fChecked
= !!(s
.nCLSwitches
& CLSW_STANDBY
); break;
5626 case ID_AFTERPLAYBACK_HIBERNATE
: fChecked
= !!(s
.nCLSwitches
& CLSW_HIBERNATE
); break;
5627 case ID_AFTERPLAYBACK_SHUTDOWN
: fChecked
= !!(s
.nCLSwitches
& CLSW_SHUTDOWN
); break;
5628 case ID_AFTERPLAYBACK_LOGOFF
: fChecked
= !!(s
.nCLSwitches
& CLSW_LOGOFF
); break;
5629 case ID_AFTERPLAYBACK_DONOTHING
: fChecked
= !(s
.nCLSwitches
& CLSW_AFTERPLAYBACK_MASK
); break;
5632 pCmdUI
->SetRadio(fChecked
);
5637 void CMainFrame::OnNavigateSkip(UINT nID
)
5639 if(m_iPlaybackMode
== PM_FILE
|| m_iPlaybackMode
== PM_CAPTURE
)
5641 if(m_iPlaybackMode
== PM_FILE
) SetupChapters();
5643 if(DWORD nChapters
= m_pCB
->ChapGetCount())
5645 REFERENCE_TIME rtCur
;
5646 pMS
->GetCurrentPosition(&rtCur
);
5648 REFERENCE_TIME rt
= rtCur
;
5652 if(nID
== ID_NAVIGATE_SKIPBACK
)
5655 i
= m_pCB
->ChapLookup(&rt
, &name
);
5657 else if(nID
== ID_NAVIGATE_SKIPFORWARD
)
5659 i
= m_pCB
->ChapLookup(&rt
, &name
) + 1;
5661 if(i
< nChapters
) m_pCB
->ChapGet(i
, &rt
, &name
);
5664 if(i
>= 0 && i
< nChapters
)
5667 SendStatusMessage(_T("Chapter: ") + CString(name
), 3000);
5672 if(nID
== ID_NAVIGATE_SKIPBACK
)
5674 SendMessage(WM_COMMAND
, ID_NAVIGATE_SKIPBACKPLITEM
);
5676 else if(nID
== ID_NAVIGATE_SKIPFORWARD
)
5678 SendMessage(WM_COMMAND
, ID_NAVIGATE_SKIPFORWARDPLITEM
);
5681 else if(m_iPlaybackMode
== PM_DVD
)
5685 if(GetMediaState() != State_Running
)
5686 SendMessage(WM_COMMAND
, ID_PLAY_PLAY
);
5688 ULONG ulNumOfVolumes
, ulVolume
;
5690 ULONG ulNumOfTitles
= 0;
5691 pDVDI
->GetDVDVolumeInfo(&ulNumOfVolumes
, &ulVolume
, &Side
, &ulNumOfTitles
);
5693 DVD_PLAYBACK_LOCATION2 Location
;
5694 pDVDI
->GetCurrentLocation(&Location
);
5696 ULONG ulNumOfChapters
= 0;
5697 pDVDI
->GetNumberOfChapters(Location
.TitleNum
, &ulNumOfChapters
);
5699 if(nID
== ID_NAVIGATE_SKIPBACK
)
5701 if(Location
.ChapterNum
== 1 && Location
.TitleNum
> 1)
5703 pDVDI
->GetNumberOfChapters(Location
.TitleNum
-1, &ulNumOfChapters
);
5704 pDVDC
->PlayChapterInTitle(Location
.TitleNum
-1, ulNumOfChapters
, DVD_CMD_FLAG_Block
|DVD_CMD_FLAG_Flush
, NULL
);
5708 pDVDC
->PlayPrevChapter(DVD_CMD_FLAG_Block
|DVD_CMD_FLAG_Flush
, NULL
);
5711 else if(nID
== ID_NAVIGATE_SKIPFORWARD
)
5713 if(Location
.ChapterNum
== ulNumOfChapters
&& Location
.TitleNum
< ulNumOfTitles
)
5715 pDVDC
->PlayChapterInTitle(Location
.TitleNum
+1, 1, DVD_CMD_FLAG_Block
|DVD_CMD_FLAG_Flush
, NULL
);
5719 pDVDC
->PlayNextChapter(DVD_CMD_FLAG_Block
|DVD_CMD_FLAG_Flush
, NULL
);
5723 if(nID == ID_NAVIGATE_SKIPBACK)
5724 pDVDC->PlayPrevChapter(DVD_CMD_FLAG_Block, NULL);
5725 else if(nID == ID_NAVIGATE_SKIPFORWARD)
5726 pDVDC->PlayNextChapter(DVD_CMD_FLAG_Block, NULL);
5731 void CMainFrame::OnUpdateNavigateSkip(CCmdUI
* pCmdUI
)
5733 // moved to the timer callback function, that runs less frequent
5734 // if(m_iPlaybackMode == PM_FILE) SetupChapters();
5736 pCmdUI
->Enable(m_iMediaLoadState
== MLS_LOADED
5737 && ((m_iPlaybackMode
== PM_DVD
5738 && m_iDVDDomain
!= DVD_DOMAIN_VideoManagerMenu
5739 && m_iDVDDomain
!= DVD_DOMAIN_VideoTitleSetMenu
)
5740 || (m_iPlaybackMode
== PM_FILE
&& (m_wndPlaylistBar
.GetCount() > 1/*0*/ || m_pCB
->ChapGetCount() > 1))
5741 || (m_iPlaybackMode
== PM_CAPTURE
&& !m_fCapturing
))); // TODO
5744 void CMainFrame::OnNavigateSkipPlaylistItem(UINT nID
)
5746 if(m_iPlaybackMode
== PM_FILE
|| m_iPlaybackMode
== PM_CAPTURE
)
5748 if(m_wndPlaylistBar
.GetCount() == 1)
5750 SendMessage(WM_COMMAND
, ID_PLAY_STOP
); // do not remove this, unless you want a circular call with OnPlayPlay()
5751 SendMessage(WM_COMMAND
, ID_PLAY_PLAY
);
5755 if(nID
== ID_NAVIGATE_SKIPBACKPLITEM
)
5757 m_wndPlaylistBar
.SetPrev();
5759 else if(nID
== ID_NAVIGATE_SKIPFORWARDPLITEM
)
5761 m_wndPlaylistBar
.SetNext();
5764 OpenCurPlaylistItem();
5769 void CMainFrame::OnUpdateNavigateSkipPlaylistItem(CCmdUI
* pCmdUI
)
5771 pCmdUI
->Enable(m_iMediaLoadState
== MLS_LOADED
5772 && ((m_iPlaybackMode
== PM_FILE
|| m_iPlaybackMode
== PM_CAPTURE
&& !m_fCapturing
) && m_wndPlaylistBar
.GetCount() > 1/*0*/));
5775 void CMainFrame::OnNavigateMenu(UINT nID
)
5777 nID
-= ID_NAVIGATE_TITLEMENU
;
5779 if(m_iMediaLoadState
!= MLS_LOADED
|| m_iPlaybackMode
!= PM_DVD
)
5784 if(GetMediaState() != State_Running
)
5785 SendMessage(WM_COMMAND
, ID_PLAY_PLAY
);
5787 pDVDC
->ShowMenu((DVD_MENU_ID
)(nID
+2), DVD_CMD_FLAG_Block
|DVD_CMD_FLAG_Flush
, NULL
);
5790 void CMainFrame::OnUpdateNavigateMenu(CCmdUI
* pCmdUI
)
5792 UINT nID
= pCmdUI
->m_nID
- ID_NAVIGATE_TITLEMENU
;
5795 if(m_iMediaLoadState
!= MLS_LOADED
|| m_iPlaybackMode
!= PM_DVD
5796 || FAILED(pDVDI
->GetCurrentUOPS(&ulUOPs
)))
5798 pCmdUI
->Enable(FALSE
);
5802 pCmdUI
->Enable(!(ulUOPs
& (UOP_FLAG_ShowMenu_Title
<< nID
)));
5805 void CMainFrame::OnNavigateAudio(UINT nID
)
5807 nID
-= ID_NAVIGATE_AUDIO_SUBITEM_START
;
5809 if(m_iPlaybackMode
== PM_FILE
)
5811 OnNavStreamSelectSubMenu(nID
, 1);
5813 else if(m_iPlaybackMode
== PM_DVD
)
5815 pDVDC
->SelectAudioStream(nID
, DVD_CMD_FLAG_Block
, NULL
);
5819 void CMainFrame::OnNavigateSubpic(UINT nID
)
5821 if(m_iPlaybackMode
== PM_FILE
)
5823 OnNavStreamSelectSubMenu(nID
- ID_NAVIGATE_SUBP_SUBITEM_START
, 2);
5825 else if(m_iPlaybackMode
== PM_DVD
)
5827 int i
= (int)nID
- (1 + ID_NAVIGATE_SUBP_SUBITEM_START
);
5831 ULONG ulStreamsAvailable
, ulCurrentStream
;
5833 if(SUCCEEDED(pDVDI
->GetCurrentSubpicture(&ulStreamsAvailable
, &ulCurrentStream
, &bIsDisabled
)))
5834 pDVDC
->SetSubpictureState(bIsDisabled
, DVD_CMD_FLAG_Block
, NULL
);
5838 pDVDC
->SelectSubpictureStream(i
, DVD_CMD_FLAG_Block
, NULL
);
5839 pDVDC
->SetSubpictureState(TRUE
, DVD_CMD_FLAG_Block
, NULL
);
5844 void CMainFrame::OnNavigateAngle(UINT nID
)
5846 nID
-= ID_NAVIGATE_ANGLE_SUBITEM_START
;
5848 if(m_iPlaybackMode
== PM_FILE
)
5850 OnNavStreamSelectSubMenu(nID
, 0);
5852 else if(m_iPlaybackMode
== PM_DVD
)
5854 pDVDC
->SelectAngle(nID
+1, DVD_CMD_FLAG_Block
, NULL
);
5858 void CMainFrame::OnNavigateChapters(UINT nID
)
5860 nID
-= ID_NAVIGATE_CHAP_SUBITEM_START
;
5862 if(m_iPlaybackMode
== PM_FILE
)
5864 if((int)nID
>= 0 && nID
< m_pCB
->ChapGetCount())
5868 if(SUCCEEDED(m_pCB
->ChapGet(nID
, &rt
, &name
)))
5871 SendStatusMessage(_T("Chapter: ") + CString(name
), 3000);
5876 nID
-= m_pCB
->ChapGetCount();
5878 if((int)nID
>= 0 && (int)nID
< m_wndPlaylistBar
.GetCount()
5879 && m_wndPlaylistBar
.GetSelIdx() != (int)nID
)
5881 m_wndPlaylistBar
.SetSelIdx(nID
);
5882 OpenCurPlaylistItem();
5885 else if(m_iPlaybackMode
== PM_DVD
)
5887 ULONG ulNumOfVolumes
, ulVolume
;
5889 ULONG ulNumOfTitles
= 0;
5890 pDVDI
->GetDVDVolumeInfo(&ulNumOfVolumes
, &ulVolume
, &Side
, &ulNumOfTitles
);
5892 DVD_PLAYBACK_LOCATION2 Location
;
5893 pDVDI
->GetCurrentLocation(&Location
);
5895 ULONG ulNumOfChapters
= 0;
5896 pDVDI
->GetNumberOfChapters(Location
.TitleNum
, &ulNumOfChapters
);
5900 if(nID
> 0 && nID
<= ulNumOfTitles
)
5902 pDVDC
->PlayTitle(nID
, DVD_CMD_FLAG_Block
|DVD_CMD_FLAG_Flush
, NULL
); // sometimes this does not do anything ...
5903 pDVDC
->PlayChapterInTitle(nID
, 1, DVD_CMD_FLAG_Block
|DVD_CMD_FLAG_Flush
, NULL
); // ... but this does!
5907 nID
-= ulNumOfTitles
;
5909 if(nID
> 0 && nID
<= ulNumOfChapters
)
5911 pDVDC
->PlayChapter(nID
, DVD_CMD_FLAG_Block
|DVD_CMD_FLAG_Flush
, NULL
);
5917 void CMainFrame::OnNavigateMenuItem(UINT nID
)
5919 nID
-= ID_NAVIGATE_MENU_LEFT
;
5921 if(m_iPlaybackMode
== PM_DVD
)
5925 case 0: pDVDC
->SelectRelativeButton(DVD_Relative_Left
); break;
5926 case 1: pDVDC
->SelectRelativeButton(DVD_Relative_Right
); break;
5927 case 2: pDVDC
->SelectRelativeButton(DVD_Relative_Upper
); break;
5928 case 3: pDVDC
->SelectRelativeButton(DVD_Relative_Lower
); break;
5929 case 4: pDVDC
->ActivateButton(); break;
5930 case 5: pDVDC
->ReturnFromSubmenu(DVD_CMD_FLAG_Block
|DVD_CMD_FLAG_Flush
, NULL
); break;
5931 case 6: pDVDC
->Resume(DVD_CMD_FLAG_Block
|DVD_CMD_FLAG_Flush
, NULL
); break;
5937 void CMainFrame::OnUpdateNavigateMenuItem(CCmdUI
* pCmdUI
)
5939 UINT nID
= pCmdUI
->m_nID
- ID_NAVIGATE_MENU_LEFT
;
5940 pCmdUI
->Enable(m_iMediaLoadState
== MLS_LOADED
&& m_iPlaybackMode
== PM_DVD
);
5945 class CDVDStateStream
: public CUnknown
, public IStream
5947 STDMETHODIMP
NonDelegatingQueryInterface(REFIID riid
, void** ppv
)
5951 CUnknown::NonDelegatingQueryInterface(riid
, ppv
);
5957 CDVDStateStream() : CUnknown(NAME("CDVDStateStream"), NULL
) {m_pos
= 0;}
5961 CAtlArray
<BYTE
> m_data
;
5963 // ISequentialStream
5964 STDMETHODIMP
Read(void* pv
, ULONG cb
, ULONG
* pcbRead
)
5966 __int64 cbRead
= min(m_data
.GetCount() - m_pos
, (__int64
)cb
);
5967 cbRead
= max(cbRead
, 0);
5968 memcpy(pv
, &m_data
[(INT_PTR
)m_pos
], (int)cbRead
);
5969 if(pcbRead
) *pcbRead
= (ULONG
)cbRead
;
5973 STDMETHODIMP
Write(const void* pv
, ULONG cb
, ULONG
* pcbWritten
)
5975 BYTE
* p
= (BYTE
*)pv
;
5976 ULONG cbWritten
= -1;
5977 while(++cbWritten
< cb
)
5979 if(pcbWritten
) *pcbWritten
= cbWritten
;
5984 STDMETHODIMP
Seek(LARGE_INTEGER dlibMove
, DWORD dwOrigin
, ULARGE_INTEGER
*plibNewPosition
) {return E_NOTIMPL
;}
5985 STDMETHODIMP
SetSize(ULARGE_INTEGER libNewSize
) {return E_NOTIMPL
;}
5986 STDMETHODIMP
CopyTo(IStream
* pstm
, ULARGE_INTEGER cb
, ULARGE_INTEGER
* pcbRead
, ULARGE_INTEGER
* pcbWritten
) {return E_NOTIMPL
;}
5987 STDMETHODIMP
Commit(DWORD grfCommitFlags
) {return E_NOTIMPL
;}
5988 STDMETHODIMP
Revert() {return E_NOTIMPL
;}
5989 STDMETHODIMP
LockRegion(ULARGE_INTEGER libOffset
, ULARGE_INTEGER cb
, DWORD dwLockType
) {return E_NOTIMPL
;}
5990 STDMETHODIMP
UnlockRegion(ULARGE_INTEGER libOffset
, ULARGE_INTEGER cb
, DWORD dwLockType
) {return E_NOTIMPL
;}
5991 STDMETHODIMP
Stat(STATSTG
* pstatstg
, DWORD grfStatFlag
) {return E_NOTIMPL
;}
5992 STDMETHODIMP
Clone(IStream
** ppstm
) {return E_NOTIMPL
;}
5996 void CMainFrame::OnFavoritesAdd()
5998 AppSettings
& s
= AfxGetAppSettings();
6000 if(m_iPlaybackMode
== PM_FILE
)
6002 CString fn
= m_wndPlaylistBar
.GetCur();
6003 if(fn
.IsEmpty()) return;
6006 desc
.Replace('\\', '/');
6007 int i
= desc
.Find(_T("://")), j
= desc
.Find(_T("?")), k
= desc
.ReverseFind('/');
6008 if(i
>= 0) desc
= j
>= 0 ? desc
.Left(j
) : desc
;
6009 else if(k
>= 0) desc
= desc
.Mid(k
+1);
6011 CFavoriteAddDlg
dlg(desc
, fn
);
6012 if(dlg
.DoModal() != IDOK
) return;
6014 CString str
= dlg
.m_name
;
6017 CString
pos(_T("0"));
6018 if(dlg
.m_fRememberPos
)
6019 pos
.Format(_T("%I64d"), GetPos());
6025 if(m_wndPlaylistBar
.GetCur(pli
))
6027 POSITION pos
= pli
.m_fns
.GetHeadPosition();
6028 while(pos
) str
+= _T(";") + pli
.m_fns
.GetNext(pos
);
6031 s
.AddFav(FAV_FILE
, str
);
6033 else if(m_iPlaybackMode
== PM_DVD
)
6035 WCHAR path
[MAX_PATH
];
6037 pDVDI
->GetDVDDirectory(path
, MAX_PATH
, &len
);
6039 fn
.TrimRight(_T("/\\"));
6041 DVD_PLAYBACK_LOCATION2 Location
;
6042 pDVDI
->GetCurrentLocation(&Location
);
6044 desc
.Format(_T("%s - T%02d C%02d - %02d:%02d:%02d"), fn
, Location
.TitleNum
, Location
.ChapterNum
,
6045 Location
.TimeCode
.bHours
, Location
.TimeCode
.bMinutes
, Location
.TimeCode
.bSeconds
);
6047 CFavoriteAddDlg
dlg(fn
, desc
);
6048 if(dlg
.DoModal() != IDOK
) return;
6050 CString str
= dlg
.m_name
;
6053 CString
pos(_T("0"));
6054 if(dlg
.m_fRememberPos
)
6056 CDVDStateStream stream
;
6059 CComPtr
<IDvdState
> pStateData
;
6060 CComQIPtr
<IPersistStream
> pPersistStream
;
6061 if(SUCCEEDED(pDVDI
->GetState(&pStateData
))
6062 && (pPersistStream
= pStateData
)
6063 && SUCCEEDED(OleSaveToStream(pPersistStream
, (IStream
*)&stream
)))
6065 pos
= BinToCString(stream
.m_data
.GetData(), stream
.m_data
.GetCount());
6075 s
.AddFav(FAV_DVD
, str
);
6077 else if(m_iPlaybackMode
== PM_CAPTURE
)
6083 void CMainFrame::OnUpdateFavoritesAdd(CCmdUI
* pCmdUI
)
6085 pCmdUI
->Enable(m_iPlaybackMode
== PM_FILE
|| m_iPlaybackMode
== PM_DVD
);
6088 void CMainFrame::OnFavoritesOrganize()
6090 CFavoriteOrganizeDlg dlg
;
6094 void CMainFrame::OnUpdateFavoritesOrganize(CCmdUI
* pCmdUI
)
6096 // TODO: Add your command update UI handler code here
6099 void CMainFrame::OnFavoritesFile(UINT nID
)
6101 nID
-= ID_FAVORITES_FILE_START
;
6103 CAtlList
<CString
> sl
;
6104 AfxGetAppSettings().GetFav(FAV_FILE
, sl
);
6106 if(POSITION pos
= sl
.FindIndex(nID
))
6108 CAtlList
<CString
> fns
;
6109 REFERENCE_TIME rtStart
= 0;
6112 for(CString s1
= sl
.GetAt(pos
), s2
= s1
.Tokenize(_T(";"), i
);
6114 s2
= s1
.Tokenize(_T(";"), i
), j
++)
6116 if(j
== 0) ; // desc
6117 else if(j
== 1) _stscanf(s2
, _T("%I64d"), &rtStart
); // pos
6118 else fns
.AddTail(s2
); // subs
6121 m_wndPlaylistBar
.Open(fns
, false);
6122 OpenCurPlaylistItem(max(rtStart
, 0));
6126 void CMainFrame::OnUpdateFavoritesFile(CCmdUI
* pCmdUI
)
6128 UINT nID
= pCmdUI
->m_nID
- ID_FAVORITES_FILE_START
;
6131 void CMainFrame::OnFavoritesDVD(UINT nID
)
6133 nID
-= ID_FAVORITES_DVD_START
;
6135 CAtlList
<CString
> sl
;
6136 AfxGetAppSettings().GetFav(FAV_DVD
, sl
);
6138 if(POSITION pos
= sl
.FindIndex(nID
))
6142 CDVDStateStream stream
;
6146 for(CString s1
= sl
.GetAt(pos
), s2
= s1
.Tokenize(_T(";"), i
);
6148 s2
= s1
.Tokenize(_T(";"), i
), j
++)
6150 if(j
== 0) ; // desc
6151 else if(j
== 1 && s2
!= _T("0")) // state
6153 CStringToBin(s2
, stream
.m_data
);
6155 else if(j
== 2) fn
= s2
; // path
6158 SendMessage(WM_COMMAND
, ID_FILE_CLOSEMEDIA
);
6160 CComPtr
<IDvdState
> pDvdState
;
6161 HRESULT hr
= OleLoadFromStream((IStream
*)&stream
, IID_IDvdState
, (void**)&pDvdState
);
6163 CAutoPtr
<OpenDVDData
> p(new OpenDVDData());
6164 if(p
) {p
->path
= fn
; p
->pDvdState
= pDvdState
;}
6169 void CMainFrame::OnUpdateFavoritesDVD(CCmdUI
* pCmdUI
)
6171 UINT nID
= pCmdUI
->m_nID
- ID_FAVORITES_DVD_START
;
6174 void CMainFrame::OnFavoritesDevice(UINT nID
)
6176 nID
-= ID_FAVORITES_DEVICE_START
;
6179 void CMainFrame::OnUpdateFavoritesDevice(CCmdUI
* pCmdUI
)
6181 UINT nID
= pCmdUI
->m_nID
- ID_FAVORITES_DEVICE_START
;
6186 void CMainFrame::OnHelpHomepage()
6188 ShellExecute(m_hWnd
, _T("open"), _T("http://sourceforge.net/projects/guliverkli2/"), NULL
, NULL
, SW_SHOWDEFAULT
);
6191 void CMainFrame::OnHelpDocumentation()
6193 ShellExecute(m_hWnd
, _T("open"), _T("http://sourceforge.net/project/showfiles.php?group_id=82303&package_id=144472"), NULL
, NULL
, SW_SHOWDEFAULT
);
6196 //////////////////////////////////
6198 static BOOL CALLBACK
MonitorEnumProc(HMONITOR hMonitor
, HDC hdcMonitor
, LPRECT lprcMonitor
, LPARAM dwData
)
6200 CAtlArray
<HMONITOR
>* ml
= (CAtlArray
<HMONITOR
>*)dwData
;
6205 void CMainFrame::SetDefaultWindowRect(int iMonitor
)
6207 AppSettings
& s
= AfxGetAppSettings();
6212 m_wndView
.GetClientRect(&r2
);
6214 CSize logosize
= m_wndView
.GetLogoSize();
6215 int _DEFCLIENTW
= max(logosize
.cx
, DEFCLIENTW
);
6216 int _DEFCLIENTH
= max(logosize
.cy
, DEFCLIENTH
);
6218 if(GetSystemMetrics(SM_REMOTESESSION
))
6221 DWORD style
= GetStyle();
6224 memset(&mbi
, 0, sizeof(mbi
));
6225 mbi
.cbSize
= sizeof(mbi
);
6226 ::GetMenuBarInfo(m_hWnd
, OBJID_MENU
, 0, &mbi
);
6228 int w
= _DEFCLIENTW
+ GetSystemMetrics((style
&WS_CAPTION
)?SM_CXSIZEFRAME
:SM_CXFIXEDFRAME
)*2
6229 + r1
.Width() - r2
.Width();
6230 int h
= _DEFCLIENTH
+ GetSystemMetrics((style
&WS_CAPTION
)?SM_CYSIZEFRAME
:SM_CYFIXEDFRAME
)*2
6231 + (mbi
.rcBar
.bottom
- mbi
.rcBar
.top
)
6232 + r1
.Height() - r2
.Height()
6235 if(style
&WS_CAPTION
) h
+= GetSystemMetrics(SM_CYCAPTION
);
6237 if(s
.HasFixedWindowSize())
6239 w
= s
.fixedWindowSize
.cx
;
6240 h
= s
.fixedWindowSize
.cy
;
6242 else if(s
.fRememberWindowSize
)
6244 w
= s
.rcLastWindowPos
.Width();
6245 h
= s
.rcLastWindowPos
.Height();
6248 HMONITOR hMonitor
= MonitorFromWindow(m_hWnd
, MONITOR_DEFAULTTONEAREST
);
6253 CAtlArray
<HMONITOR
> ml
;
6254 EnumDisplayMonitors(NULL
, NULL
, MonitorEnumProc
, (LPARAM
)&ml
);
6255 if(iMonitor
< ml
.GetCount()) hMonitor
= ml
[iMonitor
];
6259 mi
.cbSize
= sizeof(MONITORINFO
);
6260 GetMonitorInfo(hMonitor
, &mi
);
6262 int x
= (mi
.rcWork
.left
+mi
.rcWork
.right
-w
)/2;
6263 int y
= (mi
.rcWork
.top
+mi
.rcWork
.bottom
-h
)/2;
6265 if(s
.fRememberWindowPos
)
6267 CRect r
= s
.rcLastWindowPos
;
6268 // x = r.CenterPoint().x - w/2;
6269 // y = r.CenterPoint().y - h/2;
6274 UINT lastWindowType
= s
.lastWindowType
;
6276 MoveWindow(x
, y
, w
, h
);
6278 if(s
.fRememberWindowSize
&& s
.fRememberWindowPos
)
6281 memset(&wp
, 0, sizeof(wp
));
6282 wp
.length
= sizeof(WINDOWPLACEMENT
);
6283 if(lastWindowType
== SIZE_MAXIMIZED
)
6284 ShowWindow(SW_MAXIMIZE
);
6285 else if(lastWindowType
== SIZE_MINIMIZED
)
6286 ShowWindow(SW_MINIMIZE
);
6290 if(s
.fHideCaptionMenu
)
6292 ModifyStyle(WS_CAPTION
, 0, SWP_NOZORDER
);
6293 ::SetMenu(m_hWnd
, NULL
);
6294 SetWindowPos(NULL
, 0, 0, 0, 0, SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOZORDER
);
6298 void CMainFrame::RestoreDefaultWindowRect()
6300 AppSettings
& s
= AfxGetAppSettings();
6303 GetWindowPlacement(&wp
);
6304 if(!m_fFullScreen
&& wp
.showCmd
!= SW_SHOWMAXIMIZED
&& wp
.showCmd
!= SW_SHOWMINIMIZED
6305 // && (GetExStyle()&WS_EX_APPWINDOW)
6306 && !s
.fRememberWindowSize
)
6310 m_wndView
.GetClientRect(&r2
);
6312 CSize logosize
= m_wndView
.GetLogoSize();
6313 int _DEFCLIENTW
= max(logosize
.cx
, DEFCLIENTW
);
6314 int _DEFCLIENTH
= max(logosize
.cy
, DEFCLIENTH
);
6316 DWORD style
= GetStyle();
6319 memset(&mbi
, 0, sizeof(mbi
));
6320 mbi
.cbSize
= sizeof(mbi
);
6321 ::GetMenuBarInfo(m_hWnd
, OBJID_MENU
, 0, &mbi
);
6323 int w
= _DEFCLIENTW
+ GetSystemMetrics((style
&WS_CAPTION
)?SM_CXSIZEFRAME
:SM_CXFIXEDFRAME
)*2
6324 + r1
.Width() - r2
.Width();
6325 int h
= _DEFCLIENTH
+ GetSystemMetrics((style
&WS_CAPTION
)?SM_CYSIZEFRAME
:SM_CYFIXEDFRAME
)*2
6326 + (mbi
.rcBar
.bottom
- mbi
.rcBar
.top
)
6327 + r1
.Height() - r2
.Height()
6330 if(style
&WS_CAPTION
) h
+= GetSystemMetrics(SM_CYCAPTION
);
6332 if(s
.HasFixedWindowSize())
6334 w
= s
.fixedWindowSize
.cx
;
6335 h
= s
.fixedWindowSize
.cy
;
6341 int x
= r
.CenterPoint().x
- w
/2;
6342 int y
= r
.CenterPoint().y
- h
/2;
6344 if(s
.fRememberWindowPos
)
6346 CRect r
= s
.rcLastWindowPos
;
6352 MoveWindow(x
, y
, w
, h
);
6356 OAFilterState
CMainFrame::GetMediaState()
6358 OAFilterState ret
= -1;
6359 if(m_iMediaLoadState
== MLS_LOADED
) pMC
->GetState(0, &ret
);
6363 CSize
CMainFrame::GetVideoSize()
6365 bool fKeepAspectRatio
= AfxGetAppSettings().fKeepAspectRatio
;
6366 bool fCompMonDeskARDiff
= AfxGetAppSettings().fCompMonDeskARDiff
;
6369 if(m_iMediaLoadState
!= MLS_LOADED
|| m_fAudioOnly
)
6372 CSize
wh(0, 0), arxy(0, 0);
6376 wh
= m_pCAP
->GetVideoSize(false);
6377 arxy
= m_pCAP
->GetVideoSize(fKeepAspectRatio
);
6381 pBV
->GetVideoSize(&wh
.cx
, &wh
.cy
);
6383 long arx
= 0, ary
= 0;
6384 CComQIPtr
<IBasicVideo2
> pBV2
= pBV
;
6385 if(pBV2
&& SUCCEEDED(pBV2
->GetPreferredAspectRatio(&arx
, &ary
)) && arx
> 0 && ary
> 0)
6386 arxy
.SetSize(arx
, ary
);
6389 if(wh
.cx
<= 0 || wh
.cy
<= 0)
6392 // with the overlay mixer IBasicVideo2 won't tell the new AR when changed dynamically
6393 DVD_VideoAttributes VATR
;
6394 if(m_iPlaybackMode
== PM_DVD
&& SUCCEEDED(pDVDI
->GetCurrentVideoAttributes(&VATR
)))
6395 arxy
.SetSize(VATR
.ulAspectX
, VATR
.ulAspectY
);
6397 CSize
& ar
= AfxGetAppSettings().AspectRatio
;
6398 if(ar
.cx
&& ar
.cy
) arxy
= ar
;
6400 ret
= (!fKeepAspectRatio
|| arxy
.cx
<= 0 || arxy
.cy
<= 0)
6402 : CSize(MulDiv(wh
.cy
, arxy
.cx
, arxy
.cy
), wh
.cy
);
6404 if(fCompMonDeskARDiff
)
6405 if(HDC hDC
= ::GetDC(0))
6407 int _HORZSIZE
= GetDeviceCaps(hDC
, HORZSIZE
);
6408 int _VERTSIZE
= GetDeviceCaps(hDC
, VERTSIZE
);
6409 int _HORZRES
= GetDeviceCaps(hDC
, HORZRES
);
6410 int _VERTRES
= GetDeviceCaps(hDC
, VERTRES
);
6412 if(_HORZSIZE
> 0 && _VERTSIZE
> 0 && _HORZRES
> 0 && _VERTRES
> 0)
6414 double a
= 1.0*_HORZSIZE
/_VERTSIZE
;
6415 double b
= 1.0*_HORZRES
/_VERTRES
;
6418 ret
.cy
= (DWORD
)(1.0*ret
.cy
* a
/ b
);
6420 ret
.cx
= (DWORD
)(1.0*ret
.cx
* b
/ a
);
6423 ::ReleaseDC(0, hDC
);
6429 void CMainFrame::ToggleFullscreen(bool fToNearest
, bool fSwitchScreenResWhenHasTo
)
6432 // const CWnd* pWndInsertAfter;
6433 DWORD dwRemove
= 0, dwAdd
= 0;
6434 DWORD dwRemoveEx
= 0, dwAddEx
= 0;
6439 GetWindowRect(&m_lastWindowRect
);
6441 dispmode
& dm
= AfxGetAppSettings().dmFullscreenRes
;
6442 m_dmBeforeFullscreen
.fValid
= false;
6443 if(dm
.fValid
&& fSwitchScreenResWhenHasTo
)
6445 GetCurDispMode(m_dmBeforeFullscreen
);
6450 mi
.cbSize
= sizeof(MONITORINFO
);
6451 GetMonitorInfo(MonitorFromWindow(m_hWnd
, MONITOR_DEFAULTTONEAREST
), &mi
);
6453 dwRemove
= WS_CAPTION
|WS_THICKFRAME
;
6454 if(fToNearest
) r
= mi
.rcMonitor
;
6455 else GetDesktopWindow()->GetWindowRect(&r
);
6460 if(m_dmBeforeFullscreen
.fValid
)
6461 SetDispMode(m_dmBeforeFullscreen
);
6463 dwAdd
= (AfxGetAppSettings().fHideCaptionMenu
? 0 : WS_CAPTION
) | WS_THICKFRAME
;
6464 r
= m_lastWindowRect
;
6465 hMenu
= AfxGetAppSettings().fHideCaptionMenu
? NULL
: m_hMenuDefault
;
6468 m_lastMouseMove
.x
= m_lastMouseMove
.y
= -1;
6470 bool fAudioOnly
= m_fAudioOnly
;
6471 m_fAudioOnly
= true;
6473 m_fFullScreen
= !m_fFullScreen
;
6475 SetAlwaysOnTop(AfxGetAppSettings().iOnTop
);
6477 ModifyStyle(dwRemove
, dwAdd
, SWP_NOZORDER
);
6478 ModifyStyleEx(dwRemoveEx
, dwAddEx
, SWP_NOZORDER
);
6479 ::SetMenu(m_hWnd
, hMenu
);
6480 SetWindowPos(NULL
, r
.left
, r
.top
, r
.Width(), r
.Height(), SWP_NOZORDER
|SWP_NOSENDCHANGING
/*SWP_FRAMECHANGED*/);
6484 m_fHideCursor
= true;
6485 ShowControls(CS_NONE
, false);
6489 KillTimer(TIMER_FULLSCREENCONTROLBARHIDER
);
6490 KillTimer(TIMER_FULLSCREENMOUSEHIDER
);
6491 m_fHideCursor
= false;
6492 ShowControls(AfxGetAppSettings().nCS
);
6495 m_wndView
.SetWindowPos(NULL
, 0, 0, 0, 0, SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOZORDER
);
6497 m_fAudioOnly
= fAudioOnly
;
6502 void CMainFrame::MoveVideoWindow(bool fShowStats
)
6504 if(m_iMediaLoadState
== MLS_LOADED
&& !m_fAudioOnly
&& IsWindowVisible())
6509 m_wndView
.GetClientRect(wr
);
6510 if(!AfxGetAppSettings().fHideCaptionMenu
)
6511 wr
.DeflateRect(2, 2);
6519 m_wndView
.GetWindowRect(&r
);
6523 CRect vr
= CRect(0,0,0,0);
6525 OAFilterState fs
= GetMediaState();
6526 if(fs
== State_Paused
|| fs
== State_Running
|| fs
== State_Stopped
&& (m_fShockwaveGraph
|| m_fQuicktimeGraph
))
6528 CSize arxy
= GetVideoSize();
6530 int iDefaultVideoSize
= AfxGetAppSettings().iDefaultVideoSize
;
6533 iDefaultVideoSize
== DVS_HALF
? CSize(arxy
.cx
/2, arxy
.cy
/2) :
6534 iDefaultVideoSize
== DVS_NORMAL
? arxy
:
6535 iDefaultVideoSize
== DVS_DOUBLE
? CSize(arxy
.cx
*2, arxy
.cy
*2) :
6541 if(!m_fShockwaveGraph
) //&& !m_fQuicktimeGraph)
6543 if(iDefaultVideoSize
== DVS_FROMINSIDE
|| iDefaultVideoSize
== DVS_FROMOUTSIDE
)
6546 w
= MulDiv(h
, arxy
.cx
, arxy
.cy
);
6548 if(iDefaultVideoSize
== DVS_FROMINSIDE
&& w
> ws
.cx
6549 || iDefaultVideoSize
== DVS_FROMOUTSIDE
&& w
< ws
.cx
)
6552 h
= MulDiv(w
, arxy
.cy
, arxy
.cx
);
6562 (int)(m_PosX
*(wr
.Width()*3 - m_ZoomX
*w
) - wr
.Width()),
6563 (int)(m_PosY
*(wr
.Height()*3 - m_ZoomY
*h
) - wr
.Height()));
6566 (int)(m_PosX*(wr.Width() - size.cx)),
6567 (int)(m_PosY*(wr.Height() - size.cy)));
6570 vr
= CRect(pos
, size
);
6573 wr
|= CRect(0,0,0,0);
6574 vr
|= CRect(0,0,0,0);
6578 m_pCAP
->SetPosition(wr
, vr
);
6579 m_pCAP
->SetVideoAngle(Vector(DegToRad(m_AngleX
), DegToRad(m_AngleY
), DegToRad(m_AngleZ
)));
6584 hr
= pBV
->SetDefaultSourcePosition();
6585 hr
= pBV
->SetDestinationPosition(vr
.left
, vr
.top
, vr
.Width(), vr
.Height());
6586 hr
= pVW
->SetWindowPosition(wr
.left
, wr
.top
, wr
.Width(), wr
.Height());
6589 m_wndView
.SetVideoRect(wr
);
6591 if(fShowStats
&& vr
.Height() > 0)
6594 info
.Format(_T("Pos %.2f %.2f, Zoom %.2f %.2f, AR %.2f"), m_PosX
, m_PosY
, m_ZoomX
, m_ZoomY
, (float)vr
.Width()/vr
.Height());
6595 SendStatusMessage(info
, 3000);
6600 m_wndView
.SetVideoRect();
6604 void CMainFrame::ZoomVideoWindow(double scale
)
6606 if(m_iMediaLoadState
!= MLS_LOADED
)
6609 AppSettings
& s
= AfxGetAppSettings();
6614 s
.iZoomLevel
== 0 ? 0.5 :
6615 s
.iZoomLevel
== 1 ? 1.0 :
6616 s
.iZoomLevel
== 2 ? 2.0 :
6617 s
.iZoomLevel
== 3 ? GetZoomAutoFitScale() :
6627 OnGetMinMaxInfo(&mmi
);
6634 CSize arxy
= GetVideoSize();
6636 long lWidth
= int(arxy
.cx
* scale
+ 0.5);
6637 long lHeight
= int(arxy
.cy
* scale
+ 0.5);
6639 DWORD style
= GetStyle();
6643 m_wndView
.GetClientRect(&r2
);
6645 w
= GetSystemMetrics((style
&WS_CAPTION
)?SM_CXSIZEFRAME
:SM_CXFIXEDFRAME
)*2
6646 + r1
.Width() - r2
.Width()
6650 memset(&mbi
, 0, sizeof(mbi
));
6651 mbi
.cbSize
= sizeof(mbi
);
6652 ::GetMenuBarInfo(m_hWnd
, OBJID_MENU
, 0, &mbi
);
6654 h
= GetSystemMetrics((style
&WS_CAPTION
)?SM_CYSIZEFRAME
:SM_CYFIXEDFRAME
)*2
6655 + (mbi
.rcBar
.bottom
- mbi
.rcBar
.top
)
6656 + r1
.Height() - r2
.Height()
6659 if(style
&WS_CAPTION
)
6661 h
+= GetSystemMetrics(SM_CYCAPTION
);
6662 w
+= 2; h
+= 2; // for the 1 pixel wide sunken frame
6663 w
+= 2; h
+= 3; // for the inner black border
6668 w
= max(w
, mmi
.ptMinTrackSize
.x
);
6669 h
= max(h
, mmi
.ptMinTrackSize
.y
);
6675 w
= r
.Width(); // mmi.ptMinTrackSize.x;
6676 h
= mmi
.ptMinTrackSize
.y
;
6680 if(!s
.fRememberWindowPos
)
6682 CPoint cp
= r
.CenterPoint();
6683 r
.left
= cp
.x
- w
/2;
6687 r
.right
= r
.left
+ w
;
6688 r
.bottom
= r
.top
+ h
;
6691 mi
.cbSize
= sizeof(MONITORINFO
);
6692 GetMonitorInfo(MonitorFromWindow(m_hWnd
, MONITOR_DEFAULTTONEAREST
), &mi
);
6693 if(r
.right
> mi
.rcWork
.right
) r
.OffsetRect(mi
.rcWork
.right
-r
.right
, 0);
6694 if(r
.left
< mi
.rcWork
.left
) r
.OffsetRect(mi
.rcWork
.left
-r
.left
, 0);
6695 if(r
.bottom
> mi
.rcWork
.bottom
) r
.OffsetRect(0, mi
.rcWork
.bottom
-r
.bottom
);
6696 if(r
.top
< mi
.rcWork
.top
) r
.OffsetRect(0, mi
.rcWork
.top
-r
.top
);
6698 if(m_fFullScreen
|| !s
.HasFixedWindowSize())
6703 // ShowWindow(SW_SHOWNORMAL);
6708 double CMainFrame::GetZoomAutoFitScale()
6710 if(m_iMediaLoadState
!= MLS_LOADED
|| m_fAudioOnly
)
6713 CSize arxy
= GetVideoSize();
6715 double sx
= 2.0/3 * m_rcDesktop
.Width() / arxy
.cx
;
6716 double sy
= 2.0/3 * m_rcDesktop
.Height() / arxy
.cy
;
6718 return sx
< sy
? sx
: sy
;
6721 void CMainFrame::RepaintVideo()
6723 if(m_pCAP
) m_pCAP
->Paint(false);
6726 void CMainFrame::SetShaders()
6730 AppSettings
& s
= AfxGetAppSettings();
6732 CAtlStringMap
<const AppSettings::Shader
*> s2s
;
6734 POSITION pos
= s
.m_shaders
.GetHeadPosition();
6737 const AppSettings::Shader
* pShader
= &s
.m_shaders
.GetNext(pos
);
6738 s2s
[pShader
->label
] = pShader
;
6741 m_pCAP
->SetPixelShader(NULL
, NULL
);
6743 CAtlList
<CString
> labels
;
6745 pos
= m_shaderlabels
.GetHeadPosition();
6748 const AppSettings::Shader
* pShader
= NULL
;
6749 if(s2s
.Lookup(m_shaderlabels
.GetNext(pos
), pShader
))
6751 CStringA target
= pShader
->target
;
6752 CStringA srcdata
= pShader
->srcdata
;
6754 HRESULT hr
= m_pCAP
->SetPixelShader(srcdata
, target
);
6758 m_pCAP
->SetPixelShader(NULL
, NULL
);
6759 SendStatusMessage(_T("Could not load shader: ") + pShader
->label
, 3000);
6763 labels
.AddTail(pShader
->label
);
6767 if(m_iMediaLoadState
== MLS_LOADED
)
6769 CString str
= Implode(labels
, '|');
6770 str
.Replace(_T("|"), _T(", "));
6771 SendStatusMessage(_T("Shader: ") + str
, 3000);
6775 void CMainFrame::UpdateShaders(CString label
)
6779 if(m_shaderlabels
.GetCount() <= 1)
6780 m_shaderlabels
.RemoveAll();
6782 if(m_shaderlabels
.IsEmpty() && !label
.IsEmpty())
6783 m_shaderlabels
.AddTail(label
);
6785 bool fUpdate
= m_shaderlabels
.IsEmpty();
6787 POSITION pos
= m_shaderlabels
.GetHeadPosition();
6790 if(label
== m_shaderlabels
.GetNext(pos
))
6797 if(fUpdate
) SetShaders();
6801 void CMainFrame::SetBalance(int balance
)
6803 AfxGetAppSettings().nBalance
= balance
;
6805 int sign
= balance
>0?-1:1;
6806 balance
= max(100-abs(balance
), 1);
6807 balance
= (int)((log10(1.0*balance
)-2)*5000*sign
);
6808 balance
= max(min(balance
, 10000), -10000);
6810 if(m_iMediaLoadState
== MLS_LOADED
)
6811 pBA
->put_Balance(balance
);
6814 void CMainFrame::SetupIViAudReg()
6816 if(!AfxGetAppSettings().fAutoSpeakerConf
) return;
6818 DWORD spc
= 0, defchnum
= 0;
6820 if(AfxGetAppSettings().fAutoSpeakerConf
)
6822 CComPtr
<IDirectSound
> pDS
;
6823 if(SUCCEEDED(DirectSoundCreate(NULL
, &pDS
, NULL
))
6824 && SUCCEEDED(pDS
->SetCooperativeLevel(m_hWnd
, DSSCL_NORMAL
)))
6826 if(SUCCEEDED(pDS
->GetSpeakerConfig(&spc
)))
6830 case DSSPEAKER_DIRECTOUT
: defchnum
= 6; break;
6831 case DSSPEAKER_HEADPHONE
: defchnum
= 2; break;
6832 case DSSPEAKER_MONO
: defchnum
= 1; break;
6833 case DSSPEAKER_QUAD
: defchnum
= 4; break;
6835 case DSSPEAKER_STEREO
: defchnum
= 2; break;
6836 case DSSPEAKER_SURROUND
: defchnum
= 2; break;
6837 case DSSPEAKER_5POINT1
: defchnum
= 5; break;
6838 case DSSPEAKER_7POINT1
: defchnum
= 5; break;
6849 if(ERROR_SUCCESS
== iviaud
.Create(HKEY_LOCAL_MACHINE
, _T("SOFTWARE\\InterVideo\\Common\\AudioDec")))
6852 if(FAILED(iviaud
.QueryDWORDValue(_T("AUDIO"), chnum
))) chnum
= 0;
6853 if(chnum
<= defchnum
) // check if the user has already set it..., but we won't skip if it's lower than sensible :P
6854 iviaud
.SetDWORDValue(_T("AUDIO"), defchnum
);
6863 void CMainFrame::OpenCreateGraphObject(OpenMediaData
* pOMD
)
6865 ASSERT(pGB
== NULL
);
6867 m_fCustomGraph
= false;
6868 m_fRealMediaGraph
= m_fShockwaveGraph
= m_fQuicktimeGraph
= false;
6870 AppSettings
& s
= AfxGetAppSettings();
6872 if(OpenFileData
* p
= dynamic_cast<OpenFileData
*>(pOMD
))
6874 engine_t engine
= s
.Formats
.GetEngine(p
->fns
.GetHead());
6876 CStringA ct
= GetContentType(p
->fns
.GetHead());
6878 if(ct
== "video/x-ms-asf")
6880 // TODO: put something here to make the windows media source filter load later
6882 else if(ct
== "audio/x-pn-realaudio"
6883 || ct
== "audio/x-pn-realaudio-plugin"
6884 || ct
== "audio/x-realaudio-secure"
6885 || ct
== "video/vnd.rn-realvideo-secure"
6886 || ct
== "application/vnd.rn-realmedia"
6887 || ct
.Find("vnd.rn-") >= 0
6888 || ct
.Find("realaudio") >= 0
6889 || ct
.Find("realvideo") >= 0)
6893 else if(ct
== "application/x-shockwave-flash")
6897 else if(ct
== "video/quicktime"
6898 || ct
== "application/x-quicktimeplayer")
6904 CComPtr
<IUnknown
> pUnk
;
6906 if(engine
== RealMedia
)
6908 if(!(pUnk
= (IUnknown
*)(INonDelegatingUnknown
*)new CRealMediaGraph(m_wndView
.m_hWnd
, hr
)))
6909 throw _T("Out of memory");
6911 if(SUCCEEDED(hr
) && !!(pGB
= CComQIPtr
<IGraphBuilder
>(pUnk
)))
6912 m_fRealMediaGraph
= true;
6914 else if(engine
== ShockWave
)
6916 if(!(pUnk
= (IUnknown
*)(INonDelegatingUnknown
*)new CShockwaveGraph(m_wndView
.m_hWnd
, hr
)))
6917 throw _T("Out of memory");
6919 if(FAILED(hr
) || !(pGB
= CComQIPtr
<IGraphBuilder
>(pUnk
)))
6920 throw _T("Can't create shockwave control");
6922 m_fShockwaveGraph
= true;
6924 else if(engine
== QuickTime
)
6926 if(!(pUnk
= (IUnknown
*)(INonDelegatingUnknown
*)new CQuicktimeGraph(m_wndView
.m_hWnd
, hr
)))
6927 throw _T("Out of memory");
6929 if(SUCCEEDED(hr
) && !!(pGB
= CComQIPtr
<IGraphBuilder
>(pUnk
)))
6930 m_fQuicktimeGraph
= true;
6933 m_fCustomGraph
= m_fRealMediaGraph
|| m_fShockwaveGraph
|| m_fQuicktimeGraph
;
6937 pGB
= new CFGManagerPlayer(_T("CFGManagerPlayer"), NULL
, s
.SrcFilters
, s
.TraFilters
, m_wndView
.m_hWnd
);
6940 else if(OpenDVDData
* p
= dynamic_cast<OpenDVDData
*>(pOMD
))
6942 pGB
= new CFGManagerDVD(_T("CFGManagerDVD"), NULL
, s
.SrcFilters
, s
.TraFilters
, m_wndView
.m_hWnd
);
6944 else if(OpenDeviceData
* p
= dynamic_cast<OpenDeviceData
*>(pOMD
))
6946 pGB
= new CFGManagerCapture(_T("CFGManagerCapture"), NULL
, s
.SrcFilters
, s
.TraFilters
, m_wndView
.m_hWnd
);
6951 throw _T("Failed to create the filter graph object");
6956 pMC
= pGB
; pME
= pGB
; pMS
= pGB
; // general
6957 pVW
= pGB
; pBV
= pGB
; // video
6961 if(!(pMC
&& pME
&& pMS
)
6965 throw _T("Failed to query the needed interfaces for playback");
6968 if(FAILED(pME
->SetNotifyWindow((OAHWND
)m_hWnd
, WM_GRAPHNOTIFY
, 0)))
6970 throw _T("Could not set target window for graph notification");
6973 m_pProv
= (IUnknown
*)new CKeyProvider();
6975 if(CComQIPtr
<IObjectWithSite
> pObjectWithSite
= pGB
)
6976 pObjectWithSite
->SetSite(m_pProv
);
6978 m_pCB
= new CDSMChapterBag(NULL
, NULL
);
6981 void CMainFrame::OpenFile(OpenFileData
* pOFD
)
6983 if(pOFD
->fns
.IsEmpty())
6984 throw _T("Invalid argument");
6986 AppSettings
& s
= AfxGetAppSettings();
6990 POSITION pos
= pOFD
->fns
.GetHeadPosition();
6993 CString fn
= pOFD
->fns
.GetNext(pos
);
6996 if(fn
.IsEmpty() && !fFirst
)
6999 HRESULT hr
= pGB
->RenderFile(CStringW(fn
), NULL
);
7005 if(s
.fReportFailedPins
)
7007 CComQIPtr
<IGraphBuilderDeadEnd
> pGBDE
= pGB
;
7008 if(pGBDE
&& pGBDE
->GetCount()) CMediaTypesDlg(pGBDE
, this).DoModal();
7015 case E_ABORT
: err
= _T("Opening aborted"); break;
7016 case E_FAIL
: case E_POINTER
: default: err
= _T("Failed to render the file"); break;
7017 case E_INVALIDARG
: err
= _T("Invalid file name"); break;
7018 case E_OUTOFMEMORY
: err
= _T("Out of memory"); break;
7019 case VFW_E_CANNOT_CONNECT
: err
= _T("Cannot connect the filters"); break;
7020 case VFW_E_CANNOT_LOAD_SOURCE_FILTER
: err
= _T("Cannot load any source filter"); break;
7021 case VFW_E_CANNOT_RENDER
: err
= _T("Cannot render the file"); break;
7022 case VFW_E_INVALID_FILE_FORMAT
: err
= _T("Invalid file format"); break;
7023 case VFW_E_NOT_FOUND
: err
= _T("File not found"); break;
7024 case VFW_E_UNKNOWN_FILE_TYPE
: err
= _T("Unknown file type"); break;
7025 case VFW_E_UNSUPPORTED_STREAM
: err
= _T("Unsupported stream"); break;
7034 CRecentFileList
* pMRU
= fFirst
? &s
.MRU
: &s
.MRUDub
;
7047 if(m_fCustomGraph
) break;
7050 if(s
.fReportFailedPins
)
7052 CComQIPtr
<IGraphBuilderDeadEnd
> pGBDE
= pGB
;
7053 if(pGBDE
&& pGBDE
->GetCount()) CMediaTypesDlg(pGBDE
, this).DoModal();
7058 BeginEnumFilters(pGB
, pEF
, pBF
)
7059 if(pAMOP
= pBF
) break;
7063 if(FindFilter(__uuidof(CShoutcastSource
), pGB
))
7064 m_fUpdateInfoBar
= true;
7068 CComQIPtr
<IKeyFrameInfo
> pKFI
;
7069 BeginEnumFilters(pGB
, pEF
, pBF
)
7070 if(pKFI
= pBF
) break;
7072 UINT nKFs
= 0, nKFsTmp
= 0;
7073 if(pKFI
&& S_OK
== pKFI
->GetKeyFrameCount(nKFs
) && nKFs
> 0)
7075 m_kfs
.SetCount(nKFsTmp
= nKFs
);
7076 if(S_OK
!= pKFI
->GetKeyFrames(&TIME_FORMAT_MEDIA_TIME
, m_kfs
.GetData(), nKFsTmp
) || nKFsTmp
!= nKFs
)
7080 m_iPlaybackMode
= PM_FILE
;
7083 void CMainFrame::SetupChapters()
7087 m_pCB
->ChapRemoveAll();
7089 CInterfaceList
<IBaseFilter
> pBFs
;
7090 BeginEnumFilters(pGB
, pEF
, pBF
)
7096 pos
= pBFs
.GetHeadPosition();
7097 while(pos
&& !m_pCB
->ChapGetCount())
7099 IBaseFilter
* pBF
= pBFs
.GetNext(pos
);
7101 CComQIPtr
<IDSMChapterBag
> pCB
= pBF
;
7104 for(DWORD i
= 0, cnt
= pCB
->ChapGetCount(); i
< cnt
; i
++)
7108 if(SUCCEEDED(pCB
->ChapGet(i
, &rt
, &name
)))
7109 m_pCB
->ChapAppend(rt
, name
);
7113 pos
= pBFs
.GetHeadPosition();
7114 while(pos
&& !m_pCB
->ChapGetCount())
7116 IBaseFilter
* pBF
= pBFs
.GetNext(pos
);
7118 CComQIPtr
<IChapterInfo
> pCI
= pBF
;
7122 ::GetLocaleInfoA(LOCALE_USER_DEFAULT
, LOCALE_SISO639LANGNAME
, iso6391
, 3);
7123 CStringA iso6392
= ISO6391To6392(iso6391
);
7124 if(iso6392
.GetLength() < 3) iso6392
= "eng";
7126 UINT cnt
= pCI
->GetChapterCount(CHAPTER_ROOT_ID
);
7127 for(UINT i
= 1; i
<= cnt
; i
++)
7129 UINT cid
= pCI
->GetChapterId(CHAPTER_ROOT_ID
, i
);
7132 if(pCI
->GetChapterInfo(cid
, &ce
))
7134 char pl
[3] = {iso6392
[0], iso6392
[1], iso6392
[2]};
7137 name
.Attach(pCI
->GetChapterStringInfo(cid
, pl
, cc
));
7138 m_pCB
->ChapAppend(ce
.rtStart
, name
);
7143 pos
= pBFs
.GetHeadPosition();
7144 while(pos
&& !m_pCB
->ChapGetCount())
7146 IBaseFilter
* pBF
= pBFs
.GetNext(pos
);
7148 CComQIPtr
<IAMExtendedSeeking
, &IID_IAMExtendedSeeking
> pES
= pBF
;
7151 long MarkerCount
= 0;
7152 if(SUCCEEDED(pES
->get_MarkerCount(&MarkerCount
)))
7154 for(long i
= 1; i
<= MarkerCount
; i
++)
7156 double MarkerTime
= 0;
7157 if(SUCCEEDED(pES
->GetMarkerTime(i
, &MarkerTime
)))
7160 name
.Format(L
"Chapter %d", i
);
7163 if(S_OK
== pES
->GetMarkerName(i
, &bstr
))
7166 m_pCB
->ChapAppend(REFERENCE_TIME(MarkerTime
*10000000), name
);
7172 pos
= pBFs
.GetHeadPosition();
7173 while(pos
&& !m_pCB
->ChapGetCount())
7175 IBaseFilter
* pBF
= pBFs
.GetNext(pos
);
7177 if(GetCLSID(pBF
) != CLSID_OggSplitter
)
7180 BeginEnumPins(pBF
, pEP
, pPin
)
7182 if(m_pCB
->ChapGetCount()) break;
7184 if(CComQIPtr
<IPropertyBag
> pPB
= pPin
)
7186 for(int i
= 1; ; i
++)
7192 str
.Format(L
"CHAPTER%02d", i
);
7193 if(S_OK
!= pPB
->Read(str
, &var
, NULL
))
7198 if(7 != swscanf(CStringW(var
), L
"%d%c%d%c%d%c%d", &h
, &wc
, &m
, &wc
, &s
, &wc
, &ms
))
7202 name
.Format(L
"Chapter %d", i
);
7205 if(S_OK
== pPB
->Read(str
, &var
, NULL
))
7208 m_pCB
->ChapAppend(10000i64
*(((h
*60 + m
)*60 + s
)*1000 + ms
), name
);
7218 void CMainFrame::OpenDVD(OpenDVDData
* pODD
)
7220 HRESULT hr
= pGB
->RenderFile(CStringW(pODD
->path
), NULL
);
7222 AppSettings
& s
= AfxGetAppSettings();
7224 if(s
.fReportFailedPins
)
7226 CComQIPtr
<IGraphBuilderDeadEnd
> pGBDE
= pGB
;
7227 if(pGBDE
&& pGBDE
->GetCount()) CMediaTypesDlg(pGBDE
, this).DoModal();
7230 BeginEnumFilters(pGB
, pEF
, pBF
)
7232 if((pDVDC
= pBF
) && (pDVDI
= pBF
))
7237 if(hr
== E_INVALIDARG
)
7238 throw _T("Cannot find DVD directory");
7239 else if(hr
== VFW_E_CANNOT_RENDER
)
7240 throw _T("Failed to render all pins of the DVD Navigator filter");
7241 else if(hr
== VFW_S_PARTIAL_RENDER
)
7242 throw _T("Failed to render some of the pins of the DVD Navigator filter");
7243 else if(hr
== E_NOINTERFACE
|| !pDVDC
|| !pDVDI
)
7244 throw _T("Failed to query the needed interfaces for DVD playback");
7245 else if(hr
== VFW_E_CANNOT_LOAD_SOURCE_FILTER
)
7246 throw _T("Can't create the DVD Navigator filter");
7250 WCHAR buff
[MAX_PATH
];
7252 if(SUCCEEDED(hr
= pDVDI
->GetDVDDirectory(buff
, countof(buff
), &len
)))
7253 pODD
->title
= CString(CStringW(buff
));
7257 pDVDC
->SetOption(DVD_ResetOnStop
, FALSE
);
7258 pDVDC
->SetOption(DVD_HMSF_TimeCodeEvents
, TRUE
);
7260 if(s
.idMenuLang
) pDVDC
->SelectDefaultMenuLanguage(s
.idMenuLang
);
7261 if(s
.idAudioLang
) pDVDC
->SelectDefaultAudioLanguage(s
.idAudioLang
, DVD_AUD_EXT_NotSpecified
);
7262 if(s
.idSubtitlesLang
) pDVDC
->SelectDefaultSubpictureLanguage(s
.idSubtitlesLang
, DVD_SP_EXT_NotSpecified
);
7264 m_iDVDDomain
= DVD_DOMAIN_Stop
;
7266 m_iPlaybackMode
= PM_DVD
;
7269 void CMainFrame::OpenCapture(OpenDeviceData
* pODD
)
7271 CStringW vidfrname
, audfrname
;
7272 CComPtr
<IBaseFilter
> pVidCapTmp
, pAudCapTmp
;
7274 m_VidDispName
= pODD
->DisplayName
[0];
7276 if(!m_VidDispName
.IsEmpty())
7278 if(!CreateFilter(m_VidDispName
, &pVidCapTmp
, vidfrname
))
7279 throw _T("Can't create video capture filter");
7282 m_AudDispName
= pODD
->DisplayName
[1];
7284 if(!m_AudDispName
.IsEmpty())
7286 if(!CreateFilter(m_AudDispName
, &pAudCapTmp
, audfrname
))
7287 throw _T("Can't create video capture filter");
7290 if(!pVidCapTmp
&& !pAudCapTmp
)
7292 throw _T("No capture filters");
7299 if(FAILED(pCGB
.CoCreateInstance(CLSID_CaptureGraphBuilder2
)))
7301 throw _T("Can't create capture graph builder object");
7306 pCGB
->SetFiltergraph(pGB
);
7310 if(FAILED(hr
= pGB
->AddFilter(pVidCapTmp
, vidfrname
)))
7312 throw _T("Can't add video capture filter to the graph");
7315 pVidCap
= pVidCapTmp
;
7319 if(FAILED(pCGB
->FindInterface(&PIN_CATEGORY_CAPTURE
, &MEDIATYPE_Interleaved
, pVidCap
, IID_IAMStreamConfig
, (void **)&pAMVSCCap
))
7320 && FAILED(pCGB
->FindInterface(&PIN_CATEGORY_CAPTURE
, &MEDIATYPE_Video
, pVidCap
, IID_IAMStreamConfig
, (void **)&pAMVSCCap
)))
7321 TRACE(_T("Warning: No IAMStreamConfig interface for vidcap capture"));
7323 if(FAILED(pCGB
->FindInterface(&PIN_CATEGORY_PREVIEW
, &MEDIATYPE_Interleaved
, pVidCap
, IID_IAMStreamConfig
, (void **)&pAMVSCPrev
))
7324 && FAILED(pCGB
->FindInterface(&PIN_CATEGORY_PREVIEW
, &MEDIATYPE_Video
, pVidCap
, IID_IAMStreamConfig
, (void **)&pAMVSCPrev
)))
7325 TRACE(_T("Warning: No IAMStreamConfig interface for vidcap capture"));
7327 if(FAILED(pCGB
->FindInterface(&PIN_CATEGORY_CAPTURE
, &MEDIATYPE_Audio
, pVidCap
, IID_IAMStreamConfig
, (void **)&pAMASC
))
7328 && FAILED(pCGB
->FindInterface(&PIN_CATEGORY_PREVIEW
, &MEDIATYPE_Audio
, pVidCap
, IID_IAMStreamConfig
, (void **)&pAMASC
)))
7330 TRACE(_T("Warning: No IAMStreamConfig interface for vidcap"));
7339 if(FAILED(pCGB
->FindInterface(&PIN_CATEGORY_CAPTURE
, &MEDIATYPE_Video
, pVidCap
, IID_IAMStreamConfig
, (void **)&pAMVSCCap
)))
7340 TRACE(_T("Warning: No IAMStreamConfig interface for vidcap capture"));
7342 if(FAILED(pCGB
->FindInterface(&PIN_CATEGORY_CAPTURE
, &MEDIATYPE_Video
, pVidCap
, IID_IAMStreamConfig
, (void **)&pAMVSCPrev
)))
7343 TRACE(_T("Warning: No IAMStreamConfig interface for vidcap capture"));
7346 if(FAILED(pCGB
->FindInterface(&LOOK_UPSTREAM_ONLY
, NULL
, pVidCap
, IID_IAMCrossbar
, (void**)&pAMXBar
)))
7347 TRACE(_T("Warning: No IAMCrossbar interface was found\n"));
7349 if(FAILED(pCGB
->FindInterface(&LOOK_UPSTREAM_ONLY
, NULL
, pVidCap
, IID_IAMTVTuner
, (void**)&pAMTuner
)))
7350 TRACE(_T("Warning: No IAMTVTuner interface was found\n"));
7354 //DumpStreamConfig(_T("c:\\mpclog.txt"), pAMVSCCap);
7355 CComQIPtr<IAMVfwCaptureDialogs> pVfwCD = pVidCap;
7356 if(!pAMXBar && pVfwCD)
7358 m_wndCaptureBar.m_capdlg.SetupVideoControls(viddispname, pAMVSCCap, pVfwCD);
7362 m_wndCaptureBar.m_capdlg.SetupVideoControls(viddispname, pAMVSCCap, pAMXBar, pAMTuner);
7366 // TODO: init pAMXBar
7368 if(pAMTuner
) // load saved channel
7370 pAMTuner
->put_CountryCode(AfxGetApp()->GetProfileInt(_T("Capture"), _T("Country"), 1));
7372 int vchannel
= pODD
->vchannel
;
7373 if(vchannel
< 0) vchannel
= AfxGetApp()->GetProfileInt(_T("Capture\\") + CString(m_VidDispName
), _T("Channel"), -1);
7376 OAFilterState fs
= State_Stopped
;
7377 pMC
->GetState(0, &fs
);
7378 if(fs
== State_Running
) pMC
->Pause();
7379 pAMTuner
->put_Channel(vchannel
, AMTUNER_SUBCHAN_DEFAULT
, AMTUNER_SUBCHAN_DEFAULT
);
7380 if(fs
== State_Running
) pMC
->Run();
7387 if(FAILED(hr
= pGB
->AddFilter(pAudCapTmp
, CStringW(audfrname
))))
7389 throw _T("Can't add audio capture filter to the graph");
7392 pAudCap
= pAudCapTmp
;
7394 if(FAILED(pCGB
->FindInterface(&PIN_CATEGORY_CAPTURE
, &MEDIATYPE_Audio
, pAudCap
, IID_IAMStreamConfig
, (void **)&pAMASC
))
7395 && FAILED(pCGB
->FindInterface(&PIN_CATEGORY_PREVIEW
, &MEDIATYPE_Audio
, pAudCap
, IID_IAMStreamConfig
, (void **)&pAMASC
)))
7397 TRACE(_T("Warning: No IAMStreamConfig interface for vidcap"));
7400 CInterfaceArray<IAMAudioInputMixer> pAMAIM;
7402 BeginEnumPins(pAudCap, pEP, pPin)
7405 if(FAILED(pPin->QueryDirection(&dir)) || dir != PINDIR_INPUT)
7408 if(CComQIPtr<IAMAudioInputMixer> pAIM = pPin)
7415 m_wndCaptureBar.m_capdlg.SetupAudioControls(auddispname, pAMASC, pAMAIM);
7420 if(!(pVidCap
|| pAudCap
))
7422 throw _T("Couldn't open any device");
7425 pODD
->title
= _T("Live");
7427 m_iPlaybackMode
= PM_CAPTURE
;
7430 void CMainFrame::OpenCustomizeGraph()
7432 if(m_iPlaybackMode
== PM_CAPTURE
)
7437 if(m_iPlaybackMode
== PM_FILE
)
7440 if(AfxGetAppSettings().fAutoloadSubtitles
) {
7441 AddTextPassThruFilter();
7446 if(m_iPlaybackMode
== PM_DVD
)
7448 BeginEnumFilters(pGB
, pEF
, pBF
)
7450 if(CComQIPtr
<IDirectVobSub2
> pDVS2
= pBF
)
7452 // pDVS2->AdviseSubClock(m_pSubClock = new CSubClock);
7455 // TODO: test multiple dvobsub instances with one clock
7456 if(!m_pSubClock
) m_pSubClock
= new CSubClock
;
7457 pDVS2
->AdviseSubClock(m_pSubClock
);
7463 BeginEnumFilters(pGB
, pEF
, pBF
)
7465 if(GetCLSID(pBF
) == CLSID_OggSplitter
)
7467 if(CComQIPtr
<IAMStreamSelect
> pSS
= pBF
)
7469 LCID idAudio
= AfxGetAppSettings().idAudioLang
;
7470 if(!idAudio
) idAudio
= GetUserDefaultLCID();
7471 LCID idSub
= AfxGetAppSettings().idSubtitlesLang
;
7472 if(!idSub
) idSub
= GetUserDefaultLCID();
7476 for(DWORD i
= 0; i
< cnt
; i
++)
7478 AM_MEDIA_TYPE
* pmt
= NULL
;
7482 WCHAR
* pszName
= NULL
;
7483 if(SUCCEEDED(pSS
->Info((long)i
, &pmt
, &dwFlags
, &lcid
, &dwGroup
, &pszName
, NULL
, NULL
)))
7485 CStringW
name(pszName
), sound(L
"Sound"), subtitle(L
"Subtitle");
7487 if(idAudio
!= -1 && (idAudio
&0x3ff) == (lcid
&0x3ff) // sublang seems to be zeroed out in ogm...
7488 && name
.GetLength() > sound
.GetLength()
7489 && !name
.Left(sound
.GetLength()).CompareNoCase(sound
))
7491 if(SUCCEEDED(pSS
->Enable(i
, AMSTREAMSELECTENABLE_ENABLE
)))
7495 if(idSub
!= -1 && (idSub
&0x3ff) == (lcid
&0x3ff) // sublang seems to be zeroed out in ogm...
7496 && name
.GetLength() > subtitle
.GetLength()
7497 && !name
.Left(subtitle
.GetLength()).CompareNoCase(subtitle
)
7498 && name
.Mid(subtitle
.GetLength()).Trim().CompareNoCase(L
"off"))
7500 if(SUCCEEDED(pSS
->Enable(i
, AMSTREAMSELECTENABLE_ENABLE
)))
7504 if(pmt
) DeleteMediaType(pmt
);
7505 if(pszName
) CoTaskMemFree(pszName
);
7516 void CMainFrame::OpenSetupVideo()
7518 m_fAudioOnly
= true;
7522 CSize vs
= m_pCAP
->GetVideoSize();
7523 m_fAudioOnly
= (vs
.cx
<= 0 || vs
.cy
<= 0);
7530 if(CComQIPtr
<IBasicVideo
> pBV
= pGB
)
7532 pBV
->GetVideoSize(&w
, &h
);
7537 m_fAudioOnly
= false;
7543 BeginEnumFilters(pGB
, pEF
, pBF
)
7547 if(CComQIPtr
<IVideoWindow
> pVW
= pBF
)
7550 if(FAILED(pVW
->get_Visible(&lVisible
)))
7554 pVW
->get_Height(&h
);
7559 m_fAudioOnly
= false;
7567 if(m_fShockwaveGraph
)
7569 m_fAudioOnly
= false;
7580 pVW
->put_Owner((OAHWND
)m_wndView
.m_hWnd
);
7581 pVW
->put_WindowStyle(WS_CHILD
|WS_CLIPSIBLINGS
|WS_CLIPCHILDREN
);
7582 pVW
->put_MessageDrain((OAHWND
)m_hWnd
);
7584 for(CWnd
* pWnd
= m_wndView
.GetWindow(GW_CHILD
); pWnd
; pWnd
= pWnd
->GetNextWindow())
7585 pWnd
->EnableWindow(FALSE
); // little trick to let WM_SETCURSOR thru
7589 void CMainFrame::OpenSetupAudio()
7591 pBA
->put_Volume(m_wndToolBar
.Volume
);
7594 int balance
= AfxGetAppSettings().nBalance
;
7595 int sign
= balance
>0?-1:1;
7596 balance
= max(100-abs(balance
), 1);
7597 balance
= (int)((log10(1.0*balance
)-2)*5000*sign
);
7598 balance
= max(min(balance
, 10000), -10000);
7599 pBA
->put_Balance(balance
);
7602 void CMainFrame::OpenSetupToolBar()
7604 // m_wndToolBar.Volume = AfxGetAppSettings().nVolume;
7605 // SetBalance(AfxGetAppSettings().nBalance);
7608 void CMainFrame::OpenSetupCaptureBar()
7610 if(m_iPlaybackMode
== PM_CAPTURE
)
7612 if(pVidCap
&& pAMVSCCap
)
7614 CComQIPtr
<IAMVfwCaptureDialogs
> pVfwCD
= pVidCap
;
7616 if(!pAMXBar
&& pVfwCD
)
7618 m_wndCaptureBar
.m_capdlg
.SetupVideoControls(m_VidDispName
, pAMVSCCap
, pVfwCD
);
7622 m_wndCaptureBar
.m_capdlg
.SetupVideoControls(m_VidDispName
, pAMVSCCap
, pAMXBar
, pAMTuner
);
7626 if(pAudCap
&& pAMASC
)
7628 CInterfaceArray
<IAMAudioInputMixer
> pAMAIM
;
7630 BeginEnumPins(pAudCap
, pEP
, pPin
)
7632 if(CComQIPtr
<IAMAudioInputMixer
> pAIM
= pPin
)
7637 m_wndCaptureBar
.m_capdlg
.SetupAudioControls(m_AudDispName
, pAMASC
, pAMAIM
);
7641 BuildGraphVideoAudio(
7642 m_wndCaptureBar
.m_capdlg
.m_fVidPreview
, false,
7643 m_wndCaptureBar
.m_capdlg
.m_fAudPreview
, false);
7646 void CMainFrame::OpenSetupInfoBar()
7648 if(m_iPlaybackMode
== PM_FILE
)
7651 BeginEnumFilters(pGB
, pEF
, pBF
)
7653 if(CComQIPtr
<IAMMediaContent
, &IID_IAMMediaContent
> pAMMC
= pBF
)
7656 if(SUCCEEDED(pAMMC
->get_Title(&bstr
))) {m_wndInfoBar
.SetLine(ResStr(IDS_INFOBAR_TITLE
), bstr
.m_str
); if(bstr
.Length()) fEmpty
= false;}
7657 if(SUCCEEDED(pAMMC
->get_AuthorName(&bstr
))) {m_wndInfoBar
.SetLine(ResStr(IDS_INFOBAR_AUTHOR
), bstr
.m_str
); if(bstr
.Length()) fEmpty
= false;}
7658 if(SUCCEEDED(pAMMC
->get_Copyright(&bstr
))) {m_wndInfoBar
.SetLine(ResStr(IDS_INFOBAR_COPYRIGHT
), bstr
.m_str
); if(bstr
.Length()) fEmpty
= false;}
7659 if(SUCCEEDED(pAMMC
->get_Rating(&bstr
))) {m_wndInfoBar
.SetLine(ResStr(IDS_INFOBAR_RATING
), bstr
.m_str
); if(bstr
.Length()) fEmpty
= false;}
7660 if(SUCCEEDED(pAMMC
->get_Description(&bstr
))) {m_wndInfoBar
.SetLine(ResStr(IDS_INFOBAR_DESCRIPTION
), bstr
.m_str
); if(bstr
.Length()) fEmpty
= false;}
7670 else if(m_iPlaybackMode
== PM_DVD
)
7673 m_wndInfoBar
.SetLine(ResStr(IDS_INFOBAR_DOMAIN
), info
);
7674 m_wndInfoBar
.SetLine(ResStr(IDS_INFOBAR_LOCATION
), info
);
7675 m_wndInfoBar
.SetLine(ResStr(IDS_INFOBAR_VIDEO
), info
);
7676 m_wndInfoBar
.SetLine(ResStr(IDS_INFOBAR_AUDIO
), info
);
7677 m_wndInfoBar
.SetLine(ResStr(IDS_INFOBAR_SUBTITLES
), info
);
7682 void CMainFrame::OpenSetupStatsBar()
7686 BeginEnumFilters(pGB
, pEF
, pBF
)
7688 if(!pQP
&& (pQP
= pBF
))
7690 m_wndStatsBar
.SetLine(_T("Frame-rate"), info
);
7691 m_wndStatsBar
.SetLine(_T("Sync Offset"), info
);
7692 m_wndStatsBar
.SetLine(_T("Frames"), info
);
7693 m_wndStatsBar
.SetLine(_T("Jitter"), info
);
7694 m_wndStatsBar
.SetLine(_T("Buffers"), info
);
7695 m_wndStatsBar
.SetLine(_T("Bitrate"), info
);
7699 if(!pBI
&& (pBI
= pBF
))
7701 m_wndStatsBar
.SetLine(_T("Buffers"), info
);
7702 m_wndStatsBar
.SetLine(_T("Bitrate"), info
); // FIXME: shouldn't be here
7709 void CMainFrame::OpenSetupStatusBar()
7711 m_wndStatusBar
.ShowTimer(true);
7717 UINT id
= IDB_NOAUDIO
;
7719 BeginEnumFilters(pGB
, pEF
, pBF
)
7721 CComQIPtr
<IBasicAudio
> pBA
= pBF
;
7724 BeginEnumPins(pBF
, pEP
, pPin
)
7726 if(S_OK
== pGB
->IsPinDirection(pPin
, PINDIR_INPUT
)
7727 && S_OK
== pGB
->IsPinConnected(pPin
))
7730 memset(&mt
, 0, sizeof(mt
));
7731 pPin
->ConnectionMediaType(&mt
);
7733 if(mt
.majortype
== MEDIATYPE_Audio
&& mt
.formattype
== FORMAT_WaveFormatEx
)
7735 switch(((WAVEFORMATEX
*)mt
.pbFormat
)->nChannels
)
7737 case 1: id
= IDB_MONO
; break;
7738 case 2: default: id
= IDB_STEREO
; break;
7742 else if(mt
.majortype
== MEDIATYPE_Midi
)
7751 if(id
!= IDB_NOAUDIO
)
7758 m_wndStatusBar
.SetStatusBitmap(id
);
7765 if(m_iPlaybackMode
== PM_FILE
)
7767 CString fn
= m_wndPlaylistBar
.GetCur();
7768 CString ext
= fn
.Mid(fn
.ReverseFind('.')+1);
7769 hIcon
= LoadIcon(ext
, true);
7771 else if(m_iPlaybackMode
== PM_DVD
)
7773 hIcon
= LoadIcon(_T(".ifo"), true);
7775 else if(m_iPlaybackMode
== PM_DVD
)
7777 // hIcon = ; // TODO
7780 m_wndStatusBar
.SetStatusTypeIcon(hIcon
);
7783 void CMainFrame::OpenSetupWindowTitle(CString fn
)
7785 CString
title(MAKEINTRESOURCE(IDR_MAINFRAME
));
7787 AppSettings
& s
= AfxGetAppSettings();
7789 int i
= s
.iTitleBarTextStyle
;
7791 if(!fn
.IsEmpty() && (i
== 0 || i
== 1))
7795 if(m_iPlaybackMode
== PM_FILE
)
7797 fn
.Replace('\\', '/');
7798 CString fn2
= fn
.Mid(fn
.ReverseFind('/')+1);
7799 if(!fn2
.IsEmpty()) fn
= fn2
;
7801 if(s
.fTitleBarTextTitle
)
7803 BeginEnumFilters(pGB
, pEF
, pBF
)
7805 if(CComQIPtr
<IAMMediaContent
, &IID_IAMMediaContent
> pAMMC
= pBF
)
7808 if(SUCCEEDED(pAMMC
->get_Title(&bstr
)) && bstr
.Length())
7810 fn
= CString(bstr
.m_str
);
7818 else if(m_iPlaybackMode
== PM_DVD
)
7822 else if(m_iPlaybackMode
== PM_CAPTURE
)
7828 title
= fn
+ _T(" - ") + title
;
7831 SetWindowText(title
);
7834 bool CMainFrame::OpenMediaPrivate(CAutoPtr
<OpenMediaData
> pOMD
)
7836 if(m_iMediaLoadState
!= MLS_CLOSED
&& m_iMediaLoadState
!= MLS_LOADING
)
7842 m_iMediaLoadState
= MLS_LOADING
;
7844 // FIXME: Don't show "Closed" initially
7845 PostMessage(WM_KICKIDLE
);
7847 CString err
, aborted(_T("Aborted"));
7849 m_fUpdateInfoBar
= false;
7853 if(m_fOpeningAborted
) throw aborted
;
7855 if(OpenFileData
* pOFD
= dynamic_cast<OpenFileData
*>(pOMD
.m_p
))
7857 if(pOFD
->fns
.IsEmpty()) throw _T("File not found");
7859 CString fn
= pOFD
->fns
.GetHead();
7861 int i
= fn
.Find(_T(":\\"));
7864 CString drive
= fn
.Left(i
+2);
7865 UINT type
= GetDriveType(drive
);
7866 CAtlList
<CString
> sl
;
7867 if(type
== DRIVE_REMOVABLE
|| type
== DRIVE_CDROM
&& GetCDROMType(drive
[0], sl
) != CDROM_Audio
)
7870 while(ret
== IDRETRY
)
7872 WIN32_FIND_DATA findFileData
;
7873 HANDLE h
= FindFirstFile(fn
, &findFileData
);
7874 if(h
!= INVALID_HANDLE_VALUE
)
7882 msg
.Format(_T("%s was not found, please insert media containing this file."), fn
);
7883 ret
= AfxMessageBox(msg
, MB_RETRYCANCEL
);
7887 if(ret
!= IDOK
) throw aborted
;
7892 if(m_fOpeningAborted
) throw aborted
;
7894 OpenCreateGraphObject(pOMD
);
7896 if(m_fOpeningAborted
) throw aborted
;
7900 if(m_fOpeningAborted
) throw aborted
;
7902 if(OpenFileData
* p
= dynamic_cast<OpenFileData
*>(pOMD
.m_p
)) OpenFile(p
);
7903 else if(OpenDVDData
* p
= dynamic_cast<OpenDVDData
*>(pOMD
.m_p
)) OpenDVD(p
);
7904 else if(OpenDeviceData
* p
= dynamic_cast<OpenDeviceData
*>(pOMD
.m_p
)) OpenCapture(p
);
7905 else throw _T("Can't open, invalid input parameters");
7907 pGB
->FindInterface(__uuidof(ISubPicAllocatorPresenter
), (void**)&m_pCAP
, TRUE
);
7909 if(m_fOpeningAborted
) throw aborted
;
7911 OpenCustomizeGraph();
7913 if(m_fOpeningAborted
) throw aborted
;
7917 if(m_fOpeningAborted
) throw aborted
;
7921 if(m_fOpeningAborted
) throw aborted
;
7923 if(m_pCAP
&& (!m_fAudioOnly
|| m_fRealMediaGraph
))
7925 POSITION pos
= pOMD
->subs
.GetHeadPosition();
7926 while(pos
) LoadSubtitle(pOMD
->subs
.GetNext(pos
));
7928 if(AfxGetAppSettings().fEnableSubtitles
&& m_pSubStreams
.GetCount() > 0)
7929 SetSubtitle(m_pSubStreams
.GetHead());
7932 if(m_fOpeningAborted
) throw aborted
;
7934 OpenSetupWindowTitle(pOMD
->title
);
7936 if(::GetCurrentThreadId() == AfxGetApp()->m_nThreadID
)
7938 OnFilePostOpenmedia();
7942 PostMessage(WM_COMMAND
, ID_FILE_POST_OPENMEDIA
);
7945 while(m_iMediaLoadState
!= MLS_LOADED
7946 && m_iMediaLoadState
!= MLS_CLOSING
// FIXME
7952 // PostMessage instead of SendMessage because the user might call CloseMedia and then we would deadlock
7954 PostMessage(WM_COMMAND
, ID_PLAY_PAUSE
);
7956 if(!(AfxGetAppSettings().nCLSwitches
&CLSW_OPEN
))
7957 PostMessage(WM_COMMAND
, ID_PLAY_PLAY
);
7959 AfxGetAppSettings().nCLSwitches
&= ~CLSW_OPEN
;
7961 if(OpenFileData
* p
= dynamic_cast<OpenFileData
*>(pOMD
.m_p
))
7964 PostMessage(WM_RESUMEFROMSTATE
, (WPARAM
)PM_FILE
, (LPARAM
)(p
->rtStart
/10000)); // REFERENCE_TIME doesn't fit in LPARAM under a 32bit env.
7966 else if(OpenDVDData
* p
= dynamic_cast<OpenDVDData
*>(pOMD
.m_p
))
7969 PostMessage(WM_RESUMEFROMSTATE
, (WPARAM
)PM_DVD
, (LPARAM
)(CComPtr
<IDvdState
>(p
->pDvdState
).Detach())); // must be released by the called message handler
7971 else if(OpenDeviceData
* p
= dynamic_cast<OpenDeviceData
*>(pOMD
.m_p
))
7973 m_wndCaptureBar
.m_capdlg
.SetVideoInput(p
->vinput
);
7974 m_wndCaptureBar
.m_capdlg
.SetVideoChannel(p
->vchannel
);
7975 m_wndCaptureBar
.m_capdlg
.SetAudioInput(p
->ainput
);
7989 CloseMediaPrivate();
7992 OpenFileData
* p
= dynamic_cast<OpenFileData
*>(pOMD
.m_p
);
7993 if(p
&& err
!= aborted
)
7995 m_wndPlaylistBar
.SetCurValid(false);
7996 if(m_wndPlaylistBar
.GetCount() > 1)
7998 CPlaylistItem pli
[2];
7999 m_wndPlaylistBar
.GetCur(pli
[0]);
8000 m_wndPlaylistBar
.SetNext();
8001 m_wndPlaylistBar
.GetCur(pli
[1]);
8002 if(pli
[0].m_id
!= pli
[1].m_id
)
8004 CAutoPtr
<OpenMediaData
> p(m_wndPlaylistBar
.GetCurOMD());
8005 if(p
) OpenMediaPrivate(p
);
8012 m_wndPlaylistBar
.SetCurValid(true);
8015 PostMessage(WM_KICKIDLE
); // calls main thread to update things
8017 return(err
.IsEmpty());
8020 void CMainFrame::CloseMediaPrivate()
8022 m_iMediaLoadState
= MLS_CLOSING
;
8024 OnPlayStop(); // SendMessage(WM_COMMAND, ID_PLAY_STOP);
8026 m_iPlaybackMode
= PM_NONE
;
8031 m_fEndOfStream
= false;
8033 m_rtDurationOverride
= -1;
8039 // if(pVW) pVW->put_Visible(OAFALSE);
8040 // if(pVW) pVW->put_MessageDrain((OAHWND)NULL), pVW->put_Owner((OAHWND)NULL);
8042 m_pCAP
= NULL
; // IMPORTANT: IVMRSurfaceAllocatorNotify/IVMRSurfaceAllocatorNotify9 has to be released before the VMR/VMR9, otherwise it will crash in Release()
8044 pAMXBar
.Release(); pAMTuner
.Release(); pAMDF
.Release();
8045 pAMVCCap
.Release(); pAMVCPrev
.Release(); pAMVSCCap
.Release(); pAMVSCPrev
.Release(); pAMASC
.Release();
8046 pVidCap
.Release(); pAudCap
.Release();
8048 pDVDC
.Release(); pDVDI
.Release();
8049 pQP
.Release(); pBI
.Release(); pAMOP
.Release(); pFS
.Release();
8050 pMC
.Release(); pME
.Release(); pMS
.Release();
8051 pVW
.Release(); pBV
.Release();
8054 if(pGB
) pGB
->RemoveFromROT();
8057 m_fRealMediaGraph
= m_fShockwaveGraph
= m_fQuicktimeGraph
= false;
8064 CAutoLock
cAutoLock(&m_csSubLock
);
8065 m_pSubStreams
.RemoveAll();
8068 m_VidDispName
.Empty();
8069 m_AudDispName
.Empty();
8071 m_closingmsg
= ResStr(IDS_CONTROLS_CLOSED
);
8073 AfxGetAppSettings().nCLSwitches
&= CLSW_OPEN
|CLSW_PLAY
|CLSW_AFTERPLAYBACK_MASK
|CLSW_NOFOCUS
;
8075 m_iMediaLoadState
= MLS_CLOSED
;
8080 void CMainFrame::SendNowPlayingToMSN()
8082 if(!AfxGetAppSettings().fNotifyMSN
)
8085 CString title
, author
;
8087 if(m_iMediaLoadState
== MLS_LOADED
)
8089 m_wndInfoBar
.GetLine(ResStr(IDS_INFOBAR_TITLE
), title
);
8090 m_wndInfoBar
.GetLine(ResStr(IDS_INFOBAR_AUTHOR
), author
);
8095 m_wndPlaylistBar
.GetCur(pli
);
8097 if(!pli
.m_fns
.IsEmpty())
8099 CString label
= !pli
.m_label
.IsEmpty() ? pli
.m_label
: pli
.m_fns
.GetHead();
8101 if(m_iPlaybackMode
== PM_FILE
)
8104 if(fn
.Find(_T("://")) >= 0) {int i
= fn
.Find('?'); if(i
>= 0) fn
= fn
.Left(i
);}
8108 path
.RemoveExtension();
8109 title
= (LPCTSTR
)path
;
8112 else if(m_iPlaybackMode
== PM_CAPTURE
)
8114 title
= label
!= pli
.m_fns
.GetHead() ? label
: _T("Live");
8117 else if(m_iPlaybackMode
== PM_DVD
)
8127 buff
+= L
"\\0Music\\0";
8128 buff
+= title
.IsEmpty() ? L
"0" : L
"1";
8130 buff
+= author
.IsEmpty() ? L
"{0}" : L
"{0} - {1}";
8132 if(!author
.IsEmpty()) {buff
+= CStringW(author
) + L
"\\0";}
8133 buff
+= CStringW(title
) + L
"\\0";
8136 COPYDATASTRUCT data
;
8137 data
.dwData
= 0x0547;
8138 data
.lpData
= (PVOID
)(LPCWSTR
)buff
;
8139 data
.cbData
= buff
.GetLength() * 2 + 2;
8142 while(hWnd
= ::FindWindowEx(NULL
, hWnd
, _T("MsnMsgrUIManager"), NULL
))
8143 ::SendMessage(hWnd
, WM_COPYDATA
, (WPARAM
)NULL
, (LPARAM
)&data
);
8148 void CMainFrame::SendNowPlayingTomIRC()
8150 if(!AfxGetAppSettings().fNotifyGTSdll
)
8153 for(int i
= 0; i
< 20; i
++)
8155 HANDLE hFMap
= CreateFileMapping(INVALID_HANDLE_VALUE
, NULL
, PAGE_READWRITE
, 0, 1024, _T("mIRC"));
8158 if(GetLastError() == ERROR_ALREADY_EXISTS
)
8165 if(LPVOID lpMappingAddress
= MapViewOfFile(hFMap
, FILE_MAP_WRITE
, 0, 0, 0))
8167 LPCSTR cmd
= m_fAudioOnly
? "/.timerAUDGTS 1 5 mpcaud" : "/.timerVIDGTS 1 5 mpcvid";
8168 strcpy((char*)lpMappingAddress
, cmd
);
8170 if(HWND hWnd
= ::FindWindow(_T("mIRC"), NULL
))
8171 ::SendMessage(hWnd
, (WM_USER
+ 200), (WPARAM
)1, (LPARAM
)0);
8173 UnmapViewOfFile(lpMappingAddress
);
8184 void CMainFrame::SetupOpenCDSubMenu()
8186 CMenu
* pSub
= &m_opencds
;
8188 if(!IsMenu(pSub
->m_hMenu
)) pSub
->CreatePopupMenu();
8189 else while(pSub
->RemoveMenu(0, MF_BYPOSITION
));
8191 if(m_iMediaLoadState
== MLS_LOADING
) return;
8193 if(AfxGetAppSettings().fHideCDROMsSubMenu
) return;
8195 UINT id
= ID_FILE_OPEN_CD_START
;
8197 for(TCHAR drive
= 'C'; drive
<= 'Z'; drive
++)
8199 CString label
= GetDriveLabel(drive
), str
;
8201 CAtlList
<CString
> files
;
8202 switch(GetCDROMType(drive
, files
))
8205 if(label
.IsEmpty()) label
= _T("Audio CD");
8206 str
.Format(_T("%s (%c:)"), label
, drive
);
8209 if(label
.IsEmpty()) label
= _T("(S)VCD");
8210 str
.Format(_T("%s (%c:)"), label
, drive
);
8212 case CDROM_DVDVideo
:
8213 if(label
.IsEmpty()) label
= _T("DVD Video");
8214 str
.Format(_T("%s (%c:)"), label
, drive
);
8221 pSub
->AppendMenu(MF_BYCOMMAND
|MF_STRING
|MF_ENABLED
, id
++, str
);
8225 void CMainFrame::SetupFiltersSubMenu()
8227 CMenu
* pSub
= &m_filters
;
8229 if(!IsMenu(pSub
->m_hMenu
)) pSub
->CreatePopupMenu();
8230 else while(pSub
->RemoveMenu(0, MF_BYPOSITION
));
8232 m_filterpopups
.RemoveAll();
8234 m_pparray
.RemoveAll();
8235 m_ssarray
.RemoveAll();
8237 if(m_iMediaLoadState
== MLS_LOADED
)
8240 UINT ids
= ID_FILTERS_SUBITEM_START
;
8241 UINT idl
= ID_FILTERSTREAMS_SUBITEM_START
;
8243 BeginEnumFilters(pGB
, pEF
, pBF
)
8245 CString
name(GetFilterName(pBF
));
8246 if(name
.GetLength() >= 43) name
= name
.Left(40) + _T("...");
8248 CLSID clsid
= GetCLSID(pBF
);
8249 if(clsid
== CLSID_AVIDec
)
8251 CComPtr
<IPin
> pPin
= GetFirstPin(pBF
);
8253 if(pPin
&& SUCCEEDED(pPin
->ConnectionMediaType(&mt
)))
8255 DWORD c
= ((VIDEOINFOHEADER
*)mt
.pbFormat
)->bmiHeader
.biCompression
;
8258 case BI_RGB
: name
+= _T(" (RGB)"); break;
8259 case BI_RLE4
: name
+= _T(" (RLE4)"); break;
8260 case BI_RLE8
: name
+= _T(" (RLE8)"); break;
8261 case BI_BITFIELDS
: name
+= _T(" (BITF)"); break;
8262 default: name
.Format(_T("%s (%c%c%c%c)"),
8263 CString(name
), (TCHAR
)((c
>>0)&0xff), (TCHAR
)((c
>>8)&0xff), (TCHAR
)((c
>>16)&0xff), (TCHAR
)((c
>>24)&0xff)); break;
8267 else if(clsid
== CLSID_ACMWrapper
)
8269 CComPtr
<IPin
> pPin
= GetFirstPin(pBF
);
8271 if(pPin
&& SUCCEEDED(pPin
->ConnectionMediaType(&mt
)))
8273 WORD c
= ((WAVEFORMATEX
*)mt
.pbFormat
)->wFormatTag
;
8274 name
.Format(_T("%s (0x%04x)"), CString(name
), (int)c
);
8277 else if(clsid
== __uuidof(CTextPassThruFilter
) || clsid
== __uuidof(CNullTextRenderer
)
8278 || clsid
== GUIDFromCString(_T("{48025243-2D39-11CE-875D-00608CB78066}"))) // ISCR
8284 CAutoPtr
<CMenu
> pSubSub(new CMenu
);
8285 pSubSub
->CreatePopupMenu();
8289 CComQIPtr
<ISpecifyPropertyPages
> pSPP
= pBF
;
8294 caGUID.pElems = NULL;
8295 if(SUCCEEDED(pSPP->GetPages(&caGUID)) && caGUID.cElems > 0)
8297 */ m_pparray
.Add(pBF
);
8298 pSubSub
->AppendMenu(MF_BYCOMMAND
|MF_STRING
|MF_ENABLED
, ids
, _T("&Properties..."));
8300 if(caGUID.pElems) CoTaskMemFree(caGUID.pElems);
8306 BeginEnumPins(pBF
, pEP
, pPin
)
8308 CString name
= GetPinName(pPin
);
8309 name
.Replace(_T("&"), _T("&&"));
8314 caGUID
.pElems
= NULL
;
8315 if(SUCCEEDED(pSPP
->GetPages(&caGUID
)) && caGUID
.cElems
> 0)
8317 m_pparray
.Add(pPin
);
8318 pSubSub
->AppendMenu(MF_BYCOMMAND
|MF_STRING
|MF_ENABLED
, ids
+nPPages
, name
+ _T(" (pin) properties..."));
8320 if(caGUID
.pElems
) CoTaskMemFree(caGUID
.pElems
);
8328 CComQIPtr
<IAMStreamSelect
> pSS
= pBF
;
8331 DWORD nStreams
= 0, flags
, group
, prevgroup
= -1;
8333 WCHAR
* wname
= NULL
;
8334 CComPtr
<IUnknown
> pObj
, pUnk
;
8336 pSS
->Count(&nStreams
);
8338 if(nStreams
> 0 && nPPages
> 0) pSubSub
->AppendMenu(MF_SEPARATOR
|MF_ENABLED
);
8340 UINT idlstart
= idl
;
8342 for(DWORD i
= 0; i
< nStreams
; i
++, pObj
= NULL
, pUnk
= NULL
)
8348 pSS
->Info(i
, NULL
, &flags
, &lcid
, &group
, &wname
, &pObj
, &pUnk
);
8350 if(group
!= prevgroup
&& idl
> idlstart
)
8351 pSubSub
->AppendMenu(MF_SEPARATOR
|MF_ENABLED
);
8354 if(flags
& AMSTREAMSELECTINFO_EXCLUSIVE
)
8357 else if(flags
& AMSTREAMSELECTINFO_ENABLED
)
8363 CStringW
stream(L
"Unknown Stream");
8364 wname
= (WCHAR
*)CoTaskMemAlloc((stream
.GetLength()+3+1)*sizeof(WCHAR
));
8365 swprintf(wname
, L
"%s %d", stream
, min(i
+1,999));
8368 CString
name(wname
);
8369 name
.Replace(_T("&"), _T("&&"));
8371 pSubSub
->AppendMenu(MF_BYCOMMAND
|MF_STRING
|MF_ENABLED
, idl
++, name
);
8373 CoTaskMemFree(wname
);
8376 if(nStreams
== 0) pSS
.Release();
8379 if(nPPages
== 1 && !pSS
)
8381 pSub
->AppendMenu(MF_BYCOMMAND
|MF_STRING
|MF_ENABLED
, ids
, name
);
8385 pSub
->AppendMenu(MF_BYPOSITION
|MF_STRING
|MF_DISABLED
|MF_GRAYED
, idf
, name
);
8387 if(nPPages
> 0 || pSS
)
8390 mii
.cbSize
= sizeof(mii
);
8391 mii
.fMask
= MIIM_STATE
|MIIM_SUBMENU
;
8392 mii
.fType
= MF_POPUP
;
8393 mii
.hSubMenu
= pSubSub
->m_hMenu
;
8394 mii
.fState
= (pSPP
|| pSS
) ? MF_ENABLED
: (MF_DISABLED
|MF_GRAYED
);
8395 pSub
->SetMenuItemInfo(idf
, &mii
, TRUE
);
8397 m_filterpopups
.Add(pSubSub
);
8408 void CMainFrame::SetupAudioSwitcherSubMenu()
8410 CMenu
* pSub
= &m_audios
;
8412 if(!IsMenu(pSub
->m_hMenu
)) pSub
->CreatePopupMenu();
8413 else while(pSub
->RemoveMenu(0, MF_BYPOSITION
));
8415 if(m_iMediaLoadState
== MLS_LOADED
)
8417 UINT id
= ID_AUDIO_SUBITEM_START
;
8419 CComQIPtr
<IAMStreamSelect
> pSS
= FindFilter(__uuidof(CAudioSwitcherFilter
), pGB
);
8420 if(!pSS
) pSS
= FindFilter(L
"{D3CD7858-971A-4838-ACEC-40CA5D529DC8}", pGB
);
8425 if(SUCCEEDED(pSS
->Count(&cStreams
)) && cStreams
> 0)
8427 pSub
->AppendMenu(MF_BYCOMMAND
|MF_STRING
|MF_ENABLED
, id
++, ResStr(IDS_SUBTITLES_OPTIONS
));
8428 pSub
->AppendMenu(MF_SEPARATOR
|MF_ENABLED
);
8430 for(int i
= 0; i
< (int)cStreams
; i
++)
8432 WCHAR
* pName
= NULL
;
8433 if(FAILED(pSS
->Info(i
, NULL
, NULL
, NULL
, NULL
, &pName
, NULL
, NULL
)))
8436 CString
name(pName
);
8437 name
.Replace(_T("&"), _T("&&"));
8439 pSub
->AppendMenu(MF_BYCOMMAND
|MF_STRING
|MF_ENABLED
, id
++, name
);
8441 CoTaskMemFree(pName
);
8448 void CMainFrame::SetupSubtitlesSubMenu()
8450 CMenu
* pSub
= &m_subtitles
;
8452 if(!IsMenu(pSub
->m_hMenu
)) pSub
->CreatePopupMenu();
8453 else while(pSub
->RemoveMenu(0, MF_BYPOSITION
));
8455 if(m_iMediaLoadState
!= MLS_LOADED
|| m_fAudioOnly
|| !m_pCAP
)
8458 UINT id
= ID_SUBTITLES_SUBITEM_START
;
8460 POSITION pos
= m_pSubStreams
.GetHeadPosition();
8464 pSub
->AppendMenu(MF_BYCOMMAND
|MF_STRING
|MF_ENABLED
, id
++, ResStr(IDS_SUBTITLES_OPTIONS
));
8465 pSub
->AppendMenu(MF_BYCOMMAND
|MF_STRING
|MF_ENABLED
, id
++, ResStr(IDS_SUBTITLES_STYLES
));
8466 pSub
->AppendMenu(MF_BYCOMMAND
|MF_STRING
|MF_ENABLED
, id
++, ResStr(IDS_SUBTITLES_RELOAD
));
8467 pSub
->AppendMenu(MF_SEPARATOR
);
8469 pSub
->AppendMenu(MF_BYCOMMAND
|MF_STRING
|MF_ENABLED
, id
++, ResStr(IDS_SUBTITLES_ENABLE
));
8470 pSub
->AppendMenu(MF_SEPARATOR
);
8475 CComPtr
<ISubStream
> pSubStream
= m_pSubStreams
.GetNext(pos
);
8476 if(!pSubStream
) continue;
8478 for(int i
= 0, j
= pSubStream
->GetStreamCount(); i
< j
; i
++)
8480 WCHAR
* pName
= NULL
;
8481 if(SUCCEEDED(pSubStream
->GetStreamInfo(i
, &pName
, NULL
)))
8483 CString
name(pName
);
8484 name
.Replace(_T("&"), _T("&&"));
8486 pSub
->AppendMenu(MF_BYCOMMAND
|MF_STRING
|MF_ENABLED
, id
++, name
);
8487 CoTaskMemFree(pName
);
8491 pSub
->AppendMenu(MF_BYCOMMAND
|MF_STRING
|MF_ENABLED
, id
++, _T("<Unknown>"));
8495 // TODO: find a better way to group these entries
8496 if(pos
&& m_pSubStreams
.GetAt(pos
))
8499 pSubStream
->GetClassID(&cur
);
8500 m_pSubStreams
.GetAt(pos
)->GetClassID(&next
);
8503 pSub
->AppendMenu(MF_SEPARATOR
);
8508 void CMainFrame::SetupNavAudioSubMenu()
8510 CMenu
* pSub
= &m_navaudio
;
8512 if(!IsMenu(pSub
->m_hMenu
)) pSub
->CreatePopupMenu();
8513 else while(pSub
->RemoveMenu(0, MF_BYPOSITION
));
8515 if(m_iMediaLoadState
!= MLS_LOADED
) return;
8517 UINT id
= ID_NAVIGATE_AUDIO_SUBITEM_START
;
8519 if(m_iPlaybackMode
== PM_FILE
)
8521 SetupNavStreamSelectSubMenu(pSub
, id
, 1);
8523 else if(m_iPlaybackMode
== PM_DVD
)
8525 ULONG ulStreamsAvailable
, ulCurrentStream
;
8526 if(FAILED(pDVDI
->GetCurrentAudio(&ulStreamsAvailable
, &ulCurrentStream
)))
8530 DVD_AUDIO_LANG_EXT ext
;
8531 if(FAILED(pDVDI
->GetDefaultAudioLanguage(&DefLanguage
, &ext
)))
8534 for(ULONG i
= 0; i
< ulStreamsAvailable
; i
++)
8537 if(FAILED(pDVDI
->GetAudioLanguage(i
, &Language
)))
8540 UINT flags
= MF_BYCOMMAND
|MF_STRING
|MF_ENABLED
;
8541 if(Language
== DefLanguage
) flags
|= MF_DEFAULT
;
8542 if(i
== ulCurrentStream
) flags
|= MF_CHECKED
;
8544 CString
str(_T("Unknown"));
8547 int len
= GetLocaleInfo(Language
, LOCALE_SENGLANGUAGE
, str
.GetBuffer(256), 256);
8548 str
.ReleaseBufferSetLength(max(len
-1, 0));
8551 DVD_AudioAttributes ATR
;
8552 if(SUCCEEDED(pDVDI
->GetAudioAttributes(i
, &ATR
)))
8554 switch(ATR
.LanguageExtension
)
8556 case DVD_AUD_EXT_NotSpecified
:
8558 case DVD_AUD_EXT_Captions
: str
+= _T(" (Captions)"); break;
8559 case DVD_AUD_EXT_VisuallyImpaired
: str
+= _T(" (Visually Impaired)"); break;
8560 case DVD_AUD_EXT_DirectorComments1
: str
+= _T(" (Director Comments 1)"); break;
8561 case DVD_AUD_EXT_DirectorComments2
: str
+= _T(" (Director Comments 2)"); break;
8565 switch(ATR
.AudioFormat
)
8567 case DVD_AudioFormat_AC3
: format
= _T("AC3"); break;
8568 case DVD_AudioFormat_MPEG1
:
8569 case DVD_AudioFormat_MPEG1_DRC
: format
= _T("MPEG1"); break;
8570 case DVD_AudioFormat_MPEG2
:
8571 case DVD_AudioFormat_MPEG2_DRC
: format
= _T("MPEG2"); break;
8572 case DVD_AudioFormat_LPCM
: format
= _T("LPCM"); break;
8573 case DVD_AudioFormat_DTS
: format
= _T("DTS"); break;
8574 case DVD_AudioFormat_SDDS
: format
= _T("SDDS"); break;
8577 if(!format
.IsEmpty())
8579 str
.Format(_T("%s, %s %dHz %dbits %d channel(s)"),
8584 ATR
.bNumberOfChannels
);
8588 str
.Replace(_T("&"), _T("&&"));
8590 pSub
->AppendMenu(flags
, id
++, str
);
8595 void CMainFrame::SetupNavSubtitleSubMenu()
8597 CMenu
* pSub
= &m_navsubtitle
;
8599 if(!IsMenu(pSub
->m_hMenu
)) pSub
->CreatePopupMenu();
8600 else while(pSub
->RemoveMenu(0, MF_BYPOSITION
));
8602 if(m_iMediaLoadState
!= MLS_LOADED
) return;
8604 UINT id
= ID_NAVIGATE_SUBP_SUBITEM_START
;
8606 if(m_iPlaybackMode
== PM_FILE
)
8608 SetupNavStreamSelectSubMenu(pSub
, id
, 2);
8610 else if(m_iPlaybackMode
== PM_DVD
)
8612 ULONG ulStreamsAvailable
, ulCurrentStream
;
8614 if(FAILED(pDVDI
->GetCurrentSubpicture(&ulStreamsAvailable
, &ulCurrentStream
, &bIsDisabled
))
8615 || ulStreamsAvailable
== 0)
8619 DVD_SUBPICTURE_LANG_EXT ext
;
8620 if(FAILED(pDVDI
->GetDefaultSubpictureLanguage(&DefLanguage
, &ext
)))
8623 pSub
->AppendMenu(MF_BYCOMMAND
|MF_STRING
|(bIsDisabled
?0:MF_CHECKED
), id
++, _T("Enabled"));
8624 pSub
->AppendMenu(MF_BYCOMMAND
|MF_SEPARATOR
|MF_ENABLED
);
8626 for(ULONG i
= 0; i
< ulStreamsAvailable
; i
++)
8629 if(FAILED(pDVDI
->GetSubpictureLanguage(i
, &Language
)))
8632 UINT flags
= MF_BYCOMMAND
|MF_STRING
|MF_ENABLED
;
8633 if(Language
== DefLanguage
) flags
|= MF_DEFAULT
;
8634 if(i
== ulCurrentStream
) flags
|= MF_CHECKED
;
8636 CString
str(_T("Unknown"));
8639 int len
= GetLocaleInfo(Language
, LOCALE_SENGLANGUAGE
, str
.GetBuffer(256), 256);
8640 str
.ReleaseBufferSetLength(max(len
-1, 0));
8643 DVD_SubpictureAttributes ATR
;
8644 if(SUCCEEDED(pDVDI
->GetSubpictureAttributes(i
, &ATR
)))
8646 switch(ATR
.LanguageExtension
)
8648 case DVD_SP_EXT_NotSpecified
:
8650 case DVD_SP_EXT_Caption_Normal
: str
+= _T(""); break;
8651 case DVD_SP_EXT_Caption_Big
: str
+= _T(" (Big)"); break;
8652 case DVD_SP_EXT_Caption_Children
: str
+= _T(" (Children)"); break;
8653 case DVD_SP_EXT_CC_Normal
: str
+= _T(" (CC)"); break;
8654 case DVD_SP_EXT_CC_Big
: str
+= _T(" (CC Big)"); break;
8655 case DVD_SP_EXT_CC_Children
: str
+= _T(" (CC Children)"); break;
8656 case DVD_SP_EXT_Forced
: str
+= _T(" (Forced)"); break;
8657 case DVD_SP_EXT_DirectorComments_Normal
: str
+= _T(" (Director Comments)"); break;
8658 case DVD_SP_EXT_DirectorComments_Big
: str
+= _T(" (Director Comments, Big)"); break;
8659 case DVD_SP_EXT_DirectorComments_Children
: str
+= _T(" (Director Comments, Children)"); break;
8663 str
.Replace(_T("&"), _T("&&"));
8665 pSub
->AppendMenu(flags
, id
++, str
);
8670 void CMainFrame::SetupNavAngleSubMenu()
8672 CMenu
* pSub
= &m_navangle
;
8674 if(!IsMenu(pSub
->m_hMenu
)) pSub
->CreatePopupMenu();
8675 else while(pSub
->RemoveMenu(0, MF_BYPOSITION
));
8677 if(m_iMediaLoadState
!= MLS_LOADED
) return;
8679 UINT id
= ID_NAVIGATE_ANGLE_SUBITEM_START
;
8681 if(m_iPlaybackMode
== PM_FILE
)
8683 SetupNavStreamSelectSubMenu(pSub
, id
, 0);
8685 else if(m_iPlaybackMode
== PM_DVD
)
8687 ULONG ulStreamsAvailable
, ulCurrentStream
;
8688 if(FAILED(pDVDI
->GetCurrentAngle(&ulStreamsAvailable
, &ulCurrentStream
)))
8691 if(ulStreamsAvailable
< 2) return; // one choice is not a choice...
8693 for(ULONG i
= 1; i
<= ulStreamsAvailable
; i
++)
8695 UINT flags
= MF_BYCOMMAND
|MF_STRING
|MF_ENABLED
;
8696 if(i
== ulCurrentStream
) flags
|= MF_CHECKED
;
8699 str
.Format(_T("Angle %d"), i
);
8701 pSub
->AppendMenu(flags
, id
++, str
);
8706 void CMainFrame::SetupNavChaptersSubMenu()
8708 CMenu
* pSub
= &m_navchapters
;
8710 if(!IsMenu(pSub
->m_hMenu
)) pSub
->CreatePopupMenu();
8711 else while(pSub
->RemoveMenu(0, MF_BYPOSITION
));
8713 if(m_iMediaLoadState
!= MLS_LOADED
)
8716 UINT id
= ID_NAVIGATE_CHAP_SUBITEM_START
;
8718 if(m_iPlaybackMode
== PM_FILE
)
8722 REFERENCE_TIME rt
= GetPos();
8723 DWORD j
= m_pCB
->ChapLookup(&rt
, NULL
);
8725 for(DWORD i
= 0; i
< m_pCB
->ChapGetCount(); i
++, id
++)
8729 if(FAILED(m_pCB
->ChapGet(i
, &rt
, &bstr
)))
8732 int s
= (int)((rt
/10000000)%60);
8733 int m
= (int)((rt
/10000000/60)%60);
8734 int h
= (int)((rt
/10000000/60/60));
8737 time
.Format(_T("[%02d:%02d:%02d] "), h
, m
, s
);
8739 CString name
= CString(bstr
);
8740 name
.Replace(_T("&"), _T("&&"));
8741 name
.Replace(_T("\t"), _T(" "));
8743 UINT flags
= MF_BYCOMMAND
|MF_STRING
|MF_ENABLED
;
8744 if(i
== j
) flags
|= MF_CHECKED
;
8745 if(id
!= ID_NAVIGATE_CHAP_SUBITEM_START
&& i
== 0) pSub
->AppendMenu(MF_SEPARATOR
);
8746 pSub
->AppendMenu(flags
, id
, name
+ '\t' + time
);
8749 if(m_wndPlaylistBar
.GetCount() > 1)
8751 POSITION pos
= m_wndPlaylistBar
.m_pl
.GetHeadPosition();
8754 UINT flags
= MF_BYCOMMAND
|MF_STRING
|MF_ENABLED
;
8755 if(pos
== m_wndPlaylistBar
.m_pl
.GetPos()) flags
|= MF_CHECKED
;
8756 if(id
!= ID_NAVIGATE_CHAP_SUBITEM_START
&& pos
== m_wndPlaylistBar
.m_pl
.GetHeadPosition())
8757 pSub
->AppendMenu(MF_SEPARATOR
);
8758 CPlaylistItem
& pli
= m_wndPlaylistBar
.m_pl
.GetNext(pos
);
8759 CString name
= pli
.GetLabel();
8760 name
.Replace(_T("&"), _T("&&"));
8761 pSub
->AppendMenu(flags
, id
++, name
);
8765 else if(m_iPlaybackMode
== PM_DVD
)
8767 ULONG ulNumOfVolumes
, ulVolume
;
8769 ULONG ulNumOfTitles
= 0;
8770 pDVDI
->GetDVDVolumeInfo(&ulNumOfVolumes
, &ulVolume
, &Side
, &ulNumOfTitles
);
8772 DVD_PLAYBACK_LOCATION2 Location
;
8773 pDVDI
->GetCurrentLocation(&Location
);
8775 ULONG ulNumOfChapters
= 0;
8776 pDVDI
->GetNumberOfChapters(Location
.TitleNum
, &ulNumOfChapters
);
8779 pDVDI
->GetCurrentUOPS(&ulUOPs
);
8781 for(ULONG i
= 1; i
<= ulNumOfTitles
; i
++)
8783 UINT flags
= MF_BYCOMMAND
|MF_STRING
|MF_ENABLED
;
8784 if(i
== Location
.TitleNum
) flags
|= MF_CHECKED
;
8785 if(ulUOPs
&UOP_FLAG_Play_Title
) flags
|= MF_DISABLED
|MF_GRAYED
;
8788 str
.Format(_T("Title %d"), i
);
8790 pSub
->AppendMenu(flags
, id
++, str
);
8793 for(ULONG i
= 1; i
<= ulNumOfChapters
; i
++)
8795 UINT flags
= MF_BYCOMMAND
|MF_STRING
|MF_ENABLED
;
8796 if(i
== Location
.ChapterNum
) flags
|= MF_CHECKED
;
8797 if(ulUOPs
&UOP_FLAG_Play_Chapter
) flags
|= MF_DISABLED
|MF_GRAYED
;
8798 if(i
== 1) flags
|= MF_MENUBARBREAK
;
8801 str
.Format(_T("Chapter %d"), i
);
8803 pSub
->AppendMenu(flags
, id
++, str
);
8808 void CMainFrame::SetupNavStreamSelectSubMenu(CMenu
* pSub
, UINT id
, DWORD dwSelGroup
)
8812 CComQIPtr
<IAMStreamSelect
> pSS
= FindFilter(CLSID_OggSplitter
, pGB
);
8813 if(!pSS
) pSS
= FindFilter(L
"{55DA30FC-F16B-49fc-BAA5-AE59FC65F82D}", pGB
);
8817 if(FAILED(pSS
->Count(&cStreams
)))
8820 DWORD dwPrevGroup
= -1;
8822 for(int i
= 0, j
= cStreams
; i
< j
; i
++)
8824 DWORD dwFlags
, dwGroup
;
8826 WCHAR
* pszName
= NULL
;
8828 if(FAILED(pSS
->Info(i
, NULL
, &dwFlags
, &lcid
, &dwGroup
, &pszName
, NULL
, NULL
))
8832 CString
name(pszName
);
8833 CString lcname
= CString(name
).MakeLower();
8835 if(pszName
) CoTaskMemFree(pszName
);
8837 if(dwGroup
!= dwSelGroup
)
8840 if(dwPrevGroup
!= -1 && dwPrevGroup
!= dwGroup
)
8841 pSub
->AppendMenu(MF_SEPARATOR
);
8842 dwPrevGroup
= dwGroup
;
8846 if(lcname
.Find(_T(" off")) >= 0)
8848 str
= _T("Disabled");
8854 str
.Format(_T("Unknown %d"), id
- baseid
);
8858 int len
= GetLocaleInfo(lcid
, LOCALE_SENGLANGUAGE
, str
.GetBuffer(64), 64);
8859 str
.ReleaseBufferSetLength(max(len
-1, 0));
8862 CString lcstr
= CString(str
).MakeLower();
8864 if(str
.IsEmpty() || lcname
.Find(lcstr
) >= 0) str
= name
;
8865 else if(!name
.IsEmpty()) str
= CString(name
) + _T(" (") + str
+ _T(")");
8868 UINT flags
= MF_BYCOMMAND
|MF_STRING
|MF_ENABLED
;
8869 if(dwFlags
) flags
|= MF_CHECKED
;
8871 str
.Replace(_T("&"), _T("&&"));
8872 pSub
->AppendMenu(flags
, id
++, str
);
8876 void CMainFrame::OnNavStreamSelectSubMenu(UINT id
, DWORD dwSelGroup
)
8878 CComQIPtr
<IAMStreamSelect
> pSS
= FindFilter(CLSID_OggSplitter
, pGB
);
8879 if(!pSS
) pSS
= FindFilter(L
"{55DA30FC-F16B-49fc-BAA5-AE59FC65F82D}", pGB
);
8883 if(FAILED(pSS
->Count(&cStreams
)))
8886 for(int i
= 0, j
= cStreams
; i
< j
; i
++)
8888 DWORD dwFlags
, dwGroup
;
8890 WCHAR
* pszName
= NULL
;
8892 if(FAILED(pSS
->Info(i
, NULL
, &dwFlags
, &lcid
, &dwGroup
, &pszName
, NULL
, NULL
))
8896 if(pszName
) CoTaskMemFree(pszName
);
8898 if(dwGroup
!= dwSelGroup
)
8903 pSS
->Enable(i
, AMSTREAMSELECTENABLE_ENABLE
);
8911 void CMainFrame::SetupFavoritesSubMenu()
8913 CMenu
* pSub
= &m_favorites
;
8915 if(!IsMenu(pSub
->m_hMenu
)) pSub
->CreatePopupMenu();
8916 else while(pSub
->RemoveMenu(0, MF_BYPOSITION
));
8918 AppSettings
& s
= AfxGetAppSettings();
8920 pSub
->AppendMenu(MF_BYCOMMAND
|MF_STRING
|MF_ENABLED
, ID_FAVORITES_ADD
, ResStr(IDS_FAVORITES_ADD
));
8921 pSub
->AppendMenu(MF_BYCOMMAND
|MF_STRING
|MF_ENABLED
, ID_FAVORITES_ORGANIZE
, ResStr(IDS_FAVORITES_ORGANIZE
));
8923 int nLastGroupStart
= pSub
->GetMenuItemCount();
8925 UINT id
= ID_FAVORITES_FILE_START
;
8927 CAtlList
<CString
> sl
;
8928 AfxGetAppSettings().GetFav(FAV_FILE
, sl
);
8930 POSITION pos
= sl
.GetHeadPosition();
8933 UINT flags
= MF_BYCOMMAND
|MF_STRING
|MF_ENABLED
;
8935 CString str
= sl
.GetNext(pos
);
8936 str
.Replace(_T("&"), _T("&&"));
8937 str
.Replace(_T("\t"), _T(" "));
8939 CAtlList
<CString
> sl
;
8940 Explode(str
, sl
, ';', 2);
8942 str
= sl
.RemoveHead();
8946 REFERENCE_TIME rt
= 0;
8947 if(1 == _stscanf(sl
.GetHead(), _T("%I64d"), &rt
) && rt
> 0)
8949 DVD_HMSF_TIMECODE hmsf
= RT2HMSF(rt
, 0);
8950 str
.Format(_T("%s\t[%02d:%02d:%02d]"), CString(str
), hmsf
.bHours
, hmsf
.bMinutes
, hmsf
.bSeconds
);
8955 pSub
->AppendMenu(flags
, id
, str
);
8960 if(id
> ID_FAVORITES_FILE_START
)
8961 pSub
->InsertMenu(nLastGroupStart
, MF_SEPARATOR
|MF_ENABLED
|MF_BYPOSITION
);
8963 nLastGroupStart
= pSub
->GetMenuItemCount();
8965 id
= ID_FAVORITES_DVD_START
;
8967 AfxGetAppSettings().GetFav(FAV_DVD
, sl
);
8969 pos
= sl
.GetHeadPosition();
8972 UINT flags
= MF_BYCOMMAND
|MF_STRING
|MF_ENABLED
;
8974 CString str
= sl
.GetNext(pos
);
8975 str
.Replace(_T("&"), _T("&&"));
8977 CAtlList
<CString
> sl
;
8978 Explode(str
, sl
, ';', 2);
8980 str
= sl
.RemoveHead();
8988 pSub
->AppendMenu(flags
, id
, str
);
8993 if(id
> ID_FAVORITES_DVD_START
)
8994 pSub
->InsertMenu(nLastGroupStart
, MF_SEPARATOR
|MF_ENABLED
|MF_BYPOSITION
);
8996 nLastGroupStart
= pSub
->GetMenuItemCount();
8998 id
= ID_FAVORITES_DEVICE_START
;
9000 AfxGetAppSettings().GetFav(FAV_DEVICE
, sl
);
9002 pos
= sl
.GetHeadPosition();
9005 UINT flags
= MF_BYCOMMAND
|MF_STRING
|MF_ENABLED
;
9007 CString str
= sl
.GetNext(pos
);
9008 str
.Replace(_T("&"), _T("&&"));
9010 CAtlList
<CString
> sl
;
9011 Explode(str
, sl
, ';', 2);
9013 str
= sl
.RemoveHead();
9016 pSub
->AppendMenu(flags
, id
, str
);
9022 void CMainFrame::SetupShadersSubMenu()
9024 CMenu
* pSub
= &m_shaders
;
9026 if(!IsMenu(pSub
->m_hMenu
)) pSub
->CreatePopupMenu();
9027 else while(pSub
->RemoveMenu(0, MF_BYPOSITION
));
9029 CWinApp
* pApp
= AfxGetApp();
9031 pSub
->AppendMenu(MF_BYCOMMAND
|MF_STRING
|MF_ENABLED
, ID_SHADERS_START
, ResStr(IDS_SHADER_OFF
));
9033 UINT id
= ID_SHADERS_START
+1;
9035 if(POSITION pos
= AfxGetAppSettings().m_shaders
.GetHeadPosition())
9037 pSub
->AppendMenu(MF_BYCOMMAND
|MF_STRING
|MF_ENABLED
, id
++, ResStr(IDS_SHADER_COMBINE
));
9038 pSub
->AppendMenu(MF_BYCOMMAND
|MF_STRING
|MF_ENABLED
, id
++, ResStr(IDS_SHADER_EDIT
));
9039 pSub
->AppendMenu(MF_SEPARATOR
);
9042 memset(&mii
, 0, sizeof(mii
));
9043 mii
.cbSize
= sizeof(mii
);
9044 mii
.fMask
|= MIIM_DATA
;
9048 const AppSettings::Shader
& s
= AfxGetAppSettings().m_shaders
.GetNext(pos
);
9049 CString label
= s
.label
;
9050 label
.Replace(_T("&"), _T("&&"));
9051 pSub
->AppendMenu(MF_BYCOMMAND
|MF_STRING
|MF_ENABLED
, id
, label
);
9052 mii
.dwItemData
= (ULONG_PTR
)&s
;
9053 pSub
->SetMenuItemInfo(id
, &mii
);
9061 void CMainFrame::ShowControls(int nCS
, bool fSave
)
9063 int nCSprev
= AfxGetAppSettings().nCS
;
9064 int hbefore
= 0, hafter
= 0;
9068 POSITION pos
= m_bars
.GetHeadPosition();
9069 for(int i
= 1; pos
; i
<<= 1)
9071 CControlBar
* pNext
= m_bars
.GetNext(pos
);
9072 ShowControlBar(pNext
, !!(nCS
&i
), TRUE
);
9073 if(nCS
&i
) m_pLastBar
= pNext
;
9075 CSize s
= pNext
->CalcFixedLayout(FALSE
, TRUE
);
9076 if(nCSprev
&i
) hbefore
+= s
.cy
;
9077 if(nCS
&i
) hafter
+= s
.cy
;
9081 wp
.length
= sizeof(wp
);
9082 GetWindowPlacement(&wp
);
9084 if(wp
.showCmd
!= SW_SHOWMAXIMIZED
&& !m_fFullScreen
)
9088 MoveWindow(r
.left
, r
.top
, r
.Width(), r
.Height()+(hafter
-hbefore
));
9092 AfxGetAppSettings().nCS
= nCS
;
9097 void CMainFrame::SetAlwaysOnTop(int i
)
9099 AfxGetAppSettings().iOnTop
= i
;
9103 const CWnd
* pInsertAfter
= NULL
;
9106 pInsertAfter
= &wndNoTopMost
;
9108 pInsertAfter
= &wndTopMost
;
9110 pInsertAfter
= GetMediaState() == State_Running
? &wndTopMost
: &wndNoTopMost
;
9112 SetWindowPos(pInsertAfter
, 0, 0, 0, 0, SWP_NOMOVE
|SWP_NOSIZE
|SWP_NOACTIVATE
);
9114 else if(!(GetWindowLong(m_hWnd
, GWL_EXSTYLE
)&WS_EX_TOPMOST
))
9116 SetWindowPos(&wndTopMost
, 0, 0, 0, 0, SWP_NOMOVE
|SWP_NOSIZE
|SWP_NOACTIVATE
);
9120 void CMainFrame::AddTextPassThruFilter()
9122 BeginEnumFilters(pGB
, pEF
, pBF
)
9124 if(!IsSplitter(pBF
)) continue;
9126 BeginEnumPins(pBF
, pEP
, pPin
)
9128 CComPtr
<IPin
> pPinTo
;
9130 if(FAILED(pPin
->ConnectedTo(&pPinTo
)) || !pPinTo
9131 || FAILED(pPin
->ConnectionMediaType(&mt
))
9132 || mt
.majortype
!= MEDIATYPE_Text
&& mt
.majortype
!= MEDIATYPE_Subtitle
)
9135 CComQIPtr
<IBaseFilter
> pTPTF
= new CTextPassThruFilter(this);
9137 name
.Format(L
"TextPassThru%08x", pTPTF
);
9138 if(FAILED(pGB
->AddFilter(pTPTF
, name
)))
9143 hr
= pPinTo
->Disconnect();
9144 hr
= pPin
->Disconnect();
9146 if(FAILED(hr
= pGB
->ConnectDirect(pPin
, GetFirstPin(pTPTF
, PINDIR_INPUT
), NULL
))
9147 || FAILED(hr
= pGB
->ConnectDirect(GetFirstPin(pTPTF
, PINDIR_OUTPUT
), pPinTo
, NULL
)))
9148 hr
= pGB
->ConnectDirect(pPin
, pPinTo
, NULL
);
9150 m_pSubStreams
.AddTail(CComQIPtr
<ISubStream
>(pTPTF
));
9157 bool CMainFrame::LoadSubtitle(CString fn
)
9159 CComPtr
<ISubStream
> pSubStream
;
9161 // TMP: maybe this will catch something for those who get a runtime error dialog when opening subtitles from cds
9166 CAutoPtr
<CVobSubFile
> p(new CVobSubFile(&m_csSubLock
));
9167 if(CString(CPath(fn
).GetExtension()).MakeLower() == _T(".idx") && p
&& p
->Open(fn
) && p
->GetStreamCount() > 0)
9168 pSubStream
= p
.Detach();
9173 CAutoPtr
<ssf::CRenderer
> p(new ssf::CRenderer(&m_csSubLock
));
9174 if(p
&& p
->Open(fn
) && p
->GetStreamCount() > 0)
9175 pSubStream
= p
.Detach();
9180 CAutoPtr
<CRenderedTextSubtitle
> p(new CRenderedTextSubtitle(&m_csSubLock
));
9181 if(p
&& p
->Open(fn
, DEFAULT_CHARSET
) && p
->GetStreamCount() > 0)
9182 pSubStream
= p
.Detach();
9185 catch(CException
* e
)
9192 m_pSubStreams
.AddTail(pSubStream
);
9195 return(!!pSubStream
);
9198 void CMainFrame::UpdateSubtitle(bool fApplyDefStyle
)
9202 int i
= m_iSubtitleSel
;
9204 POSITION pos
= m_pSubStreams
.GetHeadPosition();
9205 while(pos
&& i
>= 0)
9207 CComPtr
<ISubStream
> pSubStream
= m_pSubStreams
.GetNext(pos
);
9209 if(i
< pSubStream
->GetStreamCount())
9211 CAutoLock
cAutoLock(&m_csSubLock
);
9212 pSubStream
->SetStream(i
);
9213 SetSubtitle(pSubStream
, fApplyDefStyle
);
9217 i
-= pSubStream
->GetStreamCount();
9220 m_pCAP
->SetSubPicProvider(NULL
);
9223 void CMainFrame::SetSubtitle(ISubStream
* pSubStream
, bool fApplyDefStyle
)
9225 AppSettings
& s
= AfxGetAppSettings();
9230 pSubStream
->GetClassID(&clsid
);
9232 if(clsid
== __uuidof(CVobSubFile
))
9234 CVobSubFile
* pVSF
= (CVobSubFile
*)(ISubStream
*)pSubStream
;
9238 pVSF
->SetAlignment(s
.fOverridePlacement
, s
.nHorPos
, s
.nVerPos
, 1, 1);
9241 else if(clsid
== __uuidof(CVobSubStream
))
9243 CVobSubStream
* pVSS
= (CVobSubStream
*)(ISubStream
*)pSubStream
;
9247 pVSS
->SetAlignment(s
.fOverridePlacement
, s
.nHorPos
, s
.nVerPos
, 1, 1);
9250 else if(clsid
== __uuidof(CRenderedTextSubtitle
))
9252 CRenderedTextSubtitle
* pRTS
= (CRenderedTextSubtitle
*)(ISubStream
*)pSubStream
;
9256 if(fApplyDefStyle
|| pRTS
->m_fUsingAutoGeneratedDefaultStyle
)
9258 style
= s
.subdefstyle
;
9260 if(s
.fOverridePlacement
)
9262 style
.scrAlignment
= 2;
9263 int w
= pRTS
->m_dstScreenSize
.cx
;
9264 int h
= pRTS
->m_dstScreenSize
.cy
;
9265 int mw
= w
- style
.marginRect
.left
- style
.marginRect
.right
;
9266 style
.marginRect
.bottom
= h
- MulDiv(h
, s
.nVerPos
, 100);
9267 style
.marginRect
.left
= MulDiv(w
, s
.nHorPos
, 100) - mw
/2;
9268 style
.marginRect
.right
= w
- (style
.marginRect
.left
+ mw
);
9271 pRTS
->SetDefaultStyle(style
);
9274 if(pRTS
->GetDefaultStyle(style
) && style
.relativeTo
== 2)
9276 style
.relativeTo
= s
.subdefstyle
.relativeTo
;
9277 pRTS
->SetDefaultStyle(style
);
9286 m_iSubtitleSel
= -1;
9293 POSITION pos
= m_pSubStreams
.GetHeadPosition();
9296 CComPtr
<ISubStream
> pSubStream2
= m_pSubStreams
.GetNext(pos
);
9298 if(pSubStream
== pSubStream2
)
9300 m_iSubtitleSel
= i
+ pSubStream2
->GetStream();
9304 i
+= pSubStream2
->GetStreamCount();
9310 m_nSubtitleId
= (DWORD_PTR
)pSubStream
;
9314 m_pCAP
->SetSubPicProvider(CComQIPtr
<ISubPicProvider
>(pSubStream
));
9315 m_wndSubresyncBar
.SetSubtitle(pSubStream
, m_pCAP
->GetFPS());
9319 void CMainFrame::ReplaceSubtitle(ISubStream
* pSubStreamOld
, ISubStream
* pSubStreamNew
)
9321 POSITION pos
= m_pSubStreams
.GetHeadPosition();
9325 if(pSubStreamOld
== m_pSubStreams
.GetNext(pos
))
9327 m_pSubStreams
.SetAt(cur
, pSubStreamNew
);
9334 void CMainFrame::InvalidateSubtitle(DWORD_PTR nSubtitleId
, REFERENCE_TIME rtInvalidate
)
9338 if(nSubtitleId
== -1 || nSubtitleId
== m_nSubtitleId
)
9339 m_pCAP
->Invalidate(rtInvalidate
);
9343 void CMainFrame::ReloadSubtitle()
9345 POSITION pos
= m_pSubStreams
.GetHeadPosition();
9346 while(pos
) m_pSubStreams
.GetNext(pos
)->Reload();
9350 REFERENCE_TIME
CMainFrame::GetPos()
9352 return(m_iMediaLoadState
== MLS_LOADED
? m_wndSeekBar
.GetPos() : 0);
9355 REFERENCE_TIME
CMainFrame::GetDur()
9357 __int64 start
, stop
;
9358 m_wndSeekBar
.GetRange(start
, stop
);
9359 return(m_iMediaLoadState
== MLS_LOADED
? stop
: 0);
9362 void CMainFrame::SeekTo(REFERENCE_TIME rtPos
, bool fSeekToKeyFrame
)
9364 OAFilterState fs
= GetMediaState();
9366 if(rtPos
< 0) rtPos
= 0;
9368 if(m_iPlaybackMode
== PM_FILE
)
9370 if(fs
== State_Stopped
)
9371 SendMessage(WM_COMMAND
, ID_PLAY_PAUSE
);
9377 if(!m_kfs
.IsEmpty())
9379 int i
= rangebsearch(rtPos
, m_kfs
);
9380 if(i
>= 0 && i
< m_kfs
.GetCount())
9385 hr
= pMS
->SetPositions(&rtPos
, AM_SEEKING_AbsolutePositioning
, NULL
, AM_SEEKING_NoPositioning
);
9387 else if(m_iPlaybackMode
== PM_DVD
&& m_iDVDDomain
== DVD_DOMAIN_Title
)
9389 if(fs
!= State_Running
)
9390 SendMessage(WM_COMMAND
, ID_PLAY_PLAY
);
9392 DVD_HMSF_TIMECODE tc
= RT2HMSF(rtPos
);
9393 pDVDC
->PlayAtTime(&tc
, DVD_CMD_FLAG_Block
|DVD_CMD_FLAG_Flush
, NULL
);
9395 // if(fs != State_Running)
9396 // SendMessage(WM_COMMAND, ID_PLAY_PAUSE);
9398 else if(m_iPlaybackMode
== PM_CAPTURE
)
9400 TRACE(_T("Warning (CMainFrame::SeekTo): Trying to seek in capture mode"));
9403 m_fEndOfStream
= false;
9406 void CMainFrame::CleanGraph()
9410 BeginEnumFilters(pGB
, pEF
, pBF
)
9412 CComQIPtr
<IAMFilterMiscFlags
> pAMMF(pBF
);
9413 if(pAMMF
&& (pAMMF
->GetMiscFlags()&AM_FILTER_MISC_FLAGS_IS_SOURCE
))
9416 // some capture filters forget to set AM_FILTER_MISC_FLAGS_IS_SOURCE
9417 // or to implement the IAMFilterMiscFlags interface
9418 if(pBF
== pVidCap
|| pBF
== pAudCap
)
9421 if(CComQIPtr
<IFileSourceFilter
>(pBF
))
9424 int nIn
, nOut
, nInC
, nOutC
;
9425 if(CountPins(pBF
, nIn
, nOut
, nInC
, nOutC
) > 0 && (nInC
+nOutC
) == 0)
9427 TRACE(CStringW(L
"Removing: ") + GetFilterName(pBF
) + '\n');
9429 pGB
->RemoveFilter(pBF
);
9436 #define AUDIOBUFFERLEN 500
9438 static void SetLatency(IBaseFilter
* pBF
, int cbBuffer
)
9440 BeginEnumPins(pBF
, pEP
, pPin
)
9442 if(CComQIPtr
<IAMBufferNegotiation
> pAMBN
= pPin
)
9444 ALLOCATOR_PROPERTIES ap
;
9445 ap
.cbAlign
= -1; // -1 means no preference.
9446 ap
.cbBuffer
= cbBuffer
;
9449 pAMBN
->SuggestAllocatorProperties(&ap
);
9455 HRESULT
CMainFrame::BuildCapture(IPin
* pPin
, IBaseFilter
* pBF
[3], const GUID
& majortype
, AM_MEDIA_TYPE
* pmt
)
9457 IBaseFilter
* pBuff
= pBF
[0];
9458 IBaseFilter
* pEnc
= pBF
[1];
9459 IBaseFilter
* pMux
= pBF
[2];
9461 if(!pPin
|| !pMux
) return E_FAIL
;
9468 if(FAILED(pMux
->QueryFilterInfo(&fi
)) || !fi
.pGraph
)
9469 pGB
->AddFilter(pMux
, L
"Multiplexer");
9471 CStringW prefix
, prefixl
;
9472 if(majortype
== MEDIATYPE_Video
) prefix
= L
"Video ";
9473 else if(majortype
== MEDIATYPE_Audio
) prefix
= L
"Audio ";
9475 prefixl
.MakeLower();
9479 hr
= pGB
->AddFilter(pBuff
, prefix
+ L
"Buffer");
9482 err
= _T("Can't add ") + CString(prefixl
) + _T("buffer filter");
9487 hr
= pGB
->ConnectFilter(pPin
, pBuff
);
9490 err
= _T("Error connecting the ") + CString(prefixl
) + _T("buffer filter");
9495 pPin
= GetFirstPin(pBuff
, PINDIR_OUTPUT
);
9500 hr
= pGB
->AddFilter(pEnc
, prefix
+ L
"Encoder");
9503 err
= _T("Can't add ") + CString(prefixl
) + _T("encoder filter");
9508 hr
= pGB
->ConnectFilter(pPin
, pEnc
);
9511 err
= _T("Error connecting the ") + CString(prefixl
) + _T("encoder filter");
9516 pPin
= GetFirstPin(pEnc
, PINDIR_OUTPUT
);
9518 if(CComQIPtr
<IAMStreamConfig
> pAMSC
= pPin
)
9520 if(pmt
->majortype
== majortype
)
9522 hr
= pAMSC
->SetFormat(pmt
);
9525 err
= _T("Can't set compression format on the ") + CString(prefixl
) + _T("encoder filter");
9536 hr
= pGB
->ConnectFilter(pPin
, pMux
);
9539 err
= _T("Error connecting ") + CString(prefixl
) + _T(" to the muliplexer filter");
9550 bool CMainFrame::BuildToCapturePreviewPin(
9551 IBaseFilter
* pVidCap
, IPin
** ppVidCapPin
, IPin
** ppVidPrevPin
,
9552 IBaseFilter
* pAudCap
, IPin
** ppAudCapPin
, IPin
** ppAudPrevPin
)
9556 *ppVidCapPin
= *ppVidPrevPin
= NULL
;
9557 *ppAudCapPin
= *ppAudPrevPin
= NULL
;
9559 CComPtr
<IPin
> pDVAudPin
;
9564 if(!pAudCap
// only look for interleaved stream when we don't use any other audio capture source
9565 && SUCCEEDED(pCGB
->FindPin(pVidCap
, PINDIR_OUTPUT
, &PIN_CATEGORY_CAPTURE
, &MEDIATYPE_Interleaved
, TRUE
, 0, &pPin
)))
9567 CComPtr
<IBaseFilter
> pDVSplitter
;
9568 hr
= pDVSplitter
.CoCreateInstance(CLSID_DVSplitter
);
9569 hr
= pGB
->AddFilter(pDVSplitter
, L
"DV Splitter");
9571 hr
= pCGB
->RenderStream(NULL
, &MEDIATYPE_Interleaved
, pPin
, NULL
, pDVSplitter
);
9574 hr
= pCGB
->FindPin(pDVSplitter
, PINDIR_OUTPUT
, NULL
, &MEDIATYPE_Video
, TRUE
, 0, &pPin
);
9575 hr
= pCGB
->FindPin(pDVSplitter
, PINDIR_OUTPUT
, NULL
, &MEDIATYPE_Audio
, TRUE
, 0, &pDVAudPin
);
9577 CComPtr
<IBaseFilter
> pDVDec
;
9578 hr
= pDVDec
.CoCreateInstance(CLSID_DVVideoCodec
);
9579 hr
= pGB
->AddFilter(pDVDec
, L
"DV Video Decoder");
9581 hr
= pGB
->ConnectFilter(pPin
, pDVDec
);
9584 hr
= pCGB
->FindPin(pDVDec
, PINDIR_OUTPUT
, NULL
, &MEDIATYPE_Video
, TRUE
, 0, &pPin
);
9586 else if(SUCCEEDED(pCGB
->FindPin(pVidCap
, PINDIR_OUTPUT
, &PIN_CATEGORY_CAPTURE
, &MEDIATYPE_Video
, TRUE
, 0, &pPin
)))
9591 AfxMessageBox(_T("No video capture pin was found"));
9595 CComPtr
<IBaseFilter
> pSmartTee
;
9596 hr
= pSmartTee
.CoCreateInstance(CLSID_SmartTee
);
9597 hr
= pGB
->AddFilter(pSmartTee
, L
"Smart Tee (video)");
9599 hr
= pGB
->ConnectFilter(pPin
, pSmartTee
);
9601 hr
= pSmartTee
->FindPin(L
"Preview", ppVidPrevPin
);
9602 hr
= pSmartTee
->FindPin(L
"Capture", ppVidCapPin
);
9605 if(pAudCap
|| pDVAudPin
)
9612 else if(SUCCEEDED(pCGB
->FindPin(pAudCap
, PINDIR_OUTPUT
, &PIN_CATEGORY_CAPTURE
, &MEDIATYPE_Audio
, TRUE
, 0, &pPin
)))
9617 AfxMessageBox(_T("No audio capture pin was found"));
9621 CComPtr
<IBaseFilter
> pSmartTee
;
9622 hr
= pSmartTee
.CoCreateInstance(CLSID_SmartTee
);
9623 hr
= pGB
->AddFilter(pSmartTee
, L
"Smart Tee (audio)");
9625 hr
= pGB
->ConnectFilter(pPin
, pSmartTee
);
9627 hr
= pSmartTee
->FindPin(L
"Preview", ppAudPrevPin
);
9628 hr
= pSmartTee
->FindPin(L
"Capture", ppAudCapPin
);
9634 bool CMainFrame::BuildGraphVideoAudio(int fVPreview
, bool fVCapture
, int fAPreview
, bool fACapture
)
9636 if(!pCGB
) return(false);
9642 pGB
->NukeDownstream(pVidCap
);
9643 pGB
->NukeDownstream(pAudCap
);
9647 if(pAMVSCCap
) hr
= pAMVSCCap
->SetFormat(&m_wndCaptureBar
.m_capdlg
.m_mtv
);
9648 if(pAMVSCPrev
) hr
= pAMVSCPrev
->SetFormat(&m_wndCaptureBar
.m_capdlg
.m_mtv
);
9649 if(pAMASC
) hr
= pAMASC
->SetFormat(&m_wndCaptureBar
.m_capdlg
.m_mta
);
9651 CComPtr
<IBaseFilter
> pVidBuffer
= m_wndCaptureBar
.m_capdlg
.m_pVidBuffer
;
9652 CComPtr
<IBaseFilter
> pAudBuffer
= m_wndCaptureBar
.m_capdlg
.m_pAudBuffer
;
9653 CComPtr
<IBaseFilter
> pVidEnc
= m_wndCaptureBar
.m_capdlg
.m_pVidEnc
;
9654 CComPtr
<IBaseFilter
> pAudEnc
= m_wndCaptureBar
.m_capdlg
.m_pAudEnc
;
9655 CComPtr
<IBaseFilter
> pMux
= m_wndCaptureBar
.m_capdlg
.m_pMux
;
9656 CComPtr
<IBaseFilter
> pDst
= m_wndCaptureBar
.m_capdlg
.m_pDst
;
9657 CComPtr
<IBaseFilter
> pAudMux
= m_wndCaptureBar
.m_capdlg
.m_pAudMux
;
9658 CComPtr
<IBaseFilter
> pAudDst
= m_wndCaptureBar
.m_capdlg
.m_pAudDst
;
9660 bool fFileOutput
= (pMux
&& pDst
) || (pAudMux
&& pAudDst
);
9661 bool fCapture
= (fVCapture
|| fACapture
);
9665 AM_MEDIA_TYPE
* pmt
= &m_wndCaptureBar
.m_capdlg
.m_mta
;
9666 int ms
= (fACapture
&& fFileOutput
&& m_wndCaptureBar
.m_capdlg
.m_fAudOutput
) ? AUDIOBUFFERLEN
: 60;
9667 if(pMux
!= pAudMux
&& fACapture
) SetLatency(pAudCap
, -1);
9668 else if(pmt
->pbFormat
) SetLatency(pAudCap
, ((WAVEFORMATEX
*)pmt
->pbFormat
)->nAvgBytesPerSec
* ms
/ 1000);
9671 CComPtr
<IPin
> pVidCapPin
, pVidPrevPin
, pAudCapPin
, pAudPrevPin
;
9672 BuildToCapturePreviewPin(pVidCap
, &pVidCapPin
, &pVidPrevPin
, pAudCap
, &pAudCapPin
, &pAudPrevPin
);
9676 bool fVidPrev
= pVidPrevPin
&& fVPreview
;
9677 bool fVidCap
= pVidCapPin
&& fVCapture
&& fFileOutput
&& m_wndCaptureBar
.m_capdlg
.m_fVidOutput
;
9679 if(fVPreview
== 2 && !fVidCap
&& pVidCapPin
)
9681 pVidPrevPin
= pVidCapPin
;
9688 pGB
->Render(pVidPrevPin
);
9689 pGB
->FindInterface(__uuidof(ISubPicAllocatorPresenter
), (void**)&m_pCAP
, TRUE
);
9694 IBaseFilter
* pBF
[3] = {pVidBuffer
, pVidEnc
, pMux
};
9695 HRESULT hr
= BuildCapture(pVidCapPin
, pBF
, MEDIATYPE_Video
, &m_wndCaptureBar
.m_capdlg
.m_mtcv
);
9699 pCGB
->FindInterface(&PIN_CATEGORY_CAPTURE
, &MEDIATYPE_Video
, pVidCap
, IID_IAMDroppedFrames
, (void**)&pAMDF
);
9704 bool fAudPrev
= pAudPrevPin
&& fAPreview
;
9705 bool fAudCap
= pAudCapPin
&& fACapture
&& fFileOutput
&& m_wndCaptureBar
.m_capdlg
.m_fAudOutput
;
9707 if(fAPreview
== 2 && !fAudCap
&& pAudCapPin
)
9709 pAudPrevPin
= pAudCapPin
;
9715 pGB
->Render(pAudPrevPin
);
9720 IBaseFilter
* pBF
[3] = {pAudBuffer
, pAudEnc
, pAudMux
? pAudMux
: pMux
};
9721 HRESULT hr
= BuildCapture(pAudCapPin
, pBF
, MEDIATYPE_Audio
, &m_wndCaptureBar
.m_capdlg
.m_mtca
);
9725 if((pVidCap
|| pAudCap
) && fCapture
&& fFileOutput
)
9729 hr
= pGB
->AddFilter(pDst
, L
"File Writer V/A");
9730 hr
= pGB
->ConnectFilter(GetFirstPin(pMux
, PINDIR_OUTPUT
), pDst
);
9733 if(CComQIPtr
<IConfigAviMux
> pCAM
= pMux
)
9735 int nIn
, nOut
, nInC
, nOutC
;
9736 CountPins(pMux
, nIn
, nOut
, nInC
, nOutC
);
9737 pCAM
->SetMasterStream(nInC
-1);
9738 // pCAM->SetMasterStream(-1);
9739 pCAM
->SetOutputCompatibilityIndex(FALSE
);
9742 if(CComQIPtr
<IConfigInterleaving
> pCI
= pMux
)
9744 // if(FAILED(pCI->put_Mode(INTERLEAVE_CAPTURE)))
9745 if(FAILED(pCI
->put_Mode(INTERLEAVE_NONE_BUFFERED
)))
9746 pCI
->put_Mode(INTERLEAVE_NONE
);
9748 REFERENCE_TIME rtInterleave
= 10000i64
*AUDIOBUFFERLEN
, rtPreroll
= 0;//10000i64*500
9749 pCI
->put_Interleaving(&rtInterleave
, &rtPreroll
);
9752 if(pMux
!= pAudMux
&& pAudMux
!= pAudDst
)
9754 hr
= pGB
->AddFilter(pAudDst
, L
"File Writer A");
9755 hr
= pGB
->ConnectFilter(GetFirstPin(pAudMux
, PINDIR_OUTPUT
), pAudDst
);
9759 REFERENCE_TIME stop
= MAX_TIME
;
9760 hr
= pCGB
->ControlStream(&PIN_CATEGORY_CAPTURE
, NULL
, NULL
, NULL
, &stop
, 0, 0); // stop in the infinite
9766 OpenSetupStatsBar();
9767 OpenSetupStatusBar();
9774 bool CMainFrame::StartCapture()
9776 if(!pCGB
|| m_fCapturing
) return(false);
9778 if(!m_wndCaptureBar
.m_capdlg
.m_pMux
&& !m_wndCaptureBar
.m_capdlg
.m_pDst
) return(false);
9782 ::SetPriorityClass(::GetCurrentProcess(), HIGH_PRIORITY_CLASS
);
9784 // rare to see two capture filters to support IAMPushSource at the same time...
9785 // hr = CComQIPtr<IAMGraphStreams>(pGB)->SyncUsingStreamOffset(TRUE); // TODO:
9787 BuildGraphVideoAudio(
9788 m_wndCaptureBar
.m_capdlg
.m_fVidPreview
, true,
9789 m_wndCaptureBar
.m_capdlg
.m_fAudPreview
, true);
9791 hr
= pME
->CancelDefaultHandling(EC_REPAINT
);
9793 SendMessage(WM_COMMAND
, ID_PLAY_PLAY
);
9795 m_fCapturing
= true;
9800 bool CMainFrame::StopCapture()
9802 if(!pCGB
|| !m_fCapturing
) return(false);
9804 if(!m_wndCaptureBar
.m_capdlg
.m_pMux
&& !m_wndCaptureBar
.m_capdlg
.m_pDst
) return(false);
9808 m_wndStatusBar
.SetStatusMessage(ResStr(IDS_CONTROLS_COMPLETING
));
9810 m_fCapturing
= false;
9812 BuildGraphVideoAudio(
9813 m_wndCaptureBar
.m_capdlg
.m_fVidPreview
, false,
9814 m_wndCaptureBar
.m_capdlg
.m_fAudPreview
, false);
9816 hr
= pME
->RestoreDefaultHandling(EC_REPAINT
);
9818 ::SetPriorityClass(::GetCurrentProcess(), AfxGetAppSettings().priority
);
9820 m_rtDurationOverride
= -1;
9827 void CMainFrame::ShowOptions(int idPage
)
9829 AppSettings
& s
= AfxGetAppSettings();
9831 CPPageSheet
options(ResStr(IDS_OPTIONS_CAPTION
), pGB
, this, idPage
);
9833 if(options
.DoModal() == IDOK
)
9836 SetAlwaysOnTop(s
.iOnTop
);
9838 m_wndView
.LoadLogo();
9844 void CMainFrame::StartWebServer(int nPort
)
9847 m_pWebServer
.Attach(new CWebServer(this, nPort
));
9850 void CMainFrame::StopWebServer()
9853 m_pWebServer
.Free();
9856 CString
CMainFrame::GetStatusMessage()
9859 m_wndStatusBar
.m_status
.GetWindowText(str
);
9863 void CMainFrame::SendStatusMessage(CString msg
, int nTimeOut
)
9865 KillTimer(TIMER_STATUSERASER
);
9867 m_playingmsg
.Empty();
9868 if(nTimeOut
<= 0) return;
9871 SetTimer(TIMER_STATUSERASER
, nTimeOut
, NULL
);
9874 void CMainFrame::OpenCurPlaylistItem(REFERENCE_TIME rtStart
)
9876 if(m_wndPlaylistBar
.GetCount() == 0)
9880 if(!m_wndPlaylistBar
.GetCur(pli
)) m_wndPlaylistBar
.SetFirst();
9881 if(!m_wndPlaylistBar
.GetCur(pli
)) return;
9883 CAutoPtr
<OpenMediaData
> p(m_wndPlaylistBar
.GetCurOMD(rtStart
));
9887 void CMainFrame::AddCurDevToPlaylist()
9889 if(m_iPlaybackMode
== PM_CAPTURE
)
9891 m_wndPlaylistBar
.Append(
9894 m_wndCaptureBar
.m_capdlg
.GetVideoInput(),
9895 m_wndCaptureBar
.m_capdlg
.GetVideoChannel(),
9896 m_wndCaptureBar
.m_capdlg
.GetAudioInput()
9901 static int s_fOpenedThruThread
= false;
9903 void CMainFrame::OpenMedia(CAutoPtr
<OpenMediaData
> pOMD
)
9906 if(OpenDeviceData
* p
= dynamic_cast<OpenDeviceData
*>(pOMD
.m_p
))
9908 if(m_iMediaLoadState
== MLS_LOADED
&& pAMTuner
9909 && m_VidDispName
== p
->DisplayName
[0] && m_AudDispName
== p
->DisplayName
[1])
9911 m_wndCaptureBar
.m_capdlg
.SetVideoInput(p
->vinput
);
9912 m_wndCaptureBar
.m_capdlg
.SetVideoChannel(p
->vchannel
);
9913 m_wndCaptureBar
.m_capdlg
.SetAudioInput(p
->ainput
);
9914 SendNowPlayingToMSN();
9915 SendNowPlayingTomIRC();
9920 if(m_iMediaLoadState
!= MLS_CLOSED
)
9923 m_iMediaLoadState
= MLS_LOADING
; // HACK: hides the logo
9925 AppSettings
& s
= AfxGetAppSettings();
9927 bool fUseThread
= true;
9929 if(OpenFileData
* p
= dynamic_cast<OpenFileData
*>(pOMD
.m_p
))
9931 if(p
->fns
.GetCount() > 0)
9933 engine_t e
= s
.Formats
.GetEngine(p
->fns
.GetHead());
9934 fUseThread
= e
== DirectShow
/*|| e == RealMedia || e == QuickTime*/;
9937 else if(OpenDeviceData
* p
= dynamic_cast<OpenDeviceData
*>(pOMD
.m_p
))
9942 if(m_pGraphThread
&& fUseThread
9943 && AfxGetAppSettings().fEnableWorkerThreadForOpening
)
9945 m_pGraphThread
->PostThreadMessage(CGraphThread::TM_OPEN
, 0, (LPARAM
)pOMD
.Detach());
9946 s_fOpenedThruThread
= true;
9950 OpenMediaPrivate(pOMD
);
9951 s_fOpenedThruThread
= false;
9955 void CMainFrame::CloseMedia()
9957 if(m_iMediaLoadState
== MLS_CLOSING
)
9959 TRACE(_T("WARNING: CMainFrame::CloseMedia() called twice or more\n"));
9963 int nTimeWaited
= 0;
9965 while(m_iMediaLoadState
== MLS_LOADING
)
9967 m_fOpeningAborted
= true;
9969 if(pGB
) pGB
->Abort(); // TODO: lock on graph objects somehow, this is not thread safe
9971 if(nTimeWaited
> 5*1000 && m_pGraphThread
)
9973 MessageBeep(MB_ICONEXCLAMATION
);
9974 TRACE(_T("CRITICAL ERROR: !!! Must kill opener thread !!!"));
9975 TerminateThread(m_pGraphThread
->m_hThread
, -1);
9976 m_pGraphThread
= (CGraphThread
*)AfxBeginThread(RUNTIME_CLASS(CGraphThread
));
9977 s_fOpenedThruThread
= false;
9986 m_fOpeningAborted
= false;
9988 m_closingmsg
.Empty();
9990 m_iMediaLoadState
= MLS_CLOSING
;
9992 OnFilePostClosemedia();
9994 if(m_pGraphThread
&& s_fOpenedThruThread
)
9997 m_pGraphThread
->PostThreadMessage(CGraphThread::TM_CLOSE
, 0, (LPARAM
)&e
);
9998 e
.Wait(); // either opening or closing has to be blocked to prevent reentering them, closing is the better choice
10002 CloseMediaPrivate();
10005 UnloadExternalObjects();
10012 IMPLEMENT_DYNCREATE(CGraphThread
, CWinThread
)
10014 BOOL
CGraphThread::InitInstance()
10017 return SUCCEEDED(CoInitialize(0)) ? TRUE
: FALSE
;
10020 int CGraphThread::ExitInstance()
10023 return __super::ExitInstance();
10026 BEGIN_MESSAGE_MAP(CGraphThread
, CWinThread
)
10027 ON_THREAD_MESSAGE(TM_EXIT
, OnExit
)
10028 ON_THREAD_MESSAGE(TM_OPEN
, OnOpen
)
10029 ON_THREAD_MESSAGE(TM_CLOSE
, OnClose
)
10032 void CGraphThread::OnExit(WPARAM wParam
, LPARAM lParam
)
10034 PostQuitMessage(0);
10035 if(CAMEvent
* e
= (CAMEvent
*)lParam
) e
->Set();
10038 void CGraphThread::OnOpen(WPARAM wParam
, LPARAM lParam
)
10042 CAutoPtr
<OpenMediaData
> pOMD((OpenMediaData
*)lParam
);
10043 m_pMainFrame
->OpenMediaPrivate(pOMD
);
10047 void CGraphThread::OnClose(WPARAM wParam
, LPARAM lParam
)
10049 if(m_pMainFrame
) m_pMainFrame
->CloseMediaPrivate();
10050 if(CAMEvent
* e
= (CAMEvent
*)lParam
) e
->Set();
10053 afx_msg
void CMainFrame::OnSubtitleDelay(UINT nID
)
10057 int oldDelay
= m_pCAP
->GetSubtitleDelay();
10059 if(nID
== ID_SUB_DELAY_DOWN
)
10060 newDelay
= oldDelay
-AfxGetAppSettings().nSubDelayInterval
;
10062 newDelay
= oldDelay
+AfxGetAppSettings().nSubDelayInterval
;
10064 SetSubtitleDelay(newDelay
);