MainFrm.cpp
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:234k
源码类别:

多媒体编程

开发平台:

Visual C++

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