MainFrm.cpp
上传用户:tangyu_668
上传日期:2014-02-27
资源大小:678k
文件大小:244k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. /* 
  2.  * Copyright (C) 2003-2006 Gabest
  3.  * http://www.gabest.org
  4.  *
  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)
  8.  *  any later version.
  9.  *   
  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.
  14.  *   
  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
  19.  *
  20.  */
  21. // MainFrm.cpp : implementation of the CMainFrame class
  22. //
  23. #include "stdafx.h"
  24. #include "mplayerc.h"
  25. #include "MainFrm.h"
  26. #include <math.h>
  27. #include <afxpriv.h>
  28. #include <atlconv.h>
  29. #include <atlrx.h>
  30. #include <atlsync.h>
  31. #include "OpenFileDlg.h"
  32. #include "OpenDlg.h"
  33. #include "SaveDlg.h"
  34. #include "GoToDlg.h"
  35. #include "PnSPresetsDlg.h"
  36. #include "MediaTypesDlg.h"
  37. #include "SaveTextFileDialog.h"
  38. #include "SaveThumbnailsDialog.h"
  39. #include "FavoriteAddDlg.h"
  40. #include "FavoriteOrganizeDlg.h"
  41. #include "ConvertDlg.h"
  42. #include "ShaderCombineDlg.h"
  43. #include <mtype.h>
  44. #include <Mpconfig.h>
  45. #include <ks.h>
  46. #include <ksmedia.h>
  47. #include <dvdevcod.h>
  48. #include <dsound.h>
  49. #include <initguid.h>
  50. #include <uuids.h>
  51. #include "......includemoreuuids.h"
  52. #include <Qnetwork.h>
  53. #include <qedit.h>
  54. #include "....DSUtilDSUtil.h"
  55. #include "FGManager.h"
  56. #include "textpassthrufilter.h"
  57. #include "....filtersfilters.h"
  58. #include "....filtersPinInfoWnd.h"
  59. #include "DX7AllocatorPresenter.h"
  60. #include "DX9AllocatorPresenter.h"
  61. #include "....subtitlesSSF.h"
  62. #define DEFCLIENTW 292
  63. #define DEFCLIENTH 200
  64. static UINT s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated"));
  65. static UINT WM_NOTIFYICON = RegisterWindowMessage(TEXT("MYWM_NOTIFYICON"));
  66. #include "....filterstransformvsfilterIDirectVobSub.h"
  67. class CSubClock : public CUnknown, public ISubClock
  68. {
  69. STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv)
  70. {
  71. return 
  72. QI(ISubClock)
  73. CUnknown::NonDelegatingQueryInterface(riid, ppv);
  74. }
  75. REFERENCE_TIME m_rt;
  76. public:
  77. CSubClock() : CUnknown(NAME("CSubClock"), NULL) {m_rt = 0;}
  78. DECLARE_IUNKNOWN;
  79. // ISubClock
  80. STDMETHODIMP SetTime(REFERENCE_TIME rt) {m_rt = rt; return S_OK;}
  81. STDMETHODIMP_(REFERENCE_TIME) GetTime() {return(m_rt);}
  82. };
  83. //
  84. #define SaveMediaState 
  85. OAFilterState __fs = GetMediaState(); 
  86.  
  87. REFERENCE_TIME __rt = 0; 
  88. if(m_iMediaLoadState == MLS_LOADED) __rt = GetPos(); 
  89.  
  90. if(__fs != State_Stopped) 
  91. SendMessage(WM_COMMAND, ID_PLAY_STOP); 
  92. #define RestoreMediaState 
  93. if(m_iMediaLoadState == MLS_LOADED) 
  94. SeekTo(__rt); 
  95.  
  96. if(__fs == State_Stopped) 
  97. SendMessage(WM_COMMAND, ID_PLAY_STOP); 
  98. else if(__fs == State_Paused) 
  99. SendMessage(WM_COMMAND, ID_PLAY_PAUSE); 
  100. else if(__fs == State_Running) 
  101. SendMessage(WM_COMMAND, ID_PLAY_PLAY); 
  102. /*
  103. #ifdef _DEBUG
  104. #define new DEBUG_NEW
  105. #undef THIS_FILE
  106. static char THIS_FILE[] = __FILE__;
  107. #endif
  108. */
  109. /////////////////////////////////////////////////////////////////////////////
  110. // CMainFrame
  111. IMPLEMENT_DYNAMIC(CMainFrame, CFrameWnd)
  112. BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
  113. ON_WM_CREATE()
  114. ON_WM_DESTROY()
  115. ON_WM_CLOSE()
  116. ON_REGISTERED_MESSAGE(s_uTaskbarRestart, OnTaskBarRestart)
  117. ON_REGISTERED_MESSAGE(WM_NOTIFYICON, OnNotifyIcon)
  118. ON_WM_SETFOCUS()
  119. ON_WM_GETMINMAXINFO()
  120. ON_WM_MOVE()
  121. ON_WM_MOVING()
  122. ON_WM_SIZE()
  123. ON_WM_SIZING()
  124. ON_MESSAGE_VOID(WM_DISPLAYCHANGE, OnDisplayChange)
  125. ON_WM_SYSCOMMAND()
  126. ON_WM_ACTIVATEAPP()
  127. ON_MESSAGE(WM_APPCOMMAND, OnAppCommand)
  128. ON_WM_TIMER()
  129. ON_MESSAGE(WM_GRAPHNOTIFY, OnGraphNotify)
  130. ON_MESSAGE(WM_REARRANGERENDERLESS, OnRepaintRenderLess)
  131. ON_MESSAGE(WM_RESUMEFROMSTATE, OnResumeFromState)
  132. ON_WM_LBUTTONDOWN()
  133. ON_WM_LBUTTONUP()
  134. ON_WM_LBUTTONDBLCLK()
  135. ON_WM_MBUTTONDOWN()
  136. ON_WM_MBUTTONUP()
  137. ON_WM_MBUTTONDBLCLK()
  138. ON_WM_RBUTTONDOWN()
  139. ON_WM_RBUTTONUP()
  140. ON_WM_RBUTTONDBLCLK()
  141. ON_MESSAGE(WM_XBUTTONDOWN, OnXButtonDown)
  142. ON_MESSAGE(WM_XBUTTONUP, OnXButtonUp)
  143. ON_MESSAGE(WM_XBUTTONDBLCLK, OnXButtonDblClk)
  144. ON_WM_MOUSEWHEEL()
  145. ON_WM_MOUSEMOVE()
  146. ON_WM_NCHITTEST()
  147. ON_WM_HSCROLL()
  148. ON_WM_INITMENU()
  149. ON_WM_INITMENUPOPUP()
  150. ON_COMMAND(ID_MENU_PLAYER_SHORT, OnMenuPlayerShort)
  151. ON_COMMAND(ID_MENU_PLAYER_LONG, OnMenuPlayerLong)
  152. ON_COMMAND(ID_MENU_FILTERS, OnMenuFilters)
  153. ON_UPDATE_COMMAND_UI(IDC_PLAYERSTATUS, OnUpdatePlayerStatus)
  154. ON_COMMAND(ID_FILE_POST_OPENMEDIA, OnFilePostOpenmedia)
  155. ON_UPDATE_COMMAND_UI(ID_FILE_POST_OPENMEDIA, OnUpdateFilePostOpenmedia)
  156. ON_COMMAND(ID_FILE_POST_CLOSEMEDIA, OnFilePostClosemedia)
  157. ON_UPDATE_COMMAND_UI(ID_FILE_POST_CLOSEMEDIA, OnUpdateFilePostClosemedia)
  158. ON_COMMAND(ID_BOSS, OnBossKey)
  159. ON_COMMAND_RANGE(ID_STREAM_AUDIO_NEXT, ID_STREAM_AUDIO_PREV, OnStreamAudio)
  160. ON_COMMAND_RANGE(ID_STREAM_SUB_NEXT, ID_STREAM_SUB_PREV, OnStreamSub)
  161. ON_COMMAND(ID_STREAM_SUB_ONOFF, OnStreamSubOnOff)
  162. ON_COMMAND_RANGE(ID_OGM_AUDIO_NEXT, ID_OGM_AUDIO_PREV, OnOgmAudio)
  163. ON_COMMAND_RANGE(ID_OGM_SUB_NEXT, ID_OGM_SUB_PREV, OnOgmSub)
  164. ON_COMMAND_RANGE(ID_DVD_ANGLE_NEXT, ID_DVD_ANGLE_PREV, OnDvdAngle)
  165. ON_COMMAND_RANGE(ID_DVD_AUDIO_NEXT, ID_DVD_AUDIO_PREV, OnDvdAudio)
  166. ON_COMMAND_RANGE(ID_DVD_SUB_NEXT, ID_DVD_SUB_PREV, OnDvdSub)
  167. ON_COMMAND(ID_DVD_SUB_ONOFF, OnDvdSubOnOff)
  168. ON_COMMAND(ID_FILE_OPENQUICK, OnFileOpenQuick)
  169. ON_UPDATE_COMMAND_UI(ID_FILE_OPENMEDIA, OnUpdateFileOpen)
  170. ON_COMMAND(ID_FILE_OPENMEDIA, OnFileOpenmedia)
  171. ON_UPDATE_COMMAND_UI(ID_FILE_OPENMEDIA, OnUpdateFileOpen)
  172. ON_WM_COPYDATA()
  173. ON_COMMAND(ID_FILE_OPENDVD, OnFileOpendvd)
  174. ON_UPDATE_COMMAND_UI(ID_FILE_OPENDVD, OnUpdateFileOpen)
  175. ON_COMMAND(ID_FILE_OPENDEVICE, OnFileOpendevice)
  176. ON_UPDATE_COMMAND_UI(ID_FILE_OPENDEVICE, OnUpdateFileOpen)
  177. ON_COMMAND_RANGE(ID_FILE_OPEN_CD_START, ID_FILE_OPEN_CD_END, OnFileOpenCD)
  178. ON_UPDATE_COMMAND_UI_RANGE(ID_FILE_OPEN_CD_START, ID_FILE_OPEN_CD_END, OnUpdateFileOpen)
  179. ON_WM_DROPFILES()
  180. ON_COMMAND(ID_FILE_SAVE_COPY, OnFileSaveAs)
  181. ON_UPDATE_COMMAND_UI(ID_FILE_SAVE_COPY, OnUpdateFileSaveAs)
  182. ON_COMMAND(ID_FILE_SAVE_IMAGE, OnFileSaveImage)
  183. ON_UPDATE_COMMAND_UI(ID_FILE_SAVE_IMAGE, OnUpdateFileSaveImage)
  184. ON_COMMAND(ID_FILE_SAVE_IMAGE_AUTO, OnFileSaveImageAuto)
  185. ON_UPDATE_COMMAND_UI(ID_FILE_SAVE_IMAGE_AUTO, OnUpdateFileSaveImage)
  186. ON_COMMAND(ID_FILE_SAVE_THUMBNAILS, OnFileSaveThumbnails)
  187. ON_UPDATE_COMMAND_UI(ID_FILE_SAVE_THUMBNAILS, OnUpdateFileSaveThumbnails)
  188. ON_COMMAND(ID_FILE_CONVERT, OnFileConvert)
  189. ON_UPDATE_COMMAND_UI(ID_FILE_CONVERT, OnUpdateFileConvert)
  190. ON_COMMAND(ID_FILE_LOAD_SUBTITLE, OnFileLoadsubtitle)
  191. ON_UPDATE_COMMAND_UI(ID_FILE_LOAD_SUBTITLE, OnUpdateFileLoadsubtitle)
  192. ON_COMMAND(ID_FILE_SAVE_SUBTITLE, OnFileSavesubtitle)
  193. ON_UPDATE_COMMAND_UI(ID_FILE_SAVE_SUBTITLE, OnUpdateFileSavesubtitle)
  194. ON_COMMAND(ID_FILE_ISDB_SEARCH, OnFileISDBSearch)
  195. ON_UPDATE_COMMAND_UI(ID_FILE_ISDB_SEARCH, OnUpdateFileISDBSearch)
  196. ON_COMMAND(ID_FILE_ISDB_UPLOAD, OnFileISDBUpload)
  197. ON_UPDATE_COMMAND_UI(ID_FILE_ISDB_UPLOAD, OnUpdateFileISDBUpload)
  198. ON_COMMAND(ID_FILE_ISDB_DOWNLOAD, OnFileISDBDownload)
  199. ON_UPDATE_COMMAND_UI(ID_FILE_ISDB_DOWNLOAD, OnUpdateFileISDBDownload)
  200. ON_COMMAND(ID_FILE_PROPERTIES, OnFileProperties)
  201. ON_UPDATE_COMMAND_UI(ID_FILE_PROPERTIES, OnUpdateFileProperties)
  202. ON_COMMAND(ID_FILE_CLOSEPLAYLIST, OnFileClosePlaylist)
  203. ON_COMMAND(ID_FILE_CLOSEMEDIA, OnFileCloseMedia)
  204. ON_UPDATE_COMMAND_UI(ID_FILE_CLOSEMEDIA, OnUpdateFileClose)
  205. ON_COMMAND(ID_VIEW_CAPTIONMENU, OnViewCaptionmenu)
  206. ON_UPDATE_COMMAND_UI(ID_VIEW_CAPTIONMENU, OnUpdateViewCaptionmenu)
  207. ON_COMMAND_RANGE(ID_VIEW_SEEKER, ID_VIEW_STATUS, OnViewControlBar)
  208. ON_UPDATE_COMMAND_UI_RANGE(ID_VIEW_SEEKER, ID_VIEW_STATUS, OnUpdateViewControlBar)
  209. ON_COMMAND(ID_VIEW_SUBRESYNC, OnViewSubresync)
  210. ON_UPDATE_COMMAND_UI(ID_VIEW_SUBRESYNC, OnUpdateViewSubresync)
  211. ON_COMMAND(ID_VIEW_PLAYLIST, OnViewPlaylist)
  212. ON_UPDATE_COMMAND_UI(ID_VIEW_PLAYLIST, OnUpdateViewPlaylist)
  213. ON_COMMAND(ID_VIEW_CAPTURE, OnViewCapture)
  214. ON_UPDATE_COMMAND_UI(ID_VIEW_CAPTURE, OnUpdateViewCapture)
  215. ON_COMMAND(ID_VIEW_SHADEREDITOR, OnViewShaderEditor)
  216. ON_UPDATE_COMMAND_UI(ID_VIEW_SHADEREDITOR, OnUpdateViewShaderEditor)
  217. ON_COMMAND(ID_VIEW_PRESETS_MINIMAL, OnViewMinimal)
  218. ON_UPDATE_COMMAND_UI(ID_VIEW_PRESETS_MINIMAL, OnUpdateViewMinimal)
  219. ON_COMMAND(ID_VIEW_PRESETS_COMPACT, OnViewCompact)
  220. ON_UPDATE_COMMAND_UI(ID_VIEW_PRESETS_COMPACT, OnUpdateViewCompact)
  221. ON_COMMAND(ID_VIEW_PRESETS_NORMAL, OnViewNormal)
  222. ON_UPDATE_COMMAND_UI(ID_VIEW_PRESETS_NORMAL, OnUpdateViewNormal)
  223. ON_COMMAND(ID_VIEW_FULLSCREEN, OnViewFullscreen)
  224. ON_COMMAND(ID_VIEW_FULLSCREEN_SECONDARY, OnViewFullscreenSecondary)
  225. ON_UPDATE_COMMAND_UI(ID_VIEW_FULLSCREEN, OnUpdateViewFullscreen)
  226. ON_COMMAND_RANGE(ID_VIEW_ZOOM_50, ID_VIEW_ZOOM_200, OnViewZoom)
  227. ON_UPDATE_COMMAND_UI_RANGE(ID_VIEW_ZOOM_50, ID_VIEW_ZOOM_200, OnUpdateViewZoom)
  228. ON_COMMAND(ID_VIEW_ZOOM_AUTOFIT, OnViewZoomAutoFit)
  229. ON_UPDATE_COMMAND_UI(ID_VIEW_ZOOM_AUTOFIT, OnUpdateViewZoom)
  230. ON_COMMAND_RANGE(ID_VIEW_VF_HALF, ID_VIEW_VF_FROMOUTSIDE, OnViewDefaultVideoFrame)
  231. ON_UPDATE_COMMAND_UI_RANGE(ID_VIEW_VF_HALF, ID_VIEW_VF_FROMOUTSIDE, OnUpdateViewDefaultVideoFrame)
  232. ON_COMMAND(ID_VIEW_VF_KEEPASPECTRATIO, OnViewKeepaspectratio)
  233. ON_UPDATE_COMMAND_UI(ID_VIEW_VF_KEEPASPECTRATIO, OnUpdateViewKeepaspectratio)
  234. ON_COMMAND(ID_VIEW_VF_COMPMONDESKARDIFF, OnViewCompMonDeskARDiff)
  235. ON_UPDATE_COMMAND_UI(ID_VIEW_VF_COMPMONDESKARDIFF, OnUpdateViewCompMonDeskARDiff)
  236. ON_COMMAND_RANGE(ID_VIEW_RESET, ID_PANSCAN_CENTER, OnViewPanNScan)
  237. ON_UPDATE_COMMAND_UI_RANGE(ID_VIEW_RESET, ID_PANSCAN_CENTER, OnUpdateViewPanNScan)
  238. ON_COMMAND_RANGE(ID_PANNSCAN_PRESETS_START, ID_PANNSCAN_PRESETS_END, OnViewPanNScanPresets)
  239. ON_UPDATE_COMMAND_UI_RANGE(ID_PANNSCAN_PRESETS_START, ID_PANNSCAN_PRESETS_END, OnUpdateViewPanNScanPresets)
  240. ON_COMMAND_RANGE(ID_PANSCAN_ROTATEXP, ID_PANSCAN_ROTATEZM, OnViewRotate)
  241. ON_UPDATE_COMMAND_UI_RANGE(ID_PANSCAN_ROTATEXP, ID_PANSCAN_ROTATEZM, OnUpdateViewRotate)
  242. ON_COMMAND_RANGE(ID_ASPECTRATIO_START, ID_ASPECTRATIO_END, OnViewAspectRatio)
  243. ON_UPDATE_COMMAND_UI_RANGE(ID_ASPECTRATIO_START, ID_ASPECTRATIO_END, OnUpdateViewAspectRatio)
  244. ON_COMMAND(ID_ASPECTRATIO_NEXT, OnViewAspectRatioNext)
  245. ON_COMMAND_RANGE(ID_ONTOP_NEVER, ID_ONTOP_WHILEPLAYING, OnViewOntop)
  246. ON_UPDATE_COMMAND_UI_RANGE(ID_ONTOP_NEVER, ID_ONTOP_WHILEPLAYING, OnUpdateViewOntop)
  247. ON_COMMAND(ID_VIEW_OPTIONS, OnViewOptions)
  248. ON_COMMAND(ID_PLAY_PLAY, OnPlayPlay)
  249. ON_COMMAND(ID_PLAY_PAUSE, OnPlayPause)
  250. ON_COMMAND(ID_PLAY_PLAYPAUSE, OnPlayPlaypause)
  251. ON_COMMAND(ID_PLAY_STOP, OnPlayStop)
  252. ON_UPDATE_COMMAND_UI(ID_PLAY_PLAY, OnUpdatePlayPauseStop)
  253. ON_UPDATE_COMMAND_UI(ID_PLAY_PAUSE, OnUpdatePlayPauseStop)
  254. ON_UPDATE_COMMAND_UI(ID_PLAY_PLAYPAUSE, OnUpdatePlayPauseStop)
  255. ON_UPDATE_COMMAND_UI(ID_PLAY_STOP, OnUpdatePlayPauseStop)
  256. ON_COMMAND_RANGE(ID_PLAY_FRAMESTEP, ID_PLAY_FRAMESTEPCANCEL, OnPlayFramestep)
  257. ON_UPDATE_COMMAND_UI_RANGE(ID_PLAY_FRAMESTEP, ID_PLAY_FRAMESTEPCANCEL, OnUpdatePlayFramestep)
  258. ON_COMMAND_RANGE(ID_PLAY_SEEKBACKWARDSMALL, ID_PLAY_SEEKFORWARDLARGE, OnPlaySeek)
  259. ON_COMMAND_RANGE(ID_PLAY_SEEKKEYBACKWARD, ID_PLAY_SEEKKEYFORWARD, OnPlaySeekKey)
  260. ON_UPDATE_COMMAND_UI_RANGE(ID_PLAY_SEEKBACKWARDSMALL, ID_PLAY_SEEKFORWARDLARGE, OnUpdatePlaySeek)
  261. ON_UPDATE_COMMAND_UI_RANGE(ID_PLAY_SEEKKEYBACKWARD, ID_PLAY_SEEKKEYFORWARD, OnUpdatePlaySeek)
  262. ON_COMMAND(ID_PLAY_GOTO, OnPlayGoto)
  263. ON_UPDATE_COMMAND_UI(ID_PLAY_GOTO, OnUpdateGoto)
  264. ON_COMMAND_RANGE(ID_PLAY_DECRATE, ID_PLAY_INCRATE, OnPlayChangeRate)
  265. ON_UPDATE_COMMAND_UI_RANGE(ID_PLAY_DECRATE, ID_PLAY_INCRATE, OnUpdatePlayChangeRate)
  266. ON_COMMAND(ID_PLAY_RESETRATE, OnPlayResetRate)
  267. ON_UPDATE_COMMAND_UI(ID_PLAY_RESETRATE, OnUpdatePlayResetRate)
  268. ON_COMMAND_RANGE(ID_PLAY_INCAUDDELAY, ID_PLAY_DECAUDDELAY, OnPlayChangeAudDelay)
  269. ON_UPDATE_COMMAND_UI_RANGE(ID_PLAY_INCAUDDELAY, ID_PLAY_DECAUDDELAY, OnUpdatePlayChangeAudDelay)
  270. ON_COMMAND_RANGE(ID_FILTERS_SUBITEM_START, ID_FILTERS_SUBITEM_END, OnPlayFilters)
  271. ON_UPDATE_COMMAND_UI_RANGE(ID_FILTERS_SUBITEM_START, ID_FILTERS_SUBITEM_END, OnUpdatePlayFilters)
  272. ON_COMMAND_RANGE(ID_SHADERS_START, ID_SHADERS_END, OnPlayShaders)
  273. ON_UPDATE_COMMAND_UI_RANGE(ID_SHADERS_START, ID_SHADERS_END, OnUpdatePlayShaders)
  274. ON_COMMAND_RANGE(ID_AUDIO_SUBITEM_START, ID_AUDIO_SUBITEM_END, OnPlayAudio)
  275. ON_UPDATE_COMMAND_UI_RANGE(ID_AUDIO_SUBITEM_START, ID_AUDIO_SUBITEM_END, OnUpdatePlayAudio)
  276. ON_COMMAND_RANGE(ID_SUBTITLES_SUBITEM_START, ID_SUBTITLES_SUBITEM_END, OnPlaySubtitles)
  277. ON_UPDATE_COMMAND_UI_RANGE(ID_SUBTITLES_SUBITEM_START, ID_SUBTITLES_SUBITEM_END, OnUpdatePlaySubtitles)
  278. ON_COMMAND_RANGE(ID_FILTERSTREAMS_SUBITEM_START, ID_FILTERSTREAMS_SUBITEM_END, OnPlayLanguage)
  279. ON_UPDATE_COMMAND_UI_RANGE(ID_FILTERSTREAMS_SUBITEM_START, ID_FILTERSTREAMS_SUBITEM_END, OnUpdatePlayLanguage)
  280. ON_COMMAND_RANGE(ID_VOLUME_UP, ID_VOLUME_MUTE, OnPlayVolume)
  281. ON_COMMAND_RANGE(ID_VOLUME_BOOST_INC, ID_VOLUME_BOOST_MAX, OnPlayVolumeBoost)
  282. ON_UPDATE_COMMAND_UI_RANGE(ID_VOLUME_BOOST_INC, ID_VOLUME_BOOST_MAX, OnUpdatePlayVolumeBoost)
  283. ON_COMMAND_RANGE(ID_AFTERPLAYBACK_CLOSE, ID_AFTERPLAYBACK_DONOTHING, OnAfterplayback)
  284. ON_UPDATE_COMMAND_UI_RANGE(ID_AFTERPLAYBACK_CLOSE, ID_AFTERPLAYBACK_DONOTHING, OnUpdateAfterplayback)
  285. ON_COMMAND_RANGE(ID_NAVIGATE_SKIPBACK, ID_NAVIGATE_SKIPFORWARD, OnNavigateSkip)
  286. ON_UPDATE_COMMAND_UI_RANGE(ID_NAVIGATE_SKIPBACK, ID_NAVIGATE_SKIPFORWARD, OnUpdateNavigateSkip)
  287. ON_COMMAND_RANGE(ID_NAVIGATE_SKIPBACKPLITEM, ID_NAVIGATE_SKIPFORWARDPLITEM, OnNavigateSkipPlaylistItem)
  288. ON_UPDATE_COMMAND_UI_RANGE(ID_NAVIGATE_SKIPBACKPLITEM, ID_NAVIGATE_SKIPFORWARDPLITEM, OnUpdateNavigateSkipPlaylistItem)
  289. ON_COMMAND_RANGE(ID_NAVIGATE_TITLEMENU, ID_NAVIGATE_CHAPTERMENU, OnNavigateMenu)
  290. ON_UPDATE_COMMAND_UI_RANGE(ID_NAVIGATE_TITLEMENU, ID_NAVIGATE_CHAPTERMENU, OnUpdateNavigateMenu)
  291. ON_COMMAND_RANGE(ID_NAVIGATE_AUDIO_SUBITEM_START, ID_NAVIGATE_AUDIO_SUBITEM_END, OnNavigateAudio)
  292. ON_COMMAND_RANGE(ID_NAVIGATE_SUBP_SUBITEM_START, ID_NAVIGATE_SUBP_SUBITEM_END, OnNavigateSubpic)
  293. ON_COMMAND_RANGE(ID_NAVIGATE_ANGLE_SUBITEM_START, ID_NAVIGATE_ANGLE_SUBITEM_END, OnNavigateAngle)
  294. ON_COMMAND_RANGE(ID_NAVIGATE_CHAP_SUBITEM_START, ID_NAVIGATE_CHAP_SUBITEM_END, OnNavigateChapters)
  295. ON_COMMAND_RANGE(ID_NAVIGATE_MENU_LEFT, ID_NAVIGATE_MENU_LEAVE, OnNavigateMenuItem)
  296. ON_UPDATE_COMMAND_UI_RANGE(ID_NAVIGATE_MENU_LEFT, ID_NAVIGATE_MENU_LEAVE, OnUpdateNavigateMenuItem)
  297. ON_COMMAND(ID_FAVORITES_ADD, OnFavoritesAdd)
  298. ON_UPDATE_COMMAND_UI(ID_FAVORITES_ADD, OnUpdateFavoritesAdd)
  299. ON_COMMAND(ID_FAVORITES_ORGANIZE, OnFavoritesOrganize)
  300. ON_UPDATE_COMMAND_UI(ID_FAVORITES_ORGANIZE, OnUpdateFavoritesOrganize)
  301. ON_COMMAND_RANGE(ID_FAVORITES_FILE_START, ID_FAVORITES_FILE_END, OnFavoritesFile)
  302. ON_UPDATE_COMMAND_UI_RANGE(ID_FAVORITES_FILE_START, ID_FAVORITES_FILE_END, OnUpdateFavoritesFile)
  303. ON_COMMAND_RANGE(ID_FAVORITES_DVD_START, ID_FAVORITES_DVD_END, OnFavoritesDVD)
  304. ON_UPDATE_COMMAND_UI_RANGE(ID_FAVORITES_DVD_START, ID_FAVORITES_DVD_END, OnUpdateFavoritesDVD)
  305. ON_COMMAND_RANGE(ID_FAVORITES_DEVICE_START, ID_FAVORITES_DEVICE_END, OnFavoritesDevice)
  306. ON_UPDATE_COMMAND_UI_RANGE(ID_FAVORITES_DEVICE_START, ID_FAVORITES_DEVICE_END, OnUpdateFavoritesDevice)
  307. ON_COMMAND(ID_HELP_HOMEPAGE, OnHelpHomepage)
  308. ON_COMMAND(ID_HELP_DOCUMENTATION, OnHelpDocumentation)
  309. ON_COMMAND(ID_HELP_DONATE, OnHelpDonate)
  310. END_MESSAGE_MAP()
  311. /////////////////////////////////////////////////////////////////////////////
  312. // CMainFrame construction/destruction
  313. #pragma warning(disable : 4355)
  314. CMainFrame::CMainFrame() : 
  315. m_dwRegister(0),
  316. m_iMediaLoadState(MLS_CLOSED),
  317. m_iPlaybackMode(PM_NONE),
  318. m_iSpeedLevel(0),
  319. m_rtDurationOverride(-1),
  320. m_fFullScreen(false),
  321. m_fHideCursor(false),
  322. m_lastMouseMove(-1, -1),
  323. m_pLastBar(NULL),
  324. m_nLoops(0),
  325. m_iSubtitleSel(-1),
  326. m_ZoomX(1), m_ZoomY(1), m_PosX(0.5), m_PosY(0.5),
  327. m_AngleX(0), m_AngleY(0), m_AngleZ(0),
  328. m_fCustomGraph(false),
  329. m_fRealMediaGraph(false), m_fShockwaveGraph(false), m_fQuicktimeGraph(false),
  330. m_fFrameSteppingActive(false),
  331. m_fEndOfStream(false),
  332. m_fCapturing(false),
  333. m_fLiveWM(false),
  334. m_fOpeningAborted(false),
  335. m_fBuffering(false),
  336. m_fileDropTarget(this),
  337. m_fTrayIcon(false)
  338. {
  339. }
  340. CMainFrame::~CMainFrame()
  341. {
  342. // m_owner.DestroyWindow();
  343. }
  344. int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
  345. {
  346. if(__super::OnCreate(lpCreateStruct) == -1)
  347. return -1;
  348. m_popup.LoadMenu(IDR_POPUP);
  349. m_popupmain.LoadMenu(IDR_POPUPMAIN);
  350. GetMenu()->ModifyMenu(ID_FAVORITES, MF_BYCOMMAND|MF_STRING, IDR_MAINFRAME, ResStr(IDS_FAVORITES_POPUP));
  351. // create a view to occupy the client area of the frame
  352. if(!m_wndView.Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,
  353. CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, NULL))
  354. {
  355. TRACE0("Failed to create view windown");
  356. return -1;
  357. }
  358. // static bars
  359. if(!m_wndStatusBar.Create(this)
  360. || !m_wndStatsBar.Create(this)
  361. || !m_wndInfoBar.Create(this)
  362. || !m_wndToolBar.Create(this)
  363. || !m_wndSeekBar.Create(this))
  364. {
  365. TRACE0("Failed to create all control barsn");
  366. return -1;      // fail to create
  367. }
  368. m_bars.AddTail(&m_wndSeekBar);
  369. m_bars.AddTail(&m_wndToolBar);
  370. m_bars.AddTail(&m_wndInfoBar);
  371. m_bars.AddTail(&m_wndStatsBar);
  372. m_bars.AddTail(&m_wndStatusBar);
  373. m_wndSeekBar.Enable(false);
  374. // dockable bars
  375. EnableDocking(CBRS_ALIGN_ANY);
  376. m_dockingbars.RemoveAll();
  377. m_wndSubresyncBar.Create(this, &m_csSubLock);
  378. m_wndSubresyncBar.SetBarStyle(m_wndSubresyncBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
  379. m_wndSubresyncBar.EnableDocking(CBRS_ALIGN_ANY);
  380. m_wndSubresyncBar.SetHeight(200);
  381. LoadControlBar(&m_wndSubresyncBar, AFX_IDW_DOCKBAR_TOP);
  382. m_wndPlaylistBar.Create(this);
  383. m_wndPlaylistBar.SetBarStyle(m_wndPlaylistBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
  384. m_wndPlaylistBar.EnableDocking(CBRS_ALIGN_ANY);
  385. m_wndPlaylistBar.SetHeight(100);
  386. LoadControlBar(&m_wndPlaylistBar, AFX_IDW_DOCKBAR_BOTTOM);
  387. m_wndPlaylistBar.LoadPlaylist();
  388. m_wndCaptureBar.Create(this);
  389. m_wndCaptureBar.SetBarStyle(m_wndCaptureBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
  390. m_wndCaptureBar.EnableDocking(CBRS_ALIGN_LEFT|CBRS_ALIGN_RIGHT);
  391. LoadControlBar(&m_wndCaptureBar, AFX_IDW_DOCKBAR_LEFT);
  392. m_wndShaderEditorBar.Create(this);
  393. m_wndShaderEditorBar.SetBarStyle(m_wndShaderEditorBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
  394. m_wndShaderEditorBar.EnableDocking(CBRS_ALIGN_ANY);
  395. LoadControlBar(&m_wndShaderEditorBar, AFX_IDW_DOCKBAR_TOP);
  396. m_fileDropTarget.Register(this);
  397. GetDesktopWindow()->GetWindowRect(&m_rcDesktop);
  398. AppSettings& s = AfxGetAppSettings();
  399. ShowControls(s.nCS);
  400. SetAlwaysOnTop(s.iOnTop);
  401. ShowTrayIcon(s.fTrayIcon);
  402. SetFocus();
  403. m_pGraphThread = (CGraphThread*)AfxBeginThread(RUNTIME_CLASS(CGraphThread));
  404. if(m_pGraphThread)
  405. m_pGraphThread->SetMainFrame(this);
  406. if(s.fEnableWebServer)
  407. StartWebServer(s.nWebServerPort);
  408. return 0;
  409. }
  410. void CMainFrame::OnDestroy()
  411. {
  412. ShowTrayIcon(false);
  413. m_fileDropTarget.Revoke();
  414. if(m_pGraphThread)
  415. {
  416. CAMEvent e;
  417. m_pGraphThread->PostThreadMessage(CGraphThread::TM_EXIT, 0, (LPARAM)&e);
  418. if(!e.Wait(5000))
  419. {
  420. TRACE(_T("ERROR: Must call TerminateThread() on CMainFrame::m_pGraphThread->m_hThreadn")); 
  421. TerminateThread(m_pGraphThread->m_hThread, -1);
  422. }
  423. }
  424. __super::OnDestroy();
  425. }
  426. void CMainFrame::OnClose()
  427. {
  428. m_wndPlaylistBar.SavePlaylist();
  429. SaveControlBars();
  430. ShowWindow(SW_HIDE);
  431. CloseMedia();
  432. __super::OnClose();
  433. }
  434. DROPEFFECT CMainFrame::OnDragEnter(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point)
  435. {
  436. return DROPEFFECT_NONE;
  437. }
  438. DROPEFFECT CMainFrame::OnDragOver(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point)
  439. {
  440. UINT CF_URL = RegisterClipboardFormat(_T("UniformResourceLocator"));
  441. return pDataObject->IsDataAvailable(CF_URL) ? DROPEFFECT_COPY : DROPEFFECT_NONE;
  442. }
  443. BOOL CMainFrame::OnDrop(COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point)
  444. {
  445. UINT CF_URL = RegisterClipboardFormat(_T("UniformResourceLocator"));
  446. BOOL bResult = FALSE;
  447. if(pDataObject->IsDataAvailable(CF_URL)) 
  448. {
  449. FORMATETC fmt = {CF_URL, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  450. if(HGLOBAL hGlobal = pDataObject->GetGlobalData(CF_URL, &fmt))
  451. {
  452. LPCSTR pText = (LPCSTR)GlobalLock(hGlobal);
  453. if(AfxIsValidString(pText))
  454. {
  455. CStringA url(pText);
  456. SetForegroundWindow();
  457. CAtlList<CString> sl;
  458. sl.AddTail(CString(url));
  459. if(m_wndPlaylistBar.IsWindowVisible())
  460. {
  461. m_wndPlaylistBar.Append(sl, true);
  462. }
  463. else
  464. {
  465. m_wndPlaylistBar.Open(sl, true);
  466. OpenCurPlaylistItem();
  467. }
  468. GlobalUnlock(hGlobal);
  469. bResult = TRUE;
  470. }
  471. }
  472. }
  473. return bResult;
  474. }
  475. DROPEFFECT CMainFrame::OnDropEx(COleDataObject* pDataObject, DROPEFFECT dropDefault, DROPEFFECT dropList, CPoint point)
  476. {
  477. return (DROPEFFECT)-1;
  478. }
  479. void CMainFrame::OnDragLeave()
  480. {
  481. }
  482. DROPEFFECT CMainFrame::OnDragScroll(DWORD dwKeyState, CPoint point)
  483. {
  484. return DROPEFFECT_NONE;
  485. }
  486. void CMainFrame::LoadControlBar(CControlBar* pBar, UINT defDockBarID)
  487. {
  488. if(!pBar) return;
  489. CString str;
  490. pBar->GetWindowText(str);
  491. if(str.IsEmpty()) return;
  492. CString section = _T("ToolBars\") + str;
  493. CWinApp* pApp = AfxGetApp();
  494. UINT nID = pApp->GetProfileInt(section, _T("DockState"), defDockBarID);
  495. if(nID != AFX_IDW_DOCKBAR_FLOAT)
  496. {
  497. DockControlBar(pBar, nID);
  498. }
  499. pBar->ShowWindow(
  500. pApp->GetProfileInt(section, _T("Visible"), FALSE) 
  501. && pBar != &m_wndSubresyncBar 
  502. && pBar != &m_wndCaptureBar
  503. && pBar != &m_wndShaderEditorBar
  504. ? SW_SHOW
  505. : SW_HIDE);
  506. if(CSizingControlBar* pSCB = dynamic_cast<CSizingControlBar*>(pBar))
  507. {
  508. pSCB->LoadState(section + _T("\State"));
  509. m_dockingbars.AddTail(pSCB);
  510. }
  511. }
  512. void CMainFrame::RestoreFloatingControlBars()
  513. {
  514. CWinApp* pApp = AfxGetApp();
  515. CRect r;
  516. GetWindowRect(r);
  517. POSITION pos = m_dockingbars.GetHeadPosition();
  518. while(pos)
  519. {
  520. CSizingControlBar* pBar = m_dockingbars.GetNext(pos);
  521. CString str;
  522. pBar->GetWindowText(str);
  523. if(str.IsEmpty()) return;
  524. CString section = _T("ToolBars\") + str;
  525. if(pApp->GetProfileInt(section, _T("DockState"), ~AFX_IDW_DOCKBAR_FLOAT) == AFX_IDW_DOCKBAR_FLOAT)
  526. {
  527. CPoint p;
  528. p.x = pApp->GetProfileInt(section, _T("DockPosX"), r.right);
  529. p.y = pApp->GetProfileInt(section, _T("DockPosY"), r.top);
  530. if(p.x < m_rcDesktop.left) p.x = m_rcDesktop.left;
  531. if(p.y < m_rcDesktop.top) p.y = m_rcDesktop.top;
  532. if(p.x >= m_rcDesktop.right) p.x = m_rcDesktop.right-1;
  533. if(p.y >= m_rcDesktop.bottom) p.y = m_rcDesktop.bottom-1;
  534. FloatControlBar(pBar, p);
  535. }
  536. }
  537. }
  538. void CMainFrame::SaveControlBars()
  539. {
  540. CWinApp* pApp = AfxGetApp();
  541. POSITION pos = m_dockingbars.GetHeadPosition();
  542. while(pos)
  543. {
  544. CSizingControlBar* pBar = m_dockingbars.GetNext(pos);
  545. CString str;
  546. pBar->GetWindowText(str);
  547. if(str.IsEmpty()) return;
  548. CString section = _T("ToolBars\") + str;
  549. pApp->WriteProfileInt(section, _T("Visible"), pBar->IsWindowVisible());
  550. if(CSizingControlBar* pSCB = dynamic_cast<CSizingControlBar*>(pBar))
  551. {
  552. pSCB->SaveState(section + _T("\State"));
  553. }
  554. UINT nID = pBar->GetParent()->GetDlgCtrlID();
  555. if(nID == AFX_IDW_DOCKBAR_FLOAT)
  556. {
  557. CRect r;
  558. pBar->GetParent()->GetParent()->GetWindowRect(r);
  559. pApp->WriteProfileInt(section, _T("DockPosX"), r.left);
  560. pApp->WriteProfileInt(section, _T("DockPosY"), r.top);
  561. }
  562. pApp->WriteProfileInt(section, _T("DockState"), nID);
  563. }
  564. }
  565. LRESULT CMainFrame::OnTaskBarRestart(WPARAM, LPARAM)
  566. {
  567. m_fTrayIcon = false;
  568. ShowTrayIcon(AfxGetAppSettings().fTrayIcon);
  569. return 0;
  570. }
  571. LRESULT CMainFrame::OnNotifyIcon(WPARAM wParam, LPARAM lParam)
  572. {
  573.     if((UINT)wParam != IDR_MAINFRAME)
  574. return -1;
  575. switch((UINT)lParam)
  576. {
  577. case WM_LBUTTONDOWN:
  578. ShowWindow(SW_SHOW);
  579. MoveVideoWindow();
  580. SetForegroundWindow();
  581. break;
  582. case WM_LBUTTONDBLCLK:
  583. PostMessage(WM_COMMAND, ID_FILE_OPENMEDIA);
  584. break;
  585. case WM_RBUTTONDOWN:
  586. {
  587. POINT p;
  588. GetCursorPos(&p);
  589. SetForegroundWindow();
  590. m_popupmain.GetSubMenu(0)->TrackPopupMenu(TPM_RIGHTBUTTON|TPM_NOANIMATION, p.x, p.y, this);
  591. PostMessage(WM_NULL);
  592. break; 
  593. }
  594. case WM_MOUSEMOVE:
  595. {
  596. CString str;
  597. GetWindowText(str);
  598. SetTrayTip(str);
  599. break;
  600. }
  601. default: 
  602. break; 
  603. }
  604. return 0;
  605. }
  606. void CMainFrame::ShowTrayIcon(bool fShow)
  607. {
  608.     BOOL bWasVisible = ShowWindow(SW_HIDE);
  609. if(fShow)
  610. {
  611. if(!m_fTrayIcon)
  612. {
  613. NOTIFYICONDATA tnid; 
  614. tnid.cbSize = sizeof(NOTIFYICONDATA); 
  615. tnid.hWnd = m_hWnd; 
  616. tnid.uID = IDR_MAINFRAME; 
  617. // tnid.hIcon = (HICON)LoadIcon(AfxGetResourceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME));
  618. tnid.hIcon = (HICON)LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
  619. tnid.uFlags = NIF_MESSAGE|NIF_ICON|NIF_TIP; 
  620. tnid.uCallbackMessage = WM_NOTIFYICON; 
  621. lstrcpyn(tnid.szTip, TEXT("Media Player Classic"), sizeof(tnid.szTip)); 
  622. Shell_NotifyIcon(NIM_ADD, &tnid);
  623. m_fTrayIcon = true;
  624. }
  625. }
  626. else
  627. {
  628. if(m_fTrayIcon)
  629. {
  630. NOTIFYICONDATA tnid; 
  631. tnid.cbSize = sizeof(NOTIFYICONDATA); 
  632. tnid.hWnd = m_hWnd;
  633. tnid.uID = IDR_MAINFRAME; 
  634. Shell_NotifyIcon(NIM_DELETE, &tnid); 
  635. m_fTrayIcon = false;
  636. }
  637. }
  638. if(bWasVisible)
  639. ShowWindow(SW_SHOW);
  640. }
  641. void CMainFrame::SetTrayTip(CString str)
  642. {
  643. NOTIFYICONDATA tnid; 
  644. tnid.cbSize = sizeof(NOTIFYICONDATA); 
  645. tnid.hWnd = m_hWnd; 
  646. tnid.uID = IDR_MAINFRAME; 
  647. tnid.uFlags = NIF_TIP; 
  648. lstrcpyn(tnid.szTip, str, sizeof(tnid.szTip)); 
  649. Shell_NotifyIcon(NIM_MODIFY, &tnid);
  650. }
  651. BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
  652. {
  653. if(!__super::PreCreateWindow(cs))
  654. return FALSE;
  655. cs.dwExStyle &= ~WS_EX_CLIENTEDGE;
  656. cs.lpszClass = MPC_WND_CLASS_NAME; //AfxRegisterWndClass(0);
  657. return TRUE;
  658. }
  659. BOOL CMainFrame::PreTranslateMessage(MSG* pMsg)
  660. {
  661. if(pMsg->message == WM_KEYDOWN)
  662. {
  663. /* if(m_fShockwaveGraph
  664. && (pMsg->wParam == VK_LEFT || pMsg->wParam == VK_RIGHT
  665. || pMsg->wParam == VK_UP || pMsg->wParam == VK_DOWN))
  666. return FALSE;
  667. */
  668. if(pMsg->wParam == VK_ESCAPE && m_iMediaLoadState == MLS_LOADED && m_fFullScreen)
  669. {
  670. OnViewFullscreen();
  671. PostMessage(WM_COMMAND, ID_PLAY_PAUSE);
  672. return TRUE;
  673. }
  674. else if(pMsg->wParam == VK_ESCAPE && (IsCaptionMenuHidden()))
  675. {
  676. PostMessage(WM_COMMAND, ID_VIEW_CAPTIONMENU);
  677. return TRUE;
  678. }
  679. else if(pMsg->wParam == VK_LEFT && pAMTuner)
  680. {
  681. PostMessage(WM_COMMAND, ID_NAVIGATE_SKIPBACK);
  682. return TRUE;
  683. }
  684. else if(pMsg->wParam == VK_RIGHT && pAMTuner)
  685. {
  686. PostMessage(WM_COMMAND, ID_NAVIGATE_SKIPFORWARD);
  687. return TRUE;
  688. }
  689. }
  690. return __super::PreTranslateMessage(pMsg);
  691. }
  692. void CMainFrame::RecalcLayout(BOOL bNotify)
  693. {
  694. __super::RecalcLayout(bNotify);
  695. CRect r;
  696. GetWindowRect(&r);
  697. MINMAXINFO mmi;
  698. memset(&mmi, 0, sizeof(mmi));
  699. SendMessage(WM_GETMINMAXINFO, 0, (LPARAM)&mmi);
  700. r |= CRect(r.TopLeft(), CSize(r.Width(), mmi.ptMinTrackSize.y));
  701. MoveWindow(&r);
  702. }
  703. /////////////////////////////////////////////////////////////////////////////
  704. // CMainFrame diagnostics
  705. #ifdef _DEBUG
  706. void CMainFrame::AssertValid() const
  707. {
  708. __super::AssertValid();
  709. }
  710. void CMainFrame::Dump(CDumpContext& dc) const
  711. {
  712. __super::Dump(dc);
  713. }
  714. #endif //_DEBUG
  715. /////////////////////////////////////////////////////////////////////////////
  716. // CMainFrame message handlers
  717. void CMainFrame::OnSetFocus(CWnd* pOldWnd)
  718. {
  719. SetAlwaysOnTop(AfxGetAppSettings().iOnTop);
  720. // forward focus to the view window
  721. if(IsWindow(m_wndView.m_hWnd))
  722. m_wndView.SetFocus();
  723. }
  724. BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
  725. {
  726. // let the view have first crack at the command
  727. if(m_wndView.OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
  728. return TRUE;
  729. POSITION pos = m_bars.GetHeadPosition();
  730. while(pos) 
  731. {
  732. if(m_bars.GetNext(pos)->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
  733. return TRUE;
  734. }
  735. pos = m_dockingbars.GetHeadPosition();
  736. while(pos) 
  737. {
  738. if(m_dockingbars.GetNext(pos)->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
  739. return TRUE;
  740. }
  741. // otherwise, do default handling
  742. return __super::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
  743. }
  744. void CMainFrame::OnGetMinMaxInfo(MINMAXINFO* lpMMI)
  745. {
  746. DWORD style = GetStyle();
  747. MENUBARINFO mbi;
  748. memset(&mbi, 0, sizeof(mbi));
  749. mbi.cbSize = sizeof(mbi);
  750. ::GetMenuBarInfo(m_hWnd, OBJID_MENU, 0, &mbi);
  751. lpMMI->ptMinTrackSize.x = 0;
  752. if(!IsCaptionMenuHidden())
  753. {
  754. lpMMI->ptMinTrackSize.x = 10;
  755. CRect r;
  756. for(int i = 0; ::GetMenuItemRect(m_hWnd, mbi.hMenu, i, &r); i++)
  757. lpMMI->ptMinTrackSize.x += r.Width();
  758. lpMMI->ptMinTrackSize.x = max(DEFCLIENTW, lpMMI->ptMinTrackSize.x);
  759. }
  760. if(style&WS_THICKFRAME) lpMMI->ptMinTrackSize.x += GetSystemMetrics((style&WS_CAPTION)?SM_CXSIZEFRAME:SM_CXFIXEDFRAME)*2;
  761. memset(&mbi, 0, sizeof(mbi));
  762. mbi.cbSize = sizeof(mbi);
  763. ::GetMenuBarInfo(m_hWnd, OBJID_MENU, 0, &mbi);
  764. lpMMI->ptMinTrackSize.y = 0;
  765. if(style&WS_CAPTION) lpMMI->ptMinTrackSize.y += GetSystemMetrics(SM_CYCAPTION);
  766. if(style&WS_THICKFRAME) lpMMI->ptMinTrackSize.y += GetSystemMetrics((style&WS_CAPTION)?SM_CYSIZEFRAME:SM_CYFIXEDFRAME)*2;
  767. lpMMI->ptMinTrackSize.y += (mbi.rcBar.bottom - mbi.rcBar.top);
  768. if(!AfxGetAppSettings().fHideCaptionMenu) lpMMI->ptMinTrackSize.y += 3;
  769. POSITION pos = m_bars.GetHeadPosition();
  770. while(pos) 
  771. {
  772. CControlBar* pCB = m_bars.GetNext(pos);
  773. if(!IsWindow(pCB->m_hWnd) || !pCB->IsVisible()) continue;
  774. lpMMI->ptMinTrackSize.y += pCB->CalcFixedLayout(TRUE, TRUE).cy;
  775. }
  776. pos = m_dockingbars.GetHeadPosition();
  777. while(pos)
  778. {
  779. CSizingControlBar* pCB = m_dockingbars.GetNext(pos);
  780. if(IsWindow(pCB->m_hWnd) && pCB->IsWindowVisible() && !pCB->IsFloating())
  781. lpMMI->ptMinTrackSize.y += pCB->CalcFixedLayout(TRUE, TRUE).cy-2;
  782. }
  783. __super::OnGetMinMaxInfo(lpMMI);
  784. }
  785. void CMainFrame::OnMove(int x, int y)
  786. {
  787. __super::OnMove(x, y);
  788. MoveVideoWindow();
  789. WINDOWPLACEMENT wp;
  790. GetWindowPlacement(&wp);
  791. if(!m_fFullScreen && wp.flags != WPF_RESTORETOMAXIMIZED && wp.showCmd != SW_SHOWMINIMIZED)
  792. GetWindowRect(AfxGetAppSettings().rcLastWindowPos);
  793. }
  794. void CMainFrame::OnMoving(UINT fwSide, LPRECT pRect)
  795. {
  796. __super::OnMoving(fwSide, pRect);
  797. if(AfxGetAppSettings().fSnapToDesktopEdges)
  798. {
  799. const CPoint threshold(3, 3);
  800. CRect r0 = m_rcDesktop;
  801. CRect r1 = r0 + threshold;
  802. CRect r2 = r0 - threshold;
  803. RECT& wr = *pRect;
  804. CSize ws = CRect(wr).Size();
  805. if(wr.left < r1.left && wr.left > r2.left)
  806. wr.right = (wr.left = r0.left) + ws.cx;
  807. if(wr.top < r1.top && wr.top > r2.top)
  808. wr.bottom = (wr.top = r0.top) + ws.cy;
  809. if(wr.right < r1.right && wr.right > r2.right)
  810. wr.left = (wr.right = r0.right) - ws.cx;
  811. if(wr.bottom < r1.bottom && wr.bottom > r2.bottom)
  812. wr.top = (wr.bottom = r0.bottom) - ws.cy;
  813. }
  814. }
  815. void CMainFrame::OnSize(UINT nType, int cx, int cy)
  816. {
  817. __super::OnSize(nType, cx, cy);
  818. if(nType == SIZE_RESTORED && m_fTrayIcon)
  819. {
  820. ShowWindow(SW_SHOW);
  821. }
  822. if(!m_fFullScreen)
  823. {
  824. AppSettings& s = AfxGetAppSettings();
  825. if(nType != SIZE_MAXIMIZED && nType != SIZE_MINIMIZED)
  826. GetWindowRect(s.rcLastWindowPos);
  827. s.lastWindowType = nType;
  828. }
  829. }
  830. void CMainFrame::OnSizing(UINT fwSide, LPRECT pRect)
  831. {
  832. __super::OnSizing(fwSide, pRect);
  833. AppSettings& s = AfxGetAppSettings();
  834. bool fCtrl = !!(GetAsyncKeyState(VK_CONTROL)&0x80000000);
  835. if(m_iMediaLoadState != MLS_LOADED || m_fFullScreen
  836. || s.iDefaultVideoSize == DVS_STRETCH
  837. || (fCtrl ^ s.fFreeWindowResizing))
  838. return;
  839. CSize wsize(pRect->right - pRect->left, pRect->bottom - pRect->top);
  840. CSize vsize = GetVideoSize();
  841. CSize fsize(0, 0);
  842. if(!vsize.cx || !vsize.cy)
  843. return;
  844. // TODO
  845. {
  846. DWORD style = GetStyle();
  847. MENUBARINFO mbi;
  848. memset(&mbi, 0, sizeof(mbi));
  849. mbi.cbSize = sizeof(mbi);
  850. ::GetMenuBarInfo(m_hWnd, OBJID_MENU, 0, &mbi);
  851. fsize.cx += GetSystemMetrics((style&WS_CAPTION)?SM_CXSIZEFRAME:SM_CXFIXEDFRAME)*2;
  852. if(style&WS_CAPTION) fsize.cy += GetSystemMetrics(SM_CYCAPTION);
  853. if(style&WS_THICKFRAME) fsize.cy += GetSystemMetrics((style&WS_CAPTION)?SM_CYSIZEFRAME:SM_CYFIXEDFRAME)*2;
  854. fsize.cy += mbi.rcBar.bottom - mbi.rcBar.top;
  855. if(!AfxGetAppSettings().fHideCaptionMenu) fsize.cy += 3;
  856. POSITION pos = m_bars.GetHeadPosition();
  857. while(pos) 
  858. {
  859. CControlBar* pCB = m_bars.GetNext(pos);
  860. if(IsWindow(pCB->m_hWnd) && pCB->IsVisible())
  861. fsize.cy += pCB->CalcFixedLayout(TRUE, TRUE).cy;
  862. }
  863. pos = m_dockingbars.GetHeadPosition();
  864. while(pos)
  865. {
  866. CSizingControlBar* pCB = m_dockingbars.GetNext(pos);
  867. if(IsWindow(pCB->m_hWnd) && pCB->IsWindowVisible())
  868. {
  869. if(pCB->IsHorzDocked()) fsize.cy += pCB->CalcFixedLayout(TRUE, TRUE).cy-2;
  870. else if(pCB->IsVertDocked()) fsize.cx += pCB->CalcFixedLayout(TRUE, FALSE).cx;
  871. }
  872. }
  873. }
  874. wsize -= fsize;
  875. bool fWider = wsize.cy < wsize.cx;
  876. wsize.SetSize(
  877. wsize.cy * vsize.cx / vsize.cy,
  878. wsize.cx * vsize.cy / vsize.cx);
  879. wsize += fsize;
  880. if(fwSide == WMSZ_TOP || fwSide == WMSZ_BOTTOM || !fWider && (fwSide == WMSZ_TOPRIGHT || fwSide == WMSZ_BOTTOMRIGHT))
  881. {
  882. pRect->right = pRect->left + wsize.cx;
  883. }
  884. else if(fwSide == WMSZ_LEFT || fwSide == WMSZ_RIGHT || fWider && (fwSide == WMSZ_BOTTOMLEFT || fwSide == WMSZ_BOTTOMRIGHT))
  885. {
  886. pRect->bottom = pRect->top + wsize.cy;
  887. }
  888. else if(!fWider && (fwSide == WMSZ_TOPLEFT || fwSide == WMSZ_BOTTOMLEFT))
  889. {
  890. pRect->left = pRect->right - wsize.cx;
  891. }
  892. else if(fWider && (fwSide == WMSZ_TOPLEFT || fwSide == WMSZ_TOPRIGHT))
  893. {
  894. pRect->top = pRect->bottom - wsize.cy;
  895. }
  896. }
  897. void CMainFrame::OnDisplayChange() // untested, not sure if it's working...
  898. {
  899. TRACE(_T("*** CMainFrame::OnDisplayChange()n"));
  900. /*
  901. if(m_iMediaLoadState == MLS_LOADED && m_pCAP) 
  902. m_pCAP->OnDisplayChange();
  903. */
  904. GetDesktopWindow()->GetWindowRect(&m_rcDesktop);
  905. }
  906. #include <psapi.h>
  907. void CMainFrame::OnSysCommand(UINT nID, LPARAM lParam)
  908. {
  909. if((nID & 0xFFF0) == SC_SCREENSAVE)
  910. {
  911. TRACE(_T("SC_SCREENSAVE, nID = %d, lParam = %dn"), nID, lParam);
  912. }
  913. else if((nID & 0xFFF0) == SC_MINIMIZE && m_fTrayIcon)
  914. {
  915. ShowWindow(SW_HIDE);
  916. return;
  917. }
  918. __super::OnSysCommand(nID, lParam);
  919. }
  920. void CMainFrame::OnActivateApp(BOOL bActive, DWORD dwThreadID)
  921. {
  922. __super::OnActivateApp(bActive, dwThreadID);
  923. MONITORINFO mi;
  924. mi.cbSize = sizeof(MONITORINFO);
  925. GetMonitorInfo(MonitorFromWindow(m_hWnd, MONITOR_DEFAULTTONEAREST), &mi);
  926. if(!bActive && (mi.dwFlags&MONITORINFOF_PRIMARY) && m_fFullScreen && m_iMediaLoadState == MLS_LOADED)
  927. {
  928. bool fExitFullscreen = true;
  929. if(CWnd* pWnd = GetForegroundWindow())
  930. {
  931. HMONITOR hMonitor1 = MonitorFromWindow(m_hWnd, MONITOR_DEFAULTTONEAREST);
  932. HMONITOR hMonitor2 = MonitorFromWindow(pWnd->m_hWnd, MONITOR_DEFAULTTONEAREST);
  933. if(hMonitor1 && hMonitor2 && hMonitor1 != hMonitor2) fExitFullscreen = false;
  934. CString title;
  935. pWnd->GetWindowText(title);
  936. CString module;
  937. if(GetVersion()&0x80000000)
  938. {
  939. module.ReleaseBufferSetLength(GetWindowModuleFileName(pWnd->m_hWnd, module.GetBuffer(MAX_PATH), MAX_PATH));
  940. }
  941. else
  942. {
  943. DWORD pid; 
  944. GetWindowThreadProcessId(pWnd->m_hWnd, &pid); 
  945. if(HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid))
  946. {
  947. HMODULE hMod; 
  948. DWORD cbNeeded; 
  949. if(EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded))
  950. {
  951. module.ReleaseBufferSetLength(GetModuleFileNameEx(hProcess, hMod, module.GetBuffer(MAX_PATH), MAX_PATH)); 
  952. CloseHandle(hProcess); 
  953. }
  954. CPath p(module);
  955. p.StripPath();
  956. module = (LPCTSTR)p;
  957. module.MakeLower();
  958. CString str;
  959. str.Format(_T("Focus lost to: %s - %s"), module, title);
  960. SendStatusMessage(str, 5000);
  961. }
  962. if(fExitFullscreen) OnViewFullscreen();
  963. }
  964. }
  965. LRESULT CMainFrame::OnAppCommand(WPARAM wParam, LPARAM lParam)
  966. {
  967. UINT cmd  = GET_APPCOMMAND_LPARAM(lParam);
  968. UINT uDevice = GET_DEVICE_LPARAM(lParam);
  969. UINT dwKeys = GET_KEYSTATE_LPARAM(lParam);
  970. if(uDevice != FAPPCOMMAND_OEM)
  971. {
  972. AppSettings& s = AfxGetAppSettings();
  973. BOOL fRet = FALSE;
  974. POSITION pos = s.wmcmds.GetHeadPosition();
  975. while(pos)
  976. {
  977. wmcmd& wc = s.wmcmds.GetNext(pos);
  978. if(wc.appcmd == cmd && TRUE == SendMessage(WM_COMMAND, wc.cmd)) 
  979. fRet = TRUE;
  980. }
  981. if(fRet) return TRUE;
  982. }
  983. return Default();
  984. }
  985. void CMainFrame::OnTimer(UINT nIDEvent)
  986. {
  987. if(nIDEvent == TIMER_STREAMPOSPOLLER && m_iMediaLoadState == MLS_LOADED)
  988. {
  989. REFERENCE_TIME rtNow = 0, rtDur = 0;
  990. if(m_iPlaybackMode == PM_FILE)
  991. {
  992. pMS->GetCurrentPosition(&rtNow);
  993. pMS->GetDuration(&rtDur);
  994. if(m_rtDurationOverride >= 0) rtDur = m_rtDurationOverride;
  995. m_wndSeekBar.Enable(rtDur > 0);
  996. m_wndSeekBar.SetRange(0, rtDur);
  997. m_wndSeekBar.SetPos(rtNow);
  998. }
  999. else if(m_iPlaybackMode == PM_CAPTURE)
  1000. {
  1001. if(m_fCapturing && m_wndCaptureBar.m_capdlg.m_pMux)
  1002. {
  1003. CComQIPtr<IMediaSeeking> pMuxMS = m_wndCaptureBar.m_capdlg.m_pMux;
  1004. if(!pMuxMS || FAILED(pMuxMS->GetCurrentPosition(&rtNow))) rtNow = 0;
  1005. }
  1006. if(m_rtDurationOverride >= 0) rtDur = m_rtDurationOverride;
  1007.             
  1008. m_wndSeekBar.Enable(false);
  1009. m_wndSeekBar.SetRange(0, rtDur);
  1010. m_wndSeekBar.SetPos(rtNow);
  1011. /*
  1012. if(m_fCapturing)
  1013. {
  1014. if(rtNow > 10000i64*1000*60*60*3)
  1015. {
  1016. m_wndCaptureBar.m_capdlg.OnRecord();
  1017. }
  1018. }
  1019. */
  1020. }
  1021. if(m_pCAP && m_iPlaybackMode != PM_FILE) m_pCAP->SetTime(/*rtNow*/m_wndSeekBar.GetPos());
  1022. }
  1023. else if(nIDEvent == TIMER_STREAMPOSPOLLER2 && m_iMediaLoadState == MLS_LOADED)
  1024. {
  1025. __int64 start, stop, pos;
  1026. m_wndSeekBar.GetRange(start, stop);
  1027. pos = m_wndSeekBar.GetPosReal();
  1028. GUID tf;
  1029. pMS->GetTimeFormat(&tf);
  1030. if(m_iPlaybackMode == PM_CAPTURE && !m_fCapturing)
  1031. {
  1032. CString str = _T("Live");
  1033. long lChannel = 0, lVivSub = 0, lAudSub = 0;
  1034. if(pAMTuner 
  1035. && m_wndCaptureBar.m_capdlg.IsTunerActive()
  1036. && SUCCEEDED(pAMTuner->get_Channel(&lChannel, &lVivSub, &lAudSub)))
  1037. {
  1038. CString ch;
  1039. ch.Format(_T(" (ch%d)"), lChannel);
  1040. str += ch;
  1041. }
  1042. m_wndStatusBar.SetStatusTimer(str);
  1043. }
  1044. else
  1045. {
  1046. m_wndStatusBar.SetStatusTimer(pos, stop, !!m_wndSubresyncBar.IsWindowVisible(), &tf);
  1047. }
  1048. m_wndSubresyncBar.SetTime(pos);
  1049. if(m_pCAP && GetMediaState() == State_Paused) m_pCAP->Paint(true);
  1050. }
  1051. else if(nIDEvent == TIMER_FULLSCREENCONTROLBARHIDER)
  1052. {
  1053. CPoint p;
  1054. GetCursorPos(&p);
  1055. CRect r;
  1056. GetWindowRect(r);
  1057. bool fCursorOutside = !r.PtInRect(p);
  1058. CWnd* pWnd = WindowFromPoint(p);
  1059. if(pWnd && (m_wndView == *pWnd || m_wndView.IsChild(pWnd) || fCursorOutside))
  1060. {
  1061. if(AfxGetAppSettings().nShowBarsWhenFullScreenTimeOut >= 0)
  1062. ShowControls(CS_NONE, false);
  1063. }
  1064. }
  1065. else if(nIDEvent == TIMER_FULLSCREENMOUSEHIDER)
  1066. {
  1067. CPoint p;
  1068. GetCursorPos(&p);
  1069. CRect r;
  1070. GetWindowRect(r);
  1071. bool fCursorOutside = !r.PtInRect(p);
  1072. CWnd* pWnd = WindowFromPoint(p);
  1073. if(pWnd && (m_wndView == *pWnd || m_wndView.IsChild(pWnd) || fCursorOutside))
  1074. {
  1075. m_fHideCursor = true;
  1076. SetCursor(NULL);
  1077. }
  1078. }
  1079. else if(nIDEvent == TIMER_STATS)
  1080. {
  1081. if(pQP)
  1082. {
  1083. CString rate;
  1084. if(m_iSpeedLevel >= -11 && m_iSpeedLevel <= 3 && m_iSpeedLevel != -4)
  1085. {
  1086. CString speeds[] = {_T("1/8"),_T("1/4"),_T("1/2"),_T("1"),_T("2"),_T("4"),_T("8")};
  1087. rate = speeds[(m_iSpeedLevel >= -3 ? m_iSpeedLevel : (-m_iSpeedLevel - 8)) + 3];
  1088. if(m_iSpeedLevel < -4) rate = _T("-") + rate;
  1089. if(!rate.IsEmpty()) rate = _T("(") + rate + _T("X)");
  1090. }
  1091. CString info;
  1092. int val;
  1093. pQP->get_AvgFrameRate(&val);
  1094. info.Format(_T("%d.%02d %s"), val/100, val%100, rate);
  1095. m_wndStatsBar.SetLine(_T("Frame-rate"), info);
  1096. int avg, dev;
  1097. pQP->get_AvgSyncOffset(&avg);
  1098. pQP->get_DevSyncOffset(&dev);
  1099. info.Format(_T("avg: %d ms, dev: %d ms"), avg, dev);
  1100. m_wndStatsBar.SetLine(_T("Sync Offset"), info);
  1101. int drawn, dropped;
  1102. pQP->get_FramesDrawn(&drawn);
  1103. pQP->get_FramesDroppedInRenderer(&dropped);
  1104. info.Format(_T("drawn: %d, dropped: %d"), drawn, dropped);
  1105. m_wndStatsBar.SetLine(_T("Frames"), info);
  1106. pQP->get_Jitter(&val);
  1107. info.Format(_T("%d ms"), val);
  1108. m_wndStatsBar.SetLine(_T("Jitter"), info);
  1109. }
  1110. if(pBI)
  1111. {
  1112. CAtlList<CString> sl;
  1113. for(int i = 0, j = pBI->GetCount(); i < j; i++)
  1114. {
  1115. int samples, size;
  1116. if(S_OK == pBI->GetStatus(i, samples, size))
  1117. {
  1118. CString str;
  1119. str.Format(_T("[%d]: %03d/%d KB"), i, samples, size / 1024);
  1120. sl.AddTail(str);
  1121. }
  1122. }
  1123. if(!sl.IsEmpty())
  1124. {
  1125. CString str;
  1126. str.Format(_T("%s (p%d)"), Implode(sl, ' '), pBI->GetPriority());
  1127. m_wndStatsBar.SetLine(_T("Buffers"), str);
  1128. }
  1129. }
  1130. CInterfaceList<IBitRateInfo> pBRIs;
  1131. BeginEnumFilters(pGB, pEF, pBF)
  1132. {
  1133. BeginEnumPins(pBF, pEP, pPin)
  1134. {
  1135. if(CComQIPtr<IBitRateInfo> pBRI = pPin)
  1136. {
  1137. pBRIs.AddTail(pBRI);
  1138. }
  1139. }
  1140. EndEnumPins
  1141. if(!pBRIs.IsEmpty())
  1142. {
  1143. CAtlList<CString> sl;
  1144. POSITION pos = pBRIs.GetHeadPosition();
  1145. for(int i = 0; pos; i++)
  1146. {
  1147. IBitRateInfo* pBRI = pBRIs.GetNext(pos);
  1148. DWORD cur = pBRI->GetCurrentBitRate() / 1000;
  1149. DWORD avg = pBRI->GetAverageBitRate() / 1000;
  1150. if(avg == 0) continue;
  1151. CString str;
  1152. if(cur != avg) str.Format(_T("[%d]: %d/%d Kb/s"), i, avg, cur);
  1153. else str.Format(_T("[%d]: %d Kb/s"), i, avg);
  1154. sl.AddTail(str);
  1155. }
  1156. if(!sl.IsEmpty())
  1157. {
  1158. m_wndStatsBar.SetLine(_T("Bitrate"), Implode(sl, ' ') + _T(" (avg/cur)"));
  1159. }
  1160. break;
  1161. }
  1162. }
  1163. EndEnumFilters
  1164. if(m_iPlaybackMode == PM_FILE)
  1165. {
  1166. SetupChapters();
  1167. }
  1168. if(m_iPlaybackMode == PM_DVD) // we also use this timer to update the info panel for dvd playback
  1169. {
  1170. ULONG ulAvailable, ulCurrent;
  1171. // Location
  1172. CString Location('-');
  1173. DVD_PLAYBACK_LOCATION2 loc;
  1174. ULONG ulNumOfVolumes, ulVolume;
  1175. DVD_DISC_SIDE Side;
  1176. ULONG ulNumOfTitles;
  1177. ULONG ulNumOfChapters;
  1178. if(SUCCEEDED(pDVDI->GetCurrentLocation(&loc))
  1179. && SUCCEEDED(pDVDI->GetNumberOfChapters(loc.TitleNum, &ulNumOfChapters))
  1180. && SUCCEEDED(pDVDI->GetDVDVolumeInfo(&ulNumOfVolumes, &ulVolume, &Side, &ulNumOfTitles)))
  1181. {
  1182. Location.Format(_T("Volume: %02d/%02d, Title: %02d/%02d, Chapter: %02d/%02d"), 
  1183. ulVolume, ulNumOfVolumes, 
  1184. loc.TitleNum, ulNumOfTitles, 
  1185. loc.ChapterNum, ulNumOfChapters);
  1186. }
  1187. m_wndInfoBar.SetLine(ResStr(IDS_INFOBAR_LOCATION), Location);
  1188. // Video
  1189. CString Video('-');
  1190. DVD_VideoAttributes VATR;
  1191. if(SUCCEEDED(pDVDI->GetCurrentAngle(&ulAvailable, &ulCurrent))
  1192. && SUCCEEDED(pDVDI->GetCurrentVideoAttributes(&VATR)))
  1193. {
  1194. Video.Format(_T("Angle: %02d/%02d, %dx%d %dHz %d:%d"), 
  1195. ulAvailable, ulCurrent,
  1196. VATR.ulSourceResolutionX, VATR.ulSourceResolutionY, VATR.ulFrameRate,
  1197. VATR.ulAspectX, VATR.ulAspectY);
  1198. }
  1199. m_wndInfoBar.SetLine(ResStr(IDS_INFOBAR_VIDEO), Video);
  1200. // Audio
  1201. CString Audio('-');
  1202. DVD_AudioAttributes AATR;
  1203. if(SUCCEEDED(pDVDI->GetCurrentAudio(&ulAvailable, &ulCurrent))
  1204. && SUCCEEDED(pDVDI->GetAudioAttributes(ulCurrent, &AATR)))
  1205. {
  1206. CString lang;
  1207. int len = GetLocaleInfo(AATR.Language, LOCALE_SENGLANGUAGE, lang.GetBuffer(64), 64);
  1208. lang.ReleaseBufferSetLength(max(len-1, 0));
  1209. switch(AATR.LanguageExtension)
  1210. {
  1211. case DVD_AUD_EXT_NotSpecified:
  1212. default: break;
  1213. case DVD_AUD_EXT_Captions: lang += _T(" (Captions)"); break;
  1214. case DVD_AUD_EXT_VisuallyImpaired: lang += _T(" (Visually Impaired)"); break;
  1215. case DVD_AUD_EXT_DirectorComments1: lang += _T(" (Director Comments 1)"); break;
  1216. case DVD_AUD_EXT_DirectorComments2: lang += _T(" (Director Comments 2)"); break;
  1217. }
  1218. CString format;
  1219. switch(AATR.AudioFormat)
  1220. {
  1221. case DVD_AudioFormat_AC3: format = _T("AC3"); break;
  1222. case DVD_AudioFormat_MPEG1: 
  1223. case DVD_AudioFormat_MPEG1_DRC: format = _T("MPEG1"); break;
  1224. case DVD_AudioFormat_MPEG2: 
  1225. case DVD_AudioFormat_MPEG2_DRC: format = _T("MPEG2"); break;
  1226. case DVD_AudioFormat_LPCM: format = _T("LPCM"); break;
  1227. case DVD_AudioFormat_DTS: format = _T("DTS"); break;
  1228. case DVD_AudioFormat_SDDS: format = _T("SDDS"); break;
  1229. case DVD_AudioFormat_Other: 
  1230. default: format = _T("Unknown format"); break;
  1231. }
  1232. Audio.Format(_T("%s, %s %dHz %dbits %d channel(s)"), 
  1233. lang, 
  1234. format,
  1235. AATR.dwFrequency,
  1236. AATR.bQuantization,
  1237. AATR.bNumberOfChannels);
  1238. m_wndStatusBar.SetStatusBitmap(
  1239. AATR.bNumberOfChannels == 1 ? IDB_MONO 
  1240. : AATR.bNumberOfChannels >= 2 ? IDB_STEREO 
  1241. : IDB_NOAUDIO);
  1242. }
  1243. m_wndInfoBar.SetLine(ResStr(IDS_INFOBAR_AUDIO), Audio);
  1244. // Subtitles
  1245. CString Subtitles('-');
  1246. BOOL bIsDisabled;
  1247. DVD_SubpictureAttributes SATR;
  1248. if(SUCCEEDED(pDVDI->GetCurrentSubpicture(&ulAvailable, &ulCurrent, &bIsDisabled))
  1249. && SUCCEEDED(pDVDI->GetSubpictureAttributes(ulCurrent, &SATR)))
  1250. {
  1251. CString lang;
  1252. int len = GetLocaleInfo(SATR.Language, LOCALE_SENGLANGUAGE, lang.GetBuffer(64), 64);
  1253. lang.ReleaseBufferSetLength(max(len-1, 0));
  1254. switch(SATR.LanguageExtension)
  1255. {
  1256. case DVD_SP_EXT_NotSpecified:
  1257. default: break;
  1258. case DVD_SP_EXT_Caption_Normal: lang += _T(""); break;
  1259. case DVD_SP_EXT_Caption_Big: lang += _T(" (Big)"); break;
  1260. case DVD_SP_EXT_Caption_Children: lang += _T(" (Children)"); break;
  1261. case DVD_SP_EXT_CC_Normal: lang += _T(" (CC)"); break;
  1262. case DVD_SP_EXT_CC_Big: lang += _T(" (CC Big)"); break;
  1263. case DVD_SP_EXT_CC_Children: lang += _T(" (CC Children)"); break;
  1264. case DVD_SP_EXT_Forced: lang += _T(" (Forced)"); break;
  1265. case DVD_SP_EXT_DirectorComments_Normal: lang += _T(" (Director Comments)"); break;
  1266. case DVD_SP_EXT_DirectorComments_Big: lang += _T(" (Director Comments, Big)"); break;
  1267. case DVD_SP_EXT_DirectorComments_Children: lang += _T(" (Director Comments, Children)"); break;
  1268. }
  1269. if(bIsDisabled) lang = _T("-");
  1270. Subtitles.Format(_T("%s"), 
  1271. lang);
  1272. }
  1273. m_wndInfoBar.SetLine(ResStr(IDS_INFOBAR_SUBTITLES), Subtitles);
  1274. }
  1275. if(GetMediaState() == State_Running)
  1276. {
  1277. UINT fSaverActive = 0;
  1278. if(SystemParametersInfo(SPI_GETSCREENSAVEACTIVE, 0, (PVOID)&fSaverActive, 0))
  1279. {
  1280. SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 0, 0, SPIF_SENDWININICHANGE); // this might not be needed at all...
  1281. SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, fSaverActive, 0, SPIF_SENDWININICHANGE);
  1282. }
  1283. fSaverActive = 0;
  1284. if(SystemParametersInfo(SPI_GETPOWEROFFACTIVE, 0, (PVOID)&fSaverActive, 0))
  1285. {
  1286. SystemParametersInfo(SPI_SETPOWEROFFACTIVE, 0, 0, SPIF_SENDWININICHANGE); // this might not be needed at all...
  1287. SystemParametersInfo(SPI_SETPOWEROFFACTIVE, fSaverActive, 0, SPIF_SENDWININICHANGE);
  1288. }
  1289. }
  1290. }
  1291. else if(nIDEvent == TIMER_STATUSERASER)
  1292. {
  1293. KillTimer(TIMER_STATUSERASER);
  1294. m_playingmsg.Empty();
  1295. }
  1296. __super::OnTimer(nIDEvent);
  1297. }
  1298. static bool SetShutdownPrivilege()
  1299. {
  1300.    HANDLE hToken; 
  1301.    TOKEN_PRIVILEGES tkp; 
  1302.  
  1303.    // Get a token for this process. 
  1304.  
  1305.    if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
  1306.    return(false);
  1307.  
  1308.    // Get the LUID for the shutdown privilege. 
  1309.  
  1310.    LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid); 
  1311.  
  1312.    tkp.PrivilegeCount = 1;  // one privilege to set    
  1313.    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 
  1314.  
  1315.    // Get the shutdown privilege for this process. 
  1316.  
  1317.    AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0); 
  1318.  
  1319.    if(GetLastError() != ERROR_SUCCESS)
  1320.    return false;
  1321.    return true;
  1322. }
  1323. bool CMainFrame::DoAfterPlaybackEvent()
  1324. {
  1325. AppSettings& s = AfxGetAppSettings();
  1326. bool fExit = false;
  1327. if(s.nCLSwitches&CLSW_CLOSE)
  1328. {
  1329. fExit = true;
  1330. }
  1331. if(s.nCLSwitches&CLSW_STANDBY)
  1332. {
  1333. SetShutdownPrivilege();
  1334. SetSystemPowerState(TRUE, TRUE);
  1335. fExit = true; // TODO: unless the app closes, it will call standby or hibernate once again forever, how to avoid that?
  1336. }
  1337. else if(s.nCLSwitches&CLSW_HIBERNATE)
  1338. {
  1339. SetShutdownPrivilege();
  1340. SetSystemPowerState(FALSE, TRUE);
  1341. fExit = true; // TODO: unless the app closes, it will call standby or hibernate once again forever, how to avoid that?
  1342. }
  1343. else if(s.nCLSwitches&CLSW_SHUTDOWN)
  1344. {
  1345. SetShutdownPrivilege();
  1346. ExitWindowsEx(EWX_SHUTDOWN|EWX_POWEROFF|EWX_FORCEIFHUNG, 0);
  1347. fExit = true;
  1348. }
  1349. else if(s.nCLSwitches&CLSW_LOGOFF)
  1350. {
  1351. SetShutdownPrivilege();
  1352. ExitWindowsEx(EWX_LOGOFF|EWX_FORCEIFHUNG, 0);
  1353. fExit = true;
  1354. }
  1355. if(!fExit) return false;
  1356. SendMessage(WM_COMMAND, ID_FILE_EXIT);
  1357. return true;
  1358. }
  1359. //
  1360. // our WM_GRAPHNOTIFY handler
  1361. //
  1362. #include <comdef.h>
  1363. LRESULT CMainFrame::OnGraphNotify(WPARAM wParam, LPARAM lParam)
  1364. {
  1365.     HRESULT hr = S_OK;
  1366. LONG evCode, evParam1, evParam2;
  1367.     while(pME && SUCCEEDED(pME->GetEvent(&evCode, (LONG_PTR*)&evParam1, (LONG_PTR*)&evParam2, 0)))
  1368.     {
  1369. CString str;
  1370. if(m_fCustomGraph)
  1371. {
  1372. if(EC_BG_ERROR == evCode)
  1373. {
  1374. str = CString((char*)evParam1);
  1375. }
  1376. }
  1377. hr = pME->FreeEventParams(evCode, evParam1, evParam2);
  1378.         if(EC_COMPLETE == evCode)
  1379.         {
  1380. AppSettings& s = AfxGetAppSettings();
  1381. if(m_wndPlaylistBar.GetCount() <= 1)
  1382. {
  1383. m_nLoops++;
  1384. if(DoAfterPlaybackEvent()) return hr;
  1385. if(s.fLoopForever || m_nLoops < s.nLoops)
  1386. {
  1387. if(GetMediaState() == State_Stopped)
  1388. {
  1389. SendMessage(WM_COMMAND, ID_PLAY_PLAY);
  1390. }
  1391. else
  1392. {
  1393. LONGLONG pos = 0;
  1394. pMS->SetPositions(&pos, AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning);
  1395. if(GetMediaState() == State_Paused)
  1396. {
  1397. SendMessage(WM_COMMAND, ID_PLAY_PLAY);
  1398. }
  1399. }
  1400. }
  1401. else 
  1402. {
  1403. if(s.fRewind) SendMessage(WM_COMMAND, ID_PLAY_STOP);
  1404. else m_fEndOfStream = true;
  1405. SendMessage(WM_COMMAND, ID_PLAY_PAUSE);
  1406. if(m_fFullScreen && s.fExitFullScreenAtTheEnd) 
  1407. OnViewFullscreen();
  1408. }
  1409. }
  1410. else if(m_wndPlaylistBar.GetCount() > 1)
  1411. {
  1412. if(m_wndPlaylistBar.IsAtEnd())
  1413. {
  1414. if(DoAfterPlaybackEvent()) return hr;
  1415. m_nLoops++;
  1416. }
  1417. if(s.fLoopForever || m_nLoops < s.nLoops)
  1418. {
  1419. int nLoops = m_nLoops;
  1420. PostMessage(WM_COMMAND, ID_NAVIGATE_SKIPFORWARD);
  1421. m_nLoops = nLoops;
  1422. }
  1423. else 
  1424. {
  1425. if(m_fFullScreen && s.fExitFullScreenAtTheEnd) 
  1426. OnViewFullscreen();
  1427. if(s.fRewind)
  1428. {
  1429. AfxGetAppSettings().nCLSwitches |= CLSW_OPEN; // HACK
  1430. PostMessage(WM_COMMAND, ID_NAVIGATE_SKIPFORWARD);
  1431. }
  1432. else
  1433. {
  1434. m_fEndOfStream = true;
  1435. PostMessage(WM_COMMAND, ID_PLAY_PAUSE);
  1436. }
  1437. }
  1438. }
  1439.         }
  1440. else if(EC_ERRORABORT == evCode)
  1441. {
  1442. TRACE(_T("EC_ERRORABORT, hr = %08xn"), (HRESULT)evParam1);
  1443. // SendMessage(WM_COMMAND, ID_FILE_CLOSEMEDIA);
  1444. // m_closingmsg = _com_error((HRESULT)evParam1).ErrorMessage();
  1445. }
  1446. else if(EC_REPAINT == evCode)
  1447. {
  1448. TRACE(_T("EC_REPAINTn"));
  1449. }
  1450. else if(EC_BUFFERING_DATA == evCode)
  1451. {
  1452. TRACE(_T("EC_BUFFERING_DATA, %d, %dn"), (HRESULT)evParam1, evParam2);
  1453. m_fBuffering = ((HRESULT)evParam1 != S_OK);
  1454. }
  1455. else if(EC_STEP_COMPLETE == evCode)
  1456. {
  1457. if(m_fFrameSteppingActive)
  1458. {
  1459. m_fFrameSteppingActive = false;
  1460. pBA->put_Volume(m_VolumeBeforeFrameStepping);
  1461. }
  1462. }
  1463. else if(EC_DEVICE_LOST == evCode)
  1464. {
  1465. CComQIPtr<IBaseFilter> pBF;
  1466. if(m_iPlaybackMode == PM_CAPTURE 
  1467. && (!pVidCap && pVidCap == (pBF = (IUnknown*)evParam1) 
  1468. || !pAudCap && pAudCap == (pBF = (IUnknown*)evParam1))
  1469. && evParam2 == 0)
  1470. {
  1471. SendMessage(WM_COMMAND, ID_FILE_CLOSEMEDIA);
  1472. }
  1473. }
  1474. else if(EC_DVD_TITLE_CHANGE == evCode)
  1475. {
  1476. if(m_iPlaybackMode == PM_FILE)
  1477. {
  1478. SetupChapters();
  1479. }
  1480. else if(m_iPlaybackMode == PM_DVD)
  1481. {
  1482. m_iDVDTitle = (DWORD)evParam1;
  1483. if(m_iDVDDomain == DVD_DOMAIN_Title)
  1484. {
  1485. CString Domain;
  1486. Domain.Format(_T("Title %d"), m_iDVDTitle);
  1487. m_wndInfoBar.SetLine(ResStr(IDS_INFOBAR_DOMAIN), Domain);
  1488. }
  1489. }
  1490. }
  1491. else if(EC_DVD_DOMAIN_CHANGE == evCode)
  1492. {
  1493. m_iDVDDomain = (DVD_DOMAIN)evParam1;
  1494. CString Domain('-');
  1495. switch(m_iDVDDomain)
  1496. {
  1497. case DVD_DOMAIN_FirstPlay: Domain = _T("First Play"); break;
  1498. case DVD_DOMAIN_VideoManagerMenu: Domain = _T("Video Manager Menu"); break;
  1499. case DVD_DOMAIN_VideoTitleSetMenu: Domain = _T("Video Title Set Menu"); break;
  1500. case DVD_DOMAIN_Title: Domain.Format(_T("Title %d"), m_iDVDTitle); break;
  1501. case DVD_DOMAIN_Stop: Domain = _T("Stop"); break;
  1502. default: Domain = _T("-"); break;
  1503. }
  1504. m_wndInfoBar.SetLine(ResStr(IDS_INFOBAR_DOMAIN), Domain);
  1505. MoveVideoWindow(); // AR might have changed
  1506. }
  1507. else if(EC_DVD_CURRENT_HMSF_TIME == evCode)
  1508. {
  1509. double fps = evParam2 == DVD_TC_FLAG_25fps ? 25.0
  1510. : evParam2 == DVD_TC_FLAG_30fps ? 30.0
  1511. : evParam2 == DVD_TC_FLAG_DropFrame ? 29.97
  1512. : 25.0;
  1513. REFERENCE_TIME rtDur = 0;
  1514. DVD_HMSF_TIMECODE tcDur;
  1515. ULONG ulFlags;
  1516. if(SUCCEEDED(pDVDI->GetTotalTitleTime(&tcDur, &ulFlags)))
  1517. rtDur = HMSF2RT(tcDur, fps);
  1518. m_wndSeekBar.Enable(rtDur > 0);
  1519. m_wndSeekBar.SetRange(0, rtDur);
  1520. REFERENCE_TIME rtNow = HMSF2RT(*((DVD_HMSF_TIMECODE*)&evParam1), fps);
  1521. m_wndSeekBar.SetPos(rtNow);
  1522. if(m_pSubClock) m_pSubClock->SetTime(rtNow);
  1523. }
  1524. else if(EC_DVD_ERROR == evCode)
  1525. {
  1526. TRACE(_T("EC_DVD_ERROR %d %dn"), evParam1, evParam2);
  1527. CString err;
  1528. switch(evParam1)
  1529. {
  1530. case DVD_ERROR_Unexpected: default: err = _T("DVD: Unexpected error"); break;
  1531. case DVD_ERROR_CopyProtectFail: err = _T("DVD: Copy-Protect Fail"); break;
  1532. case DVD_ERROR_InvalidDVD1_0Disc: err = _T("DVD: Invalid DVD 1.x Disc"); break;
  1533. case DVD_ERROR_InvalidDiscRegion: err = _T("DVD: Invalid Disc Region"); break;
  1534. case DVD_ERROR_LowParentalLevel: err = _T("DVD: Low Parental Level"); break;
  1535. case DVD_ERROR_MacrovisionFail: err = _T("DVD: Macrovision Fail"); break;
  1536. case DVD_ERROR_IncompatibleSystemAndDecoderRegions: err = _T("DVD: Incompatible System And Decoder Regions"); break;
  1537. case DVD_ERROR_IncompatibleDiscAndDecoderRegions: err = _T("DVD: Incompatible Disc And Decoder Regions"); break;
  1538. }
  1539. SendMessage(WM_COMMAND, ID_FILE_CLOSEMEDIA);
  1540. m_closingmsg = err;
  1541. }
  1542. else if(EC_DVD_WARNING == evCode)
  1543. {
  1544. TRACE(_T("EC_DVD_WARNING %d %dn"), evParam1, evParam2);
  1545. }
  1546. else if(EC_VIDEO_SIZE_CHANGED == evCode)
  1547. {
  1548. TRACE(_T("EC_VIDEO_SIZE_CHANGED %dx%dn"), CSize(evParam1));
  1549. WINDOWPLACEMENT wp;
  1550. wp.length = sizeof(wp);
  1551. GetWindowPlacement(&wp);
  1552. CSize size(evParam1);
  1553. m_fAudioOnly = (size.cx <= 0 || size.cy <= 0);
  1554. if(AfxGetAppSettings().fRememberZoomLevel
  1555. && !(m_fFullScreen || wp.showCmd == SW_SHOWMAXIMIZED || wp.showCmd == SW_SHOWMINIMIZED))
  1556. {
  1557. ZoomVideoWindow();
  1558. }
  1559. else
  1560. {
  1561. MoveVideoWindow();
  1562. }
  1563. if(m_iMediaLoadState == MLS_LOADED
  1564. && !m_fAudioOnly && (AfxGetAppSettings().nCLSwitches&CLSW_FULLSCREEN))
  1565. {
  1566. PostMessage(WM_COMMAND, ID_VIEW_FULLSCREEN);
  1567. AfxGetAppSettings().nCLSwitches &= ~CLSW_FULLSCREEN;
  1568. }
  1569. }
  1570. else if(EC_LENGTH_CHANGED == evCode)
  1571. {
  1572. __int64 rtDur = 0;
  1573. pMS->GetDuration(&rtDur);
  1574. m_wndPlaylistBar.SetCurTime(rtDur);
  1575. }
  1576. else if(!m_fCustomGraph)
  1577. {
  1578. TRACE(_T("evCode: %dn"), evCode);
  1579. }
  1580. else if(EC_BG_AUDIO_CHANGED == evCode)
  1581. {
  1582. int nAudioChannels = evParam1;
  1583. m_wndStatusBar.SetStatusBitmap(nAudioChannels == 1 ? IDB_MONO 
  1584. : nAudioChannels >= 2 ? IDB_STEREO 
  1585. : IDB_NOAUDIO);
  1586. }
  1587. else if(EC_BG_ERROR == evCode)
  1588. {
  1589. SendMessage(WM_COMMAND, ID_FILE_CLOSEMEDIA);
  1590. m_closingmsg = !str.IsEmpty() ? str : _T("Unspecified graph error");
  1591. m_wndPlaylistBar.SetCurValid(false);
  1592. break;
  1593. }
  1594. }
  1595.     return hr;
  1596. }
  1597. LRESULT CMainFrame::OnRepaintRenderLess(WPARAM wParam, LPARAM lParam)
  1598. {
  1599. MoveVideoWindow();
  1600. return TRUE;
  1601. }
  1602. LRESULT CMainFrame::OnResumeFromState(WPARAM wParam, LPARAM lParam)
  1603. {
  1604. int iPlaybackMode = (int)wParam;
  1605. if(iPlaybackMode == PM_FILE)
  1606. {
  1607. SeekTo(10000i64*int(lParam));
  1608. }
  1609. else if(iPlaybackMode == PM_DVD)
  1610. {
  1611. CComPtr<IDvdState> pDvdState;
  1612. pDvdState.Attach((IDvdState*)lParam);
  1613. if(pDVDC) pDVDC->SetState(pDvdState, DVD_CMD_FLAG_Block, NULL);
  1614. }
  1615. else if(iPlaybackMode == PM_CAPTURE)
  1616. {
  1617. // not implemented
  1618. }
  1619. else
  1620. {
  1621. ASSERT(0);
  1622. return FALSE;
  1623. }
  1624. return TRUE;
  1625. }
  1626. BOOL CMainFrame::OnButton(UINT id, UINT nFlags, CPoint point)
  1627. {
  1628. SetFocus();
  1629. CRect r;
  1630. m_wndView.GetClientRect(r);
  1631. m_wndView.MapWindowPoints(this, &r);
  1632. if(id != wmcmd::WDOWN && id != wmcmd::WUP && !r.PtInRect(point)) return FALSE;
  1633. BOOL ret = FALSE;
  1634. AppSettings& s = AfxGetAppSettings();
  1635. POSITION pos = s.wmcmds.GetHeadPosition();
  1636. while(pos)
  1637. {
  1638. wmcmd& wc = s.wmcmds.GetNext(pos);
  1639. if(wc.mouse == id)
  1640. {
  1641. SendMessage(WM_COMMAND, wc.cmd);
  1642. ret = true;
  1643. }
  1644. }
  1645. return ret;
  1646. }
  1647. static bool s_fLDown = false;
  1648. void CMainFrame::OnLButtonDown(UINT nFlags, CPoint point)
  1649. {
  1650. SetFocus();
  1651. bool fClicked = false;
  1652. if(m_iPlaybackMode == PM_DVD)
  1653. {
  1654. CPoint p = point - m_wndView.GetVideoRect().TopLeft();
  1655. if(SUCCEEDED(pDVDC->ActivateAtPosition(p))
  1656. || m_iDVDDomain == DVD_DOMAIN_VideoManagerMenu 
  1657. || m_iDVDDomain == DVD_DOMAIN_VideoTitleSetMenu)
  1658. fClicked = true;
  1659. }
  1660. if(!fClicked)
  1661. {
  1662. bool fLeftMouseBtnUnassigned = true;
  1663. AppSettings& s = AfxGetAppSettings();
  1664. POSITION pos = s.wmcmds.GetHeadPosition();
  1665. while(pos && fLeftMouseBtnUnassigned)
  1666. if(s.wmcmds.GetNext(pos).mouse == wmcmd::LDOWN)
  1667. fLeftMouseBtnUnassigned = false;
  1668. if(!m_fFullScreen && (IsCaptionMenuHidden() || fLeftMouseBtnUnassigned))
  1669. {
  1670. PostMessage(WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x, point.y));
  1671. }
  1672. else
  1673. {
  1674. s_fLDown = true;
  1675. if(OnButton(wmcmd::LDOWN, nFlags, point))
  1676. return;
  1677. }
  1678. }
  1679. __super::OnLButtonDown(nFlags, point);
  1680. }
  1681. void CMainFrame::OnLButtonUp(UINT nFlags, CPoint point)
  1682. {
  1683. if(!OnButton(wmcmd::LUP, nFlags, point))
  1684. __super::OnLButtonUp(nFlags, point);
  1685. }
  1686. void CMainFrame::OnLButtonDblClk(UINT nFlags, CPoint point)
  1687. {
  1688. if(s_fLDown)
  1689. {
  1690. SendMessage(WM_LBUTTONDOWN, nFlags, MAKELPARAM(point.x, point.y));
  1691. s_fLDown = false;
  1692. }
  1693. if(!OnButton(wmcmd::LDBLCLK, nFlags, point))
  1694. __super::OnLButtonDblClk(nFlags, point);
  1695. }
  1696. void CMainFrame::OnMButtonDown(UINT nFlags, CPoint point)
  1697. {
  1698. SendMessage(WM_CANCELMODE);
  1699. if(!OnButton(wmcmd::MDOWN, nFlags, point))
  1700. __super::OnMButtonDown(nFlags, point);
  1701. }
  1702. void CMainFrame::OnMButtonUp(UINT nFlags, CPoint point)
  1703. {
  1704. if(!OnButton(wmcmd::MUP, nFlags, point))
  1705. __super::OnMButtonUp(nFlags, point);
  1706. }
  1707. void CMainFrame::OnMButtonDblClk(UINT nFlags, CPoint point)
  1708. {
  1709. SendMessage(WM_MBUTTONDOWN, nFlags, MAKELPARAM(point.x, point.y));
  1710. if(!OnButton(wmcmd::MDBLCLK, nFlags, point))
  1711. __super::OnMButtonDblClk(nFlags, point);
  1712. }
  1713. void CMainFrame::OnRButtonDown(UINT nFlags, CPoint point)
  1714. {
  1715. if(!OnButton(wmcmd::RDOWN, nFlags, point))
  1716. __super::OnRButtonDown(nFlags, point);
  1717. }
  1718. void CMainFrame::OnRButtonUp(UINT nFlags, CPoint point)
  1719. {
  1720. if(!OnButton(wmcmd::RUP, nFlags, point))
  1721. __super::OnRButtonUp(nFlags, point);
  1722. }
  1723. void CMainFrame::OnRButtonDblClk(UINT nFlags, CPoint point)
  1724. {
  1725. SendMessage(WM_RBUTTONDOWN, nFlags, MAKELPARAM(point.x, point.y));
  1726. if(!OnButton(wmcmd::RDBLCLK, nFlags, point))
  1727. __super::OnRButtonDblClk(nFlags, point);
  1728. }
  1729. LRESULT CMainFrame::OnXButtonDown(WPARAM wParam, LPARAM lParam)
  1730. {
  1731. SendMessage(WM_CANCELMODE);
  1732. UINT fwButton = GET_XBUTTON_WPARAM(wParam); 
  1733. return OnButton(fwButton == XBUTTON1 ? wmcmd::X1DOWN : fwButton == XBUTTON2 ? wmcmd::X2DOWN : wmcmd::NONE,
  1734. GET_KEYSTATE_WPARAM(wParam), CPoint(lParam));
  1735. }
  1736. LRESULT CMainFrame::OnXButtonUp(WPARAM wParam, LPARAM lParam)
  1737. {
  1738. UINT fwButton = GET_XBUTTON_WPARAM(wParam); 
  1739. return OnButton(fwButton == XBUTTON1 ? wmcmd::X1UP : fwButton == XBUTTON2 ? wmcmd::X2UP : wmcmd::NONE,
  1740. GET_KEYSTATE_WPARAM(wParam), CPoint(lParam));
  1741. }
  1742. LRESULT CMainFrame::OnXButtonDblClk(WPARAM wParam, LPARAM lParam)
  1743. {
  1744. SendMessage(WM_XBUTTONDOWN, wParam, lParam);
  1745. UINT fwButton = GET_XBUTTON_WPARAM(wParam); 
  1746. return OnButton(fwButton == XBUTTON1 ? wmcmd::X1DBLCLK : fwButton == XBUTTON2 ? wmcmd::X2DBLCLK : wmcmd::NONE,
  1747. GET_KEYSTATE_WPARAM(wParam), CPoint(lParam));
  1748. }
  1749. BOOL CMainFrame::OnMouseWheel(UINT nFlags, short zDelta, CPoint point)
  1750. {
  1751. ScreenToClient(&point);
  1752. BOOL fRet = 
  1753. zDelta > 0 ? OnButton(wmcmd::WUP, nFlags, point) :
  1754. zDelta < 0 ? OnButton(wmcmd::WDOWN, nFlags, point) : 
  1755. FALSE;
  1756. return fRet;
  1757. }
  1758. void CMainFrame::OnMouseMove(UINT nFlags, CPoint point)
  1759. {
  1760. if(m_iPlaybackMode == PM_DVD)
  1761. {
  1762. CPoint vp = point - m_wndView.GetVideoRect().TopLeft();
  1763. pDVDC->SelectAtPosition(vp);
  1764. }
  1765. CSize diff = m_lastMouseMove - point;
  1766. if(m_fFullScreen && (abs(diff.cx)+abs(diff.cy)) >= 1)
  1767. {
  1768. int nTimeOut = AfxGetAppSettings().nShowBarsWhenFullScreenTimeOut;
  1769. if(nTimeOut < 0)
  1770. {
  1771. m_fHideCursor = false;
  1772. if(AfxGetAppSettings().fShowBarsWhenFullScreen)
  1773. ShowControls(AfxGetAppSettings().nCS);
  1774. KillTimer(TIMER_FULLSCREENCONTROLBARHIDER);
  1775. SetTimer(TIMER_FULLSCREENMOUSEHIDER, 2000, NULL);
  1776. }
  1777. else if(nTimeOut == 0)
  1778. {
  1779. CRect r;
  1780. GetClientRect(r);
  1781. r.top = r.bottom;
  1782. POSITION pos = m_bars.GetHeadPosition();
  1783. for(int i = 1; pos; i <<= 1)
  1784. {
  1785. CControlBar* pNext = m_bars.GetNext(pos);
  1786. CSize s = pNext->CalcFixedLayout(FALSE, TRUE);
  1787. if(AfxGetAppSettings().nCS&i) r.top -= s.cy;
  1788. }
  1789. // HACK: the controls would cover the menu too early hiding some buttons
  1790. if(m_iPlaybackMode == PM_DVD
  1791. && (m_iDVDDomain == DVD_DOMAIN_VideoManagerMenu
  1792. || m_iDVDDomain == DVD_DOMAIN_VideoTitleSetMenu))
  1793. r.top = r.bottom - 10;
  1794. m_fHideCursor = false;
  1795. if(r.PtInRect(point))
  1796. {
  1797. if(AfxGetAppSettings().fShowBarsWhenFullScreen)
  1798. ShowControls(AfxGetAppSettings().nCS);
  1799. }
  1800. else
  1801. {
  1802. if(AfxGetAppSettings().fShowBarsWhenFullScreen)
  1803. ShowControls(CS_NONE, false);
  1804. }
  1805. SetTimer(TIMER_FULLSCREENMOUSEHIDER, 2000, NULL);
  1806. }
  1807. else
  1808. {
  1809. m_fHideCursor = false;
  1810. if(AfxGetAppSettings().fShowBarsWhenFullScreen)
  1811. ShowControls(AfxGetAppSettings().nCS);
  1812. SetTimer(TIMER_FULLSCREENCONTROLBARHIDER, nTimeOut*1000, NULL);
  1813. SetTimer(TIMER_FULLSCREENMOUSEHIDER, max(nTimeOut*1000, 2000), NULL);
  1814. }
  1815. }
  1816. m_lastMouseMove = point;
  1817. __super::OnMouseMove(nFlags, point);
  1818. }
  1819. LRESULT CMainFrame::OnNcHitTest(CPoint point)
  1820. {
  1821. LRESULT nHitTest = __super::OnNcHitTest(point);
  1822. return ((IsCaptionMenuHidden()) && nHitTest == HTCLIENT) ? HTCAPTION : nHitTest;
  1823. }
  1824. void CMainFrame::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
  1825. {
  1826. if(pScrollBar->IsKindOf(RUNTIME_CLASS(CVolumeCtrl)))
  1827. {
  1828. OnPlayVolume(0);
  1829. }
  1830. else if(pScrollBar->IsKindOf(RUNTIME_CLASS(CPlayerSeekBar)) && m_iMediaLoadState == MLS_LOADED)
  1831. {
  1832. SeekTo(m_wndSeekBar.GetPos(), !!(::GetKeyState(VK_SHIFT)&0x8000));
  1833. }
  1834. __super::OnHScroll(nSBCode, nPos, pScrollBar);
  1835. }
  1836. void CMainFrame::OnInitMenu(CMenu* pMenu)
  1837. {
  1838. __super::OnInitMenu(pMenu);
  1839. MENUITEMINFO mii;
  1840. mii.cbSize = sizeof(mii);
  1841. for(UINT i = 0, j = pMenu->GetMenuItemCount(); i < j; i++)
  1842. {
  1843. CString str;
  1844. pMenu->GetMenuString(i, str, MF_BYPOSITION);
  1845. CMenu* pSubMenu = NULL;
  1846. if(str == ResStr(IDS_FAVORITES_POPUP))
  1847. {
  1848. SetupFavoritesSubMenu();
  1849. pSubMenu = &m_favorites;
  1850. }
  1851. if(pSubMenu)
  1852. {
  1853. mii.fMask = MIIM_STATE|MIIM_SUBMENU;
  1854. mii.fType = MF_POPUP;
  1855. mii.hSubMenu = pSubMenu->m_hMenu;
  1856. mii.fState = (pSubMenu->GetMenuItemCount() > 0 ? MF_ENABLED : (MF_DISABLED|MF_GRAYED));
  1857. pMenu->SetMenuItemInfo(i, &mii, TRUE);
  1858. }
  1859. }
  1860. }
  1861. void CMainFrame::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu)
  1862. {
  1863. __super::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu);
  1864. static CAtlStringMap<UINT> transl;
  1865. if(transl.IsEmpty())
  1866. {
  1867. transl[_T("Navigate")] = IDS_NAVIGATE_POPUP;
  1868. transl[_T("Open Disc")] = IDS_OPENCDROM_POPUP;
  1869. transl[_T("Filters")] = IDS_FILTERS_POPUP;
  1870. transl[_T("Audio")] = IDS_AUDIO_POPUP;
  1871. transl[_T("Subtitles")] = IDS_SUBTITLES_POPUP;
  1872. transl[_T("Audio Language")] = IDS_AUDIOLANGUAGE_POPUP;
  1873. transl[_T("Subtitle Language")] = IDS_SUBTITLELANGUAGE_POPUP;
  1874. transl[_T("Video Angle")] = IDS_VIDEOANGLE_POPUP;
  1875. transl[_T("Jump To...")] = IDS_JUMPTO_POPUP;
  1876. transl[_T("Favorites")] = IDS_FAVORITES_POPUP;
  1877. transl[_T("Shaders")] = IDS_SHADER_POPUP;
  1878. transl[_T("Video Frame")] = IDS_VIDEOFRAME_POPUP;
  1879. transl[_T("PanScan")] = IDS_PANSCAN_POPUP;
  1880. transl[_T("Aspect Ratio")] = IDS_ASPECTRATIO_POPUP;
  1881. transl[_T("Zoom")] = IDS_ZOOM_POPUP;
  1882. }
  1883. MENUITEMINFO mii;
  1884. mii.cbSize = sizeof(mii);
  1885. for(UINT i = 0, j = pPopupMenu->GetMenuItemCount(); i < j; i++)
  1886. {
  1887. CString str;
  1888. pPopupMenu->GetMenuString(i, str, MF_BYPOSITION);
  1889. CString lookupstr = str;
  1890. lookupstr.Remove('&');
  1891. CMenu* pSubMenu = NULL;
  1892. UINT id;
  1893. if(transl.Lookup(lookupstr, id))
  1894. {
  1895. str = ResStr(id);
  1896. // pPopupMenu->ModifyMenu(i, MF_BYPOSITION|MF_STRING, 0, str);
  1897. MENUITEMINFO mii;
  1898. mii.cbSize = sizeof(mii);
  1899. mii.fMask = MIIM_STRING;
  1900. mii.dwTypeData = (LPTSTR)(LPCTSTR)str;
  1901. pPopupMenu->SetMenuItemInfo(i, &mii, TRUE);
  1902. }
  1903. if(str == ResStr(IDS_NAVIGATE_POPUP))
  1904. {
  1905. UINT fState = (m_iMediaLoadState == MLS_LOADED 
  1906. && (1/*m_iPlaybackMode == PM_DVD *//*|| (m_iPlaybackMode == PM_FILE && m_PlayList.GetCount() > 0)*/)) 
  1907. ? MF_ENABLED 
  1908. : (MF_DISABLED|MF_GRAYED);
  1909. pPopupMenu->EnableMenuItem(i, MF_BYPOSITION|fState);
  1910. }
  1911. else if(str == ResStr(IDS_VIDEOFRAME_POPUP)
  1912. || str == ResStr(IDS_PANSCAN_POPUP)
  1913. || str == ResStr(IDS_ASPECTRATIO_POPUP)
  1914. || str == ResStr(IDS_ZOOM_POPUP))
  1915. {
  1916. UINT fState = (m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly) 
  1917. ? MF_ENABLED 
  1918. : (MF_DISABLED|MF_GRAYED);
  1919. pPopupMenu->EnableMenuItem(i, MF_BYPOSITION|fState);
  1920. }
  1921. else if(str == ResStr(IDS_OPENCDROM_POPUP))
  1922. {
  1923. SetupOpenCDSubMenu();
  1924. pSubMenu = &m_opencds;
  1925. }
  1926. else if(str == ResStr(IDS_FILTERS_POPUP))
  1927. {
  1928. SetupFiltersSubMenu();
  1929. pSubMenu = &m_filters;
  1930. }
  1931. else if(str == ResStr(IDS_AUDIO_POPUP))
  1932. {
  1933. SetupAudioSwitcherSubMenu();
  1934. pSubMenu = &m_audios;
  1935. }
  1936. else if(str == ResStr(IDS_SUBTITLES_POPUP))
  1937. {
  1938. SetupSubtitlesSubMenu();
  1939. pSubMenu = &m_subtitles;
  1940. }
  1941. else if(str == ResStr(IDS_AUDIOLANGUAGE_POPUP))
  1942. {
  1943. SetupNavAudioSubMenu();
  1944. pSubMenu = &m_navaudio;
  1945. }
  1946. else if(str == ResStr(IDS_SUBTITLELANGUAGE_POPUP))
  1947. {
  1948. SetupNavSubtitleSubMenu();
  1949. pSubMenu = &m_navsubtitle;
  1950. }
  1951. else if(str == ResStr(IDS_VIDEOANGLE_POPUP))
  1952. {
  1953. SetupNavAngleSubMenu();
  1954. pSubMenu = &m_navangle;
  1955. }
  1956. else if(str == ResStr(IDS_JUMPTO_POPUP))
  1957. {
  1958. SetupNavChaptersSubMenu();
  1959. pSubMenu = &m_navchapters;
  1960. }
  1961. else if(str == ResStr(IDS_FAVORITES_POPUP))
  1962. {
  1963. SetupFavoritesSubMenu();
  1964. pSubMenu = &m_favorites;
  1965. }
  1966. else if(str == ResStr(IDS_SHADER_POPUP))
  1967. {
  1968. SetupShadersSubMenu();
  1969. pSubMenu = &m_shaders;
  1970. }
  1971. if(pSubMenu)
  1972. {
  1973. mii.fMask = MIIM_STATE|MIIM_SUBMENU;
  1974. mii.fType = MF_POPUP;
  1975. mii.hSubMenu = pSubMenu->m_hMenu;
  1976. mii.fState = (pSubMenu->GetMenuItemCount() > 0 ? MF_ENABLED : (MF_DISABLED|MF_GRAYED));
  1977. pPopupMenu->SetMenuItemInfo(i, &mii, TRUE);
  1978. }
  1979. }
  1980. //
  1981. for(UINT i = 0, j = pPopupMenu->GetMenuItemCount(); i < j; i++)
  1982. {
  1983. UINT nID = pPopupMenu->GetMenuItemID(i);
  1984. if(nID == ID_SEPARATOR || nID == -1
  1985. || nID >= ID_FAVORITES_FILE_START && nID <= ID_FAVORITES_FILE_END
  1986. || nID >= ID_NAVIGATE_CHAP_SUBITEM_START && nID <= ID_NAVIGATE_CHAP_SUBITEM_END)
  1987. continue;
  1988. CString str;
  1989. pPopupMenu->GetMenuString(i, str, MF_BYPOSITION);
  1990. int k = str.Find('t');
  1991. if(k > 0) str = str.Left(k);
  1992. CString key = CPPageAccelTbl::MakeAccelShortcutLabel(nID);
  1993. if(!key.IsEmpty()) str += _T("t") + key;
  1994. if(key.IsEmpty() && i < 0) continue;
  1995. // BUG(?): this disables menu item update ui calls for some reason...
  1996. // pPopupMenu->ModifyMenu(i, MF_BYPOSITION|MF_STRING, nID, str);
  1997. // this works fine
  1998. MENUITEMINFO mii;
  1999. mii.cbSize = sizeof(mii);
  2000. mii.fMask = MIIM_STRING;
  2001. mii.dwTypeData = (LPTSTR)(LPCTSTR)str;
  2002. pPopupMenu->SetMenuItemInfo(i, &mii, TRUE);
  2003. }
  2004. //
  2005. bool fPnSPresets = false;
  2006. for(UINT i = 0, j = pPopupMenu->GetMenuItemCount(); i < j; i++)
  2007. {
  2008. UINT nID = pPopupMenu->GetMenuItemID(i);
  2009. if(nID >= ID_PANNSCAN_PRESETS_START && nID < ID_PANNSCAN_PRESETS_END)
  2010. {
  2011. do
  2012. {
  2013. nID = pPopupMenu->GetMenuItemID(i);
  2014. pPopupMenu->DeleteMenu(i, MF_BYPOSITION);
  2015. j--;
  2016. }
  2017. while(i < j && nID >= ID_PANNSCAN_PRESETS_START && nID < ID_PANNSCAN_PRESETS_END);
  2018. nID = pPopupMenu->GetMenuItemID(i);
  2019. }
  2020. if(nID == ID_VIEW_RESET)
  2021. {
  2022. fPnSPresets = true;
  2023. }
  2024. }
  2025. if(fPnSPresets)
  2026. {
  2027. AppSettings& s = AfxGetAppSettings();
  2028. int i = 0, j = s.m_pnspresets.GetCount();
  2029. for(; i < j; i++)
  2030. {
  2031. int k = 0;
  2032. CString label = s.m_pnspresets[i].Tokenize(_T(","), k);
  2033. pPopupMenu->InsertMenu(ID_VIEW_RESET, MF_BYCOMMAND, ID_PANNSCAN_PRESETS_START+i, label);
  2034. }
  2035. // if(j > 0)
  2036. {
  2037. pPopupMenu->InsertMenu(ID_VIEW_RESET, MF_BYCOMMAND, ID_PANNSCAN_PRESETS_START+i, ResStr(IDS_PANSCAN_EDIT));
  2038. pPopupMenu->InsertMenu(ID_VIEW_RESET, MF_BYCOMMAND|MF_SEPARATOR);
  2039. }
  2040. }
  2041. }
  2042. BOOL CMainFrame::OnMenu(CMenu* pMenu)
  2043. {
  2044. if(!pMenu) return FALSE;
  2045. KillTimer(TIMER_FULLSCREENMOUSEHIDER);
  2046. m_fHideCursor = false;
  2047. CPoint point;
  2048. GetCursorPos(&point);
  2049. pMenu->TrackPopupMenu(TPM_RIGHTBUTTON|TPM_NOANIMATION, point.x+1, point.y+1, this);
  2050. return TRUE;
  2051. }
  2052. void CMainFrame::OnMenuPlayerShort()
  2053. {
  2054. if(IsCaptionMenuHidden())
  2055. {
  2056. OnMenu(m_popupmain.GetSubMenu(0));
  2057. }
  2058. else
  2059. {
  2060. OnMenu(m_popup.GetSubMenu(0));
  2061. }
  2062. }
  2063. void CMainFrame::OnMenuPlayerLong()
  2064. {
  2065. OnMenu(m_popupmain.GetSubMenu(0));
  2066. }
  2067. void CMainFrame::OnMenuFilters()
  2068. {
  2069. SetupFiltersSubMenu();
  2070. OnMenu(&m_filters);
  2071. }
  2072. void CMainFrame::OnUpdatePlayerStatus(CCmdUI* pCmdUI)
  2073. {
  2074. if(m_iMediaLoadState == MLS_LOADING)
  2075. {
  2076. pCmdUI->SetText(ResStr(IDS_CONTROLS_OPENING));
  2077. }
  2078. else if(m_iMediaLoadState == MLS_LOADED)
  2079. {
  2080. CString msg;
  2081. if(!m_playingmsg.IsEmpty())
  2082. {
  2083. msg = m_playingmsg;
  2084. }
  2085. else if(m_fCapturing)
  2086. {
  2087. msg = ResStr(IDS_CONTROLS_CAPTURING);
  2088. if(pAMDF)
  2089. {
  2090. long lDropped = 0;
  2091. pAMDF->GetNumDropped(&lDropped);
  2092. long lNotDropped = 0;
  2093. pAMDF->GetNumNotDropped(&lNotDropped);
  2094. if((lDropped + lNotDropped) > 0)
  2095. {
  2096. CString str;
  2097. str.Format(_T(", Total: %d, Dropped: %d"), lDropped + lNotDropped, lDropped);
  2098. msg += str;
  2099. }
  2100. }
  2101. CComPtr<IPin> pPin;
  2102. if(SUCCEEDED(pCGB->FindPin(m_wndCaptureBar.m_capdlg.m_pDst, PINDIR_INPUT, NULL, NULL, FALSE, 0, &pPin)))
  2103. {
  2104. LONGLONG size = 0;
  2105. if(CComQIPtr<IStream> pStream = pPin)
  2106. {
  2107. pStream->Commit(STGC_DEFAULT);
  2108. WIN32_FIND_DATA findFileData;
  2109. HANDLE h = FindFirstFile(m_wndCaptureBar.m_capdlg.m_file, &findFileData);
  2110. if(h != INVALID_HANDLE_VALUE)
  2111. {
  2112. size = ((LONGLONG)findFileData.nFileSizeHigh << 32) | findFileData.nFileSizeLow;
  2113. CString str;
  2114. if(size < 1024i64*1024)
  2115. str.Format(_T(", Size: %I64dKB"), size/1024);
  2116. else //if(size < 1024i64*1024*1024)
  2117. str.Format(_T(", Size: %I64dMB"), size/1024/1024);
  2118. msg += str;
  2119. FindClose(h);
  2120. }
  2121. }
  2122. ULARGE_INTEGER FreeBytesAvailable, TotalNumberOfBytes, TotalNumberOfFreeBytes;
  2123. if(GetDiskFreeSpaceEx(
  2124. m_wndCaptureBar.m_capdlg.m_file.Left(m_wndCaptureBar.m_capdlg.m_file.ReverseFind('\')+1), 
  2125. &FreeBytesAvailable, &TotalNumberOfBytes, &TotalNumberOfFreeBytes))
  2126. {
  2127. CString str;
  2128. if(FreeBytesAvailable.QuadPart < 1024i64*1024)
  2129. str.Format(_T(", Free: %I64dKB"), FreeBytesAvailable.QuadPart/1024);
  2130. else //if(FreeBytesAvailable.QuadPart < 1024i64*1024*1024)
  2131. str.Format(_T(", Free: %I64dMB"), FreeBytesAvailable.QuadPart/1024/1024);
  2132. msg += str;
  2133. }
  2134. if(m_wndCaptureBar.m_capdlg.m_pMux)
  2135. {
  2136. __int64 pos = 0;
  2137. CComQIPtr<IMediaSeeking> pMuxMS = m_wndCaptureBar.m_capdlg.m_pMux;
  2138. if(pMuxMS && SUCCEEDED(pMuxMS->GetCurrentPosition(&pos)) && pos > 0)
  2139. {
  2140. double bytepersec = 10000000.0 * size / pos;
  2141. if(bytepersec > 0)
  2142. m_rtDurationOverride = __int64(10000000.0 * (FreeBytesAvailable.QuadPart+size) / bytepersec);
  2143. }
  2144. }
  2145. if(m_wndCaptureBar.m_capdlg.m_pVidBuffer
  2146. || m_wndCaptureBar.m_capdlg.m_pAudBuffer)
  2147. {
  2148. int nFreeVidBuffers = 0, nFreeAudBuffers = 0;
  2149. if(CComQIPtr<IBufferFilter> pVB = m_wndCaptureBar.m_capdlg.m_pVidBuffer)
  2150. nFreeVidBuffers = pVB->GetFreeBuffers();
  2151. if(CComQIPtr<IBufferFilter> pAB = m_wndCaptureBar.m_capdlg.m_pAudBuffer)
  2152. nFreeAudBuffers = pAB->GetFreeBuffers();
  2153. CString str;
  2154. str.Format(_T(", Free V/A Buffers: %03d/%03d"), nFreeVidBuffers, nFreeAudBuffers);
  2155. msg += str;
  2156. }
  2157. }
  2158. }
  2159. else if(m_fBuffering)
  2160. {
  2161. BeginEnumFilters(pGB, pEF, pBF)
  2162. {
  2163. if(CComQIPtr<IAMNetworkStatus, &IID_IAMNetworkStatus> pAMNS = pBF)
  2164. {
  2165. long BufferingProgress = 0;
  2166. if(SUCCEEDED(pAMNS->get_BufferingProgress(&BufferingProgress)) && BufferingProgress > 0)
  2167. {
  2168. msg.Format(ResStr(IDS_CONTROLS_BUFFERING), BufferingProgress);
  2169. __int64 start = 0, stop = 0;
  2170. m_wndSeekBar.GetRange(start, stop);
  2171. m_fLiveWM = (stop == start);
  2172. }
  2173. break;
  2174. }
  2175. }
  2176. EndEnumFilters
  2177. }
  2178. else if(pAMOP)
  2179. {
  2180. __int64 t = 0, c = 0;
  2181. if(SUCCEEDED(pAMOP->QueryProgress(&t, &c)) && t > 0 && c < t)
  2182. msg.Format(ResStr(IDS_CONTROLS_BUFFERING), c*100/t);
  2183. if(m_fUpdateInfoBar)
  2184. OpenSetupInfoBar();
  2185. }
  2186. OAFilterState fs = GetMediaState();
  2187. pCmdUI->SetText(
  2188. !msg.IsEmpty() ? msg : 
  2189. fs == State_Stopped ? ResStr(IDS_CONTROLS_STOPPED) :
  2190. (fs == State_Paused || m_fFrameSteppingActive) ? ResStr(IDS_CONTROLS_PAUSED) :
  2191. fs == State_Running ? ResStr(IDS_CONTROLS_PLAYING) :
  2192. _T(""));
  2193. }
  2194. else if(m_iMediaLoadState == MLS_CLOSING)
  2195. {
  2196. pCmdUI->SetText(ResStr(IDS_CONTROLS_CLOSING));
  2197. }
  2198. else
  2199. {
  2200. pCmdUI->SetText(m_closingmsg);
  2201. }
  2202. }
  2203. void CMainFrame::OnFilePostOpenmedia()
  2204. {
  2205. OpenSetupInfoBar();
  2206. OpenSetupStatsBar();
  2207. OpenSetupStatusBar();
  2208. // OpenSetupToolBar();
  2209. OpenSetupCaptureBar();
  2210. __int64 rtDur = 0;
  2211. pMS->GetDuration(&rtDur);
  2212. m_wndPlaylistBar.SetCurTime(rtDur);
  2213. if(m_iPlaybackMode == PM_CAPTURE)
  2214. {
  2215. ShowControlBar(&m_wndSubresyncBar, FALSE, TRUE);
  2216. // ShowControlBar(&m_wndPlaylistBar, FALSE, TRUE);
  2217. // ShowControlBar(&m_wndCaptureBar, TRUE, TRUE);
  2218. }
  2219. m_iMediaLoadState = MLS_LOADED;
  2220. // IMPORTANT: must not call any windowing msgs before
  2221. // this point, it will deadlock when OpenMediaPrivate is
  2222. // still running and the renderer window was created on
  2223. // the same worker-thread
  2224. {
  2225. WINDOWPLACEMENT wp;
  2226. wp.length = sizeof(wp);
  2227. GetWindowPlacement(&wp);
  2228. // restore magnification
  2229. if(IsWindowVisible() && AfxGetAppSettings().fRememberZoomLevel
  2230. && !(m_fFullScreen || wp.showCmd == SW_SHOWMAXIMIZED || wp.showCmd == SW_SHOWMINIMIZED))
  2231. {
  2232. ZoomVideoWindow();
  2233. }
  2234. }
  2235. if(!m_fAudioOnly && (AfxGetAppSettings().nCLSwitches&CLSW_FULLSCREEN))
  2236. {
  2237. SendMessage(WM_COMMAND, ID_VIEW_FULLSCREEN);
  2238. AfxGetAppSettings().nCLSwitches &= ~CLSW_FULLSCREEN;
  2239. }
  2240. SendNowPlayingToMSN();
  2241. SendNowPlayingTomIRC();
  2242. }
  2243. void CMainFrame::OnUpdateFilePostOpenmedia(CCmdUI* pCmdUI)
  2244. {
  2245. pCmdUI->Enable(m_iMediaLoadState == MLS_LOADING);
  2246. }
  2247. void CMainFrame::OnFilePostClosemedia()
  2248. {
  2249. m_wndView.SetVideoRect();
  2250. m_wndSeekBar.Enable(false);
  2251. m_wndSeekBar.SetPos(0);
  2252. m_wndInfoBar.RemoveAllLines();
  2253. m_wndStatsBar.RemoveAllLines();
  2254. m_wndStatusBar.Clear();
  2255. m_wndStatusBar.ShowTimer(false);
  2256. if(IsWindow(m_wndSubresyncBar.m_hWnd))
  2257. {
  2258. ShowControlBar(&m_wndSubresyncBar, FALSE, TRUE); 
  2259. SetSubtitle(NULL);
  2260. }
  2261. if(IsWindow(m_wndCaptureBar.m_hWnd))
  2262. {
  2263. ShowControlBar(&m_wndCaptureBar, FALSE, TRUE);
  2264. m_wndCaptureBar.m_capdlg.SetupVideoControls(_T(""), NULL, NULL, NULL);
  2265. m_wndCaptureBar.m_capdlg.SetupAudioControls(_T(""), NULL, CInterfaceArray<IAMAudioInputMixer>());
  2266. }
  2267. RecalcLayout();
  2268. SetWindowText(ResStr(IDR_MAINFRAME));
  2269. SetAlwaysOnTop(AfxGetAppSettings().iOnTop);
  2270. // this will prevent any further UI updates on the dynamically added menu items
  2271. SetupFiltersSubMenu();
  2272. SetupAudioSwitcherSubMenu();
  2273. SetupSubtitlesSubMenu();
  2274. SetupNavAudioSubMenu();
  2275. SetupNavSubtitleSubMenu();
  2276. SetupNavAngleSubMenu();
  2277. SetupNavChaptersSubMenu();
  2278. SetupFavoritesSubMenu();
  2279. SendNowPlayingToMSN();
  2280. }
  2281. void CMainFrame::OnUpdateFilePostClosemedia(CCmdUI* pCmdUI)
  2282. {
  2283. pCmdUI->Enable(!!m_hWnd && m_iMediaLoadState == MLS_CLOSING);
  2284. }
  2285. void CMainFrame::OnBossKey()
  2286. {
  2287. SendMessage(WM_COMMAND, ID_PLAY_PAUSE);
  2288. if(m_fFullScreen) SendMessage(WM_COMMAND, ID_VIEW_FULLSCREEN);
  2289. SendMessage(WM_SYSCOMMAND, SC_MINIMIZE, -1);
  2290. }
  2291. void CMainFrame::OnStreamAudio(UINT nID)
  2292. {
  2293. nID -= ID_STREAM_AUDIO_NEXT;
  2294. if(m_iMediaLoadState != MLS_LOADED) return;
  2295. CComQIPtr<IAMStreamSelect> pSS = FindFilter(__uuidof(CAudioSwitcherFilter), pGB);
  2296. if(!pSS) pSS = FindFilter(L"{D3CD7858-971A-4838-ACEC-40CA5D529DC8}", pGB); // morgan's switcher
  2297. DWORD cStreams = 0;
  2298. if(pSS && SUCCEEDED(pSS->Count(&cStreams)) && cStreams > 1)
  2299. {
  2300. for(int i = 0; i < (int)cStreams; i++)
  2301. {
  2302. AM_MEDIA_TYPE* pmt = NULL;
  2303. DWORD dwFlags = 0;
  2304. LCID lcid = 0;
  2305. DWORD dwGroup = 0;
  2306. WCHAR* pszName = NULL;
  2307. if(FAILED(pSS->Info(i, &pmt, &dwFlags, &lcid, &dwGroup, &pszName, NULL, NULL)))
  2308. return;
  2309. if(pmt) DeleteMediaType(pmt);
  2310. if(pszName) CoTaskMemFree(pszName);
  2311. if(dwFlags&(AMSTREAMSELECTINFO_ENABLED|AMSTREAMSELECTINFO_EXCLUSIVE))
  2312. {
  2313. pSS->Enable((i+(nID==0?1:cStreams-1))%cStreams, AMSTREAMSELECTENABLE_ENABLE);
  2314. break;
  2315. }
  2316. }
  2317. }
  2318. else if(m_iPlaybackMode == PM_FILE) SendMessage(WM_COMMAND, ID_OGM_AUDIO_NEXT+nID);
  2319. else if(m_iPlaybackMode == PM_DVD) SendMessage(WM_COMMAND, ID_DVD_AUDIO_NEXT+nID);
  2320. }
  2321. void CMainFrame::OnStreamSub(UINT nID)
  2322. {
  2323. nID -= ID_STREAM_SUB_NEXT;
  2324. if(m_iMediaLoadState != MLS_LOADED) return;
  2325. int cnt = 0;
  2326. POSITION pos = m_pSubStreams.GetHeadPosition();
  2327. while(pos) cnt += m_pSubStreams.GetNext(pos)->GetStreamCount();
  2328. if(cnt > 1)
  2329. {
  2330. int i = ((m_iSubtitleSel&0x7fffffff)+(nID==0?1:cnt-1))%cnt;
  2331. m_iSubtitleSel = i | (m_iSubtitleSel&0x80000000);
  2332. UpdateSubtitle();
  2333. SetFocus();
  2334. }
  2335. else if(m_iPlaybackMode == PM_FILE) SendMessage(WM_COMMAND, ID_OGM_SUB_NEXT+nID);
  2336. else if(m_iPlaybackMode == PM_DVD) SendMessage(WM_COMMAND, ID_DVD_SUB_NEXT+nID);
  2337. }
  2338. void CMainFrame::OnStreamSubOnOff()
  2339. {
  2340. if(m_iMediaLoadState != MLS_LOADED) return;
  2341. int cnt = 0;
  2342. POSITION pos = m_pSubStreams.GetHeadPosition();
  2343. while(pos) cnt += m_pSubStreams.GetNext(pos)->GetStreamCount();
  2344. if(cnt > 0)
  2345. {
  2346. m_iSubtitleSel ^= 0x80000000;
  2347. UpdateSubtitle();
  2348. SetFocus();
  2349. }
  2350. else if(m_iPlaybackMode == PM_DVD) SendMessage(WM_COMMAND, ID_DVD_SUB_ONOFF);
  2351. }
  2352. void CMainFrame::OnOgmAudio(UINT nID)
  2353. {
  2354. nID -= ID_OGM_AUDIO_NEXT;
  2355. if(m_iMediaLoadState != MLS_LOADED) return;
  2356. CComQIPtr<IAMStreamSelect> pSS = FindFilter(CLSID_OggSplitter, pGB);
  2357. if(!pSS) pSS = FindFilter(L"{55DA30FC-F16B-49fc-BAA5-AE59FC65F82D}", pGB);
  2358. if(!pSS) return;
  2359.     CAtlArray<int> snds;
  2360. int iSel = -1;
  2361. DWORD cStreams = 0;
  2362. if(SUCCEEDED(pSS->Count(&cStreams)) && cStreams > 1)
  2363. {
  2364. for(int i = 0; i < (int)cStreams; i++)
  2365. {
  2366. AM_MEDIA_TYPE* pmt = NULL;
  2367. DWORD dwFlags = 0;
  2368. LCID lcid = 0;
  2369. DWORD dwGroup = 0;
  2370. WCHAR* pszName = NULL;
  2371. if(FAILED(pSS->Info(i, &pmt, &dwFlags, &lcid, &dwGroup, &pszName, NULL, NULL)))
  2372. return;
  2373. if(dwGroup == 1)
  2374. {
  2375. if(dwFlags&(AMSTREAMSELECTINFO_ENABLED|AMSTREAMSELECTINFO_EXCLUSIVE))
  2376. iSel = snds.GetCount();
  2377. snds.Add(i);
  2378. }
  2379. if(pmt) DeleteMediaType(pmt);
  2380. if(pszName) CoTaskMemFree(pszName);
  2381. }
  2382. int cnt = snds.GetCount();
  2383. if(cnt > 1 && iSel >= 0)
  2384. pSS->Enable(snds[(iSel+(nID==0?1:cnt-1))%cnt], AMSTREAMSELECTENABLE_ENABLE);
  2385. }
  2386. }
  2387. void CMainFrame::OnOgmSub(UINT nID)
  2388. {
  2389. nID -= ID_OGM_SUB_NEXT;
  2390. if(m_iMediaLoadState != MLS_LOADED) return;
  2391. CComQIPtr<IAMStreamSelect> pSS = FindFilter(CLSID_OggSplitter, pGB);
  2392. if(!pSS) pSS = FindFilter(L"{55DA30FC-F16B-49fc-BAA5-AE59FC65F82D}", pGB);
  2393. if(!pSS) return;
  2394.     CAtlArray<int> subs;
  2395. int iSel = -1;
  2396. DWORD cStreams = 0;
  2397. if(SUCCEEDED(pSS->Count(&cStreams)) && cStreams > 1)
  2398. {
  2399. for(int i = 0; i < (int)cStreams; i++)
  2400. {
  2401. AM_MEDIA_TYPE* pmt = NULL;
  2402. DWORD dwFlags = 0;
  2403. LCID lcid = 0;
  2404. DWORD dwGroup = 0;
  2405. WCHAR* pszName = NULL;
  2406. if(FAILED(pSS->Info(i, &pmt, &dwFlags, &lcid, &dwGroup, &pszName, NULL, NULL)))
  2407. return;
  2408. if(dwGroup == 2)
  2409. {
  2410. if(dwFlags&(AMSTREAMSELECTINFO_ENABLED|AMSTREAMSELECTINFO_EXCLUSIVE))
  2411. iSel = subs.GetCount();
  2412. subs.Add(i);
  2413. }
  2414. if(pmt) DeleteMediaType(pmt);
  2415. if(pszName) CoTaskMemFree(pszName);
  2416. }
  2417. int cnt = subs.GetCount();
  2418. if(cnt > 1 && iSel >= 0)
  2419. pSS->Enable(subs[(iSel+(nID==0?1:cnt-1))%cnt], AMSTREAMSELECTENABLE_ENABLE);
  2420. }
  2421. }
  2422. void CMainFrame::OnDvdAngle(UINT nID)
  2423. {
  2424. nID -= ID_DVD_ANGLE_NEXT;
  2425. if(m_iMediaLoadState != MLS_LOADED) return;
  2426. if(pDVDI && pDVDC)
  2427. {
  2428. ULONG ulAnglesAvailable, ulCurrentAngle;
  2429. if(SUCCEEDED(pDVDI->GetCurrentAngle(&ulAnglesAvailable, &ulCurrentAngle)) && ulAnglesAvailable > 1)
  2430. {
  2431. ulCurrentAngle += nID==0 ? 1 : ulAnglesAvailable-1;
  2432. if(ulCurrentAngle > ulAnglesAvailable) ulCurrentAngle = 1;
  2433. else if(ulCurrentAngle < 1) ulCurrentAngle = ulAnglesAvailable;
  2434. pDVDC->SelectAngle(ulCurrentAngle, DVD_CMD_FLAG_Block, NULL);
  2435. }
  2436. }
  2437. }
  2438. void CMainFrame::OnDvdAudio(UINT nID)
  2439. {
  2440. nID -= ID_DVD_AUDIO_NEXT;
  2441. if(m_iMediaLoadState != MLS_LOADED) return;
  2442. if(pDVDI && pDVDC)
  2443. {
  2444. ULONG nStreamsAvailable, nCurrentStream;
  2445. if(SUCCEEDED(pDVDI->GetCurrentAudio(&nStreamsAvailable, &nCurrentStream)) && nStreamsAvailable > 1)
  2446. pDVDC->SelectAudioStream((nCurrentStream+(nID==0?1:nStreamsAvailable-1))%nStreamsAvailable, DVD_CMD_FLAG_Block, NULL);
  2447. }
  2448. }
  2449. void CMainFrame::OnDvdSub(UINT nID)
  2450. {
  2451. nID -= ID_DVD_SUB_NEXT;
  2452. if(m_iMediaLoadState != MLS_LOADED) return;
  2453. if(pDVDI && pDVDC)
  2454. {
  2455. ULONG ulStreamsAvailable, ulCurrentStream;
  2456. BOOL bIsDisabled;
  2457. if(SUCCEEDED(pDVDI->GetCurrentSubpicture(&ulStreamsAvailable, &ulCurrentStream, &bIsDisabled))
  2458. && ulStreamsAvailable > 1)
  2459. {
  2460. pDVDC->SelectSubpictureStream(
  2461. (ulCurrentStream+(nID==0?1:ulStreamsAvailable-1))%ulStreamsAvailable, 
  2462. DVD_CMD_FLAG_Block, NULL);
  2463. }
  2464. }
  2465. }
  2466. void CMainFrame::OnDvdSubOnOff()
  2467. {
  2468. if(m_iMediaLoadState != MLS_LOADED) return;
  2469. if(pDVDI && pDVDC)
  2470. {
  2471. ULONG ulStreamsAvailable, ulCurrentStream;
  2472. BOOL bIsDisabled;
  2473. if(SUCCEEDED(pDVDI->GetCurrentSubpicture(&ulStreamsAvailable, &ulCurrentStream, &bIsDisabled)))
  2474. {
  2475. pDVDC->SetSubpictureState(bIsDisabled, DVD_CMD_FLAG_Block, NULL);
  2476. }
  2477. }
  2478. }
  2479. //
  2480. // menu item handlers
  2481. //
  2482. // file
  2483. void CMainFrame::OnFileOpenQuick()
  2484. {
  2485. if(m_iMediaLoadState == MLS_LOADING || !IsWindow(m_wndPlaylistBar)) return;
  2486. CString filter;
  2487. CAtlArray<CString> mask;
  2488. AfxGetAppSettings().Formats.GetFilter(filter, mask);
  2489. COpenFileDlg fd(mask, true, NULL, NULL, 
  2490. OFN_EXPLORER|OFN_ENABLESIZING|OFN_HIDEREADONLY|OFN_ALLOWMULTISELECT|OFN_ENABLEINCLUDENOTIFY, 
  2491. filter, this);
  2492. if(fd.DoModal() != IDOK) return;
  2493. CAtlList<CString> fns;
  2494. POSITION pos = fd.GetStartPosition();
  2495. while(pos) fns.AddTail(fd.GetNextPathName(pos));
  2496. bool fMultipleFiles = false;
  2497. if(fns.GetCount() > 1 
  2498. || fns.GetCount() == 1 
  2499. && (fns.GetHead()[fns.GetHead().GetLength()-1] == '\'
  2500. || fns.GetHead()[fns.GetHead().GetLength()-1] == '*'))
  2501. {
  2502. fMultipleFiles = true;
  2503. }
  2504. SendMessage(WM_COMMAND, ID_FILE_CLOSEMEDIA);
  2505. ShowWindow(SW_SHOW);
  2506. SetForegroundWindow();
  2507. m_wndPlaylistBar.Open(fns, fMultipleFiles);
  2508. if(m_wndPlaylistBar.GetCount() == 1 && m_wndPlaylistBar.IsWindowVisible() && !m_wndPlaylistBar.IsFloating())
  2509. {
  2510. ShowControlBar(&m_wndPlaylistBar, FALSE, TRUE);
  2511. }
  2512. OpenCurPlaylistItem();
  2513. }
  2514. void CMainFrame::OnFileOpenmedia()
  2515. {
  2516. if(m_iMediaLoadState == MLS_LOADING || !IsWindow(m_wndPlaylistBar)) return;
  2517. COpenDlg dlg;
  2518. if(dlg.DoModal() != IDOK || dlg.m_fns.GetCount() == 0) return;
  2519. if(dlg.m_fAppendPlaylist)
  2520. {
  2521. m_wndPlaylistBar.Append(dlg.m_fns, dlg.m_fMultipleFiles);
  2522. return;
  2523. }
  2524. SendMessage(WM_COMMAND, ID_FILE_CLOSEMEDIA);
  2525. ShowWindow(SW_SHOW);
  2526. SetForegroundWindow();
  2527. m_wndPlaylistBar.Open(dlg.m_fns, dlg.m_fMultipleFiles);
  2528. if(m_wndPlaylistBar.GetCount() == 1 && m_wndPlaylistBar.IsWindowVisible() && !m_wndPlaylistBar.IsFloating())
  2529. {
  2530. ShowControlBar(&m_wndPlaylistBar, FALSE, TRUE);
  2531. }
  2532. OpenCurPlaylistItem();
  2533. }
  2534. void CMainFrame::OnUpdateFileOpen(CCmdUI* pCmdUI)
  2535. {
  2536. pCmdUI->Enable(m_iMediaLoadState != MLS_LOADING);
  2537. }
  2538. BOOL CMainFrame::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCDS)
  2539. {
  2540. if(m_iMediaLoadState == MLS_LOADING || !IsWindow(m_wndPlaylistBar))
  2541. return FALSE;
  2542. if(pCDS->dwData != 0x6ABE51 || pCDS->cbData < sizeof(DWORD))
  2543. return FALSE;
  2544. DWORD len = *((DWORD*)pCDS->lpData);
  2545. TCHAR* pBuff = (TCHAR*)((DWORD*)pCDS->lpData + 1);
  2546. TCHAR* pBuffEnd = (TCHAR*)((BYTE*)pBuff + pCDS->cbData - sizeof(DWORD));
  2547. CAtlList<CString> cmdln;
  2548. while(len-- > 0)
  2549. {
  2550. CString str;
  2551. while(pBuff < pBuffEnd && *pBuff) str += *pBuff++;
  2552. pBuff++;
  2553. cmdln.AddTail(str);
  2554. }
  2555. AppSettings& s = AfxGetAppSettings();
  2556. s.ParseCommandLine(cmdln);
  2557. POSITION pos = s.slFilters.GetHeadPosition();
  2558. while(pos)
  2559. {
  2560. CString fullpath = MakeFullPath(s.slFilters.GetNext(pos));
  2561. CPath tmp(fullpath);
  2562. tmp.RemoveFileSpec();
  2563. tmp.AddBackslash();
  2564. CString path = tmp;
  2565. WIN32_FIND_DATA fd = {0};
  2566. HANDLE hFind = FindFirstFile(fullpath, &fd);
  2567. if(hFind != INVALID_HANDLE_VALUE)
  2568. {
  2569. do
  2570. {
  2571. if(fd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) continue;
  2572. CFilterMapper2 fm2(false);
  2573. fm2.Register(path + fd.cFileName);
  2574. while(!fm2.m_filters.IsEmpty())
  2575. {
  2576. if(FilterOverride* f = fm2.m_filters.RemoveTail())
  2577. {
  2578. f->fTemporary = true;
  2579. bool fFound = false;
  2580. POSITION pos2 = s.filters.GetHeadPosition();
  2581. while(pos2)
  2582. {
  2583. FilterOverride* f2 = s.filters.GetNext(pos2);
  2584. if(f2->type == FilterOverride::EXTERNAL && !f2->path.CompareNoCase(f->path))
  2585. {
  2586. fFound = true;
  2587. break;
  2588. }
  2589. }
  2590. if(!fFound)
  2591. {
  2592. CAutoPtr<FilterOverride> p(f);
  2593. s.filters.AddHead(p);
  2594. }
  2595. }
  2596. }
  2597. }
  2598. while(FindNextFile(hFind, &fd));
  2599. FindClose(hFind);
  2600. }
  2601. }
  2602. bool fSetForegroundWindow = false;
  2603. if((s.nCLSwitches&CLSW_DVD) && !s.slFiles.IsEmpty())
  2604. {
  2605. SendMessage(WM_COMMAND, ID_FILE_CLOSEMEDIA);
  2606. fSetForegroundWindow = true;
  2607. CAutoPtr<OpenDVDData> p(new OpenDVDData());
  2608. if(p) {p->path = s.slFiles.GetHead(); p->subs.AddTailList(&s.slSubs);}
  2609. OpenMedia(p);
  2610. }
  2611. else if(s.nCLSwitches&CLSW_CD)
  2612. {
  2613. SendMessage(WM_COMMAND, ID_FILE_CLOSEMEDIA);
  2614. fSetForegroundWindow = true;
  2615. CAtlList<CString> sl;
  2616. if(!s.slFiles.IsEmpty())
  2617. {
  2618. GetCDROMType(s.slFiles.GetHead()[0], sl);
  2619. }
  2620. else
  2621. {
  2622. CString dir;
  2623. dir.ReleaseBufferSetLength(GetCurrentDirectory(MAX_PATH, dir.GetBuffer(MAX_PATH)));
  2624. GetCDROMType(dir[0], sl);
  2625. for(TCHAR drive = 'C'; sl.IsEmpty() && drive <= 'Z'; drive++)
  2626. {
  2627. GetCDROMType(drive, sl);
  2628. }
  2629. }
  2630. m_wndPlaylistBar.Open(sl, true);
  2631. OpenCurPlaylistItem();
  2632. }
  2633. else if(!s.slFiles.IsEmpty())
  2634. {
  2635. bool fMulti = s.slFiles.GetCount() > 1;
  2636. CAtlList<CString> sl;
  2637. sl.AddTailList(&s.slFiles);
  2638. if(!fMulti) sl.AddTailList(&s.slDubs);
  2639. if((s.nCLSwitches&CLSW_ADD) && m_wndPlaylistBar.GetCount() > 0)
  2640. {
  2641. m_wndPlaylistBar.Append(sl, fMulti, &s.slSubs);
  2642.   if(s.nCLSwitches&(CLSW_OPEN|CLSW_PLAY))
  2643. {
  2644. m_wndPlaylistBar.SetLast();
  2645. OpenCurPlaylistItem();
  2646. }
  2647. }
  2648. else
  2649. {
  2650. SendMessage(WM_COMMAND, ID_FILE_CLOSEMEDIA);
  2651. fSetForegroundWindow = true;
  2652. m_wndPlaylistBar.Open(sl, fMulti, &s.slSubs);
  2653. OpenCurPlaylistItem((s.nCLSwitches&CLSW_STARTVALID) ? s.rtStart : 0);
  2654. s.nCLSwitches &= ~CLSW_STARTVALID;
  2655. s.rtStart = 0;
  2656. }
  2657. }
  2658. else
  2659. {
  2660. s.nCLSwitches = CLSW_NONE;
  2661. }
  2662. if(fSetForegroundWindow && !(s.nCLSwitches&CLSW_NOFOCUS))
  2663. SetForegroundWindow();
  2664. s.nCLSwitches &= ~CLSW_NOFOCUS;
  2665. return TRUE;
  2666. }
  2667. void CMainFrame::OnFileOpendvd()
  2668. {
  2669. if(m_iMediaLoadState == MLS_LOADING) return;
  2670. SendMessage(WM_COMMAND, ID_FILE_CLOSEMEDIA);
  2671. SetForegroundWindow();
  2672. ShowWindow(SW_SHOW);
  2673. CAutoPtr<OpenDVDData> p(new OpenDVDData());
  2674. if(p)
  2675. {
  2676.         AppSettings& s = AfxGetAppSettings();
  2677. if(s.fUseDVDPath && !s.sDVDPath.IsEmpty())
  2678. {
  2679. p->path = s.sDVDPath;
  2680. p->path.Replace('/', '\');
  2681. if(p->path[p->path.GetLength()-1] != '\') p->path += '\';
  2682. }
  2683. }
  2684. OpenMedia(p);
  2685. }
  2686. void CMainFrame::OnFileOpendevice()
  2687. {
  2688. if(m_iMediaLoadState == MLS_LOADING) return;
  2689. COpenCapDeviceDlg capdlg;
  2690. if(capdlg.DoModal() != IDOK)
  2691. return;
  2692. SendMessage(WM_COMMAND, ID_FILE_CLOSEMEDIA);
  2693. SetForegroundWindow();
  2694. ShowWindow(SW_SHOW);
  2695. m_wndPlaylistBar.Empty();
  2696. CAutoPtr<OpenDeviceData> p(new OpenDeviceData());
  2697. if(p) {p->DisplayName[0] = capdlg.m_vidstr; p->DisplayName[1] = capdlg.m_audstr;}
  2698. OpenMedia(p);
  2699. }
  2700. void CMainFrame::OnFileOpenCD(UINT nID)
  2701. {
  2702. nID -= ID_FILE_OPEN_CD_START;
  2703. nID++;
  2704. for(TCHAR drive = 'C'; drive <= 'Z'; drive++)
  2705. {
  2706. CAtlList<CString> sl;
  2707. switch(GetCDROMType(drive, sl))
  2708. {
  2709. case CDROM_Audio:
  2710. case CDROM_VideoCD:
  2711. case CDROM_DVDVideo:
  2712. nID--;
  2713. break;
  2714. default:
  2715. break;
  2716. }
  2717. if(nID == 0)
  2718. {
  2719. SendMessage(WM_COMMAND, ID_FILE_CLOSEMEDIA);
  2720. SetForegroundWindow();
  2721. ShowWindow(SW_SHOW);
  2722. m_wndPlaylistBar.Open(sl, true);
  2723. OpenCurPlaylistItem();
  2724. break;
  2725. }
  2726. }
  2727. }
  2728. void CMainFrame::OnDropFiles(HDROP hDropInfo)
  2729. {
  2730. SetForegroundWindow();
  2731. if(m_wndPlaylistBar.IsWindowVisible())
  2732. {
  2733. m_wndPlaylistBar.OnDropFiles(hDropInfo);
  2734. return;
  2735. }
  2736. CAtlList<CString> sl;
  2737. UINT nFiles = ::DragQueryFile(hDropInfo, (UINT)-1, NULL, 0);
  2738. for(UINT iFile = 0; iFile < nFiles; iFile++)
  2739. {
  2740. CString fn;
  2741. fn.ReleaseBuffer(::DragQueryFile(hDropInfo, iFile, fn.GetBuffer(MAX_PATH), MAX_PATH));
  2742. sl.AddTail(fn);
  2743. }
  2744. ::DragFinish(hDropInfo);
  2745. if(sl.IsEmpty()) return;
  2746. if(sl.GetCount() == 1 && m_iMediaLoadState == MLS_LOADED && m_pCAP)
  2747. {
  2748. if(LoadSubtitle(sl.GetHead()))
  2749. {
  2750. SetSubtitle(m_pSubStreams.GetTail());
  2751. CPath p(sl.GetHead());
  2752. p.StripPath();
  2753. SendStatusMessage(CString((LPCTSTR)p) + _T(" loaded successfully"), 3000);
  2754. return;
  2755. }
  2756. }
  2757. m_wndPlaylistBar.Open(sl, true);
  2758. OpenCurPlaylistItem();
  2759. }
  2760. void CMainFrame::OnFileSaveAs()
  2761. {
  2762. CString ext, in = m_wndPlaylistBar.GetCur(), out = in;
  2763. if(out.Find(_T("://")) < 0)
  2764. {
  2765. ext = CString(CPath(out).GetExtension()).MakeLower();
  2766. if(ext == _T(".cda")) out = out.Left(out.GetLength()-4) + _T(".wav");
  2767. else if(ext == _T(".ifo")) out = out.Left(out.GetLength()-4) + _T(".vob");
  2768. }
  2769. else
  2770. {
  2771. out.Empty();
  2772. }
  2773. CFileDialog fd(FALSE, 0, out, 
  2774. OFN_EXPLORER|OFN_ENABLESIZING|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_PATHMUSTEXIST, 
  2775. _T("All files (*.*)|*.*||"), this, 0); 
  2776. if(fd.DoModal() != IDOK || !in.CompareNoCase(fd.GetPathName())) return;
  2777. CPath p(fd.GetPathName());
  2778. if(!ext.IsEmpty()) p.AddExtension(ext);
  2779. OAFilterState fs = State_Stopped;
  2780. pMC->GetState(0, &fs);
  2781. if(fs == State_Running) pMC->Pause();
  2782. CSaveDlg dlg(in, p);
  2783. dlg.DoModal();
  2784. if(fs == State_Running) pMC->Run();
  2785. }
  2786. void CMainFrame::OnUpdateFileSaveAs(CCmdUI* pCmdUI)
  2787. {
  2788. if(m_iMediaLoadState != MLS_LOADED || m_iPlaybackMode != PM_FILE)
  2789. {
  2790. pCmdUI->Enable(FALSE);
  2791. return;
  2792. }
  2793.     CString fn = m_wndPlaylistBar.GetCur();
  2794. CString ext = fn.Mid(fn.ReverseFind('.')+1).MakeLower();
  2795. int i = fn.Find(_T("://"));
  2796. if(i >= 0)
  2797. {
  2798. CString protocol = fn.Left(i).MakeLower();
  2799. if(protocol != _T("http"))
  2800. {
  2801. pCmdUI->Enable(FALSE);
  2802. return;
  2803. }
  2804. }
  2805. if((GetVersion()&0x80000000) && (ext == _T("cda") || ext == _T("ifo")))
  2806. {
  2807. pCmdUI->Enable(FALSE);
  2808. return;
  2809. }
  2810. pCmdUI->Enable(TRUE);
  2811. }
  2812. bool CMainFrame::GetDIB(BYTE** ppData, long& size, bool fSilent)
  2813. {
  2814. if(!ppData) return false;
  2815. *ppData = NULL;
  2816. size = 0;
  2817. bool fNeedsToPause = !m_pCAP;
  2818. if(fNeedsToPause) fNeedsToPause = !IsVMR7InGraph(pGB);
  2819. if(fNeedsToPause) fNeedsToPause = !IsVMR9InGraph(pGB);
  2820. OAFilterState fs = GetMediaState();
  2821. if(!(m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly && (fs == State_Paused || fs == State_Running)))
  2822. return false;
  2823. if(fs == State_Running && fNeedsToPause)
  2824. {
  2825. pMC->Pause();
  2826. GetMediaState(); // wait for completion of the pause command
  2827. }
  2828. HRESULT hr = S_OK;
  2829. CString errmsg;
  2830. do
  2831. {
  2832. if(m_pCAP)
  2833. {
  2834. hr = m_pCAP->GetDIB(NULL, (DWORD*)&size);
  2835. if(FAILED(hr)) {errmsg.Format(_T("GetDIB failed, hr = %08x"), hr); break;}
  2836. if(!(*ppData = new BYTE[size])) return false;
  2837. hr = m_pCAP->GetDIB(*ppData, (DWORD*)&size);
  2838. if(FAILED(hr)) {errmsg.Format(_T("GetDIB failed, hr = %08x"), hr); break;}
  2839. }
  2840. else
  2841. {
  2842. hr = pBV->GetCurrentImage(&size, NULL);
  2843. if(FAILED(hr) || size == 0) {errmsg.Format(_T("GetCurrentImage failed, hr = %08x"), hr); break;}
  2844. if(!(*ppData = new BYTE[size])) return false;
  2845. hr = pBV->GetCurrentImage(&size, (long*)*ppData);
  2846. if(FAILED(hr)) {errmsg.Format(_T("GetCurrentImage failed, hr = %08x"), hr); break;}
  2847. }
  2848. }
  2849. while(0);
  2850. if(!fSilent)
  2851. {
  2852. if(!errmsg.IsEmpty())
  2853. {
  2854. AfxMessageBox(errmsg, MB_OK);
  2855. }
  2856. }
  2857. if(fs == State_Running && GetMediaState() != State_Running)
  2858. {
  2859. pMC->Run();
  2860. }
  2861. if(FAILED(hr))
  2862. {
  2863. if(*ppData) {ASSERT(0); delete [] *ppData; *ppData = NULL;} // huh?
  2864. return false;
  2865. }
  2866. return true;
  2867. }
  2868. #include "jpeg.h"
  2869. void CMainFrame::SaveDIB(LPCTSTR fn, BYTE* pData, long size)
  2870. {
  2871. CString ext = CString(CPath(fn).GetExtension()).MakeLower();
  2872. if(ext == _T(".bmp"))
  2873. {
  2874. if(FILE* f = _tfopen(fn, _T("wb")))
  2875. {
  2876. BITMAPINFO* bi = (BITMAPINFO*)pData;
  2877. BITMAPFILEHEADER bfh;
  2878. bfh.bfType = 'MB';
  2879. bfh.bfOffBits = sizeof(bfh) + sizeof(bi->bmiHeader);
  2880. bfh.bfSize = sizeof(bfh) + size;
  2881. bfh.bfReserved1 = bfh.bfReserved2 = 0;
  2882. if(bi->bmiHeader.biBitCount <= 8)
  2883. {
  2884. if(bi->bmiHeader.biClrUsed) bfh.bfOffBits += bi->bmiHeader.biClrUsed * sizeof(bi->bmiColors[0]);
  2885. else bfh.bfOffBits += (1 << bi->bmiHeader.biBitCount) * sizeof(bi->bmiColors[0]);
  2886. }
  2887. fwrite(&bfh, 1, sizeof(bfh), f);
  2888. fwrite(pData, 1, size, f);
  2889. fclose(f);
  2890. }
  2891. else
  2892. {
  2893. AfxMessageBox(_T("Cannot create file"), MB_OK);
  2894. }
  2895. }
  2896. else if(ext == _T(".jpg"))
  2897. {
  2898. CJpegEncoderFile(fn).Encode(pData);
  2899. }
  2900. CPath p(fn);
  2901. if(CDC* pDC = m_wndStatusBar.m_status.GetDC())
  2902. {
  2903. CRect r;
  2904. m_wndStatusBar.m_status.GetClientRect(r);
  2905. p.CompactPath(pDC->m_hDC, r.Width());
  2906. m_wndStatusBar.m_status.ReleaseDC(pDC);
  2907. }
  2908. SendStatusMessage((LPCTSTR)p, 3000);
  2909. }
  2910. void CMainFrame::SaveImage(LPCTSTR fn)
  2911. {
  2912. BYTE* pData = NULL;
  2913. long size = 0;
  2914. if(GetDIB(&pData, size))
  2915. {
  2916. SaveDIB(fn, pData, size);
  2917. delete [] pData;
  2918. }
  2919. }
  2920. void CMainFrame::SaveThumbnails(LPCTSTR fn)
  2921. {
  2922. if(!pMC || !pMS || m_iPlaybackMode != PM_FILE /*&& m_iPlaybackMode != PM_DVD*/) 
  2923. return;
  2924. REFERENCE_TIME rtPos = GetPos();
  2925. REFERENCE_TIME rtDur = GetDur();
  2926. if(rtDur <= 0)
  2927. {
  2928. AfxMessageBox(_T("Cannot create thumbnails for files with no duration"));
  2929. return;
  2930. }
  2931. pMC->Pause();
  2932. GetMediaState(); // wait for completion of the pause command
  2933. //
  2934. CSize video, wh(0, 0), arxy(0, 0);
  2935. if(m_pCAP)
  2936. {
  2937. wh = m_pCAP->GetVideoSize(false);
  2938. arxy = m_pCAP->GetVideoSize(true);
  2939. }
  2940. else
  2941. {
  2942. pBV->GetVideoSize(&wh.cx, &wh.cy);
  2943. long arx = 0, ary = 0;
  2944. CComQIPtr<IBasicVideo2> pBV2 = pBV;
  2945. if(pBV2 && SUCCEEDED(pBV2->GetPreferredAspectRatio(&arx, &ary)) && arx > 0 && ary > 0)
  2946. arxy.SetSize(arx, ary);
  2947. }
  2948. if(wh.cx <= 0 || wh.cy <= 0)
  2949. {
  2950. AfxMessageBox(_T("Failed to get video frame size"));
  2951. return;
  2952. }
  2953. // with the overlay mixer IBasicVideo2 won't tell the new AR when changed dynamically
  2954. DVD_VideoAttributes VATR;
  2955. if(m_iPlaybackMode == PM_DVD && SUCCEEDED(pDVDI->GetCurrentVideoAttributes(&VATR)))
  2956. arxy.SetSize(VATR.ulAspectX, VATR.ulAspectY);
  2957. video = (arxy.cx <= 0 || arxy.cy <= 0) ? wh : CSize(MulDiv(wh.cy, arxy.cx, arxy.cy), wh.cy);
  2958. //
  2959. AppSettings& s = AfxGetAppSettings();
  2960. int cols = s.ThumbCols, rows = s.ThumbRows;
  2961. int margin = 5;
  2962. int infoheight = 70;
  2963. int width = s.ThumbWidth;
  2964. int height = width * video.cy / video.cx * rows / cols + infoheight;
  2965. int dibsize = sizeof(BITMAPINFOHEADER) + width*height*4;
  2966. CAutoVectorPtr<BYTE> dib;
  2967. if(!dib.Allocate(dibsize))
  2968. {
  2969. AfxMessageBox(_T("Out of memory, go buy some more!"));
  2970. return;
  2971. }
  2972. BITMAPINFOHEADER* bih = (BITMAPINFOHEADER*)(BYTE*)dib;
  2973. memset(bih, 0, sizeof(BITMAPINFOHEADER));
  2974. bih->biSize = sizeof(BITMAPINFOHEADER);
  2975. bih->biWidth = width;
  2976. bih->biHeight = height;
  2977. bih->biPlanes = 1;
  2978. bih->biBitCount = 32;
  2979. bih->biCompression = BI_RGB;
  2980. bih->biSizeImage = width*height*4;
  2981. memsetd(bih + 1, 0xffffff, bih->biSizeImage);
  2982. SubPicDesc spd;
  2983. spd.w = width;
  2984. spd.h = height;
  2985. spd.bpp = 32;
  2986. spd.pitch = -width*4;
  2987. spd.bits = (BYTE*)(bih + 1) + (width*4)*(height-1);
  2988. {
  2989. BYTE* p = (BYTE*)spd.bits;
  2990. for(int y = 0; y < spd.h; y++, p += spd.pitch)
  2991. for(int x = 0; x < spd.w; x++)
  2992. ((DWORD*)p)[x] = 0x010101 * (0xe0 + 0x08*y/spd.h + 0x18*(spd.w-x)/spd.w);
  2993. }
  2994. CCritSec csSubLock;
  2995. RECT bbox;
  2996. for(int i = 1, pics = cols*rows; i <= pics; i++)
  2997. {
  2998. REFERENCE_TIME rt = rtDur * i / (pics+1);
  2999. DVD_HMSF_TIMECODE hmsf = RT2HMSF(rt, 25);
  3000. SeekTo(rt);
  3001. m_VolumeBeforeFrameStepping = m_wndToolBar.Volume;
  3002. pBA->put_Volume(-10000);
  3003. HRESULT hr = pFS ? pFS->Step(1, NULL) : E_FAIL;
  3004. if(FAILED(hr))
  3005. {
  3006. pBA->put_Volume(m_VolumeBeforeFrameStepping);
  3007. AfxMessageBox(_T("Cannot frame step, try a different video renderer."));
  3008. return;
  3009. }
  3010. HANDLE hGraphEvent = NULL;
  3011. pME->GetEventHandle((OAEVENT*)&hGraphEvent);
  3012. while(hGraphEvent && WaitForSingleObject(hGraphEvent, INFINITE) == WAIT_OBJECT_0)
  3013. {
  3014. LONG evCode = 0, evParam1, evParam2;
  3015. while(SUCCEEDED(pME->GetEvent(&evCode, (LONG_PTR*)&evParam1, (LONG_PTR*)&evParam2, 0)))
  3016. {
  3017. pME->FreeEventParams(evCode, evParam1, evParam2);
  3018. if(EC_STEP_COMPLETE == evCode) hGraphEvent = NULL;
  3019. }
  3020. }
  3021. pBA->put_Volume(m_VolumeBeforeFrameStepping);
  3022. int col = (i-1)%cols;
  3023. int row = (i-1)/cols;
  3024. CSize s((width-margin*2)/cols, (height-margin*2-infoheight)/rows);
  3025. CPoint p(margin+col*s.cx, margin+row*s.cy+infoheight);
  3026. CRect r(p, s);
  3027. r.DeflateRect(margin, margin);
  3028. CRenderedTextSubtitle rts(&csSubLock);
  3029. rts.CreateDefaultStyle(0);
  3030. rts.m_dstScreenSize.SetSize(width, height);
  3031. STSStyle* style = new STSStyle();
  3032. style->marginRect.SetRectEmpty();
  3033. rts.AddStyle(_T("thumbs"), style);
  3034. CStringW str;
  3035. str.Format(L"{\an7\1c&Hffffff&\4a&Hb0&\bord1\shad4\be1}{\p1}m %d %d l %d %d %d %d %d %d{\p}", 
  3036. r.left, r.top, r.right, r.top, r.right, r.bottom, r.left, r.bottom);
  3037. rts.Add(str, true, 0, 1, _T("thumbs"));
  3038. str.Format(L"{\an3\1c&Hffffff&\3c&H000000&\alpha&H80&\fs16\b1\bord2\shad0\pos(%d,%d)}%02d:%02d:%02d", 
  3039. r.right-5, r.bottom-3, hmsf.bHours, hmsf.bMinutes, hmsf.bSeconds);
  3040. rts.Add(str, true, 1, 2, _T("thumbs"));
  3041. rts.Render(spd, 0, 25, bbox);
  3042. BYTE* pData = NULL;
  3043. long size = 0;
  3044. if(!GetDIB(&pData, size)) return;
  3045. BITMAPINFO* bi = (BITMAPINFO*)pData;
  3046. if(bi->bmiHeader.biBitCount != 32)
  3047. {
  3048. delete [] pData;
  3049. CString str;
  3050. str.Format(_T("Invalid image format, cannot create thumbnails out of %d bpp dibs."), bi->bmiHeader.biBitCount);
  3051. AfxMessageBox(str);
  3052. return;
  3053. }
  3054. int sw = bi->bmiHeader.biWidth;
  3055. int sh = abs(bi->bmiHeader.biHeight);
  3056. int sp = sw*4;
  3057. const BYTE* src = pData + sizeof(bi->bmiHeader);
  3058. if(bi->bmiHeader.biHeight >= 0) {src += sp*(sh-1); sp = -sp;}
  3059. int dw = spd.w;
  3060. int dh = spd.h;
  3061. int dp = spd.pitch;
  3062. BYTE* dst = (BYTE*)spd.bits + spd.pitch*r.top + r.left*4;
  3063. for(DWORD h = r.bottom - r.top, y = 0, yd = (sh<<8)/h; h > 0; y += yd, h--)
  3064. {
  3065. DWORD yf = y&0xff;
  3066. DWORD yi = y>>8;
  3067. DWORD* s0 = (DWORD*)(src + yi*sp);
  3068. DWORD* s1 = (DWORD*)(src + yi*sp + sp);
  3069. DWORD* d = (DWORD*)dst;
  3070. for(DWORD w = r.right - r.left, x = 0, xd = (sw<<8)/w; w > 0; x += xd, w--)
  3071. {
  3072. DWORD xf = x&0xff;
  3073. DWORD xi = x>>8;
  3074. DWORD c0 = s0[xi];
  3075. DWORD c1 = s0[xi+1];
  3076. DWORD c2 = s1[xi];
  3077. DWORD c3 = s1[xi+1];
  3078. c0 = ((c0&0xff00ff) + ((((c1&0xff00ff) - (c0&0xff00ff)) * xf) >> 8)) & 0xff00ff
  3079.   | ((c0&0x00ff00) + ((((c1&0x00ff00) - (c0&0x00ff00)) * xf) >> 8)) & 0x00ff00;
  3080. c2 = ((c2&0xff00ff) + ((((c3&0xff00ff) - (c2&0xff00ff)) * xf) >> 8)) & 0xff00ff
  3081.   | ((c2&0x00ff00) + ((((c3&0x00ff00) - (c2&0x00ff00)) * xf) >> 8)) & 0x00ff00;
  3082. c0 = ((c0&0xff00ff) + ((((c2&0xff00ff) - (c0&0xff00ff)) * yf) >> 8)) & 0xff00ff
  3083.   | ((c0&0x00ff00) + ((((c2&0x00ff00) - (c0&0x00ff00)) * yf) >> 8)) & 0x00ff00;
  3084. *d++ = c0;
  3085. }
  3086. dst += dp;
  3087. }
  3088. rts.Render(spd, 10000, 25, bbox);
  3089. delete [] pData;
  3090. }
  3091. {
  3092. CRenderedTextSubtitle rts(&csSubLock);
  3093. rts.CreateDefaultStyle(0);
  3094. rts.m_dstScreenSize.SetSize(width, height);
  3095. STSStyle* style = new STSStyle();
  3096. style->marginRect.SetRect(margin*2, margin*2, margin*2, height-infoheight-margin);
  3097. rts.AddStyle(_T("thumbs"), style);
  3098. CStringW str;
  3099. str.Format(L"{\an9\fs%d\b1\bord0\shad0\1c&Hffffff&}%s", infoheight-10, width >= 550 ? L"Media Player Classic" : L"MPC");
  3100. rts.Add(str, true, 0, 1, _T("thumbs"), _T(""), _T(""), CRect(0,0,0,0), -1);
  3101. DVD_HMSF_TIMECODE hmsf = RT2HMSF(rtDur, 25);
  3102. CPath path(m_wndPlaylistBar.GetCur());
  3103. path.StripPath();
  3104. CStringW fn = (LPCTSTR)path;
  3105. CStringW fs;
  3106. WIN32_FIND_DATA wfd;
  3107. HANDLE hFind = FindFirstFile(m_wndPlaylistBar.GetCur(), &wfd);
  3108. if(hFind != INVALID_HANDLE_VALUE)
  3109. {
  3110. FindClose(hFind);
  3111. __int64 size = (__int64(wfd.nFileSizeHigh)<<32)|wfd.nFileSizeLow;
  3112. __int64 shortsize = size;
  3113. CStringW measure = _T("B");
  3114. if(shortsize > 10240) shortsize /= 1024, measure = L"KB";
  3115. if(shortsize > 10240) shortsize /= 1024, measure = L"MB";
  3116. if(shortsize > 10240) shortsize /= 1024, measure = L"GB";
  3117. fs.Format(L"File Size: %I64d%s (%I64d bytes)\N", shortsize, measure, size);
  3118. }
  3119. CStringW ar;
  3120. if(arxy.cx > 0 && arxy.cy > 0 && arxy.cx != wh.cx && arxy.cy != wh.cy)
  3121. ar.Format(L"(%d:%d)", arxy.cx, arxy.cy);
  3122. str.Format(L"{\an7\1c&H000000&\fs16\b0\bord0\shad0}File Name: %s\N%sResolution: %dx%d %s\NDuration: %02d:%02d:%02d", 
  3123. fn, fs, wh.cx, wh.cy, ar, hmsf.bHours, hmsf.bMinutes, hmsf.bSeconds);
  3124. rts.Add(str, true, 0, 1, _T("thumbs"));
  3125. rts.Render(spd, 0, 25, bbox);
  3126. }
  3127. SaveDIB(fn, (BYTE*)dib, dibsize);
  3128. SeekTo(rtPos);
  3129. }
  3130. static CString MakeSnapshotFileName(LPCTSTR prefix)
  3131. {
  3132. CTime t = CTime::GetCurrentTime();
  3133. CString fn;
  3134. fn.Format(_T("%s%s%s"), prefix, t.Format(_T("%Y%m%d%H%M%S")), AfxGetAppSettings().SnapShotExt);
  3135. return fn;
  3136. }
  3137. void CMainFrame::OnFileSaveImage()
  3138. {
  3139. AppSettings& s = AfxGetAppSettings();
  3140. CPath psrc(s.SnapShotPath);
  3141. psrc.Combine(s.SnapShotPath, MakeSnapshotFileName(_T("snapshot")));
  3142. CFileDialog fd(FALSE, 0, (LPCTSTR)psrc, 
  3143. OFN_EXPLORER|OFN_ENABLESIZING|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_PATHMUSTEXIST, 
  3144. _T("Bitmaps (*.bmp)|*.bmp|Jpeg (*.jpg)|*.jpg||"), this, 0);
  3145. if(s.SnapShotExt == _T(".bmp")) fd.m_pOFN->nFilterIndex = 1;
  3146. else if(s.SnapShotExt == _T(".jpg")) fd.m_pOFN->nFilterIndex = 2;
  3147. if(fd.DoModal() != IDOK) return;
  3148. if(fd.m_pOFN->nFilterIndex == 1) s.SnapShotExt = _T(".bmp");
  3149. else if(fd.m_pOFN->nFilterIndex = 2) s.SnapShotExt = _T(".jpg");
  3150. CPath pdst(fd.GetPathName());
  3151. if(pdst.GetExtension().MakeLower() != s.SnapShotExt) pdst = CPath((LPCTSTR)pdst + s.SnapShotExt);
  3152. CString path = (LPCTSTR)pdst;
  3153. pdst.RemoveFileSpec();
  3154. s.SnapShotPath = (LPCTSTR)pdst;
  3155. SaveImage(path);
  3156. }
  3157. void CMainFrame::OnFileSaveImageAuto()
  3158. {
  3159. CString fn;
  3160. fn.Format(_T("%s\%s"), AfxGetAppSettings().SnapShotPath, MakeSnapshotFileName(_T("snapshot")));
  3161. SaveImage(fn);
  3162. }
  3163. void CMainFrame::OnUpdateFileSaveImage(CCmdUI* pCmdUI)
  3164. {
  3165. OAFilterState fs = GetMediaState();
  3166. pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly && (fs == State_Paused || fs == State_Running));
  3167. }
  3168. void CMainFrame::OnFileSaveThumbnails()
  3169. {
  3170. AppSettings& s = AfxGetAppSettings();
  3171. CPath psrc(s.SnapShotPath);
  3172. psrc.Combine(s.SnapShotPath, MakeSnapshotFileName(_T("thumbs")));
  3173. CSaveThumbnailsDialog fd(
  3174. s.ThumbRows, s.ThumbCols, s.ThumbWidth,
  3175. 0, (LPCTSTR)psrc, 
  3176. _T("Bitmaps (*.bmp)|*.bmp|Jpeg (*.jpg)|*.jpg||"), this);
  3177. if(s.SnapShotExt == _T(".bmp")) fd.m_pOFN->nFilterIndex = 1;
  3178. else if(s.SnapShotExt == _T(".jpg")) fd.m_pOFN->nFilterIndex = 2;
  3179. if(fd.DoModal() != IDOK) return;
  3180. if(fd.m_pOFN->nFilterIndex == 1) s.SnapShotExt = _T(".bmp");
  3181. else if(fd.m_pOFN->nFilterIndex = 2) s.SnapShotExt = _T(".jpg");
  3182. s.ThumbRows = fd.m_rows;
  3183. s.ThumbCols = fd.m_cols;
  3184. s.ThumbWidth = fd.m_width;
  3185. CPath pdst(fd.GetPathName());
  3186. if(pdst.GetExtension().MakeLower() != s.SnapShotExt) pdst = CPath((LPCTSTR)pdst + s.SnapShotExt);
  3187. CString path = (LPCTSTR)pdst;
  3188. pdst.RemoveFileSpec();
  3189. s.SnapShotPath = (LPCTSTR)pdst;
  3190. SaveThumbnails(path);
  3191. }
  3192. void CMainFrame::OnUpdateFileSaveThumbnails(CCmdUI* pCmdUI)
  3193. {
  3194. OAFilterState fs = GetMediaState();
  3195. pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly && (m_iPlaybackMode == PM_FILE /*|| m_iPlaybackMode == PM_DVD*/));
  3196. }
  3197. void CMainFrame::OnFileConvert()
  3198. {
  3199. CConvertDlg().DoModal();
  3200. }
  3201. void CMainFrame::OnUpdateFileConvert(CCmdUI* pCmdUI)
  3202. {
  3203. // TODO: Add your command update UI handler code here
  3204. }
  3205. void CMainFrame::OnFileLoadsubtitle()
  3206. {
  3207. #ifndef DEBUG
  3208. if(!m_pCAP)
  3209. {
  3210. AfxMessageBox(_T("To load subtitles you have change the video renderer type and reopen the file.n")
  3211. _T("- DirectShow: VMR7/VMR9 renderless or Haali'sn")
  3212. _T("- RealMedia: Special renderer for RealMedia, or open it through DirectShown")
  3213. _T("- Quicktime: DX7 or DX9 renderer for QuickTimen")
  3214. _T("- ShockWave: n/an")
  3215. , MB_OK);
  3216. return;
  3217. }
  3218. #endif
  3219. static TCHAR BASED_CODE szFilter[] = 
  3220. _T(".srt .sub .ssa .ass .smi .psb .txt .idx .usf .xss .ssf|")
  3221. _T("*.srt;*.sub;*.ssa;*.ass;*smi;*.psb;*.txt;*.idx;*.usf;*.xss;*.ssf|")
  3222. _T("All files (*.*)|")
  3223. _T("*.*||");
  3224. CFileDialog fd(TRUE, NULL, NULL, 
  3225. OFN_EXPLORER | OFN_ENABLESIZING | OFN_HIDEREADONLY, 
  3226. szFilter, this, 0);
  3227. if(fd.DoModal() != IDOK) return;
  3228. if(LoadSubtitle(fd.GetPathName()))
  3229. SetSubtitle(m_pSubStreams.GetTail());
  3230. }
  3231. void CMainFrame::OnUpdateFileLoadsubtitle(CCmdUI *pCmdUI)
  3232. {
  3233. #ifdef DEBUG
  3234. pCmdUI->Enable();
  3235. #else
  3236. pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && /*m_pCAP &&*/ !m_fAudioOnly);
  3237. #endif
  3238. }
  3239. void CMainFrame::OnFileSavesubtitle()
  3240. {
  3241. int i = m_iSubtitleSel;
  3242. POSITION pos = m_pSubStreams.GetHeadPosition();
  3243. while(pos && i >= 0)
  3244. {
  3245. CComPtr<ISubStream> pSubStream = m_pSubStreams.GetNext(pos);
  3246. if(i < pSubStream->GetStreamCount())
  3247. {
  3248. CLSID clsid;
  3249. if(FAILED(pSubStream->GetClassID(&clsid)))
  3250. continue;
  3251. if(clsid == __uuidof(CVobSubFile))
  3252. {
  3253. CVobSubFile* pVSF = (CVobSubFile*)(ISubStream*)pSubStream;
  3254. CFileDialog fd(FALSE, NULL, NULL, 
  3255. OFN_EXPLORER|OFN_ENABLESIZING|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_PATHMUSTEXIST, 
  3256. _T("VobSub (*.idx, *.sub)|*.idx;*.sub||"), this, 0);
  3257. if(fd.DoModal() == IDOK)
  3258. {
  3259. CAutoLock cAutoLock(&m_csSubLock);
  3260. pVSF->Save(fd.GetPathName());
  3261. }
  3262.             
  3263. return;
  3264. }
  3265. else if(clsid == __uuidof(CRenderedTextSubtitle))
  3266. {
  3267. CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)pSubStream;
  3268. CString filter;
  3269. filter += _T("Subripper (*.srt)|*.srt|");
  3270. filter += _T("Microdvd (*.sub)|*.sub|");
  3271. filter += _T("Sami (*.smi)|*.smi|");
  3272. filter += _T("Psb (*.psb)|*.psb|");
  3273. filter += _T("Sub Station Alpha (*.ssa)|*.ssa|");
  3274. filter += _T("Advanced Sub Station Alpha (*.ass)|*.ass|");
  3275. filter += _T("|");
  3276. CSaveTextFileDialog fd(pRTS->m_encoding, NULL, NULL, filter, this);
  3277. if(fd.DoModal() == IDOK)
  3278. {
  3279. CAutoLock cAutoLock(&m_csSubLock);
  3280. pRTS->SaveAs(fd.GetPathName(), (exttype)(fd.m_ofn.nFilterIndex-1), m_pCAP->GetFPS(), fd.GetEncoding());
  3281. }
  3282.             
  3283. return;
  3284. }
  3285. }
  3286. i -= pSubStream->GetStreamCount();
  3287. }
  3288. }
  3289. void CMainFrame::OnUpdateFileSavesubtitle(CCmdUI* pCmdUI)
  3290. {
  3291. pCmdUI->Enable(m_iSubtitleSel >= 0);
  3292. }
  3293. ///////////////
  3294. #include "SubtitleDlDlg.h"
  3295. #include "ISDb.h"
  3296. void CMainFrame::OnFileISDBSearch()
  3297. {
  3298. CStringA url = "http://" + AfxGetAppSettings().ISDb + "/index.php?";
  3299. CStringA args = makeargs(m_wndPlaylistBar.m_pl);
  3300. ShellExecute(m_hWnd, _T("open"), CString(url+args), NULL, NULL, SW_SHOWDEFAULT);
  3301. }
  3302. void CMainFrame::OnUpdateFileISDBSearch(CCmdUI *pCmdUI)
  3303. {
  3304. pCmdUI->Enable(TRUE);
  3305. }
  3306. void CMainFrame::OnFileISDBUpload()
  3307. {
  3308. CStringA url = "http://" + AfxGetAppSettings().ISDb + "/ul.php?";
  3309. CStringA args = makeargs(m_wndPlaylistBar.m_pl);
  3310. ShellExecute(m_hWnd, _T("open"), CString(url+args), NULL, NULL, SW_SHOWDEFAULT);
  3311. }
  3312. void CMainFrame::OnUpdateFileISDBUpload(CCmdUI *pCmdUI)
  3313. {
  3314. pCmdUI->Enable(m_wndPlaylistBar.GetCount() > 0);
  3315. }
  3316. void CMainFrame::OnFileISDBDownload()
  3317. {
  3318. filehash fh;
  3319. if(!hash(m_wndPlaylistBar.GetCur(), fh))
  3320. {
  3321. MessageBeep(-1);
  3322. return;
  3323. }
  3324. // TODO: put this on a worker thread
  3325. CStringA url = "http://" + AfxGetAppSettings().ISDb + "/index.php?";
  3326. CStringA args;
  3327. args.Format("player=mpc&name[0]=%s&size[0]=%016I64x&hash[0]=%016I64x", 
  3328. UrlEncode(CStringA(fh.name)), fh.size, fh.hash);
  3329. try
  3330. {
  3331. CInternetSession is;
  3332. CStringA str;
  3333. if(!OpenUrl(is, CString(url+args), str))
  3334. {
  3335. MessageBeep(-1);
  3336. return;
  3337. }
  3338. CStringA ticket;
  3339. CList<isdb_movie> movies;
  3340. isdb_movie m;
  3341. isdb_subtitle s;
  3342. CAtlList<CStringA> sl;
  3343. Explode(str, sl, 'n');
  3344. POSITION pos = sl.GetHeadPosition();
  3345. while(pos)
  3346. {
  3347. str = sl.GetNext(pos);
  3348. CStringA param = str.Left(max(0, str.Find('=')));
  3349. CStringA value = str.Mid(str.Find('=')+1);
  3350. if(param == "ticket") ticket = value;
  3351. else if(param == "movie") {m.reset(); Explode(value, m.titles, '|');}
  3352. else if(param == "subtitle") {s.reset(); s.id = atoi(value);}
  3353. else if(param == "name") s.name = value;
  3354. else if(param == "discs") s.discs = atoi(value);
  3355. else if(param == "disc_no") s.disc_no = atoi(value);
  3356. else if(param == "format") s.format = value;
  3357. else if(param == "iso639_2") s.iso639_2 = value;
  3358. else if(param == "language") s.language = value;
  3359. else if(param == "nick") s.nick = value;
  3360. else if(param == "email") s.email = value;
  3361. else if(param == "" && value == "endsubtitle") {m.subs.AddTail(s);}
  3362. else if(param == "" && value == "endmovie") {movies.AddTail(m);}
  3363. else if(param == "" && value == "end") break;
  3364. }
  3365. CSubtitleDlDlg dlg(movies, this);
  3366. if(IDOK == dlg.DoModal())
  3367. {
  3368. if(dlg.m_fReplaceSubs)
  3369. m_pSubStreams.RemoveAll();
  3370. CComPtr<ISubStream> pSubStreamToSet;
  3371. POSITION pos = dlg.m_selsubs.GetHeadPosition();
  3372. while(pos)
  3373. {
  3374. isdb_subtitle& s = dlg.m_selsubs.GetNext(pos);
  3375. CStringA url = "http://" + AfxGetAppSettings().ISDb + "/dl.php?";
  3376. CStringA args;
  3377. args.Format("id=%d&ticket=%s", s.id, UrlEncode(ticket));
  3378. if(OpenUrl(is, CString(url+args), str))
  3379. {
  3380. CComPtr<ISubStream> pSubStream;
  3381. if(!pSubStream)
  3382. {
  3383. CAutoPtr<ssf::CRenderer> p(new ssf::CRenderer(&m_csSubLock));
  3384. if(p->Open(ssf::MemoryInputStream((BYTE*)(LPCSTR)str, str.GetLength(), false, false), CString(s.name)) && p->GetStreamCount() > 0)
  3385. {
  3386. pSubStream = p.Detach();
  3387. }
  3388. }
  3389. if(!pSubStream)
  3390. {
  3391. CAutoPtr<CRenderedTextSubtitle> p(new CRenderedTextSubtitle(&m_csSubLock));
  3392. if(p->Open((BYTE*)(LPCSTR)str, str.GetLength(), DEFAULT_CHARSET, CString(s.name)) && p->GetStreamCount() > 0)
  3393. {
  3394. pSubStream = p.Detach();
  3395. }
  3396. }
  3397. if(pSubStream)
  3398. {
  3399. m_pSubStreams.AddTail(pSubStream);
  3400. if(!pSubStreamToSet) pSubStreamToSet = pSubStream;
  3401. }
  3402. }
  3403. }
  3404. if(pSubStreamToSet)
  3405. SetSubtitle(pSubStreamToSet);
  3406. }
  3407. }
  3408. catch(CInternetException* ie)
  3409. {
  3410. ie->Delete();
  3411. return;
  3412. }
  3413. }
  3414. void CMainFrame::OnUpdateFileISDBDownload(CCmdUI *pCmdUI)
  3415. {
  3416. pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && m_pCAP && !m_fAudioOnly);
  3417. }
  3418. void CMainFrame::OnFileProperties()
  3419. {
  3420. CPPageFileInfoSheet m_fileinfo(m_wndPlaylistBar.GetCur(), this);
  3421. m_fileinfo.DoModal();
  3422. }
  3423. void CMainFrame::OnUpdateFileProperties(CCmdUI* pCmdUI)
  3424. {
  3425. pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && m_iPlaybackMode == PM_FILE);
  3426. }
  3427. void CMainFrame::OnFileCloseMedia()
  3428. {
  3429. CloseMedia();
  3430. }
  3431. void CMainFrame::OnFileClosePlaylist()
  3432. {
  3433. SendMessage(WM_COMMAND, ID_FILE_CLOSEMEDIA);
  3434. RestoreDefaultWindowRect();
  3435. }
  3436. void CMainFrame::OnUpdateFileClose(CCmdUI* pCmdUI)
  3437. {
  3438. pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED || m_iMediaLoadState == MLS_LOADING);
  3439. }
  3440. // view
  3441. void CMainFrame::OnViewCaptionmenu()
  3442. {
  3443. bool fHideCaptionMenu = AfxGetAppSettings().fHideCaptionMenu;
  3444. AfxGetAppSettings().fHideCaptionMenu = !fHideCaptionMenu;
  3445. if(m_fFullScreen) return;
  3446. DWORD dwRemove = 0, dwAdd = 0;
  3447. HMENU hMenu;
  3448. if(!fHideCaptionMenu)
  3449. {
  3450. dwRemove = WS_CAPTION;
  3451. hMenu = NULL;
  3452. }
  3453. else
  3454. {
  3455. dwAdd = WS_CAPTION;
  3456. hMenu = m_hMenuDefault;
  3457. }
  3458. ModifyStyle(dwRemove, dwAdd, SWP_NOZORDER);
  3459. ::SetMenu(m_hWnd, hMenu);
  3460. SetWindowPos(NULL, 0, 0, 0, 0, SWP_FRAMECHANGED|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER);
  3461. MoveVideoWindow();
  3462. }
  3463. void CMainFrame::OnUpdateViewCaptionmenu(CCmdUI* pCmdUI)
  3464. {
  3465. pCmdUI->SetCheck(!AfxGetAppSettings().fHideCaptionMenu);
  3466. }
  3467. void CMainFrame::OnViewControlBar(UINT nID)
  3468. {
  3469. nID -= ID_VIEW_SEEKER;
  3470. ShowControls(AfxGetAppSettings().nCS ^ (1<<nID));
  3471. }
  3472. void CMainFrame::OnUpdateViewControlBar(CCmdUI* pCmdUI)
  3473. {
  3474. UINT nID = pCmdUI->m_nID - ID_VIEW_SEEKER;
  3475. pCmdUI->SetCheck(!!(AfxGetAppSettings().nCS & (1<<nID)));
  3476. }
  3477. void CMainFrame::OnViewSubresync()
  3478. {
  3479. ShowControlBar(&m_wndSubresyncBar, !m_wndSubresyncBar.IsWindowVisible(), TRUE);
  3480. }
  3481. void CMainFrame::OnUpdateViewSubresync(CCmdUI* pCmdUI)
  3482. {
  3483. pCmdUI->SetCheck(m_wndSubresyncBar.IsWindowVisible());
  3484. pCmdUI->Enable(m_pCAP && m_iSubtitleSel >= 0);
  3485. }
  3486. void CMainFrame::OnViewPlaylist()
  3487. {
  3488. ShowControlBar(&m_wndPlaylistBar, !m_wndPlaylistBar.IsWindowVisible(), TRUE);
  3489. }
  3490. void CMainFrame::OnUpdateViewPlaylist(CCmdUI* pCmdUI)
  3491. {
  3492. pCmdUI->SetCheck(m_wndPlaylistBar.IsWindowVisible());
  3493. pCmdUI->Enable(m_iMediaLoadState == MLS_CLOSED && m_iMediaLoadState != MLS_LOADED
  3494. || m_iMediaLoadState == MLS_LOADED /*&& (m_iPlaybackMode == PM_FILE || m_iPlaybackMode == PM_CAPTURE)*/);
  3495. }
  3496. void CMainFrame::OnViewCapture()
  3497. {
  3498. ShowControlBar(&m_wndCaptureBar, !m_wndCaptureBar.IsWindowVisible(), TRUE);
  3499. }
  3500. void CMainFrame::OnUpdateViewCapture(CCmdUI* pCmdUI)
  3501. {
  3502. pCmdUI->SetCheck(m_wndCaptureBar.IsWindowVisible());
  3503. pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && m_iPlaybackMode == PM_CAPTURE);
  3504. }
  3505. void CMainFrame::OnViewShaderEditor()
  3506. {
  3507. ShowControlBar(&m_wndShaderEditorBar, !m_wndShaderEditorBar.IsWindowVisible(), TRUE);
  3508. }
  3509. void CMainFrame::OnUpdateViewShaderEditor(CCmdUI* pCmdUI)
  3510. {
  3511. pCmdUI->SetCheck(m_wndShaderEditorBar.IsWindowVisible());
  3512. pCmdUI->Enable(TRUE);
  3513. }
  3514. void CMainFrame::OnViewMinimal()
  3515. {
  3516. if(!AfxGetAppSettings().fHideCaptionMenu)
  3517. SendMessage(WM_COMMAND, ID_VIEW_CAPTIONMENU);
  3518. ShowControls(0);
  3519. }
  3520. void CMainFrame::OnUpdateViewMinimal(CCmdUI* pCmdUI)
  3521. {
  3522. }
  3523. void CMainFrame::OnViewCompact()
  3524. {
  3525. if(AfxGetAppSettings().fHideCaptionMenu)
  3526. SendMessage(WM_COMMAND, ID_VIEW_CAPTIONMENU);
  3527. ShowControls(CS_TOOLBAR);
  3528. }
  3529. void CMainFrame::OnUpdateViewCompact(CCmdUI* pCmdUI)
  3530. {
  3531. }
  3532. void CMainFrame::OnViewNormal()
  3533. {
  3534. if(AfxGetAppSettings().fHideCaptionMenu)
  3535. SendMessage(WM_COMMAND, ID_VIEW_CAPTIONMENU);
  3536. ShowControls(CS_SEEKBAR|CS_TOOLBAR|CS_STATUSBAR|CS_INFOBAR);
  3537. }
  3538. void CMainFrame::OnUpdateViewNormal(CCmdUI* pCmdUI)
  3539. {
  3540. }
  3541. void CMainFrame::OnViewFullscreen()
  3542. {
  3543. ToggleFullscreen(true, true);
  3544. }
  3545. void CMainFrame::OnViewFullscreenSecondary()
  3546. {
  3547. ToggleFullscreen(true, false);
  3548. }
  3549. void CMainFrame::OnUpdateViewFullscreen(CCmdUI* pCmdUI)
  3550. {
  3551. pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly || m_fFullScreen);
  3552. pCmdUI->SetCheck(m_fFullScreen);
  3553. }
  3554. void CMainFrame::OnViewZoom(UINT nID)
  3555. {
  3556. ZoomVideoWindow(nID == ID_VIEW_ZOOM_50 ? 0.5 : nID == ID_VIEW_ZOOM_200 ? 2.0 : 1.0);
  3557. }
  3558. void CMainFrame::OnUpdateViewZoom(CCmdUI* pCmdUI)
  3559. {
  3560. pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly);
  3561. }
  3562. void CMainFrame::OnViewZoomAutoFit()
  3563. {
  3564. ZoomVideoWindow(GetZoomAutoFitScale());
  3565. }
  3566. void CMainFrame::OnViewDefaultVideoFrame(UINT nID)
  3567. {
  3568. AfxGetAppSettings().iDefaultVideoSize = nID - ID_VIEW_VF_HALF;
  3569. m_ZoomX = m_ZoomY = 1; 
  3570. m_PosX = m_PosY = 0.5;
  3571. MoveVideoWindow();
  3572. }
  3573. void CMainFrame::OnUpdateViewDefaultVideoFrame(CCmdUI* pCmdUI)
  3574. {
  3575. pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly);
  3576. pCmdUI->SetRadio(AfxGetAppSettings().iDefaultVideoSize == (pCmdUI->m_nID - ID_VIEW_VF_HALF));
  3577. }
  3578. void CMainFrame::OnViewKeepaspectratio()
  3579. {
  3580. AfxGetAppSettings().fKeepAspectRatio = !AfxGetAppSettings().fKeepAspectRatio;
  3581. MoveVideoWindow();
  3582. }
  3583. void CMainFrame::OnUpdateViewKeepaspectratio(CCmdUI* pCmdUI)
  3584. {
  3585. pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly);
  3586. pCmdUI->SetCheck(AfxGetAppSettings().fKeepAspectRatio);
  3587. }
  3588. void CMainFrame::OnViewCompMonDeskARDiff()
  3589. {
  3590. AfxGetAppSettings().fCompMonDeskARDiff = !AfxGetAppSettings().fCompMonDeskARDiff;
  3591. MoveVideoWindow();
  3592. }
  3593. void CMainFrame::OnUpdateViewCompMonDeskARDiff(CCmdUI* pCmdUI)
  3594. {
  3595. pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly);
  3596. pCmdUI->SetCheck(AfxGetAppSettings().fCompMonDeskARDiff);
  3597. }
  3598. void CMainFrame::OnViewPanNScan(UINT nID)
  3599. {
  3600. if(m_iMediaLoadState != MLS_LOADED) return;
  3601. int x = 0, y = 0;
  3602. int dx = 0, dy = 0;
  3603. switch(nID)
  3604. {
  3605. case ID_VIEW_RESET: m_ZoomX = m_ZoomY = 1.0; m_PosX = m_PosY = 0.5; m_AngleX = m_AngleY = m_AngleZ = 0; break;
  3606. case ID_VIEW_INCSIZE: x = y = 1; break;
  3607. case ID_VIEW_DECSIZE: x = y = -1; break;
  3608. case ID_VIEW_INCWIDTH: x = 1; break;
  3609. case ID_VIEW_DECWIDTH: x = -1; break;
  3610. case ID_VIEW_INCHEIGHT: y = 1; break;
  3611. case ID_VIEW_DECHEIGHT: y = -1; break;
  3612. case ID_PANSCAN_CENTER: m_PosX = m_PosY = 0.5; break;
  3613. case ID_PANSCAN_MOVELEFT: dx = -1; break;
  3614. case ID_PANSCAN_MOVERIGHT: dx = 1; break;
  3615. case ID_PANSCAN_MOVEUP: dy = -1; break;
  3616. case ID_PANSCAN_MOVEDOWN: dy = 1; break;
  3617. case ID_PANSCAN_MOVEUPLEFT: dx = dy = -1; break;
  3618. case ID_PANSCAN_MOVEUPRIGHT: dx = 1; dy = -1; break;
  3619. case ID_PANSCAN_MOVEDOWNLEFT: dx = -1; dy = 1; break;
  3620. case ID_PANSCAN_MOVEDOWNRIGHT: dx = dy = 1; break;
  3621. default: break;
  3622. }
  3623. if(x > 0 && m_ZoomX < 3) m_ZoomX *= 1.02;
  3624. if(x < 0 && m_ZoomX > 0.2) m_ZoomX /= 1.02;
  3625. if(y > 0 && m_ZoomY < 3) m_ZoomY *= 1.02;
  3626. if(y < 0 && m_ZoomY > 0.2) m_ZoomY /= 1.02;
  3627. if(dx < 0 && m_PosX > 0) m_PosX = max(m_PosX - 0.005*m_ZoomX, 0);
  3628. if(dx > 0 && m_PosX < 1) m_PosX = min(m_PosX + 0.005*m_ZoomX, 1);
  3629. if(dy < 0 && m_PosY > 0) m_PosY = max(m_PosY - 0.005*m_ZoomY, 0);
  3630. if(dy > 0 && m_PosY < 1) m_PosY = min(m_PosY + 0.005*m_ZoomY, 1);
  3631. MoveVideoWindow(true);
  3632. }
  3633. void CMainFrame::OnUpdateViewPanNScan(CCmdUI* pCmdUI)
  3634. {
  3635. pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly);
  3636. }
  3637. void CMainFrame::OnViewPanNScanPresets(UINT nID)
  3638. {
  3639. if(m_iMediaLoadState != MLS_LOADED) return;
  3640. AppSettings& s = AfxGetAppSettings();
  3641. nID -= ID_PANNSCAN_PRESETS_START;
  3642. if(nID == s.m_pnspresets.GetCount())
  3643. {
  3644. CPnSPresetsDlg dlg;
  3645. dlg.m_pnspresets.Copy(s.m_pnspresets);
  3646. if(dlg.DoModal() == IDOK)
  3647. {
  3648. s.m_pnspresets.Copy(dlg.m_pnspresets);
  3649. s.UpdateData(true);
  3650. }
  3651. return;
  3652. }
  3653. m_PosX = 0.5;
  3654. m_PosY = 0.5;
  3655. m_ZoomX = 1.0;
  3656. m_ZoomY = 1.0;
  3657. CString str = s.m_pnspresets[nID];
  3658. int i = 0, j = 0;
  3659. for(CString token = str.Tokenize(_T(","), i); !token.IsEmpty(); token = str.Tokenize(_T(","), i), j++)
  3660. {
  3661. float f = 0;
  3662. if(_stscanf(token, _T("%f"), &f) != 1) continue;
  3663. switch(j)
  3664. {
  3665. case 0: break;
  3666. case 1: m_PosX = f; break;
  3667. case 2: m_PosY = f; break;
  3668. case 3: m_ZoomX = f; break;
  3669. case 4: m_ZoomY = f; break;
  3670. default: break;
  3671. }
  3672. }
  3673. if(j != 5) return;
  3674. m_PosX = min(max(m_PosX, 0), 1);
  3675. m_PosY = min(max(m_PosY, 0), 1);
  3676. m_ZoomX = min(max(m_ZoomX, 0.2), 3);
  3677. m_ZoomY = min(max(m_ZoomY, 0.2), 3);
  3678. MoveVideoWindow(true);
  3679. }
  3680. void CMainFrame::OnUpdateViewPanNScanPresets(CCmdUI* pCmdUI)
  3681. {
  3682. int nID = pCmdUI->m_nID - ID_PANNSCAN_PRESETS_START;
  3683. AppSettings& s = AfxGetAppSettings();
  3684. pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly && nID >= 0 && nID <= s.m_pnspresets.GetCount());
  3685. }
  3686. void CMainFrame::OnViewRotate(UINT nID)
  3687. {
  3688. if(!m_pCAP) return;
  3689. switch(nID)
  3690. {
  3691. case ID_PANSCAN_ROTATEXP: m_AngleX += 2; break;
  3692. case ID_PANSCAN_ROTATEXM: m_AngleX -= 2; break;
  3693. case ID_PANSCAN_ROTATEYP: m_AngleY += 2; break;
  3694. case ID_PANSCAN_ROTATEYM: m_AngleY -= 2; break;
  3695. case ID_PANSCAN_ROTATEZP: m_AngleZ += 2; break;
  3696. case ID_PANSCAN_ROTATEZM: m_AngleZ -= 2; break;
  3697. default: return;
  3698. }
  3699. m_pCAP->SetVideoAngle(Vector(DegToRad(m_AngleX), DegToRad(m_AngleY), DegToRad(m_AngleZ)));
  3700. CString info;
  3701. info.Format(_T("x: %d, y: %d, z: %d"), m_AngleX, m_AngleY, m_AngleZ);
  3702. SendStatusMessage(info, 3000);
  3703. }
  3704. void CMainFrame::OnUpdateViewRotate(CCmdUI* pCmdUI)
  3705. {
  3706. pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly && m_pCAP);
  3707. }
  3708. // FIXME
  3709. const static SIZE s_ar[] = {{0,0}, {4,3}, {5,4}, {16,9}};
  3710. void CMainFrame::OnViewAspectRatio(UINT nID)
  3711. {
  3712. CSize& ar = AfxGetAppSettings().AspectRatio;
  3713. ar = s_ar[nID - ID_ASPECTRATIO_START];
  3714. CString info;
  3715. if(ar.cx && ar.cy) info.Format(_T("Aspect Ratio: %d:%d"), ar.cx, ar.cy);
  3716. else info.Format(_T("Aspect Ratio: Default"));
  3717. SendStatusMessage(info, 3000);
  3718. MoveVideoWindow();
  3719. }
  3720. void CMainFrame::OnUpdateViewAspectRatio(CCmdUI* pCmdUI)
  3721. {
  3722. pCmdUI->SetRadio(AfxGetAppSettings().AspectRatio == s_ar[pCmdUI->m_nID - ID_ASPECTRATIO_START]);
  3723. pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly);
  3724. }
  3725. void CMainFrame::OnViewAspectRatioNext()
  3726. {
  3727. CSize& ar = AfxGetAppSettings().AspectRatio;
  3728. UINT nID = ID_ASPECTRATIO_START;
  3729. for(int i = 0; i < countof(s_ar); i++)
  3730. {
  3731. if(ar == s_ar[i])
  3732. {
  3733. nID += (i + 1) % countof(s_ar);
  3734. break;
  3735. }
  3736. }
  3737. OnViewAspectRatio(nID);
  3738. }
  3739. void CMainFrame::OnViewOntop(UINT nID)
  3740. {
  3741. nID -= ID_ONTOP_NEVER;
  3742. if(AfxGetAppSettings().iOnTop == nID)
  3743. nID = !nID;
  3744. SetAlwaysOnTop(nID);
  3745. }
  3746. void CMainFrame::OnUpdateViewOntop(CCmdUI* pCmdUI)
  3747. {
  3748. pCmdUI->SetRadio(AfxGetAppSettings().iOnTop == (pCmdUI->m_nID - ID_ONTOP_NEVER));
  3749. }
  3750. void CMainFrame::OnViewOptions()
  3751. {
  3752. ShowOptions();
  3753. }
  3754. // play
  3755. #include "IPinHook.h"
  3756. void CMainFrame::OnPlayPlay()
  3757. {
  3758. if(m_iMediaLoadState == MLS_LOADED)
  3759. {
  3760. if(GetMediaState() == State_Stopped) m_iSpeedLevel = 0;
  3761. if(m_iPlaybackMode == PM_FILE)
  3762. {
  3763. if(m_fEndOfStream) SendMessage(WM_COMMAND, ID_PLAY_STOP);
  3764. pMC->Run();
  3765. }
  3766. else if(m_iPlaybackMode == PM_DVD)
  3767. {
  3768. double dRate = 1.0;
  3769. if(m_iSpeedLevel != -4 && m_iSpeedLevel != 0)
  3770. dRate = pow(2.0, m_iSpeedLevel >= -3 ? m_iSpeedLevel : (-m_iSpeedLevel - 8));
  3771. pDVDC->PlayForwards(dRate, DVD_CMD_FLAG_Block, NULL);
  3772. pDVDC->Pause(FALSE);
  3773. pMC->Run();
  3774. }
  3775. else if(m_iPlaybackMode == PM_CAPTURE)
  3776. {
  3777. pMC->Stop(); // audio preview won't be in sync if we run it from paused state
  3778. pMC->Run();
  3779. }
  3780. SetTimer(TIMER_STREAMPOSPOLLER, 40, NULL);
  3781. SetTimer(TIMER_STREAMPOSPOLLER2, 500, NULL);
  3782. SetTimer(TIMER_STATS, 1000, NULL);
  3783. if(m_fFrameSteppingActive) // FIXME
  3784. {
  3785. m_fFrameSteppingActive = false;
  3786. pBA->put_Volume(m_VolumeBeforeFrameStepping);
  3787. }
  3788. SetAlwaysOnTop(AfxGetAppSettings().iOnTop);
  3789. }
  3790. MoveVideoWindow();
  3791. }
  3792. void CMainFrame::OnPlayPause()
  3793. {
  3794. if(m_iMediaLoadState == MLS_LOADED)
  3795. {
  3796. SetAlwaysOnTop(AfxGetAppSettings().iOnTop);
  3797. if(m_iPlaybackMode == PM_FILE)
  3798. {
  3799. pMC->Pause();
  3800. }
  3801. else if(m_iPlaybackMode == PM_DVD)
  3802. {
  3803. pMC->Pause();
  3804. }
  3805. else if(m_iPlaybackMode == PM_CAPTURE)
  3806. {
  3807. pMC->Pause();
  3808. SetTimer(TIMER_STREAMPOSPOLLER, 40, NULL);
  3809. SetTimer(TIMER_STREAMPOSPOLLER2, 500, NULL);
  3810. SetTimer(TIMER_STATS, 1000, NULL);
  3811. }
  3812. MoveVideoWindow();
  3813. }
  3814. void CMainFrame::OnPlayPlaypause()
  3815. {
  3816. OAFilterState fs = GetMediaState();
  3817. if(fs == State_Running) SendMessage(WM_COMMAND, ID_PLAY_PAUSE);
  3818. else if(fs == State_Stopped || fs == State_Paused) SendMessage(WM_COMMAND, ID_PLAY_PLAY);
  3819. }
  3820. void CMainFrame::OnPlayStop()
  3821. {
  3822. if(m_iMediaLoadState == MLS_LOADED)
  3823. {
  3824. if(m_iPlaybackMode == PM_FILE)
  3825. {
  3826. LONGLONG pos = 0;
  3827. pMS->SetPositions(&pos, AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning);
  3828. pMC->Stop();
  3829. // BUG: after pause or stop the netshow url source filter won't continue 
  3830. // on the next play command, unless we cheat it by setting the file name again.
  3831. // 
  3832. // Note: WMPx may be using some undocumented interface to restart streaming.
  3833. BeginEnumFilters(pGB, pEF, pBF)
  3834. {
  3835. CComQIPtr<IAMNetworkStatus, &IID_IAMNetworkStatus> pAMNS = pBF;
  3836. CComQIPtr<IFileSourceFilter> pFSF = pBF;
  3837. if(pAMNS && pFSF)
  3838. {
  3839. WCHAR* pFN = NULL;
  3840. AM_MEDIA_TYPE mt;
  3841. if(SUCCEEDED(pFSF->GetCurFile(&pFN, &mt)) && pFN && *pFN)
  3842. {
  3843. pFSF->Load(pFN, NULL);
  3844. CoTaskMemFree(pFN);
  3845. }
  3846. break;
  3847. }
  3848. }
  3849. EndEnumFilters
  3850. }
  3851. else if(m_iPlaybackMode == PM_DVD)
  3852. {
  3853. pDVDC->SetOption(DVD_ResetOnStop, TRUE);
  3854. pMC->Stop();
  3855. pDVDC->SetOption(DVD_ResetOnStop, FALSE);
  3856. }
  3857. else if(m_iPlaybackMode == PM_CAPTURE)
  3858. {
  3859. pMC->Stop();
  3860. }
  3861. m_iSpeedLevel = 0;
  3862. if(m_fFrameSteppingActive) // FIXME
  3863. {
  3864. m_fFrameSteppingActive = false;
  3865. pBA->put_Volume(m_VolumeBeforeFrameStepping);
  3866. }
  3867. m_fEndOfStream = false;
  3868. }
  3869. m_nLoops = 0;
  3870. if(m_hWnd) 
  3871. {
  3872. KillTimer(TIMER_STREAMPOSPOLLER2);
  3873. KillTimer(TIMER_STREAMPOSPOLLER);
  3874. KillTimer(TIMER_STATS);
  3875. MoveVideoWindow();
  3876. if(m_iMediaLoadState == MLS_LOADED)
  3877. {
  3878. __int64 start, stop;
  3879. m_wndSeekBar.GetRange(start, stop);
  3880. GUID tf;
  3881. pMS->GetTimeFormat(&tf);
  3882. m_wndStatusBar.SetStatusTimer(m_wndSeekBar.GetPosReal(), stop, !!m_wndSubresyncBar.IsWindowVisible(), &tf);
  3883. SetAlwaysOnTop(AfxGetAppSettings().iOnTop);
  3884. }
  3885. }
  3886. }
  3887. void CMainFrame::OnUpdatePlayPauseStop(CCmdUI* pCmdUI)
  3888. {
  3889. OAFilterState fs = m_fFrameSteppingActive ? State_Paused : GetMediaState();
  3890. pCmdUI->SetCheck(fs == State_Running && pCmdUI->m_nID == ID_PLAY_PLAY
  3891. || fs == State_Paused && pCmdUI->m_nID == ID_PLAY_PAUSE
  3892. || fs == State_Stopped && pCmdUI->m_nID == ID_PLAY_STOP
  3893. || (fs == State_Paused || fs == State_Running) && pCmdUI->m_nID == ID_PLAY_PLAYPAUSE);
  3894. bool fEnable = false;
  3895. if(fs >= 0)
  3896. {
  3897. if(m_iPlaybackMode == PM_FILE || m_iPlaybackMode == PM_CAPTURE)
  3898. {
  3899. fEnable = true;
  3900. if(fs == State_Stopped && pCmdUI->m_nID == ID_PLAY_PAUSE && m_fRealMediaGraph) fEnable = false; // can't go into paused state from stopped with rm
  3901. else if(m_fCapturing) fEnable = false;
  3902. else if(m_fLiveWM && pCmdUI->m_nID == ID_PLAY_PAUSE) fEnable = false;
  3903. }
  3904. else if(m_iPlaybackMode == PM_DVD)
  3905. {
  3906. fEnable = m_iDVDDomain != DVD_DOMAIN_VideoManagerMenu 
  3907. && m_iDVDDomain != DVD_DOMAIN_VideoTitleSetMenu;
  3908. if(fs == State_Stopped && pCmdUI->m_nID == ID_PLAY_PAUSE) fEnable = false;
  3909. }
  3910. }
  3911. pCmdUI->Enable(fEnable);
  3912. }
  3913. void CMainFrame::OnPlayFramestep(UINT nID)
  3914. {
  3915. REFERENCE_TIME rt;
  3916. if(pFS && m_fQuicktimeGraph)
  3917. {
  3918. if(GetMediaState() != State_Paused)
  3919. SendMessage(WM_COMMAND, ID_PLAY_PAUSE);
  3920. pFS->Step(nID == ID_PLAY_FRAMESTEP ? 1 : -1, NULL);
  3921. }
  3922. else if(pFS && nID == ID_PLAY_FRAMESTEP)
  3923. {
  3924. if(GetMediaState() != State_Paused)
  3925. SendMessage(WM_COMMAND, ID_PLAY_PAUSE);
  3926. m_fFrameSteppingActive = true;
  3927. m_VolumeBeforeFrameStepping = m_wndToolBar.Volume;
  3928. pBA->put_Volume(-10000);
  3929. pFS->Step(1, NULL);
  3930. }
  3931. else if(S_OK == pMS->IsFormatSupported(&TIME_FORMAT_FRAME))
  3932. {
  3933. if(GetMediaState() != State_Paused)
  3934. SendMessage(WM_COMMAND, ID_PLAY_PAUSE);
  3935. pMS->SetTimeFormat(&TIME_FORMAT_FRAME);
  3936. pMS->GetCurrentPosition(&rt);
  3937. if(nID == ID_PLAY_FRAMESTEP) rt++;
  3938. else if(nID == ID_PLAY_FRAMESTEPCANCEL) rt--;
  3939. pMS->SetPositions(&rt, AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning);
  3940. pMS->SetTimeFormat(&TIME_FORMAT_MEDIA_TIME);
  3941. }
  3942. }
  3943. void CMainFrame::OnUpdatePlayFramestep(CCmdUI* pCmdUI)
  3944. {
  3945. bool fEnable = false;
  3946. if(m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly
  3947. && (m_iPlaybackMode != PM_DVD || m_iDVDDomain == DVD_DOMAIN_Title)
  3948. && m_iPlaybackMode != PM_CAPTURE
  3949. && !m_fLiveWM)
  3950. {
  3951. REFTIME AvgTimePerFrame = 0;
  3952.         if(S_OK == pMS->IsFormatSupported(&TIME_FORMAT_FRAME)
  3953. || pCmdUI->m_nID == ID_PLAY_FRAMESTEP && pFS && pFS->CanStep(0, NULL) == S_OK
  3954. || m_fQuicktimeGraph && pFS)
  3955. {
  3956. fEnable = true;
  3957. }
  3958. }
  3959. pCmdUI->Enable(fEnable);
  3960. }
  3961. void CMainFrame::OnPlaySeek(UINT nID)
  3962. {
  3963. AppSettings& s = AfxGetAppSettings();
  3964. REFERENCE_TIME dt = 
  3965. nID == ID_PLAY_SEEKBACKWARDSMALL ? -10000i64*s.nJumpDistS : 
  3966. nID == ID_PLAY_SEEKFORWARDSMALL ? +10000i64*s.nJumpDistS : 
  3967. nID == ID_PLAY_SEEKBACKWARDMED ? -10000i64*s.nJumpDistM : 
  3968. nID == ID_PLAY_SEEKFORWARDMED ? +10000i64*s.nJumpDistM : 
  3969. nID == ID_PLAY_SEEKBACKWARDLARGE ? -10000i64*s.nJumpDistL : 
  3970. nID == ID_PLAY_SEEKFORWARDLARGE ? +10000i64*s.nJumpDistL : 
  3971. 0;
  3972. if(!dt) return;
  3973. // HACK: the custom graph should support frame based seeking instead
  3974. if(m_fShockwaveGraph) dt /= 10000i64*100;
  3975. SeekTo(m_wndSeekBar.GetPos() + dt);
  3976. }
  3977. static int rangebsearch(REFERENCE_TIME val, CAtlArray<REFERENCE_TIME>& rta)
  3978. {
  3979. int i = 0, j = rta.GetCount() - 1, ret = -1;
  3980. if(j >= 0 && val >= rta[j]) return(j);
  3981. while(i < j)
  3982. {
  3983. int mid = (i + j) >> 1;
  3984. REFERENCE_TIME midt = rta[mid];
  3985. if(val == midt) {ret = mid; break;}
  3986. else if(val < midt) {ret = -1; if(j == mid) mid--; j = mid;}
  3987. else if(val > midt) {ret = mid; if(i == mid) mid++; i = mid;}
  3988. }
  3989. return(ret);
  3990. }
  3991. void CMainFrame::OnPlaySeekKey(UINT nID)
  3992. {
  3993. if(m_kfs.GetCount() > 0)
  3994. {
  3995. HRESULT hr;
  3996. if(GetMediaState() == State_Stopped)
  3997. SendMessage(WM_COMMAND, ID_PLAY_PAUSE);
  3998. REFERENCE_TIME rtCurrent, rtDur;
  3999. hr = pMS->GetCurrentPosition(&rtCurrent);
  4000. hr = pMS->GetDuration(&rtDur);
  4001. int dec = 1;
  4002. int i = rangebsearch(rtCurrent, m_kfs);
  4003. if(i > 0) dec = (UINT)max(min(rtCurrent - m_kfs[i-1], 10000000), 0);
  4004. rtCurrent = 
  4005. nID == ID_PLAY_SEEKKEYBACKWARD ? max(rtCurrent - dec, 0) : 
  4006. nID == ID_PLAY_SEEKKEYFORWARD ? rtCurrent : 0;
  4007. i = rangebsearch(rtCurrent, m_kfs);
  4008. if(nID == ID_PLAY_SEEKKEYBACKWARD)
  4009. rtCurrent = m_kfs[max(i, 0)];
  4010. else if(nID == ID_PLAY_SEEKKEYFORWARD && i < m_kfs.GetCount()-1)
  4011. rtCurrent = m_kfs[i+1];
  4012. else
  4013. return;
  4014. // HACK: if d3d or something changes fpu control word the values of 
  4015. // m_kfs may be different now (if it was asked again), adding a little
  4016. // to the seek position eliminates this error usually.
  4017. rtCurrent += 10;
  4018. hr = pMS->SetPositions(
  4019. &rtCurrent, AM_SEEKING_AbsolutePositioning|AM_SEEKING_SeekToKeyFrame, 
  4020. NULL, AM_SEEKING_NoPositioning);
  4021. }
  4022. }
  4023. void CMainFrame::OnUpdatePlaySeek(CCmdUI* pCmdUI)
  4024. {
  4025. bool fEnable = false;
  4026. OAFilterState fs = GetMediaState();
  4027. if(m_iMediaLoadState == MLS_LOADED && (fs == State_Paused || fs == State_Running))
  4028. {
  4029. fEnable = true;
  4030. if(m_iPlaybackMode == PM_DVD && (m_iDVDDomain != DVD_DOMAIN_Title || fs != State_Running)) fEnable = false;
  4031. else if(m_iPlaybackMode == PM_CAPTURE) fEnable = false;
  4032. }
  4033. pCmdUI->Enable(fEnable);
  4034. }
  4035. void CMainFrame::OnPlayGoto()
  4036. {
  4037. if(m_iMediaLoadState != MLS_LOADED)
  4038. return;
  4039. REFTIME atpf = 0;
  4040. if(FAILED(pBV->get_AvgTimePerFrame(&atpf)) || atpf < 0)
  4041. {
  4042. atpf = 0;
  4043. BeginEnumFilters(pGB, pEF, pBF)
  4044. {
  4045. if(atpf > 0) break;
  4046. BeginEnumPins(pBF, pEP, pPin)
  4047. {
  4048. if(atpf > 0) break;
  4049. AM_MEDIA_TYPE mt;
  4050. pPin->ConnectionMediaType(&mt);
  4051. if(mt.majortype == MEDIATYPE_Video && mt.formattype == FORMAT_VideoInfo)
  4052. {
  4053. atpf = (REFTIME)((VIDEOINFOHEADER*)mt.pbFormat)->AvgTimePerFrame / 10000000i64;
  4054. }
  4055. else if(mt.majortype == MEDIATYPE_Video && mt.formattype == FORMAT_VideoInfo2)
  4056. {
  4057. atpf = (REFTIME)((VIDEOINFOHEADER2*)mt.pbFormat)->AvgTimePerFrame / 10000000i64;
  4058. }
  4059. }
  4060. EndEnumPins
  4061. }
  4062. EndEnumFilters
  4063. }
  4064. CGoToDlg dlg((int)(m_wndSeekBar.GetPos()/10000), atpf > 0 ? (float)(1.0/atpf) : 0);
  4065. if(IDOK != dlg.DoModal() || dlg.m_time < 0) return;