Main.cpp
上传用户:hxb_1234
上传日期:2010-03-30
资源大小:8328k
文件大小:97k
源码类别:

VC书籍

开发平台:

Visual C++

  1. /**************************************************************************************
  2.  *                                                                                    *
  3.  *                                                                                    *
  4.  **************************************************************************************/
  5. #include "Playa.h"
  6. #include "Skin.h"
  7. #include "Playlist.h"
  8. #include "MediaPlayback.h"
  9. #include "DirDialog.h"
  10. #include "SkinList.h"
  11. #include "Resizer.h"
  12. #include "DebugFile.h"
  13. /*
  14.  * 资源文件
  15.  *
  16.  */
  17. #ifdef WIN32
  18. #include "../build/win32/ressources.h"
  19. #include "../build/win32/resource.h"
  20. #endif
  21. #include <math.h>
  22. #include <commctrl.h>
  23. #include <windows.h>
  24. #include <windowsx.h>
  25. #include <shlobj.h>
  26. /*
  27.  * 记时器间隔
  28.  */
  29. #define TIMER_ID     1
  30. #define TIMER_RATE  50
  31. /*
  32.  * 变量
  33.  */
  34. BOOL      openning_network;
  35. DWORD     anonymous;
  36. HWND      hwndDisplay;
  37. BOOL      screenSaverActive;
  38. int       action  = ACTION_NONE;
  39. DWORD     count = 0;
  40. DWORD     use_subtitles         = 1;
  41. DWORD     no_resize             = 0;
  42. char      skinPath[MAX_PATH];
  43. COLORREF  backColor;
  44. UINT      uTimerID;
  45. RECT      clientRect, cwindowRect;
  46. RECT      windowRect, fullwindowRect;
  47. int       moveX = 0, moveY = 0;
  48. Skin     *skin;
  49. MediaPlayback *playback;
  50. CDirDialog *dirChooser;
  51. SkinList   *skinList;
  52. Resizer   *resizer;
  53. Playlist  *playlist;
  54. char      Name[] = "The "Playa"";
  55. char     *RecentFiles[5];
  56. HWND      hwnd, about, urlW = NULL;
  57. HMENU     popupMenu;
  58. HACCEL    hAccel;
  59. DWORD     id;
  60. HINSTANCE hInstance;
  61. int       showing_cursor;
  62. int       compact_mode;
  63. BOOL      openOK;
  64. char     *url;
  65. DWORD     firstStart;
  66. options_t options, tmpOptions;
  67. WCHAR     wallpaper[MAX_PATH];
  68. WCHAR     pattern[MAX_PATH];
  69. /*
  70.  * 主消息循环方法
  71.  *
  72.  */
  73. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
  74. void             UpdateMainWindow();
  75. /*
  76.  * 打开当前播放链表的位置
  77.  *
  78.  */
  79. void             OpenFileForPlaying(HWND hwnd);
  80. /*
  81.  * 重建播放链表浮动菜单
  82.  *
  83.  */
  84. void             ReBuildPlaylistMenu();
  85. /**************************************************************************************
  86.  *                                                                                    *
  87.  *                              保存和装载选项                                        *
  88.  *                                                                                    *
  89.  **************************************************************************************/
  90. void LoadOptions() {
  91. HKEY     key;
  92. DWORD created, size;
  93. LONG     result;
  94. DWORD  type, i;
  95. char      file[256], name[5];
  96. /*
  97.  * 放置缺省选项
  98.  *
  99.  */
  100. compact_mode = 0;
  101.     strcpy(skinPath, "Default");
  102. options.change_fullscreen_res = 0;
  103. options.loop                  = 1;
  104. options.on_top                = 1;
  105. options.use_bilinear          = 0;
  106. options.aspect_ratio          = ASPECT_RATIO_FREE;
  107. options.disable_screen_saver  = 1;
  108. options.save_pos              = 1;
  109. options.posX                  = 100;
  110. options.posY                  = 30;
  111. options.postprocessing        = 60;
  112. options.startFullscreen       = 0;
  113. /*
  114.  * 初始化最近的文件链表
  115.  */
  116. for(i=0; i < 5; i++) {
  117. RecentFiles[i] = NULL;
  118. }
  119. /*
  120.  * 打开注册键
  121.  */
  122. result = RegCreateKeyEx(HKEY_CURRENT_USER, "Software\DivXNetworks\ThePlaya",
  123.                   0, "CONFIG", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 
  124. NULL, &key, &created);
  125. if(result != ERROR_SUCCESS) {
  126. MP_ERROR("Couldn't load options");
  127. return;
  128. }
  129. switch(created) {
  130. case REG_CREATED_NEW_KEY:
  131. /*
  132.  * 第一次启动 (缺省)
  133.  * 
  134.  */
  135. break;
  136. case REG_OPENED_EXISTING_KEY:
  137. /*
  138.  * 读值
  139.    */
  140. size = 4;
  141. result = RegQueryValueEx(key, "UseBilinear", 0, &type, (BYTE *)&options.use_bilinear, &size);
  142. size = 4;
  143. result = RegQueryValueEx(key, "MaintainAspectRatio", 0, &type, (BYTE *)&options.aspect_ratio, &size);
  144. size = 4;
  145. result = RegQueryValueEx(key, "ChangeFullscreenRes", 0, &type, (BYTE *)&options.change_fullscreen_res, &size);
  146. size = 4;
  147. result = RegQueryValueEx(key, "UseSubtitles", 0, &type, (BYTE *)&use_subtitles, &size);
  148. size = 4;
  149. result = RegQueryValueEx(key, "Loop", 0, &type, (BYTE *)&options.loop, &size);
  150. size = 4;
  151. result = RegQueryValueEx(key, "OnTop", 0, &type, (BYTE *)&options.on_top, &size);
  152. size = 4;
  153. result = RegQueryValueEx(key, "PreventScreenSaver", 0, &type, (BYTE *)&options.disable_screen_saver, &size);
  154. size = 4;
  155. result = RegQueryValueEx(key, "SavePlayerPos", 0, &type, (BYTE *)&options.save_pos, &size);
  156. size = 4;
  157. result = RegQueryValueEx(key, "PostProcessing", 0, &type, (BYTE *)&options.postprocessing, &size);
  158. size = 4;
  159. result = RegQueryValueEx(key, "CustomAspectX", 0, &type, (BYTE *)&aspectRatios[ASPECT_RATIO_CUSTOM].xFactor, &size);
  160. size = 4;
  161. result = RegQueryValueEx(key, "CustomAspectY", 0, &type, (BYTE *)&aspectRatios[ASPECT_RATIO_CUSTOM].yFactor, &size);
  162. if(options.save_pos) {
  163. size = 4;
  164. result = RegQueryValueEx(key, "PlayerPosX", 0, &type, (BYTE *)&options.posX, &size);
  165. size = 4;
  166. result = RegQueryValueEx(key, "PlayerPosY", 0, &type, (BYTE *)&options.posY, &size);
  167. }
  168. size = MAX_PATH;
  169. result = RegQueryValueEx(key, "SkinPath", 0, &type, (BYTE *)skinPath, &size);
  170. /*
  171.  * 最近的文件
  172.  */
  173. for(i=0; i < 5; i++) {
  174. sprintf(name, "File%d", i+1);
  175. size = 256;
  176. result = RegQueryValueEx(key, name, 0, &type, (BYTE *)&file, &size);
  177. if(result == ERROR_SUCCESS) {
  178. RecentFiles[i] = (char *) new char[size];
  179. strncpy(RecentFiles[i], file, size);
  180. }
  181. }
  182. break;
  183. default:
  184. break;
  185. }
  186. RegCloseKey(key);
  187. }
  188. void SaveOptions() {
  189. HKEY     key;
  190. LONG     result;
  191. DWORD created, i;
  192. char      name[5];
  193. options.postprocessing = playback->videoDecoder->decoreDecoder->GetQuality();
  194. /*
  195.  * 尝试打开注册键
  196.  */
  197. result = RegCreateKeyEx(HKEY_CURRENT_USER, "Software\DivXNetworks\ThePlaya",
  198.               0, "CONFIG", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 
  199.               NULL, &key, &created);
  200. if(result != ERROR_SUCCESS) {
  201. MP_ERROR("Couldn't save options");
  202. RegCloseKey(key);
  203. return;
  204. }
  205. RegSetValueEx(key, "UseBilinear", 0, REG_DWORD, (BYTE *) &options.use_bilinear, 4);
  206. RegSetValueEx(key, "MaintainAspectRatio", 0, REG_DWORD, (BYTE *) &options.aspect_ratio, 4);
  207. RegSetValueEx(key, "ChangeFullscreenRes", 0, REG_DWORD, (BYTE *) &options.change_fullscreen_res, 4);
  208. RegSetValueEx(key, "UseSubtitles", 0, REG_DWORD, (BYTE *) &use_subtitles, 4);
  209. RegSetValueEx(key, "Loop", 0, REG_DWORD, (BYTE *) &options.loop, 4);
  210. RegSetValueEx(key, "OnTop", 0, REG_DWORD, (BYTE *) &options.on_top, 4);
  211. RegSetValueEx(key, "PreventScreenSaver", 0, REG_DWORD, (BYTE *) &options.disable_screen_saver, 4);
  212. RegSetValueEx(key, "SavePlayerPos", 0, REG_DWORD, (BYTE *) &options.save_pos, 4);
  213. RegSetValueEx(key, "PostProcessing", 0, REG_DWORD, (BYTE *) &options.postprocessing, 4);
  214. RegSetValueEx(key, "CustomAspectX", 0, REG_DWORD, (BYTE *) &aspectRatios[ASPECT_RATIO_CUSTOM].xFactor, 4);
  215. RegSetValueEx(key, "CustomAspectY", 0, REG_DWORD, (BYTE *) &aspectRatios[ASPECT_RATIO_CUSTOM].yFactor, 4);
  216. if(options.save_pos) {
  217. options.posX = windowRect.left;
  218. options.posY = windowRect.top;
  219. RegSetValueEx(key, "PlayerPosX", 0, REG_DWORD, (BYTE *) &options.posX, 4);
  220. RegSetValueEx(key, "PlayerPosY", 0, REG_DWORD, (BYTE *) &options.posY, 4);
  221. }
  222. if(strcmp(skinPath, "Default") != 0)
  223. RegSetValueEx(key, "SkinPath", 0, REG_SZ, (BYTE *) skinPath, strlen(skinPath));
  224. else 
  225. RegSetValueEx(key, "SkinPath", 0, REG_SZ, (BYTE *) "Default", strlen("Default"));
  226. /*
  227.  * 最近文件链表
  228.  */
  229. for(i=0; i < 5; i++) {
  230. sprintf(name, "File%d", i+1);
  231. if(RecentFiles[i] != NULL) {
  232. RegSetValueEx(key, name, 0, REG_SZ, 
  233.       (BYTE *) RecentFiles[i], strlen(RecentFiles[i]));
  234. }
  235. else {
  236. RegDeleteValue(key, name);
  237.   }
  238. }
  239. RegCloseKey(key);
  240. }
  241. /**************************************************************************************
  242.  *                                                                                    *
  243.  *                             DlgProc用于定制屏幕高宽比                              *
  244.  *                        -----------------------------------                         *
  245.  **************************************************************************************/
  246. static BOOL APIENTRY CustomAspectDlgProc( HWND hDlg, UINT message, UINT wParam, LONG lParam) {
  247. switch(message) {
  248. case WM_INITDIALOG:
  249. char buffer[256];
  250. sprintf(buffer, "%d", aspectRatios[ASPECT_RATIO_CUSTOM].xFactor);
  251. SendMessage(GetDlgItem(hDlg, IDC_CUSTOM_ASPECT_X), WM_SETTEXT, 0, (LPARAM) buffer);
  252. sprintf(buffer, "%d", aspectRatios[ASPECT_RATIO_CUSTOM].yFactor);
  253. SendMessage(GetDlgItem(hDlg, IDC_CUSTOM_ASPECT_Y), WM_SETTEXT, 0, (LPARAM) buffer);
  254. return TRUE;
  255.   case WM_COMMAND:
  256.         switch (LOWORD(wParam))
  257. {
  258. case IDC_CUSTOM_ASPECT_CANCEL:
  259. EndDialog(hDlg, TRUE);
  260. break;
  261. case IDC_CUSTOM_ASPECT_OK:
  262. EndDialog(hDlg, TRUE);
  263. DWORD xFactor, yFactor;
  264. char *data;
  265. SHORT lineLength;
  266. lineLength = (short) SendMessage(GetDlgItem(hDlg, IDC_CUSTOM_ASPECT_X), EM_LINELENGTH, 0, 0);
  267. /*
  268.  * 将url缓冲写入头两个字节
  269.  * 
  270.  *
  271.  */
  272. data = (char *) new char[lineLength + 1];
  273. memcpy(data, &lineLength, 2);
  274. SendMessage(GetDlgItem(hDlg, IDC_CUSTOM_ASPECT_X), EM_GETLINE, 0, (LONG)(LPVOID)data);
  275. data[lineLength] = '';
  276. sscanf(data, "%d", &xFactor);
  277. lineLength = (short) SendMessage(GetDlgItem(hDlg, IDC_CUSTOM_ASPECT_Y), EM_LINELENGTH, 0, 0);
  278. /*
  279.  * 将url缓冲写入头两个字节
  280.  * 
  281.  *
  282.  */
  283. data = (char *) new char[lineLength + 1];
  284. memcpy(data, &lineLength, 2);
  285. SendMessage(GetDlgItem(hDlg, IDC_CUSTOM_ASPECT_Y), EM_GETLINE, 0, (LONG)(LPVOID)data);
  286. data[lineLength] = '';
  287. sscanf(data, "%d", &yFactor);
  288. aspectRatios[ASPECT_RATIO_CUSTOM].xFactor = xFactor;
  289. aspectRatios[ASPECT_RATIO_CUSTOM].yFactor = yFactor;
  290. /*
  291.  * 进行真正的填充
  292.  */
  293. switch(options.aspect_ratio) {
  294. case ASPECT_RATIO_ORIGINAL:
  295. CheckMenuItem(popupMenu, (UINT)ID_ASPECT_ORIGINAL, MF_UNCHECKED);
  296. break;
  297. case ASPECT_RATIO_TV:
  298. CheckMenuItem(popupMenu, (UINT)ID_ASPECT_43, MF_UNCHECKED);
  299. break;
  300. case ASPECT_RATIO_FREE:
  301. CheckMenuItem(popupMenu, (UINT)ID_ASPECT_FREE, MF_UNCHECKED);
  302. break;
  303. case ASPECT_RATIO_WIDE:
  304. CheckMenuItem(popupMenu, (UINT)ID_ASPECT_169, MF_UNCHECKED);
  305. break;
  306. }
  307. options.aspect_ratio = ASPECT_RATIO_CUSTOM;
  308. CheckMenuItem(popupMenu, (UINT)ID_ASPECT_CUSTOM, MF_CHECKED);
  309. RECT  src;
  310. GetClientRect(hwnd, &src);
  311. GetWindowRect(hwnd, &windowRect);
  312. if(compact_mode) {
  313. src.bottom = (src.right - src.left)*yFactor/xFactor;
  314. }
  315. else {
  316. src.bottom = (src.right - src.left - 15)*yFactor/xFactor + 115 + 22;
  317. }
  318. AdjustWindowRect(&src, WS_POPUP|WS_SIZEBOX, 0);
  319. MoveWindow( hwnd, windowRect.left, 
  320. windowRect.top, 
  321. src.right - src.left, 
  322. src.bottom - src.top, TRUE);
  323. playback->SetVideoRect(skin->GetVideoRect());
  324. break;
  325. }
  326. case WM_DESTROY:
  327. return TRUE;
  328. }
  329. return FALSE;
  330. }
  331. /**************************************************************************************
  332.  *                                                                                    *
  333.  *                              DlgProc用于一般的参数选择                             *
  334.  *                        -----------------------------------                         *
  335.  **************************************************************************************/
  336. static BOOL APIENTRY PreferencesGeneralDlgProc( HWND hDlg, UINT message, UINT wParam, LONG lParam) {
  337. switch(message) {
  338. case WM_INITDIALOG:
  339. SetWindowPos(hDlg, HWND_TOP, 15, 35, 0, 0, SWP_NOSIZE);
  340.     CheckDlgButton(hDlg, IDC_CHECK_LOOP,   tmpOptions.loop);
  341.     CheckDlgButton(hDlg, IDC_CHECK_ON_TOP, tmpOptions.on_top);
  342.     CheckDlgButton(hDlg, IDC_CHECK_DISABLE_SS, tmpOptions.disable_screen_saver);
  343.     CheckDlgButton(hDlg, IDC_CHECK_SAVE_POS, tmpOptions.save_pos);
  344. return TRUE;
  345.   case WM_COMMAND:
  346.         switch (wParam)
  347. {
  348. case IDC_CHECK_LOOP:
  349. tmpOptions.loop = tmpOptions.loop ? 0 : 1;
  350. break;
  351. case IDC_CHECK_ON_TOP:
  352. tmpOptions.on_top = tmpOptions.on_top ? 0 : 1;
  353. break;
  354. case IDC_CHECK_DISABLE_SS:
  355. tmpOptions.disable_screen_saver = tmpOptions.disable_screen_saver ? 0 : 1;
  356. break;
  357. case IDC_CHECK_SAVE_POS:
  358. tmpOptions.save_pos = tmpOptions.save_pos ? 0 : 1;
  359. break;
  360. }
  361. case WM_DESTROY:
  362. return TRUE;
  363. }
  364. return FALSE;
  365. }
  366. /*
  367.  * 参数表链
  368.  *
  369.  */
  370. static struct prefsTabs {
  371. LPTSTR rsrc;
  372. char *name;
  373. DLGPROC dProc;
  374. } tabs[]={
  375. { MAKEINTRESOURCE(IDD_PREFS_GENERAL), "General", PreferencesGeneralDlgProc},
  376. };
  377. /**************************************************************************************
  378.  *                                                                                    *
  379.  *                              DlgProc用于主参数选择                                 *
  380.  *                        --------------------------------                            *
  381.  **************************************************************************************/
  382. static BOOL APIENTRY PreferencesDlgProc( HWND hDlg, UINT message, UINT wParam, LONG lParam) {
  383. DWORD i;
  384. switch(message) {
  385. case WM_SYSCOMMAND:
  386. if (wParam == SC_CLOSE)
  387. {
  388. EndDialog (hDlg, TRUE);
  389. return (TRUE);
  390. }
  391. break;
  392. case WM_INITDIALOG:
  393. {
  394. HWND tab = GetDlgItem(hDlg, IDC_TAB);
  395. memcpy(&tmpOptions, &options, sizeof(options_t));
  396. for(i = 0; i < (sizeof tabs/sizeof tabs[0]); i++) {
  397. TC_ITEM ti;
  398. ti.mask = TCIF_TEXT;
  399. ti.pszText = tabs[i].name;
  400. TabCtrl_InsertItem(tab, i, &ti);
  401. }
  402. hwndDisplay = CreateDialogParam(hInstance, tabs[0].rsrc, hDlg, tabs[0].dProc, (LPARAM)NULL);
  403. ShowWindow(hwndDisplay, SW_SHOW);
  404. return TRUE;
  405. }
  406. case WM_NOTIFY: {
  407. NMHDR *nm = (LPNMHDR)lParam;
  408. switch(nm->code) {
  409. case TCN_SELCHANGE:
  410. {
  411. int iTab = TabCtrl_GetCurSel(nm->hwndFrom);
  412. if (iTab>=0) {
  413. if (hwndDisplay) DestroyWindow(hwndDisplay);
  414. hwndDisplay = CreateDialogParam(hInstance, tabs[iTab].rsrc, hDlg, tabs[iTab].dProc, NULL);
  415. }
  416. ShowWindow(hwndDisplay, SW_SHOW);
  417. }
  418. return TRUE;
  419. }
  420. }
  421. break;
  422.   case WM_COMMAND:
  423.         switch (wParam)
  424. {
  425.   case IDC_PREFS_OK:
  426.   EndDialog(hDlg, TRUE);
  427.   
  428.   /*
  429.    * 保存参数的变化
  430.    */
  431.   memcpy(&options, &tmpOptions, sizeof(options_t));
  432.   /*
  433.    * 应用 
  434.    */
  435.   CheckMenuItem(popupMenu, (UINT)ID_LOOP, options.loop ? MF_CHECKED : MF_UNCHECKED);
  436.      CheckMenuItem(popupMenu, (UINT)ID_ON_TOP, options.on_top ? MF_CHECKED : MF_UNCHECKED);
  437.      CheckMenuItem(popupMenu, (UINT)ID_SCREENSAVER, options.disable_screen_saver ? MF_CHECKED : MF_UNCHECKED);
  438.   options.on_top = options.on_top ? 0 : 1;
  439.   SendMessage(hwnd, WM_COMMAND, (WPARAM)ID_ON_TOP, 0);
  440.   playback->SetLoop(options.loop);
  441.   
  442.   /*
  443.    * 结束对话框
  444.    */
  445.   
  446.   return TRUE;
  447.   break;
  448.   case IDC_PREFS_CANCEL:
  449.   EndDialog(hDlg, TRUE);
  450.   break;
  451.   default:
  452.   return 0;
  453. }
  454. break;
  455. case WM_DESTROY:
  456. return TRUE;
  457. }
  458. return FALSE;
  459. }
  460. /**************************************************************************************
  461.  *                                                                                    *
  462.  *                                 DlgProc用于重放                                    *
  463.  *                        -----------------------------------                         *
  464.  **************************************************************************************/
  465. static BOOL APIENTRY PlaybackPropertiesDlgProc( HWND hDlg, UINT message, UINT wParam, LONG lParam) {
  466. switch(message) {
  467. case WM_INITDIALOG:
  468. if(playback->HasVideo()) {
  469. if(playback->input)
  470. SendMessage(GetDlgItem(hDlg, IDC_PLAYBACK_LIST), LB_ADDSTRING, 0, (LONG) playback->input->GetName());
  471. if(playback->decaps)
  472. SendMessage(GetDlgItem(hDlg, IDC_PLAYBACK_LIST), LB_ADDSTRING, 0, (LONG) playback->decaps->GetName());
  473. if(playback->videoDecoder)
  474. SendMessage(GetDlgItem(hDlg, IDC_PLAYBACK_LIST), LB_ADDSTRING, 0, (LONG) playback->videoDecoder->GetName());
  475. if(playback->videoBuffer)
  476. SendMessage(GetDlgItem(hDlg, IDC_PLAYBACK_LIST), LB_ADDSTRING, 0, (LONG) playback->videoBuffer->GetName());
  477. if(playback->videoRenderer)
  478. SendMessage(GetDlgItem(hDlg, IDC_PLAYBACK_LIST), LB_ADDSTRING, 0, (LONG) playback->videoRenderer->GetName());
  479. }
  480. if(playback->HasAudio()) {
  481. if(playback->audioDecoder)
  482. SendMessage(GetDlgItem(hDlg, IDC_PLAYBACK_LIST), LB_ADDSTRING, 0, (LONG) playback->audioDecoder->GetName());
  483. if(playback->audioRenderer)
  484. SendMessage(GetDlgItem(hDlg, IDC_PLAYBACK_LIST), LB_ADDSTRING, 0, (LONG) playback->audioRenderer->GetName());
  485. }
  486. if(playback->hasSubtitles) {
  487. if(playback->subtitler)
  488. SendMessage(GetDlgItem(hDlg, IDC_PLAYBACK_LIST), LB_ADDSTRING, 0, (LONG) playback->subtitler->GetName());
  489. }
  490. return TRUE;
  491. case WM_SYSCOMMAND:
  492. if (wParam == SC_CLOSE)
  493. {
  494. EndDialog (hDlg, TRUE);
  495. return (TRUE);
  496. }
  497. break;
  498. case WM_COMMAND:
  499.         switch (LOWORD(wParam))
  500. {
  501. case ID_PLAYBACK_CLOSE :
  502. EndDialog (hDlg, TRUE);
  503. break;
  504. case IDC_PLAYBACK_CONFIGURE:
  505. {
  506.   int nItem;
  507.   nItem = SendMessage(GetDlgItem(hDlg, IDC_PLAYBACK_LIST), LB_GETCURSEL, 0, 0); 
  508.   switch(nItem) {
  509.   case 0:
  510.   playback->input->Configure(hInstance, hDlg);
  511.   break;
  512.   case 1:
  513.   playback->decaps->Configure(hInstance, hDlg);
  514.   break;
  515.   
  516.   case 2:
  517.   playback->videoDecoder->Configure(hInstance, hDlg);
  518.   break;
  519.   
  520.   case 3:
  521.   playback->videoBuffer->Configure(hInstance, hDlg);
  522.   break;
  523.   
  524.   case 4:
  525.   playback->videoRenderer->Configure(hInstance, hDlg);
  526.   break;
  527.   
  528.   case 5:
  529.   playback->audioDecoder->Configure(hInstance, hDlg);
  530.   break;
  531.   
  532.   case 6:
  533.   playback->audioRenderer->Configure(hInstance, hDlg);
  534.   break;
  535.   
  536.   case 7:
  537.   playback->subtitler->Configure(hInstance, hDlg);
  538.   break;
  539.   }
  540. }
  541. break;
  542. case IDC_PLAYBACK_LIST:
  543. switch (HIWORD(wParam)) { 
  544.                   
  545.   case LBN_SELCHANGE:
  546.   int nItem;
  547.   nItem = SendMessage(GetDlgItem(hDlg, IDC_PLAYBACK_LIST), LB_GETCURSEL, 0, 0); 
  548.   switch(nItem) {
  549.   case 0:
  550.   if(playback->input->GetCaps() & MEDIA_CAPS_CAN_CONFIGURE) {
  551.     EnableWindow(GetDlgItem(hDlg, IDC_PLAYBACK_CONFIGURE), TRUE);
  552.   }
  553.   else {
  554.     EnableWindow(GetDlgItem(hDlg, IDC_PLAYBACK_CONFIGURE), FALSE);
  555.   }
  556.   break;
  557.   case 1:
  558.   if(playback->decaps->GetCaps() & MEDIA_CAPS_CAN_CONFIGURE) {
  559.     EnableWindow(GetDlgItem(hDlg, IDC_PLAYBACK_CONFIGURE), TRUE);
  560.   }
  561.   else {
  562.     EnableWindow(GetDlgItem(hDlg, IDC_PLAYBACK_CONFIGURE), FALSE);
  563.   }
  564.   break;
  565.   
  566.   case 2:
  567.   if(playback->videoDecoder->GetCaps() & MEDIA_CAPS_CAN_CONFIGURE) {
  568.     EnableWindow(GetDlgItem(hDlg, IDC_PLAYBACK_CONFIGURE), TRUE);
  569.   }
  570.   else {
  571.     EnableWindow(GetDlgItem(hDlg, IDC_PLAYBACK_CONFIGURE), FALSE);
  572.   }
  573.   break;
  574.   
  575.   case 3:
  576.   if(playback->videoBuffer->GetCaps() & MEDIA_CAPS_CAN_CONFIGURE) {
  577.     EnableWindow(GetDlgItem(hDlg, IDC_PLAYBACK_CONFIGURE), TRUE);
  578.   }
  579.   else {
  580.     EnableWindow(GetDlgItem(hDlg, IDC_PLAYBACK_CONFIGURE), FALSE);
  581.   }
  582.   break;
  583.   
  584.   case 4:
  585.   if(playback->videoRenderer->GetCaps() & MEDIA_CAPS_CAN_CONFIGURE) {
  586.     EnableWindow(GetDlgItem(hDlg, IDC_PLAYBACK_CONFIGURE), TRUE);
  587.   }
  588.   else {
  589.     EnableWindow(GetDlgItem(hDlg, IDC_PLAYBACK_CONFIGURE), FALSE);
  590.   }
  591.   break;
  592.   
  593.   case 5:
  594. if(playback->audioDecoder->GetCaps() & MEDIA_CAPS_CAN_CONFIGURE) {
  595.     EnableWindow(GetDlgItem(hDlg, IDC_PLAYBACK_CONFIGURE), TRUE);
  596.   }
  597.   else {
  598.     EnableWindow(GetDlgItem(hDlg, IDC_PLAYBACK_CONFIGURE), FALSE);
  599.   }
  600.   break;
  601.   
  602.   case 6:
  603.   if(playback->audioRenderer->GetCaps() & MEDIA_CAPS_CAN_CONFIGURE) {
  604.     EnableWindow(GetDlgItem(hDlg, IDC_PLAYBACK_CONFIGURE), TRUE);
  605.   }
  606.   else {
  607.     EnableWindow(GetDlgItem(hDlg, IDC_PLAYBACK_CONFIGURE), FALSE);
  608.   }
  609.   break;
  610.   
  611.   case 7:
  612.   if(playback->subtitler->GetCaps() & MEDIA_CAPS_CAN_CONFIGURE) {
  613.     EnableWindow(GetDlgItem(hDlg, IDC_PLAYBACK_CONFIGURE), TRUE);
  614.   }
  615.   else {
  616.     EnableWindow(GetDlgItem(hDlg, IDC_PLAYBACK_CONFIGURE), FALSE);
  617.   }
  618.   break;
  619.   }
  620.   
  621.   break;
  622. }
  623. break;
  624. }
  625. break;
  626. case WM_DESTROY:
  627. return TRUE;
  628. }
  629. return FALSE;
  630. }
  631. /**************************************************************************************
  632.  *                                                                                    *
  633.  *                              DlgProc用于文件信息对话框                             *
  634.  *                        ------------------------------------                        *
  635.  **************************************************************************************/
  636. int APIENTRY PropDlgProc (HWND hDlg, WORD wMsg, LONG wParam, LONG lParam)
  637. {
  638.   switch (wMsg)
  639.     {
  640.       case WM_INITDIALOG:
  641.   char freq[20];
  642.   char channels[2];
  643.   char video_size[50];
  644.   char duration[20];
  645.   char total_size[50];
  646.   DWORD time, hours, minutes, seconds;
  647.   if(playback->HasAudio() && playback->audioDecoder) {
  648.   _ultoa(playback->audioDecoder->GetAudioFormat()->nSamplesPerSec, freq, 10);
  649.   _ultoa(playback->audioDecoder->GetAudioFormat()->nChannels, channels, 10);
  650.   }
  651.   sprintf(video_size, "%dx%d", playback->GetVideoWidth(), playback->GetVideoHeight());
  652.   
  653.   if(playback->input)
  654.   sprintf(total_size, "%d bytes", playback->input->GetSize());
  655.   time = playback->GetTotalTime();
  656.   hours   = time/3600;
  657.   minutes = (time - hours*3600)/60;
  658.   seconds = (time - hours*3600 - minutes*60)/60;
  659.   sprintf(duration, "%.2d:%.2d:%.2d", hours, minutes, seconds);
  660.   
  661.   SetWindowText(GetDlgItem(hDlg, IDC_STATIC_FILENAME),  playback->GetFilename());
  662.   SetWindowText(GetDlgItem(hDlg, IDC_STATIC_FILE_TYPE), playback->input->GetName());
  663.   SetWindowText(GetDlgItem(hDlg, IDC_STATIC_FILE_SIZE), total_size);
  664.   SetWindowText(GetDlgItem(hDlg, IDC_STATIC_DURATION),  duration);
  665.   SetWindowText(GetDlgItem(hDlg, IDC_STATIC_DECAPS),  playback->decaps->GetName());
  666.   if(playback->HasVideo()) {
  667.   SetWindowText(GetDlgItem(hDlg, IDC_STATIC_VIDEO_CODEC), playback->videoDecoder->GetName());
  668.   SetWindowText(GetDlgItem(hDlg, IDC_STATIC_VIDEO_SIZE), video_size);
  669.   switch(playback->videoRenderer->GetVideoMode()) {
  670.   case VIDEO_MODE_RGB16:
  671.   SetWindowText(GetDlgItem(hDlg, IDC_STATIC_VIDEO_MODE), "RGB 16 bpp");
  672.   break;
  673.   case VIDEO_MODE_RGB24:
  674.   SetWindowText(GetDlgItem(hDlg, IDC_STATIC_VIDEO_MODE), "RGB 24 bpp");
  675.   break;
  676.   case VIDEO_MODE_RGB32:
  677.   SetWindowText(GetDlgItem(hDlg, IDC_STATIC_VIDEO_MODE), "RGB 32 bpp");
  678.   break;
  679.   case VIDEO_MODE_YUY2:
  680.   SetWindowText(GetDlgItem(hDlg, IDC_STATIC_VIDEO_MODE), "YUY2 Overlay");
  681.   break;
  682.   case VIDEO_MODE_YUV12:
  683.   SetWindowText(GetDlgItem(hDlg, IDC_STATIC_VIDEO_MODE), "YUV 12 Overlay");
  684.   break;
  685.   case VIDEO_MODE_UYVY:
  686.   SetWindowText(GetDlgItem(hDlg, IDC_STATIC_VIDEO_MODE), "UYVY Overlay");
  687.   break;
  688.   }
  689.   SetWindowText(GetDlgItem(hDlg, IDC_STATIC_VRENDERER), playback->videoRenderer->GetName());
  690.   }
  691.   if(playback->hasAudio) {
  692.      
  693.   SetWindowText(GetDlgItem(hDlg, IDC_STATIC_AUDIO_CODEC), playback->audioDecoder->GetName());
  694.   SetWindowText(GetDlgItem(hDlg, IDC_STATIC_AUDIO_FREQUENCY), freq);
  695.   SetWindowText(GetDlgItem(hDlg, IDC_STATIC_AUDIO_CHANNELS), channels);
  696.   }
  697.   else {
  698.   SetWindowText(GetDlgItem(hDlg, IDC_STATIC_AUDIO_CODEC),     "Not Available");
  699.   SetWindowText(GetDlgItem(hDlg, IDC_STATIC_AUDIO_FREQUENCY), "Not Available");
  700.   SetWindowText(GetDlgItem(hDlg, IDC_STATIC_AUDIO_CHANNELS),  "Not Available");
  701.   }
  702.   if(playback->hasSubtitles) {
  703.   SetWindowText(GetDlgItem(hDlg, IDC_STATIC_SUB), playback->subtitler->GetName());
  704.   }
  705.   else {
  706.   SetWindowText(GetDlgItem(hDlg, IDC_STATIC_SUB),  "Not Available");
  707.   }
  708.   return (0);
  709. break;
  710.       case WM_SYSCOMMAND:
  711.         if (wParam == SC_CLOSE)
  712.           {
  713.           EndDialog (hDlg, TRUE);
  714.           return (TRUE);
  715.           }
  716.         break;
  717.   case WM_COMMAND:
  718.         switch (wParam)
  719. {
  720.   case IDB_PROPERTIES_OK:
  721.   EndDialog(hDlg, TRUE);
  722.   return TRUE;
  723.   break;
  724.   default:
  725.   return 0;
  726. }
  727. break;
  728. }
  729.   return FALSE;
  730. }
  731. /**************************************************************************************
  732.  *                                                                                    *
  733.  *                                 DlgProc用于关于对话框                              *
  734.  *                        -----------------------------------                         *
  735.  **************************************************************************************/
  736. int APIENTRY AboutDlgProc (HWND hDlg, WORD wMsg, LONG wParam, LONG lParam)
  737. {
  738.   switch (wMsg)
  739.     {
  740.       case WM_INITDIALOG:
  741.         return (0);
  742. break;
  743.       case WM_SYSCOMMAND:
  744.         if (wParam == SC_CLOSE)
  745.           {
  746.           EndDialog (hDlg, TRUE);
  747.           return (TRUE);
  748.           }
  749.         break;
  750.   case WM_COMMAND:
  751.         switch (wParam)
  752. {
  753.   case IDB_ABOUT_OK:
  754.   EndDialog(hDlg, TRUE);
  755.   return TRUE;
  756.   break;
  757.   default:
  758.   return 0;
  759. }
  760. break;
  761. }
  762.   return FALSE;
  763. }
  764. /**************************************************************************************
  765.  *                                                                                    *
  766.  *                              DlgProc用于外壳浏览对话框                             *
  767.  *                        -----------------------------------                         *
  768.  **************************************************************************************/
  769. int APIENTRY SkinBrowserDlgProc (HWND hDlg, WORD wMsg, LONG wParam, LONG lParam)
  770. {
  771.   switch (wMsg)
  772.     {
  773.       case WM_INITDIALOG:
  774.   int i;
  775.   
  776.   /*
  777.    * 初始化外壳链表
  778.    */
  779.   SendMessage(GetDlgItem(hDlg, IDC_SKIN_LIST), LB_ADDSTRING, 0, (LONG) "[Default Skin]");
  780.   SendMessage(GetDlgItem(hDlg, IDC_SKIN_LIST), LB_SETCURSEL, 0, 0); 
  781.   
  782.   if(skinList->skinsDir != NULL) {
  783.   SendMessage(GetDlgItem(hDlg, IDC_COMBO_DIR), CB_ADDSTRING, 0, (LONG)skinList->skinsDir);
  784.       SendMessage(GetDlgItem(hDlg, IDC_COMBO_DIR), CB_SETCURSEL, 0, 0);
  785.   }
  786.   skinList->Scan();
  787.   for(i=0; i < skinList->getNumberOfSkins(); i++) {
  788.   
  789.   SendMessage(GetDlgItem(hDlg, IDC_SKIN_LIST), LB_ADDSTRING, 0, (LONG) skinList->getSkinInfo(i)->name);
  790.   if(strcmp(skinList->getSkinInfo(i)->directory, skinPath) == 0) {
  791.   SendMessage(GetDlgItem(hDlg, IDC_SKIN_LIST), LB_SETCURSEL, i+1, 0); 
  792.   }
  793.   }
  794.   return (0);
  795. break;
  796.       case WM_SYSCOMMAND:
  797.         if (wParam == SC_CLOSE)
  798.           {
  799.           EndDialog (hDlg, TRUE);
  800.           return (TRUE);
  801.           }
  802.         break;
  803.   case WM_COMMAND:
  804.     switch (LOWORD(wParam))  {
  805.   
  806.           case IDC_SKIN_LIST: 
  807.               
  808.   switch (HIWORD(wParam)) { 
  809.                   
  810.   case LBN_SELCHANGE:
  811.   
  812.   int nItem;
  813.   nItem = SendMessage(GetDlgItem(hDlg, IDC_SKIN_LIST), LB_GETCURSEL, 0, 0); 
  814.   if(nItem == 0) {
  815.   
  816.   RECT rect;
  817.   skin->LoadDefault(hInstance, hwnd);
  818.   strcpy(skinPath, "Default");
  819.   UpdateMainWindow();
  820.   }
  821.   else {
  822.   
  823.   RECT rect;
  824.   skin->Load(skinList->getSkinInfo(nItem - 1)->directory, hwnd);
  825.   strcpy(skinPath, skinList->getSkinInfo(nItem  - 1)->directory);
  826.   UpdateMainWindow();
  827.   }
  828.   break;
  829.   }
  830. }
  831.         switch (wParam)
  832. {
  833.   case IDB_SKINS_OK:
  834.   EndDialog(hDlg, TRUE);
  835.   return TRUE;
  836.   break;
  837.   
  838.   case ID_SKINS_CANCEL:
  839.   EndDialog(hDlg, TRUE);
  840.   return TRUE;
  841.   break;
  842.   case IDC_CHANGE_DIR:
  843.   dirChooser = new CDirDialog();
  844.   if(dirChooser->DoBrowse()) {
  845. skinList->SetDir(dirChooser->m_strPath);
  846. SendMessage(GetDlgItem(hDlg, IDC_COMBO_DIR), CB_RESETCONTENT, 0, 0);
  847. SendMessage(GetDlgItem(hDlg, IDC_SKIN_LIST), LB_RESETCONTENT, 0, 0);
  848. SendMessage(GetDlgItem(hDlg, IDC_SKIN_LIST), LB_ADDSTRING, 0, (LONG) "[Default Skin]");
  849. SendMessage(GetDlgItem(hDlg, IDC_SKIN_LIST), LB_SETCURSEL, 0, 0); 
  850. if(skinList->skinsDir != NULL) {
  851.   SendMessage(GetDlgItem(hDlg, IDC_COMBO_DIR), CB_ADDSTRING, 0, (LONG)skinList->skinsDir);
  852.       SendMessage(GetDlgItem(hDlg, IDC_COMBO_DIR), CB_SETCURSEL, 0, 0);
  853.   }
  854.   skinList->Scan();
  855.   for(i=0; i < skinList->getNumberOfSkins(); i++) {
  856.   
  857.   SendMessage(GetDlgItem(hDlg, IDC_SKIN_LIST), LB_ADDSTRING, 0, (LONG) skinList->getSkinInfo(i)->name);
  858.   if(strcmp(skinList->getSkinInfo(i)->directory, skinPath) == 0) {
  859.   SendMessage(GetDlgItem(hDlg, IDC_SKIN_LIST), LB_SETCURSEL, 0, 0); 
  860.   }
  861.   }
  862.   }
  863.   break;
  864.   default:
  865.   return 0;
  866. }
  867. break;
  868. }
  869.   return FALSE;
  870. }
  871. /**************************************************************************************
  872.  *                                                                                    *
  873.  *                             DlgProc用于打开URL对话框                               *
  874.  *                        -----------------------------------                         *
  875.  **************************************************************************************/
  876. int APIENTRY UrlDlgProc (HWND hDlg, WORD wMsg, LONG wParam, LONG lParam)
  877. {
  878.   switch (wMsg)
  879.     {
  880.       case WM_INITDIALOG:
  881.   SendMessage(GetDlgItem(hDlg, IDC_RADIO_HTTP), BM_SETCHECK, BST_CHECKED, 0);
  882.   EnableWindow(GetDlgItem(hDlg, IDC_STATIC_FTP_USERNAME), FALSE);
  883.   EnableWindow(GetDlgItem(hDlg, IDC_STATIC_FTP_PASSWORD), FALSE);
  884.   EnableWindow(GetDlgItem(hDlg, IDC_CHECK_ANONYMOUS),     FALSE);
  885.   EnableWindow(GetDlgItem(hDlg, IDC_STATIC_FTP_SERVER),   FALSE);
  886.   EnableWindow(GetDlgItem(hDlg, IDC_COMBO_FTP),           FALSE);
  887.   EnableWindow(GetDlgItem(hDlg, IDC_EDIT_USERNAME),       FALSE);
  888.   EnableWindow(GetDlgItem(hDlg, IDC_EDIT_PASSWORD),       FALSE);
  889.   return (0);
  890. break;
  891.       case WM_SYSCOMMAND:
  892.         if (wParam == SC_CLOSE) {
  893.             EndDialog (hDlg, TRUE);
  894.             return (TRUE);
  895.         }
  896.         break;
  897.   case WM_COMMAND:
  898.         switch (wParam)
  899. {
  900. case IDC_RADIO_HTTP:
  901.     EnableWindow(GetDlgItem(hDlg, IDC_STATIC_FTP_USERNAME), FALSE);
  902.     EnableWindow(GetDlgItem(hDlg, IDC_STATIC_FTP_PASSWORD), FALSE);
  903.     EnableWindow(GetDlgItem(hDlg, IDC_CHECK_ANONYMOUS),     FALSE);
  904.     EnableWindow(GetDlgItem(hDlg, IDC_STATIC_FTP_SERVER),   FALSE);
  905.     EnableWindow(GetDlgItem(hDlg, IDC_COMBO_FTP),           FALSE);
  906.     EnableWindow(GetDlgItem(hDlg, IDC_EDIT_USERNAME),       FALSE);
  907.     EnableWindow(GetDlgItem(hDlg, IDC_EDIT_PASSWORD),       FALSE);
  908.     EnableWindow(GetDlgItem(hDlg, IDC_EXAMPLE),             TRUE);
  909.     EnableWindow(GetDlgItem(hDlg, IDC_COMBO_HTTP),  TRUE);
  910.     EnableWindow(GetDlgItem(hDlg, IDC_STATIC_HTTP), TRUE);
  911. break;
  912. case IDC_RADIO_FTP:
  913.     EnableWindow(GetDlgItem(hDlg, IDC_CHECK_ANONYMOUS),     TRUE);
  914.     EnableWindow(GetDlgItem(hDlg, IDC_STATIC_FTP_SERVER),   TRUE);
  915.     EnableWindow(GetDlgItem(hDlg, IDC_COMBO_FTP),    TRUE);
  916.     EnableWindow(GetDlgItem(hDlg, IDC_COMBO_HTTP),  FALSE);
  917.     EnableWindow(GetDlgItem(hDlg, IDC_STATIC_HTTP), FALSE);
  918.     EnableWindow(GetDlgItem(hDlg, IDC_EXAMPLE),     FALSE);
  919. anonymous = 1;
  920.     CheckDlgButton(hDlg, IDC_CHECK_ANONYMOUS, TRUE);
  921. break;
  922. case IDC_CHECK_ANONYMOUS:
  923. anonymous = anonymous ? 0 : 1;
  924. if(anonymous) {
  925.     EnableWindow(GetDlgItem(hDlg, IDC_STATIC_FTP_USERNAME), FALSE);
  926.     EnableWindow(GetDlgItem(hDlg, IDC_STATIC_FTP_PASSWORD), FALSE);
  927.     EnableWindow(GetDlgItem(hDlg, IDC_EDIT_USERNAME),       FALSE);
  928.     EnableWindow(GetDlgItem(hDlg, IDC_EDIT_PASSWORD),       FALSE);
  929. }
  930. else {
  931.     EnableWindow(GetDlgItem(hDlg, IDC_STATIC_FTP_USERNAME), TRUE);
  932.     EnableWindow(GetDlgItem(hDlg, IDC_STATIC_FTP_PASSWORD), TRUE);
  933.     EnableWindow(GetDlgItem(hDlg, IDC_EDIT_USERNAME),       TRUE);
  934.     EnableWindow(GetDlgItem(hDlg, IDC_EDIT_PASSWORD),       TRUE);
  935. }
  936. break;
  937. case IDB_URL_OK:
  938. EndDialog(hDlg, TRUE);
  939. RECT rect;
  940. GetClientRect(hwnd, &rect);
  941. InvalidateRect(hwnd, &rect, TRUE); 
  942. UpdateWindow(hwnd);
  943. openOK = FALSE;
  944. if(SendMessage(GetDlgItem(hDlg, IDC_RADIO_HTTP), BM_GETCHECK, 0, 0) == BST_CHECKED) {
  945. SHORT lineLength;
  946. lineLength = (short) SendMessage(GetDlgItem(hDlg, IDC_EDIT_HTTP), EM_LINELENGTH, 0, 0);
  947. /*
  948.  * 将url缓冲写入头两个字节
  949.  * 
  950.  */
  951. url = (char *) new char[lineLength + 1];
  952. memcpy(url, &lineLength, 2);
  953. SendMessage(GetDlgItem(hDlg, IDC_EDIT_HTTP), EM_GETLINE, 0, (LONG)(LPVOID)url);
  954. url[lineLength] = '';
  955. if(strstr(url, "http://") != NULL || strstr(url, "HTTP://") != NULL) {
  956. openOK = TRUE;
  957. return 0;
  958. }
  959. }
  960. else {
  961. SHORT lineLength;
  962. lineLength = (short) SendMessage(GetDlgItem(hDlg, IDC_RADIO_HTTP), EM_LINELENGTH, 0, 0);
  963. /*
  964.  * 将url缓冲写入头两个字节
  965.  *
  966.  */
  967. url = (char *) new char[lineLength + 1];
  968. memcpy(url, &lineLength, 2);
  969. SendMessage(GetDlgItem(hDlg, IDC_EDIT_HTTP), EM_GETLINE, 0, (LONG)(LPVOID)url);
  970. url[lineLength] = '';
  971. if(strstr(url, "ftp://") != NULL || strstr(url, "FTP://") != NULL) {
  972. if(anonymous) {
  973. openOK = TRUE;
  974. return 0;
  975. }
  976. else {
  977. }
  978. }
  979. }
  980.   
  981. return TRUE;
  982. break;
  983. case IDB_URL_CANCEL:
  984. EndDialog(hDlg, TRUE);
  985. return TRUE;
  986. break;
  987. default:
  988.   return 0;
  989. }
  990. break;
  991. }
  992.   return FALSE;
  993. }
  994. /**************************************************************************************
  995.  *                                                                                    *
  996.  *                                      清除                                          *
  997.  *                                    -------                                         *
  998.  **************************************************************************************/
  999. void Cleanup()
  1000. {
  1001. DWORD i;
  1002. for(i=0; i < 5; i++) {
  1003. if(RecentFiles[i] != NULL) {
  1004. free(RecentFiles[i]);
  1005. }
  1006. }
  1007. DestroyMenu(popupMenu);
  1008. CoUninitialize();
  1009. delete playback;
  1010. delete skinList;
  1011. delete resizer;
  1012. }
  1013. /**************************************************************************************
  1014.  *                                                                                    *
  1015.  * - ParseCmdLine():                                                                  *
  1016.  *                                                                                    *
  1017.  *   ———分析命令行和重载选项                                                             *
  1018.  *                                                                                    *
  1019.  **************************************************************************************/
  1020. void ParseCmdLine(char *lpszCmdParam)
  1021. {
  1022. char *token;
  1023. char *arg1;
  1024. token = lpszCmdParam;
  1025. while(*token != '' && (*token == ' ' || *token == 't'))
  1026. token++;
  1027. while(*token != '') {
  1028. if(*token == '/') {
  1029. token++;
  1030. if(*token == 'f') {
  1031. options.startFullscreen = 1;
  1032. token++;
  1033. }
  1034. continue;
  1035. }
  1036. if(*token == '"') {
  1037. arg1 = ++token;
  1038. while(*token != '' && *token != '"') {
  1039. token++;
  1040. }
  1041. *token++ = '';
  1042. playlist->AddItem(arg1);
  1043. }
  1044. token++;
  1045. }
  1046. }
  1047. /**************************************************************************************
  1048.  *                                                                                    *
  1049.  * - ReBuildRecentFilesMenu():                                                        *
  1050.  *                                                                                    *
  1051.  *   ———分析命令行和重载选项                                                       *
  1052.  *                                                                                    *
  1053.  **************************************************************************************/
  1054. void ReBuildRecentFilesMenu()
  1055. {
  1056.    HMENU             menu;
  1057.    MENUITEMINFO      itemInfo;
  1058.    DWORD             i,count;
  1059.    char              buffer[MAX_PATH + 4];
  1060.    menu = GetSubMenu(popupMenu, 0);
  1061.    menu = GetSubMenu(menu, 5);
  1062.    if(RecentFiles[0] != NULL) {
  1063.    count = GetMenuItemCount(menu);
  1064.    for(i=0; i<count; i++)
  1065.    RemoveMenu(menu, 0, MF_BYPOSITION);
  1066.    
  1067.    /*
  1068.  * 加入文件
  1069.  */
  1070.    
  1071.    for(i=0; i < 5; i++) {
  1072.    
  1073.    if(RecentFiles[i] != NULL) {
  1074. sprintf(buffer, "%d - ", i+1);
  1075. strcat(buffer, RecentFiles[i]);
  1076.    itemInfo.cbSize = sizeof(MENUITEMINFO);
  1077.    itemInfo.fMask  = MIIM_DATA | MIIM_TYPE | MIIM_ID;
  1078.    itemInfo.fType  = MFT_STRING;
  1079.    itemInfo.dwTypeData = buffer;
  1080.    itemInfo.cch = strlen(buffer);
  1081.    itemInfo.wID = ID_RECENT_FILE1 + i;
  1082.    
  1083.    InsertMenuItem(menu, GetMenuItemCount(menu), TRUE, &itemInfo);
  1084. }
  1085.    }
  1086.     itemInfo.cbSize = sizeof(MENUITEMINFO);
  1087.     itemInfo.fMask  = MIIM_DATA | MIIM_TYPE | MIIM_ID;
  1088.     itemInfo.fType  = MFT_SEPARATOR;
  1089.     itemInfo.dwTypeData = "";
  1090.     itemInfo.cch = strlen("");
  1091.     itemInfo.wID = ID_RECENT_FILE1 + i;
  1092.    
  1093. InsertMenuItem(menu, GetMenuItemCount(menu), TRUE, &itemInfo);
  1094.     itemInfo.cbSize = sizeof(MENUITEMINFO);
  1095.     itemInfo.fMask  = MIIM_DATA | MIIM_TYPE | MIIM_ID;
  1096.     itemInfo.fType  = MFT_STRING;
  1097.     itemInfo.dwTypeData = "Clear list";
  1098. itemInfo.cch = strlen("Clear list");
  1099. itemInfo.wID = ID_CLEAR_LIST;
  1100.    
  1101. InsertMenuItem(menu, GetMenuItemCount(menu), TRUE, &itemInfo);
  1102.    }
  1103.    else {
  1104.    count = GetMenuItemCount(menu);
  1105.    for(i=0; i<count; i++)
  1106.    RemoveMenu(menu, 0, MF_BYPOSITION);
  1107.    itemInfo.cbSize = sizeof(MENUITEMINFO);
  1108. itemInfo.fMask  = MIIM_DATA | MIIM_TYPE | MIIM_ID;
  1109.     itemInfo.fType  = MFT_STRING;
  1110.     itemInfo.dwTypeData = "No recent files...";
  1111.     itemInfo.cch = strlen("No recent files...");
  1112.     itemInfo.wID = ID_RECENT_FILE1;
  1113.    
  1114. InsertMenuItem(menu, GetMenuItemCount(menu), TRUE, &itemInfo);
  1115. EnableMenuItem(menu, ID_RECENT_FILE1, MF_GRAYED);
  1116.    }
  1117. }
  1118. /**************************************************************************************
  1119.  *                                                                                    *
  1120.  * - UpdateRecentFilesMenu():                                                         *
  1121.  *                                                                                    *
  1122.  *   ———加入(如果可以)一个条目到文件链表                                         *
  1123.  *                                                                                    *
  1124.  **************************************************************************************/
  1125. void UpdateRecentFilesMenu(char *filename)
  1126. {
  1127. DWORD i;
  1128. DWORD insert = 1;
  1129. for(i=0; i < 5; i++) {
  1130. if(RecentFiles[i] != NULL && strcmp(RecentFiles[i], filename) == 0) {
  1131. insert = 0;
  1132. }
  1133. }
  1134. if(insert) {
  1135. for(i=4; i > 0; i--) {
  1136. RecentFiles[i] = RecentFiles[i - 1];
  1137. }
  1138. RecentFiles[0] = (char *) new char[(strlen(filename) + 1)];
  1139. strncpy(RecentFiles[0], filename, strlen(filename));
  1140. RecentFiles[0][strlen(filename)] = '';
  1141. }
  1142. }
  1143. /**************************************************************************************
  1144.  *                                                                                    *
  1145.  * - PreparesDesktopMode():                                                           *
  1146.  *                                                                                    *
  1147.  *   ———设置桌面模式                                                               *
  1148.  *                                                                                    *
  1149.  **************************************************************************************/
  1150. void PrepareDesktopMode() {
  1151. HRESULT hr;
  1152. IActiveDesktop *pActiveDesktop;
  1153. /*
  1154.  * 活动桌面填充
  1155.  * --------------------
  1156.  */
  1157. hr = CoCreateInstance(CLSID_ActiveDesktop, NULL, CLSCTX_INPROC_SERVER,
  1158.       IID_IActiveDesktop, (void**)&pActiveDesktop);
  1159. if(hr == S_OK) {
  1160. wchar_t *wstr;
  1161. pActiveDesktop->GetWallpaper((LPWSTR) &wallpaper, MAX_PATH, 0);
  1162. pActiveDesktop->GetPattern((LPWSTR) &pattern, MAX_PATH, 0);
  1163. wstr = (wchar_t *) new char[2*MAX_PATH];
  1164. mbtowc(wstr, "None", MAX_PATH);
  1165. pActiveDesktop->SetWallpaper((WCHAR *) wstr, 0);
  1166. pActiveDesktop->SetPattern((WCHAR *) wstr, 0);
  1167. pActiveDesktop->ApplyChanges(AD_APPLY_ALL);
  1168. pActiveDesktop->Release();
  1169. }
  1170. /*
  1171.  * 标准填充
  1172.  * --------------
  1173.  */
  1174. COLORREF colorref;
  1175. INT      background;
  1176. background = COLOR_DESKTOP;
  1177. colorref   = DD_OVERLAY_COLORREF;
  1178. /*
  1179.  * 得到设置
  1180.  */
  1181. backColor = GetSysColor(COLOR_DESKTOP);
  1182. /*
  1183.  * 设置
  1184.  */
  1185. SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, "", 0);
  1186. SetSysColors(1, &background, &colorref);
  1187. }
  1188. /**************************************************************************************
  1189.  *                                                                                    *
  1190.  * - UnPreparesDesktopMode():                                                         *
  1191.  *                                                                                    *
  1192.  *   ———取消桌面模式的设置                                                         *
  1193.  *                                                                                    *
  1194.  **************************************************************************************/
  1195. void UnPrepareDesktopMode() {
  1196. HRESULT hr;
  1197. IActiveDesktop *pActiveDesktop;
  1198. /*
  1199.  * 活动桌面填充
  1200.  * --------------------
  1201.  */
  1202. hr = CoCreateInstance(CLSID_ActiveDesktop, NULL, CLSCTX_INPROC_SERVER,
  1203.       IID_IActiveDesktop, (void**)&pActiveDesktop);
  1204. if(hr == S_OK) {
  1205. pActiveDesktop->SetWallpaper(wallpaper, 0);
  1206. pActiveDesktop->SetPattern(pattern, 0);
  1207. pActiveDesktop->ApplyChanges(AD_APPLY_ALL);
  1208. pActiveDesktop->Release();
  1209. }
  1210. /*
  1211.  * API填充
  1212.  */
  1213. INT background = COLOR_DESKTOP;
  1214. SetSysColors(1, &background, &backColor);
  1215. SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, NULL, 0);
  1216. playback->SetDesktopMode(FALSE);
  1217. }
  1218. /**************************************************************************************
  1219.  *                                                                                    *
  1220.  * - PrepareCompactMode():                                                            *
  1221.  *                                                                                    *
  1222.  *   ———设置桌面模型                                                               *
  1223.  *                                                                                    *
  1224.  **************************************************************************************/
  1225. void PrepareCompactMode() {
  1226. HMENU        menu;
  1227. MENUITEMINFO itemInfo;
  1228. menu = GetSubMenu(popupMenu, 0);
  1229. memset(&itemInfo, 0, sizeof(MENUITEMINFO));
  1230. itemInfo.cbSize     = sizeof(MENUITEMINFO);
  1231. itemInfo.fType      = MFT_STRING;
  1232. itemInfo.fMask      = MIIM_TYPE;
  1233. itemInfo.dwTypeData = "&Standard ModetAlt+C";
  1234. SetMenuItemInfo(menu, ID_COMPACT, FALSE, &itemInfo);
  1235. }
  1236. /**************************************************************************************
  1237.  *                                                                                    *
  1238.  * - UnPrepareCompactMode():                                                          *
  1239.  *                                                                                    *
  1240.  *   ———取消桌面模式的设置                                                         *
  1241.  *                                                                                    *
  1242.  **************************************************************************************/
  1243. void UnPrepareCompactMode() {
  1244. HMENU        menu;
  1245. MENUITEMINFO itemInfo;
  1246. compact_mode = 0;
  1247. skin->SetCompact(FALSE);
  1248. /*
  1249.  * 改变菜单项文本
  1250.  */
  1251. menu = GetSubMenu(popupMenu, 0);
  1252. memset(&itemInfo, 0, sizeof(MENUITEMINFO));
  1253. itemInfo.cbSize     = sizeof(MENUITEMINFO);
  1254. itemInfo.fType      = MFT_STRING;
  1255. itemInfo.fMask      = MIIM_TYPE;
  1256. itemInfo.dwTypeData = "&Compact ModetAlt+C";
  1257. SetMenuItemInfo(menu, ID_COMPACT, FALSE, &itemInfo);
  1258. /*
  1259.  * 调整窗口大小
  1260.  */
  1261. GetWindowRect(hwnd, &windowRect);
  1262. MoveWindow( hwnd, windowRect.left - 7, 
  1263. windowRect.top - 22, 
  1264. cwindowRect.right - cwindowRect.left, 
  1265. cwindowRect.bottom - cwindowRect.top, TRUE);
  1266. playback->SetVideoRect(skin->GetVideoRect());
  1267. }
  1268. /**************************************************************************************
  1269.  *                                                                                    *
  1270.  * - ChangeMenuForNormalMode():                                                       *
  1271.  *                                                                                    *
  1272.  *   ———重新产生播放链表浮动菜单                                                   *
  1273.  *                                                                                    *
  1274.  **************************************************************************************/
  1275. void ChangeMenuForNormalMode() 
  1276. {
  1277. HMENU menu;
  1278. menu = GetSubMenu(popupMenu, 0);
  1279. /*
  1280.  * 字幕及其属性菜单
  1281.  */
  1282. MENUITEMINFO itemInfo;
  1283. /*
  1284.  * 更新菜单项
  1285.  */
  1286. EnableMenuItem(popupMenu, ID_COMPACT, MF_ENABLED);
  1287. EnableMenuItem(popupMenu, ID_FULLSCREEN, MF_ENABLED);
  1288. EnableMenuItem(popupMenu, (UINT)ID_ON_TOP,      MF_ENABLED);
  1289. EnableMenuItem(popupMenu, (UINT)ID_ASPECT_ORIGINAL, MF_ENABLED);
  1290. EnableMenuItem(popupMenu, (UINT)ID_ASPECT_FREE,     MF_ENABLED);
  1291. EnableMenuItem(popupMenu, (UINT)ID_ASPECT_43,       MF_ENABLED);
  1292. EnableMenuItem(popupMenu, (UINT)ID_ASPECT_169,      MF_ENABLED);
  1293. EnableMenuItem(popupMenu, (UINT)ID_ASPECT_CUSTOM,   MF_ENABLED);
  1294. menu = GetSubMenu(popupMenu, 0);
  1295. memset(&itemInfo, 0, sizeof(MENUITEMINFO));
  1296. itemInfo.cbSize     = sizeof(MENUITEMINFO);
  1297. itemInfo.fType      = MFT_STRING;
  1298. itemInfo.fMask      = MIIM_TYPE;
  1299. itemInfo.dwTypeData = "&Desktop modetAlt+D";
  1300. SetMenuItemInfo(menu, ID_DESKTOP, FALSE, &itemInfo);
  1301. EnableMenuItem(popupMenu, (UINT)ID_PROPERTIES,      MF_ENABLED);
  1302. EnableMenuItem(popupMenu, (UINT)ID_DESKTOP,         MF_ENABLED);
  1303. }
  1304. /**************************************************************************************
  1305.  *                                                                                    *
  1306.  * - ChangeMenuForFullscreenlMode():                                                  *
  1307.  *                                                                                    *
  1308.  *   ———重新产生播放链表浮动菜单                                                   *
  1309.  *                                                                                    *
  1310.  **************************************************************************************/
  1311. void ChangeMenuForFullscreenMode() 
  1312. {
  1313. HMENU        menu;
  1314. MENUITEMINFO itemInfo;
  1315. GetWindowRect(hwnd, &fullwindowRect);
  1316. /*
  1317.  * 使某些项无效
  1318.  */
  1319. EnableMenuItem(popupMenu, ID_COMPACT, MF_GRAYED);
  1320. EnableMenuItem(popupMenu, ID_FULLSCREEN, MF_GRAYED);
  1321. EnableMenuItem(popupMenu, (UINT)ID_ON_TOP,      MF_GRAYED);
  1322. EnableMenuItem(popupMenu, (UINT)ID_ASPECT_ORIGINAL, MF_GRAYED);
  1323. EnableMenuItem(popupMenu, (UINT)ID_ASPECT_FREE,     MF_GRAYED);
  1324. EnableMenuItem(popupMenu, (UINT)ID_ASPECT_43,       MF_GRAYED);
  1325. EnableMenuItem(popupMenu, (UINT)ID_ASPECT_169,      MF_GRAYED);
  1326. EnableMenuItem(popupMenu, (UINT)ID_ASPECT_CUSTOM,   MF_GRAYED);
  1327. menu = GetSubMenu(popupMenu, 0);
  1328. memset(&itemInfo, 0, sizeof(MENUITEMINFO));
  1329. itemInfo.cbSize     = sizeof(MENUITEMINFO);
  1330. itemInfo.fType      = MFT_STRING;
  1331. itemInfo.fMask      = MIIM_TYPE;
  1332. itemInfo.dwTypeData = "Go back to normal modetAlt+Enter";
  1333. SetMenuItemInfo(menu, ID_DESKTOP, FALSE, &itemInfo);
  1334. }
  1335. /**************************************************************************************
  1336.  *                                                                                    *
  1337.  * - ReBuildPlaylistMenu():                                                           *
  1338.  *                                                                                    *
  1339.  *   ———重新产生播放链表浮动菜单                                            *
  1340.  *                                                                                    *
  1341.  **************************************************************************************/
  1342. void ReBuildPlaylistMenu()
  1343. {
  1344. HMENU menu;
  1345. DWORD i;
  1346. DWORD count;
  1347. MENUITEMINFO itemInfo;
  1348. menu = GetSubMenu(GetSubMenu(GetSubMenu(popupMenu, 0), 9), 0);
  1349. count = GetMenuItemCount(menu);
  1350. for(i=0; i < count; i++) {
  1351. RemoveMenu(menu, 0, MF_BYPOSITION);
  1352. }
  1353. /*
  1354.  * 增加标准项
  1355.  *
  1356.  */
  1357. itemInfo.cbSize = sizeof(MENUITEMINFO);
  1358. itemInfo.fMask  = MIIM_DATA | MIIM_TYPE | MIIM_ID;
  1359. itemInfo.fType  = MFT_STRING;
  1360. itemInfo.dwTypeData = "Add Files...tAlt+A";
  1361. itemInfo.cch = strlen("Add Files...tAlt+A");
  1362. itemInfo.wID = ID_MENU_PLAYBACK_FILES_ADDFILES;
  1363.    
  1364. InsertMenuItem(menu, GetMenuItemCount(menu), TRUE, &itemInfo);
  1365. itemInfo.cbSize = sizeof(MENUITEMINFO);
  1366. itemInfo.fMask  = MIIM_DATA | MIIM_TYPE | MIIM_ID;
  1367. itemInfo.fType  = MFT_SEPARATOR;
  1368. itemInfo.dwTypeData = "-";
  1369. itemInfo.cch = strlen("-");
  1370. itemInfo.wID = 0;
  1371.    
  1372. InsertMenuItem(menu, GetMenuItemCount(menu), TRUE, &itemInfo);
  1373. /*
  1374.  * 增加文件
  1375.  */
  1376.    
  1377.     for(i=0; i < playlist->GetItemCount(); i++) {
  1378.    
  1379. char *name;
  1380. if(strrchr(playlist->GetItemAt(i)->filename, '\') != NULL) {
  1381. name = strrchr(playlist->GetItemAt(i)->filename, '\') + 1;
  1382. }
  1383. else {
  1384. name = playlist->GetItemAt(i)->filename;
  1385. }
  1386.   itemInfo.cbSize     = sizeof(MENUITEMINFO);
  1387.   itemInfo.fMask      = MIIM_DATA | MIIM_TYPE | MIIM_ID;
  1388.   itemInfo.fType      = MFT_STRING;
  1389.   itemInfo.dwTypeData = name;
  1390.   itemInfo.cch        = strlen(name);
  1391.   itemInfo.wID        = ID_PLAYLIST1 + i;
  1392.   itemInfo.dwItemData = i;
  1393.    
  1394.   InsertMenuItem(menu, GetMenuItemCount(menu), TRUE, &itemInfo);
  1395.    }
  1396. /*
  1397.  * 选择当前的项
  1398.  *
  1399.  */
  1400. CheckMenuItem(menu, ID_PLAYLIST1 + playlist->GetCurrentPosition(), MF_CHECKED);
  1401. }
  1402. /**************************************************************************************
  1403.  *                                                                                    *
  1404.  * - UpdateMainWindow():                                                              *
  1405.  *                                                                                    *
  1406.  *   ———重新绘制主窗口                                                             *
  1407.  *                                                                                    *
  1408.  **************************************************************************************/
  1409. void UpdateMainWindow()
  1410. {
  1411. RECT rect;
  1412. GetClientRect(hwnd, &rect);
  1413. InvalidateRect(hwnd, &rect, TRUE); 
  1414. UpdateWindow(hwnd);
  1415. }
  1416. /**************************************************************************************
  1417.  *                                                                                    *
  1418.  *                                      退出                                          *
  1419.  *                                    --------                                        *
  1420.  **************************************************************************************/
  1421. void Quit() 
  1422. {
  1423. SaveOptions();
  1424. playback->Close();
  1425. if(playback->desktopMode) {
  1426. UnPrepareDesktopMode();
  1427. }
  1428. if(options.disable_screen_saver) {
  1429. SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, screenSaverActive, NULL, 0);
  1430. }
  1431. Cleanup();
  1432. PostQuitMessage(0);
  1433. }
  1434. /**************************************************************************************
  1435.  *                                                                                    *
  1436.  * - WinMain():                                                                       *
  1437.  *                                                                                    *
  1438.  *   ———程序入口                                                                   *
  1439.  *                                                                                    *
  1440.  **************************************************************************************/
  1441. int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow)
  1442. POINT     pt;
  1443. POINT     pt2;
  1444.     MSG       Msg;
  1445.     WNDCLASS  W;
  1446. /*
  1447.  * 为对话框和资源保存一个全局实例
  1448.  *
  1449.  */
  1450. hInstance = hInst;
  1451. showing_cursor = 1;
  1452. firstStart     = 1;
  1453. /*
  1454.  * 装载选项
  1455.  *
  1456.  */
  1457. LoadOptions();
  1458. /*
  1459.      * 初始化视频子系统
  1460.      *
  1461.      */
  1462. playlist = new Playlist();
  1463. playback = new MediaPlayback();
  1464. skinList = new SkinList();
  1465. resizer  = new Resizer();
  1466. /*
  1467.  * 分析命令行和重载选项
  1468.  *
  1469.      */
  1470. ParseCmdLine(lpszCmdParam);
  1471. /*
  1472.  * 设置缺省设置
  1473.  *
  1474.  */
  1475. playback->SetLoop(options.loop);
  1476. playback->videoDecoder->decoreDecoder->SetQuality(options.postprocessing);
  1477. playback->SetDesktopMode(FALSE);
  1478. /*
  1479.  * 窗口大小调整
  1480.  *
  1481.  */
  1482. windowRect.left   = 0;
  1483. windowRect.right  = DEFAULT_SKIN_WIDTH;
  1484. windowRect.top    = 0;
  1485. windowRect.bottom = DEFAULT_SKIN_HEIGHT;
  1486.     AdjustWindowRect(&windowRect, WS_POPUP|WS_SIZEBOX, 0);
  1487. /*
  1488.  * 初始化COM库
  1489.  *
  1490.  */
  1491. CoInitialize(NULL);
  1492. /*
  1493.  * 注册Window类
  1494.  * 
  1495.  */
  1496. memset(&W, 0, sizeof(WNDCLASS));
  1497.    
  1498. W.style         = CS_HREDRAW | CS_VREDRAW | CS_PARENTDC;
  1499. W.lpfnWndProc   = WndProc;
  1500. W.hInstance     = hInst;
  1501. W.hbrBackground = (HBRUSH)(0);
  1502. W.hCursor       = LoadCursor(hInst, MAKEINTRESOURCE(IDC_CURSOR1));
  1503. W.hIcon         = LoadIcon(hInst, MAKEINTRESOURCE(IDB_ICON));
  1504. W.lpszClassName = Name;
  1505. W.lpszMenuName  = NULL;
  1506. RegisterClass(&W);
  1507.    /*
  1508.     * 装载菜单,并为最近文件链表改变菜单
  1509. *
  1510.     */
  1511. popupMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_MENU1));
  1512. ReBuildRecentFilesMenu();
  1513. ReBuildPlaylistMenu();
  1514.    /*
  1515.     * 产生主窗口
  1516.     *
  1517.     */
  1518. hwnd = CreateWindow(Name, Name, WS_POPUP | WS_SIZEBOX, 
  1519.                 options.posX, options.posY, 
  1520. windowRect.right - windowRect.left, 
  1521. windowRect.bottom - windowRect.top, 
  1522. NULL, NULL, hInst, NULL);
  1523.    /*
  1524.     * 设置窗口区域
  1525.     *
  1526.     */
  1527. GetClientRect(hwnd, &clientRect);
  1528. GetWindowRect(hwnd, &windowRect);
  1529. pt.x = clientRect.left;
  1530. pt.y = clientRect.top;
  1531. ClientToScreen(hwnd, &pt);
  1532. pt2.x = clientRect.right;
  1533. pt2.y = clientRect.bottom;
  1534. ClientToScreen(hwnd, &pt2);
  1535. SetWindowRgn(hwnd, CreateRectRgn( pt.x  - windowRect.left, 
  1536.      pt.y  - windowRect.top,
  1537.   (windowRect.right - windowRect.left) - (windowRect.right - pt2.x),
  1538.   (windowRect.bottom - windowRect.top) - (windowRect.bottom - pt2.y)), TRUE); 
  1539. DragAcceptFiles(hwnd, TRUE);
  1540.    /*
  1541.     * 启动定时器
  1542.     *
  1543.     */
  1544. SetTimer(hwnd, TIMER_ID, TIMER_RATE, NULL);
  1545. /*
  1546.  * 装载加速键
  1547.  */
  1548. hAccel = LoadAccelerators(hInst, MAKEINTRESOURCE(IDR_ACCELERATOR));
  1549. /*
  1550.  * 设置图标
  1551.  */
  1552. SetClassLong(hwnd, GCL_HICON, (LONG) LoadIcon(hInst, MAKEINTRESOURCE(IDB_ICON))); 
  1553.  
  1554. /*
  1555.  * 菜单项 
  1556.  */
  1557. CheckMenuItem(popupMenu, (UINT)ID_LOOP, options.loop ? MF_CHECKED : MF_UNCHECKED);
  1558. CheckMenuItem(popupMenu, (UINT)ID_ON_TOP, options.on_top ? MF_CHECKED : MF_UNCHECKED);
  1559. switch(options.aspect_ratio) {
  1560. case ASPECT_RATIO_ORIGINAL:
  1561. CheckMenuItem(popupMenu, (UINT)ID_ASPECT_FREE, MF_UNCHECKED);
  1562. CheckMenuItem(popupMenu, (UINT)ID_ASPECT_ORIGINAL, MF_CHECKED);
  1563. break;
  1564. case ASPECT_RATIO_TV:
  1565. CheckMenuItem(popupMenu, (UINT)ID_ASPECT_FREE, MF_UNCHECKED);
  1566. CheckMenuItem(popupMenu, (UINT)ID_ASPECT_43, MF_CHECKED);
  1567. break;
  1568. case ASPECT_RATIO_WIDE:
  1569. CheckMenuItem(popupMenu, (UINT)ID_ASPECT_FREE, MF_UNCHECKED);
  1570. CheckMenuItem(popupMenu, (UINT)ID_ASPECT_169, MF_CHECKED);
  1571. break;
  1572. case ASPECT_RATIO_CUSTOM:
  1573. CheckMenuItem(popupMenu, (UINT)ID_ASPECT_FREE, MF_UNCHECKED);
  1574. CheckMenuItem(popupMenu, (UINT)ID_ASPECT_CUSTOM, MF_CHECKED);
  1575. break;
  1576. }
  1577.    /*
  1578.     * 装载外壳
  1579.     *
  1580.     */
  1581.    skin = new Skin(hInst, hwnd);
  1582.    if(strcmp(skinPath, "Default") == 0) {
  1583.    skin->LoadDefault(hInst, hwnd);
  1584.    }
  1585.    else {
  1586.    skin->Load(skinPath, hwnd);
  1587.    }
  1588.    /*
  1589.     * 使屏保无效,并得到当前状态
  1590.     *
  1591.     */
  1592. screenSaverActive = FALSE;
  1593. SystemParametersInfo(SPI_GETSCREENSAVEACTIVE, 0, &screenSaverActive, 0);
  1594. if(options.disable_screen_saver) {
  1595. SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, FALSE, NULL, 0);
  1596.    }
  1597.    /*
  1598.     * 开始显示
  1599. *
  1600.     */
  1601. ShowWindow(hwnd, nCmdShow);
  1602. UpdateWindow(hwnd);
  1603. GetWindowRect(hwnd, &windowRect);
  1604. if(options.on_top)
  1605. SetWindowPos(hwnd, (HWND) -1,  windowRect.left, windowRect.top, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, TRUE);
  1606. /*
  1607.  * 消息循环
  1608.  *
  1609.  */
  1610. while (TRUE)
  1611.     {
  1612.    /*
  1613. * 得到消息
  1614. */
  1615.    if (!GetMessage(&Msg, NULL, 0, 0))
  1616. return (int) Msg.wParam;
  1617. if (!TranslateAccelerator(hwnd, hAccel, &Msg)) {
  1618. TranslateMessage(&Msg); 
  1619. DispatchMessage(&Msg); 
  1620. else {
  1621.            
  1622. TranslateMessage(&Msg);
  1623.     DispatchMessage(&Msg);
  1624. }
  1625.    }
  1626.    return Msg.wParam;
  1627. }
  1628. /**************************************************************************************
  1629.  *                                                                                    *
  1630.  * - OpenFileForPlaying():                                                            *
  1631.  *                                                                                    *
  1632.  *   ———打开当前播放链表位置                                                       *
  1633.  *                                                                                    *
  1634.  **************************************************************************************/
  1635. void OpenFileForPlaying(HWND hwnd) {
  1636. char *filename;
  1637. RECT rect, windowrect;
  1638. /*
  1639.  * 关闭最后的重放
  1640.  *
  1641.  */
  1642. playback->Close();
  1643. filename = playlist->GetCurrentItem()->filename;
  1644. /*
  1645.  * 如果没有文件被打开,简单的返回
  1646.  * 
  1647.  */
  1648. if(filename == NULL) {
  1649. return;
  1650. }
  1651. openning_network = FALSE;
  1652. /*
  1653.  * 清除
  1654.  *
  1655.  */
  1656. if(strstr(filename, "http://") != NULL ||
  1657.    strstr(filename, "HTTP://") != NULL || 
  1658.    strstr(filename, "FTP://")  != NULL ||
  1659.    strstr(filename, "ftp://")  != NULL) {
  1660. if(playback->OpenMediaSource(filename) == MP_RESULT_OK) {
  1661. openning_network = TRUE;
  1662. return;
  1663. }
  1664. MP_ERROR("The network location you selected could not be opened");
  1665. return;
  1666. }
  1667. else {
  1668. if(playback->OpenMedia(filename, hwnd) == MP_RESULT_OK) {
  1669. /*
  1670.  * 第一次调整窗口大小
  1671.  */
  1672. DWORD i, width, height;
  1673. switch(options.aspect_ratio) {
  1674. case ASPECT_RATIO_FREE:
  1675. case ASPECT_RATIO_ORIGINAL:
  1676. width  = playback->GetVideoWidth();
  1677. height = playback->GetVideoHeight();
  1678. break;
  1679. case ASPECT_RATIO_TV:
  1680. case ASPECT_RATIO_WIDE:
  1681. case ASPECT_RATIO_CUSTOM:
  1682. width  = playback->GetVideoWidth();
  1683. height = width*aspectRatios[options.aspect_ratio].yFactor/aspectRatios[options.aspect_ratio].xFactor;
  1684. break;
  1685. }
  1686. if(!playback->fullscreen) {
  1687. GetWindowRect(hwnd, &windowrect); 
  1688. }
  1689. if(compact_mode) {
  1690. rect.left   = 0;
  1691. rect.top    = 0;
  1692. rect.right  = width;
  1693. rect.bottom = height;
  1694. }
  1695. else {
  1696. rect.left   = 0;
  1697. rect.top    = 0;
  1698. rect.right  = width + 15;
  1699. rect.bottom = height + 115 + 22;
  1700. }
  1701. AdjustWindowRect(&rect, WS_POPUP|WS_SIZEBOX, FALSE);
  1702. fullwindowRect.right  = fullwindowRect.left + rect.right - rect.left;
  1703. fullwindowRect.bottom = fullwindowRect.top  + rect.bottom - rect.top;
  1704. if(!playback->fullscreen) {
  1705. MoveWindow( hwnd, windowrect.left, windowrect.top, rect.right - rect.left, rect.bottom - rect.top, TRUE);
  1706. playback->SetVideoRect(skin->GetVideoRect());
  1707. }
  1708. /*
  1709.  * 更新最近的文件链表
  1710.  */
  1711. UpdateRecentFilesMenu(filename);
  1712. /*
  1713.  * 更新菜单
  1714.  */
  1715. if(!playback->IsInFullscreen()) {
  1716. ChangeMenuForNormalMode();
  1717. /*
  1718.  * 更新最近文件链表
  1719.  */
  1720. ReBuildRecentFilesMenu();
  1721. }
  1722. /*
  1723.  * 设置音量
  1724.  */
  1725. playback->SetVolume(skin->GetVolume());
  1726. /*
  1727.  * 保存/设置后处理
  1728.  */
  1729. options.postprocessing = playback->videoDecoder->GetQuality();
  1730. playback->videoDecoder->SetQuality(options.postprocessing);
  1731. /*
  1732.    * 播放
  1733.  */
  1734. playback->Play();
  1735. /*
  1736.  * 更新窗口
  1737.  */
  1738. UpdateMainWindow();
  1739. }
  1740. else {
  1741. /*
  1742.  * 文件打开失败
  1743.  */
  1744. MP_ERROR("The location you selected could not be opened");
  1745. }
  1746.   }
  1747. }
  1748. /**************************************************************************************
  1749.  *                                                                                    *
  1750.  * - AddFilesToPlaylist():                                                            *
  1751.  *                                                                                    *
  1752.  *   ———增加文件到文件链表                                                         *
  1753.  *                                                                                    *
  1754.  **************************************************************************************/
  1755. void AddFilesToPlaylist(HWND hwnd)
  1756. {
  1757. OPENFILENAME ofn;
  1758. char szFile[260];
  1759. /*
  1760.  * 显示一个文件选择器
  1761.  */
  1762. ZeroMemory(&ofn, sizeof(OPENFILENAME));
  1763.     ZeroMemory(szFile, 260);
  1764. ofn.lStructSize = sizeof(OPENFILENAME);
  1765. ofn.hwndOwner = hwnd;
  1766. ofn.lpstrFile = szFile;
  1767. ofn.nMaxFile = sizeof(szFile);
  1768. ofn.lpstrFilter = "All*.*AVI Files*.AVI";
  1769. ofn.nFilterIndex = 2;
  1770. ofn.lpstrFileTitle = "";
  1771. ofn.nMaxFileTitle = 0;
  1772. ofn.lpstrInitialDir = NULL;
  1773. ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_ALLOWMULTISELECT | OFN_EXPLORER;
  1774. if (GetOpenFileName(&ofn) == TRUE) {
  1775. if(ofn.lpstrFile[strlen(ofn.lpstrFile) + 1] == NULL) {
  1776. /*
  1777.  * 只有一个文件被选择
  1778.  *
  1779.  */
  1780. playlist->AddItem(ofn.lpstrFile);
  1781. }
  1782. else {
  1783. /*
  1784.  * 多个文件被选择
  1785.  *
  1786.  */
  1787. DWORD index, i = 0;
  1788. char  dir[1024];
  1789. index = strlen(ofn.lpstrFile) + 1;
  1790. do {
  1791. strcpy(dir, ofn.lpstrFile);
  1792. playlist->AddItem((LPSTR)strcat(strcat(dir, "\"), ofn.lpstrFile + index));
  1793. index += strlen(dir) - strlen(ofn.lpstrFile);
  1794. }
  1795. while(ofn.lpstrFile[index] != NULL);
  1796. }
  1797. if(!playback->HasVideo()) {
  1798. OpenFileForPlaying(hwnd);
  1799. }
  1800. ReBuildPlaylistMenu();
  1801. }
  1802. }
  1803. /**************************************************************************************
  1804.  *                                                                                    *
  1805.  * - FilesOpen():                                                                     *
  1806.  *                                                                                    *
  1807.  *   ———打开文件                                                                   *
  1808.  *                                                                                    *
  1809.  **************************************************************************************/
  1810. void FilesOpen(HWND hwnd)
  1811. {
  1812. OPENFILENAME ofn;
  1813. char szFile[260];
  1814. /*
  1815.  * 显示一个文件选择器
  1816.  */
  1817. ZeroMemory(&ofn, sizeof(OPENFILENAME));
  1818.     ZeroMemory(szFile, 260);
  1819. ofn.lStructSize = sizeof(OPENFILENAME);
  1820. ofn.hwndOwner = hwnd;
  1821. ofn.lpstrFile = szFile;
  1822. ofn.nMaxFile = sizeof(szFile);
  1823. ofn.lpstrFilter = "All*.*AVI Files*.AVI";
  1824. ofn.nFilterIndex = 2;
  1825. ofn.lpstrFileTitle = "";
  1826. ofn.nMaxFileTitle = 0;
  1827. ofn.lpstrInitialDir = NULL;
  1828. ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_ALLOWMULTISELECT | OFN_EXPLORER;
  1829. if (GetOpenFileName(&ofn) == TRUE) {
  1830. playlist->Reset();
  1831. if(ofn.lpstrFile[strlen(ofn.lpstrFile) + 1] == NULL) {
  1832. /*
  1833.  * 只有一个文件被选择
  1834.  *
  1835.  */
  1836. playlist->AddItem(ofn.lpstrFile);
  1837. }
  1838. else {
  1839. /*
  1840.  * 多个文件被选择
  1841.  *
  1842.  */
  1843. DWORD index, i = 0;
  1844. char  dir[1024];
  1845. index = strlen(ofn.lpstrFile) + 1;
  1846. do {
  1847. strcpy(dir, ofn.lpstrFile);
  1848. playlist->AddItem((LPSTR)strcat(strcat(dir, "\"), ofn.lpstrFile + index));
  1849. index += strlen(dir) - strlen(ofn.lpstrFile);
  1850. }
  1851. while(ofn.lpstrFile[index] != NULL);
  1852. }
  1853. OpenFileForPlaying(hwnd);
  1854. ReBuildPlaylistMenu();
  1855. }
  1856. }
  1857. /**************************************************************************************
  1858.  *                                                                                    *
  1859.  *                              WNDPROC (主要事件方法)                                *
  1860.  *                            -------------------------                               *
  1861.  **************************************************************************************
  1862.  *                                                                                    *
  1863.  *                                                                                    *
  1864.  *                                                                                    *
  1865.  **************************************************************************************/
  1866. LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
  1867. signed short xPos, yPos;
  1868. RECT         r;
  1869. switch(Message) {
  1870. /*
  1871.  * 播放引擎发送消息
  1872.  */
  1873. case WM_PLAYA_PLAYBACK_END:
  1874. if(playlist->GetItemCount() > 0) {
  1875. if(playlist->GetCurrentPosition() < playlist->GetItemCount() - 1) {
  1876. playlist->NextItem();
  1877. OpenFileForPlaying(hwnd);
  1878. ReBuildPlaylistMenu();
  1879. }
  1880. else {
  1881. playlist->SetCurrentPosition(0);
  1882. }
  1883. }
  1884. break;
  1885. case WM_DESTROY:
  1886. Quit();
  1887. return TRUE;
  1888. break;
  1889. case WM_SYSCOMMAND:
  1890.         
  1891. if (wParam == SC_CLOSE)
  1892.           {
  1893. Quit();
  1894. return (TRUE);
  1895.           }
  1896.         break;
  1897. case WM_COMMAND :
  1898. RECT rect;
  1899.     
  1900. switch(LOWORD(wParam)) {
  1901. case ID_RECENT_FILE1:
  1902. playlist->Reset();
  1903. playlist->AddItem(RecentFiles[0]);
  1904. OpenFileForPlaying(hwnd);
  1905. ReBuildPlaylistMenu();
  1906. break;
  1907. case ID_RECENT_FILE2:
  1908. playlist->Reset();
  1909. playlist->AddItem(RecentFiles[1]);
  1910. OpenFileForPlaying(hwnd);
  1911. ReBuildPlaylistMenu();
  1912. break;
  1913. case ID_RECENT_FILE3:
  1914. playlist->Reset();
  1915. playlist->AddItem(RecentFiles[2]);
  1916. OpenFileForPlaying(hwnd);
  1917. ReBuildPlaylistMenu();
  1918. break;
  1919. case ID_RECENT_FILE4:
  1920. playlist->Reset();
  1921. playlist->AddItem(RecentFiles[3]);
  1922. OpenFileForPlaying(hwnd);
  1923. ReBuildPlaylistMenu();
  1924. break;
  1925. case ID_RECENT_FILE5:
  1926. playlist->Reset();
  1927. playlist->AddItem(RecentFiles[4]);
  1928. OpenFileForPlaying(hwnd);
  1929. ReBuildPlaylistMenu();
  1930. break;
  1931. case ID_MENU_ABOUT:
  1932.             DialogBox (hInstance, (LPCSTR)MAKEINTRESOURCE(IDD_ABOUT_DIALOG),
  1933.                        hwnd, (DLGPROC)AboutDlgProc);
  1934. break;
  1935. case ID_CLEAR_LIST:
  1936. DWORD i;
  1937. for(i=0; i<5; i++) {
  1938. if(RecentFiles[i] != NULL) {
  1939. free(RecentFiles[i]);
  1940. RecentFiles[i] = NULL;
  1941. }
  1942. }
  1943. ReBuildRecentFilesMenu();
  1944. break;
  1945. case ID_SKIN_BROWSER:
  1946.             DialogBox (hInstance, (LPCSTR)MAKEINTRESOURCE(IDD_SKIN_BROWSER),
  1947.                        hwnd, (DLGPROC)SkinBrowserDlgProc);
  1948. break;
  1949. case ID_PLAYBACK_PROPERTIES:
  1950.             if(playback->HasVideo())
  1951. DialogBox (hInstance, (LPCSTR)MAKEINTRESOURCE(IDD_PLAYBACK_PROPERTIES),
  1952.        hwnd, (DLGPROC)PlaybackPropertiesDlgProc);
  1953. break;
  1954. case ID_MENU_OPTIONS:
  1955.             DialogBox (hInstance, (LPCSTR)MAKEINTRESOURCE(IDD_PREFS),
  1956.                    hwnd, (DLGPROC)PreferencesDlgProc);
  1957. break;
  1958. case ID_OPEN_URL:
  1959.             DialogBox (hInstance, (LPCSTR)MAKEINTRESOURCE(IDD_URL_DIALOG),
  1960.                        hwnd, (DLGPROC)UrlDlgProc);
  1961. if(openOK) {
  1962. openOK = FALSE;
  1963. playlist->Reset();
  1964. playlist->AddItem(url);
  1965. OpenFileForPlaying(hwnd);
  1966. }
  1967. break;
  1968. case ID_PROPERTIES:
  1969. if(playback->HasVideo()) {
  1970. DialogBox (hInstance, (LPCSTR)MAKEINTRESOURCE(IDD_PROPERTIES),
  1971.                    hwnd, (DLGPROC)PropDlgProc);
  1972. }
  1973. break;
  1974. case ID_OPEN_FILE:
  1975. FilesOpen(hwnd);
  1976. break;
  1977. case ID_MENU_PLAYBACK_FILES_ADDFILES:
  1978. AddFilesToPlaylist(hwnd);
  1979. break;
  1980. case ID_ON_TOP:
  1981. if(!playback->IsInFullscreen()) {
  1982. options.on_top = options.on_top == 1 ? 0 : 1;
  1983. CheckMenuItem(popupMenu, (UINT)wParam, options.on_top ? MF_CHECKED : MF_UNCHECKED);
  1984. GetWindowRect(hwnd, &r);
  1985. SetWindowPos(hwnd, options.on_top ? (HWND) -1 : (HWND) 1,  r.left, r.top, r.right - r.left, r.bottom - r.top, TRUE);
  1986. if(!options.on_top)
  1987. SetWindowPos(hwnd, HWND_TOP,  r.left, r.top, r.right - r.left, r.bottom - r.top, TRUE);
  1988. }
  1989. break;
  1990. case ID_LOOP:
  1991. options.loop = options.loop == 1 ? 0 : 1;
  1992. CheckMenuItem(popupMenu, (UINT)wParam, options.loop ? MF_CHECKED : MF_UNCHECKED);
  1993. playback->SetLoop(options.loop);
  1994. break;
  1995. case ID_SCREENSAVER:
  1996. if(options.disable_screen_saver) {
  1997. options.disable_screen_saver = 0;
  1998. SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, screenSaverActive, NULL, 0);
  1999. CheckMenuItem(popupMenu, ID_SCREENSAVER, MF_UNCHECKED);
  2000. }
  2001. else {
  2002. options.disable_screen_saver = 1;
  2003. SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 0, NULL, 0);
  2004. CheckMenuItem(popupMenu, ID_SCREENSAVER, MF_CHECKED);
  2005. }
  2006. break;
  2007. case ID_DESKTOP:
  2008. if(playback->HasVideo()) {
  2009. if(!playback->IsInFullscreen() && !playback->desktopMode) {
  2010. if(playback->IsOverlay()) {
  2011. if(compact_mode) {
  2012. UnPrepareCompactMode();
  2013. }
  2014. ChangeMenuForFullscreenMode();
  2015. /*
  2016.  * 返回到前面
  2017.  */
  2018. PrepareDesktopMode();
  2019. playback->SetDesktopMode(TRUE);
  2020. playback->SetFullscreen(TRUE, GetDesktopWindow());
  2021. MoveWindow(hwnd, fullwindowRect.left, fullwindowRect.top, DEFAULT_SKIN_WIDTH, 22+115, TRUE);
  2022. }
  2023. else {
  2024. MP_ERROR("The Desktop Mode requires support for Overlays. Your current video mode does not allow Overlay creation.");
  2025. }
  2026. }
  2027. else {
  2028. RECT rect;
  2029. playback->SetFullscreen(FALSE, hwnd);
  2030. ShowCursor(1);
  2031. /*
  2032.  * 设置窗口为原始尺寸
  2033.  */
  2034. MoveWindow(hwnd, fullwindowRect.left, fullwindowRect.top, fullwindowRect.right - fullwindowRect.left, 
  2035.    fullwindowRect.bottom - fullwindowRect.top, TRUE);
  2036. playback->SetVideoRect(skin->GetVideoRect());
  2037. if(playback->desktopMode) {
  2038. UnPrepareDesktopMode();
  2039. }
  2040. ChangeMenuForNormalMode();
  2041. Sleep(100);
  2042. UpdateMainWindow();
  2043. }
  2044. }
  2045. else {
  2046. }
  2047. break;
  2048. case ID_COMPACT:
  2049. if(!playback->IsInFullscreen()) {
  2050. if(compact_mode == 0) {
  2051.    
  2052. compact_mode = 1;
  2053. skin->SetCompact(TRUE);
  2054. playback->SetVideoRect(skin->GetVideoRect());
  2055. /*
  2056.  * 改变菜单项文本
  2057.  */
  2058. PrepareCompactMode();
  2059. /*
  2060.  * 改变窗口大小
  2061.  */
  2062. if(playback->IsPlaying()) {
  2063. RECT src;
  2064. GetWindowRect(hwnd, &cwindowRect);
  2065. src.left    = 0;
  2066. src.right   = cwindowRect.right - cwindowRect.left - 15;
  2067. src.top     = 0;
  2068. src.bottom  = cwindowRect.bottom - cwindowRect.top - 115 - 22;
  2069. AdjustWindowRect(&src, WS_POPUP | WS_SIZEBOX, 0);
  2070. MoveWindow( hwnd, cwindowRect.left + 7, 
  2071. cwindowRect.top + 22, 
  2072. src.right - src.left, 
  2073. src.bottom - src.top, TRUE);
  2074. }
  2075. else {
  2076. RECT src;
  2077. GetWindowRect(hwnd, &cwindowRect);
  2078. src.left    = 0;
  2079. src.right   = 280;
  2080. src.top     = 0;
  2081. src.bottom  = 235;
  2082. AdjustWindowRect(&src, WS_POPUP|WS_SIZEBOX, 0);
  2083. MoveWindow( hwnd, cwindowRect.left + 7, 
  2084. cwindowRect.top + 22, 
  2085. src.right - src.left, 
  2086. src.bottom - src.top, TRUE);
  2087. }
  2088. }
  2089. else {
  2090.    
  2091. compact_mode = 0;
  2092. skin->SetCompact(FALSE);
  2093. /*
  2094.  * 改变菜单项文本
  2095.  */
  2096. UnPrepareCompactMode();
  2097. /*
  2098.  * 改变窗口大小
  2099.  */
  2100. GetWindowRect(hwnd, &windowRect);
  2101. MoveWindow( hwnd, windowRect.left - 7, 
  2102. windowRect.top - 22, 
  2103. cwindowRect.right - cwindowRect.left, 
  2104. cwindowRect.bottom - cwindowRect.top, TRUE);
  2105. playback->SetVideoRect(skin->GetVideoRect());
  2106. }
  2107. }
  2108. break;
  2109. case ID_PREVIOUS:
  2110. playback->Rewind();
  2111. break;
  2112. case ID_STOP:
  2113. if(playback->IsInFullscreen()) {
  2114. playback->SetFullscreen(FALSE, hwnd);
  2115. ShowCursor(1);
  2116. /*
  2117.  * 设置窗口为原始尺寸
  2118.  */
  2119. MoveWindow(hwnd, fullwindowRect.left, fullwindowRect.top, fullwindowRect.right - fullwindowRect.left, 
  2120.    fullwindowRect.bottom - fullwindowRect.top, TRUE);
  2121. ChangeMenuForNormalMode();
  2122. /*
  2123.  * 再次更新桌面
  2124.  */
  2125. if(playback->desktopMode)
  2126. playback->SetDesktopMode(FALSE);
  2127. }
  2128. playback->Stop(TRUE);
  2129. break;
  2130. case ID_PLAY:
  2131. if(playback->HasVideo() || playback->HasAudio()) {
  2132. if(playback->IsPaused()) {
  2133. playback->Pause();
  2134. }
  2135. else {
  2136. playback->Play();
  2137. if(playback->IsOverlay()) {
  2138. skin->Display(hwnd, playback);
  2139. }
  2140. }
  2141. }
  2142. else {
  2143. /*
  2144.  * 装载文件
  2145.  */
  2146. FilesOpen(hwnd);
  2147. }
  2148. break;
  2149. case ID_PAUSE:
  2150. if(playback->HasVideo() || playback->HasAudio()) {
  2151. if(playback->rewind || playback->fastForward) {
  2152. playback->Play();
  2153. }
  2154. else {
  2155. if(playback->IsPaused() || playback->IsPlaying()) {
  2156. playback->Pause();
  2157. playback->MaintainImage();
  2158. }
  2159. else {
  2160. playback->Play();
  2161. }
  2162. if(playback->IsOverlay()) {
  2163. skin->Display(hwnd, playback);
  2164. }
  2165. }
  2166. }
  2167. else {
  2168. /*
  2169.  * 装载文件
  2170.  */
  2171. FilesOpen(hwnd);
  2172. }
  2173. break;
  2174. case ID_NEXT:
  2175. playback->FastForward();
  2176. break;
  2177. case ID_NEXT_FILE:
  2178. if(playlist->GetItemCount() > 0) {
  2179. playlist->NextItem();
  2180. OpenFileForPlaying(hwnd);
  2181. ReBuildPlaylistMenu();
  2182. }
  2183. break;
  2184. case ID_PREVIOUS_FILE:
  2185. if(playlist->GetItemCount() > 0) {
  2186. playlist->PreviousItem();
  2187. OpenFileForPlaying(hwnd);
  2188. ReBuildPlaylistMenu();
  2189. }
  2190. break;
  2191. case ID_PLAYLIST1:
  2192. case ID_PLAYLIST1+1:
  2193. case ID_PLAYLIST1+2:
  2194. case ID_PLAYLIST1+3:
  2195. case ID_PLAYLIST1+4:
  2196. case ID_PLAYLIST1+5:
  2197. case ID_PLAYLIST1+6:
  2198. case ID_PLAYLIST1+7:
  2199. case ID_PLAYLIST1+8:
  2200. case ID_PLAYLIST1+9:
  2201. case ID_PLAYLIST1+10:
  2202. if(playlist->GetItemCount() > 0) {
  2203. playlist->SetCurrentPosition(LOWORD(wParam)-ID_PLAYLIST1);
  2204. OpenFileForPlaying(hwnd);
  2205. ReBuildPlaylistMenu();
  2206. }
  2207. break;
  2208. case ID_EXIT:
  2209. Quit();
  2210. break;
  2211. case ID_FULLSCREEN:
  2212. if(playback->HasVideo()) {
  2213. if(!playback->IsInFullscreen()) {
  2214. ChangeMenuForFullscreenMode();
  2215. GetWindowRect(hwnd, &fullwindowRect);
  2216. /*
  2217.  * 使窗口在上面覆盖整个桌面
  2218.  */
  2219. count          = 0;
  2220. showing_cursor = 1;
  2221. playback->SetFullscreen(TRUE, hwnd);
  2222. SetWindowPos(hwnd, (HWND) -1,  fullwindowRect.left, 
  2223.      fullwindowRect.top, fullwindowRect.right - fullwindowRect.left, 
  2224.  fullwindowRect.bottom - fullwindowRect.top, FALSE);
  2225. MoveWindow(hwnd, -5, -5, GetSystemMetrics(SM_CXFULLSCREEN) + 20, GetSystemMetrics(SM_CYFULLSCREEN) + 100, TRUE);
  2226. playback->SetVideoRect(skin->GetVideoRect());
  2227. }
  2228. else {
  2229. RECT rect;
  2230. playback->SetFullscreen(FALSE, hwnd);
  2231. ShowCursor(1);
  2232. /*
  2233.  * 设置窗口为原始尺寸
  2234.  */
  2235. MoveWindow(hwnd, fullwindowRect.left, fullwindowRect.top, fullwindowRect.right - fullwindowRect.left, 
  2236.    fullwindowRect.bottom - fullwindowRect.top, TRUE);
  2237. ChangeMenuForNormalMode();
  2238. /*
  2239.  * 重新更新桌面
  2240.  */
  2241. if(playback->desktopMode)
  2242. playback->SetDesktopMode(FALSE);
  2243. playback->SetVideoRect(skin->GetVideoRect());
  2244. UpdateMainWindow();
  2245. }
  2246. }
  2247. break;
  2248. case ID_ORIGINAL_SIZE:
  2249. if(!playback->IsInFullscreen()) {
  2250. if(playback->IsPlaying()) {
  2251. RECT src;
  2252. GetWindowRect(hwnd, &windowRect);
  2253. if(compact_mode) {
  2254. src.left    = 0;
  2255. src.right   = playback->GetVideoWidth();
  2256. src.top     = 0;
  2257. src.bottom  = playback->GetVideoHeight();
  2258. }
  2259. else {
  2260. src.left    = 0;
  2261. src.right   = playback->GetVideoWidth() + 15;
  2262. src.top     = 0;
  2263. src.bottom  = playback->GetVideoHeight() + 115 + 22;
  2264. }
  2265. AdjustWindowRect(&src, WS_POPUP|WS_SIZEBOX, 0);
  2266. MoveWindow( hwnd, windowRect.left, 
  2267. windowRect.top, 
  2268. src.right - src.left, 
  2269. src.bottom - src.top, TRUE);
  2270. playback->SetVideoRect(skin->GetVideoRect());
  2271. }
  2272. }
  2273. break;
  2274. case ID_HALF_SIZE:
  2275. if(!playback->IsInFullscreen()) {
  2276. if(playback->IsPlaying()) {
  2277. RECT src;
  2278. GetWindowRect(hwnd, &windowRect);
  2279. if(compact_mode) {
  2280. src.left    = 0;
  2281. src.right   = playback->GetVideoWidth()/2;
  2282. src.top     = 0;
  2283. src.bottom  = playback->GetVideoHeight()/2;
  2284. }
  2285. else {
  2286. src.left    = 0;
  2287. src.right   = playback->GetVideoWidth()/2 + 15;
  2288. src.top     = 0;
  2289. src.bottom  = playback->GetVideoHeight()/2 + 115 + 22;
  2290. }
  2291. AdjustWindowRect(&src, WS_POPUP|WS_SIZEBOX, 0);
  2292. MoveWindow( hwnd, windowRect.left, 
  2293. windowRect.top, 
  2294. src.right - src.left, 
  2295. src.bottom - src.top, TRUE);
  2296. playback->SetVideoRect(skin->GetVideoRect());
  2297. }
  2298. }
  2299. break;
  2300. case ID_DOUBLE_SIZE:
  2301. if(!playback->IsInFullscreen()) {
  2302.   if(playback->IsPlaying()) {
  2303. RECT src;
  2304. GetWindowRect(hwnd, &windowRect);
  2305. if(compact_mode) {
  2306. src.left    = 0;
  2307. src.right   = 2*playback->GetVideoWidth();
  2308. src.top     = 0;
  2309. src.bottom  = 2*playback->GetVideoHeight();
  2310. }
  2311. else {
  2312. src.left    = 0;
  2313. src.right   = playback->GetVideoWidth()*2 + 15;
  2314. src.top     = 0;
  2315. src.bottom  = playback->GetVideoHeight()*2 + 115 + 22;
  2316. }
  2317. AdjustWindowRect(&src, WS_OVERLAPPEDWINDOW, 0);
  2318. MoveWindow( hwnd, windowRect.left, 
  2319. windowRect.top, 
  2320. src.right - src.left, 
  2321. src.bottom - src.top, TRUE);
  2322. playback->SetVideoRect(skin->GetVideoRect());
  2323.   }
  2324. }
  2325. break;
  2326. case ID_ASPECT_FREE:
  2327. if(!playback->IsInFullscreen()) {
  2328. switch(options.aspect_ratio) {
  2329. case ASPECT_RATIO_ORIGINAL:
  2330. CheckMenuItem(popupMenu, (UINT)ID_ASPECT_ORIGINAL, MF_UNCHECKED);
  2331. break;
  2332. case ASPECT_RATIO_TV:
  2333. CheckMenuItem(popupMenu, (UINT)ID_ASPECT_43, MF_UNCHECKED);
  2334. break;
  2335. case ASPECT_RATIO_WIDE:
  2336. CheckMenuItem(popupMenu, (UINT)ID_ASPECT_169, MF_UNCHECKED);
  2337. break;
  2338. case ASPECT_RATIO_CUSTOM:
  2339. CheckMenuItem(popupMenu, (UINT)ID_ASPECT_CUSTOM, MF_UNCHECKED);
  2340. break;
  2341. }
  2342. options.aspect_ratio = ASPECT_RATIO_FREE;
  2343. CheckMenuItem(popupMenu, (UINT)ID_ASPECT_FREE, MF_CHECKED);
  2344. }
  2345. break;
  2346. case ID_ASPECT_ORIGINAL:
  2347. {
  2348. if(!playback->IsInFullscreen()) {
  2349. switch(options.aspect_ratio) {
  2350. case ASPECT_RATIO_FREE:
  2351. CheckMenuItem(popupMenu, (UINT)ID_ASPECT_FREE, MF_UNCHECKED);
  2352. break;
  2353. case ASPECT_RATIO_TV:
  2354. CheckMenuItem(popupMenu, (UINT)ID_ASPECT_43, MF_UNCHECKED);
  2355. break;
  2356. case ASPECT_RATIO_WIDE:
  2357. CheckMenuItem(popupMenu, (UINT)ID_ASPECT_169, MF_UNCHECKED);
  2358. break;
  2359. case ASPECT_RATIO_CUSTOM:
  2360. CheckMenuItem(popupMenu, (UINT)ID_ASPECT_CUSTOM, MF_UNCHECKED);
  2361. break;
  2362. }
  2363. options.aspect_ratio = ASPECT_RATIO_ORIGINAL;
  2364. CheckMenuItem(popupMenu, (UINT)ID_ASPECT_ORIGINAL, MF_CHECKED);
  2365. /*
  2366.  * 调整窗口大小
  2367.  */
  2368. RECT  src;
  2369. GetClientRect(hwnd, &src);
  2370. GetWindowRect(hwnd, &windowRect);
  2371. if(compact_mode) {
  2372. src.bottom = (src.right - src.left)*playback->GetVideoHeight()/playback->GetVideoWidth();
  2373. }
  2374. else {
  2375. src.bottom = (src.right - src.left - 15)*playback->GetVideoHeight()/playback->GetVideoWidth() + 115 + 22;
  2376. }
  2377. AdjustWindowRect(&src, WS_POPUP|WS_SIZEBOX, 0);
  2378. MoveWindow( hwnd, windowRect.left, 
  2379. windowRect.top, 
  2380. src.right - src.left, 
  2381. src.bottom - src.top, TRUE);
  2382. playback->SetVideoRect(skin->GetVideoRect());
  2383. }
  2384. }
  2385. break;
  2386. case ID_ASPECT_43:
  2387. {
  2388. /*
  2389.  * 调整窗口大小
  2390.  */
  2391. if(!playback->IsInFullscreen()) {
  2392. switch(options.aspect_ratio) {
  2393. case ASPECT_RATIO_ORIGINAL:
  2394. CheckMenuItem(popupMenu, (UINT)ID_ASPECT_ORIGINAL, MF_UNCHECKED);
  2395. break;
  2396. case ASPECT_RATIO_FREE:
  2397. CheckMenuItem(popupMenu, (UINT)ID_ASPECT_FREE, MF_UNCHECKED);
  2398. break;
  2399. case ASPECT_RATIO_WIDE:
  2400. CheckMenuItem(popupMenu, (UINT)ID_ASPECT_169, MF_UNCHECKED);
  2401. break;
  2402. case ASPECT_RATIO_CUSTOM:
  2403. CheckMenuItem(popupMenu, (UINT)ID_ASPECT_CUSTOM, MF_UNCHECKED);
  2404. break;
  2405. }
  2406. options.aspect_ratio = ASPECT_RATIO_TV;
  2407. CheckMenuItem(popupMenu, (UINT)ID_ASPECT_43, MF_CHECKED);
  2408. RECT  src;
  2409. GetClientRect(hwnd, &src);
  2410. GetWindowRect(hwnd, &windowRect);
  2411. if(compact_mode) {
  2412. src.bottom = (src.right - src.left)*3/4;
  2413. }
  2414. else {
  2415. src.bottom = (src.right - src.left - 15)*3/4 + 115 + 22;
  2416. }
  2417. AdjustWindowRect(&src, WS_POPUP|WS_SIZEBOX, 0);
  2418. MoveWindow( hwnd, windowRect.left, 
  2419. windowRect.top, 
  2420. src.right - src.left, 
  2421. src.bottom - src.top, TRUE);
  2422. playback->SetVideoRect(skin->GetVideoRect());
  2423. }
  2424. }
  2425. break;
  2426. case ID_ASPECT_169:
  2427. {
  2428. /*
  2429.  * 调整窗口大小
  2430.  */
  2431. if(!playback->IsInFullscreen()) {
  2432. switch(options.aspect_ratio) {
  2433. case ASPECT_RATIO_ORIGINAL:
  2434. CheckMenuItem(popupMenu, (UINT)ID_ASPECT_ORIGINAL, MF_UNCHECKED);
  2435. break;
  2436. case ASPECT_RATIO_TV:
  2437. CheckMenuItem(popupMenu, (UINT)ID_ASPECT_43, MF_UNCHECKED);
  2438. break;
  2439. case ASPECT_RATIO_FREE:
  2440. CheckMenuItem(popupMenu, (UINT)ID_ASPECT_FREE, MF_UNCHECKED);
  2441. break;
  2442. case ASPECT_RATIO_CUSTOM:
  2443. CheckMenuItem(popupMenu, (UINT)ID_ASPECT_CUSTOM, MF_UNCHECKED);
  2444. break;
  2445. }
  2446. options.aspect_ratio = ASPECT_RATIO_WIDE;
  2447. CheckMenuItem(popupMenu, (UINT)ID_ASPECT_169, MF_CHECKED);
  2448. RECT  src;
  2449. GetClientRect(hwnd, &src);
  2450. GetWindowRect(hwnd, &windowRect);
  2451. if(compact_mode) {
  2452. src.bottom = (src.right - src.left)*9/16;
  2453. }
  2454. else {
  2455. src.bottom = (src.right - src.left - 15)*9/16 + 115 + 22;
  2456. }
  2457. AdjustWindowRect(&src, WS_POPUP|WS_SIZEBOX, 0);
  2458. MoveWindow( hwnd, windowRect.left, 
  2459. windowRect.top, 
  2460. src.right - src.left, 
  2461. src.bottom - src.top, TRUE);
  2462. playback->SetVideoRect(skin->GetVideoRect());
  2463. }
  2464. }
  2465. break;
  2466. case ID_ASPECT_CUSTOM:
  2467. {
  2468. if(!playback->IsInFullscreen()) {
  2469. DialogBox (hInstance, (LPCSTR)MAKEINTRESOURCE(IDD_ASPECT_RATIO_DIALOG),
  2470.    hwnd, (DLGPROC)CustomAspectDlgProc);
  2471. }
  2472. }
  2473. }
  2474. break;
  2475. /*
  2476.  * 定时器
  2477.  *
  2478.  */
  2479. case WM_TIMER:
  2480. if(firstStart) {
  2481. firstStart = 0;
  2482. if(playlist->GetItemCount() > 0) {
  2483. OpenFileForPlaying(hwnd);
  2484. if(options.startFullscreen) {
  2485. ChangeMenuForFullscreenMode();
  2486. GetWindowRect(hwnd, &fullwindowRect);
  2487. /*
  2488.  * 使窗口在上面覆盖整个桌面
  2489.  */
  2490. count          = 0;
  2491. showing_cursor = 1;
  2492. playback->SetFullscreen(TRUE, hwnd);
  2493. SetWindowPos(hwnd, (HWND) -1,  fullwindowRect.left, 
  2494.      fullwindowRect.top, fullwindowRect.right - fullwindowRect.left, 
  2495.  fullwindowRect.bottom - fullwindowRect.top, FALSE);
  2496. MoveWindow(hwnd, -5, -5, GetSystemMetrics(SM_CXFULLSCREEN) + 20, GetSystemMetrics(SM_CYFULLSCREEN) + 100, TRUE);
  2497. playback->SetVideoRect(skin->GetVideoRect());
  2498. }
  2499. }
  2500. }
  2501. if(playback && playback->IsPlaying() && !(playback->IsInFullscreen() && !playback->desktopMode)) {
  2502. if(action != ACTION_PROGRESS_CURSOR && !compact_mode) {
  2503. skin->SetProgressValue(hwnd, playback->GetPlaybackProgress());
  2504. }
  2505. /*
  2506.  * 定时显示
  2507.  */
  2508. if(!compact_mode)
  2509. skin->DrawTime(hwnd, playback);
  2510. }
  2511. if(!playback->IsPlaying() && !playback->IsPaused() && !playback->IsInFullscreen()) {
  2512. if(action != ACTION_PROGRESS_CURSOR && !compact_mode) {
  2513. skin->SetProgressValue(hwnd, playback->GetPlaybackProgress());
  2514. }
  2515. }
  2516. if(playback->IsBuffering())  {
  2517. if(openning_network)
  2518. playback->UpdateBuffering();
  2519. skin->DrawBufferingState(hwnd, playback->bufferingProgress);
  2520. if((playback->input->GetBufferSize() >= playback->input->GetBufferingSize()) && openning_network) {
  2521. openning_network = FALSE;
  2522. if(playback->OpenMediaFromSource(hwnd) == MP_RESULT_OK) {
  2523. RECT windowrect;
  2524. /*
  2525.  * 第一次调整窗口大小
  2526.  */
  2527. DWORD i, width, height;
  2528. switch(options.aspect_ratio) {
  2529. case ASPECT_RATIO_FREE:
  2530. case ASPECT_RATIO_ORIGINAL:
  2531. width  = playback->GetVideoWidth();
  2532. height = playback->GetVideoHeight();
  2533. break;
  2534. case ASPECT_RATIO_TV:
  2535. width  = playback->GetVideoWidth();
  2536. height = width*3/4;
  2537. break;
  2538. case ASPECT_RATIO_WIDE:
  2539. width  = playback->GetVideoWidth();
  2540. height = width*9/16;
  2541. break;
  2542. }
  2543. if(!playback->fullscreen) {
  2544. GetWindowRect(hwnd, &windowrect); 
  2545. }
  2546. if(compact_mode) {
  2547. rect.left   = 0;
  2548. rect.top    = 0;
  2549. rect.right  = width;
  2550. rect.bottom = height;
  2551. }
  2552. else {
  2553. rect.left   = 0;
  2554. rect.top    = 0;
  2555. rect.right  = width + 15;
  2556. rect.bottom = height + 115 + 22;
  2557. }
  2558. AdjustWindowRect(&rect, WS_POPUP|WS_SIZEBOX, FALSE);
  2559. fullwindowRect.right  = fullwindowRect.left + rect.right - rect.left;
  2560. fullwindowRect.bottom = fullwindowRect.top  + rect.bottom - rect.top;
  2561. if(!playback->fullscreen) {
  2562. MoveWindow( hwnd, windowrect.left, windowrect.top, rect.right - rect.left, rect.bottom - rect.top, TRUE);
  2563. playback->SetVideoRect(skin->GetVideoRect());
  2564. }
  2565. /*
  2566.  * 调整最近的文件链表
  2567.  */
  2568. UpdateRecentFilesMenu(playback->filename);
  2569. /*
  2570.  * 更新菜单
  2571.  */
  2572. if(!playback->fullscreen) {
  2573. ReBuildRecentFilesMenu();
  2574. HMENU menu;
  2575. menu = GetSubMenu(popupMenu, 0);
  2576. /*
  2577.  * 字幕和属性菜单
  2578.  */
  2579. MENUITEMINFO itemInfo;
  2580. /*
  2581.  * 再次更新菜单项
  2582.  */
  2583. EnableMenuItem(popupMenu, ID_COMPACT, MF_ENABLED);
  2584. EnableMenuItem(popupMenu, ID_FULLSCREEN, MF_ENABLED);
  2585. EnableMenuItem(popupMenu, (UINT)ID_ON_TOP,      MF_ENABLED);
  2586. EnableMenuItem(popupMenu, (UINT)ID_ASPECT_ORIGINAL, MF_ENABLED);
  2587. EnableMenuItem(popupMenu, (UINT)ID_ASPECT_FREE,     MF_ENABLED);
  2588. EnableMenuItem(popupMenu, (UINT)ID_ASPECT_43,       MF_ENABLED);
  2589. EnableMenuItem(popupMenu, (UINT)ID_ASPECT_169,      MF_ENABLED);
  2590. EnableMenuItem(popupMenu, (UINT)ID_ASPECT_CUSTOM,   MF_ENABLED);
  2591. menu = GetSubMenu(popupMenu, 0);
  2592. memset(&itemInfo, 0, sizeof(MENUITEMINFO));
  2593. itemInfo.cbSize     = sizeof(MENUITEMINFO);
  2594. itemInfo.fType      = MFT_STRING;
  2595. itemInfo.fMask      = MIIM_TYPE;
  2596. itemInfo.dwTypeData = "&Desktop modetAlt+D";
  2597. SetMenuItemInfo(menu, ID_DESKTOP, FALSE, &itemInfo);
  2598. EnableMenuItem(popupMenu, (UINT)ID_PROPERTIES, MF_ENABLED);
  2599. EnableMenuItem(popupMenu, (UINT)ID_DESKTOP, MF_ENABLED);
  2600. }
  2601. playback->SetVolume(skin->GetVolume());
  2602. /*
  2603.    * 播放
  2604.  */
  2605. playback->Play();
  2606. /*
  2607.  * 更新窗口
  2608.  */
  2609. UpdateMainWindow();
  2610. }
  2611. else {
  2612. playback->Close();
  2613. }
  2614. }
  2615. }
  2616. if(playback->IsInFullscreen() && showing_cursor) {
  2617. if(count <= 21)
  2618. count++;
  2619. /*
  2620.  * 等待两秒钟
  2621.  */ 
  2622. if(count >= 20) {
  2623. if(!playback->desktopMode) {
  2624. ShowCursor(0);
  2625. showing_cursor = 0;
  2626. }
  2627. }
  2628. }
  2629. break;
  2630. case WM_KEYUP:
  2631. switch(wParam) {
  2632. case VK_ESCAPE:
  2633. if(playback->IsInFullscreen()) {
  2634. RECT rect;
  2635. playback->SetFullscreen(FALSE, hwnd);
  2636. ShowCursor(1);
  2637. /*
  2638.  * 设置窗口为原始尺寸
  2639.  */
  2640. MoveWindow(hwnd, fullwindowRect.left, fullwindowRect.top, fullwindowRect.right - fullwindowRect.left, 
  2641.    fullwindowRect.bottom - fullwindowRect.top, TRUE);
  2642. playback->SetVideoRect(skin->GetVideoRect());
  2643. ChangeMenuForNormalMode();
  2644. /*
  2645.  * 再次更新桌面
  2646.  */
  2647. if(playback->desktopMode)
  2648. playback->SetDesktopMode(FALSE);
  2649. Sleep(100);
  2650. UpdateMainWindow();
  2651. }
  2652. break;
  2653. default:
  2654. break;
  2655. }
  2656. break;
  2657. case WM_LBUTTONDOWN:
  2658. if(!(playback->IsInFullscreen() && !playback->desktopMode)) {
  2659. xPos = LOWORD(lParam); 
  2660. yPos = HIWORD(lParam);
  2661. if(compact_mode) {
  2662. action = ACTION_NONE;
  2663. }
  2664. else {
  2665. action = skin->GetAction(xPos, yPos);
  2666. skin->SetActionStart(hwnd, action);
  2667. }
  2668. if(action == ACTION_RESIZE) {
  2669. if(!playback->desktopMode) {
  2670. POINT pt;
  2671. pt.x = xPos;
  2672. pt.y = yPos;
  2673. ClientToScreen(hwnd, &pt);
  2674. moveX = pt.x;
  2675. moveY = pt.y;
  2676. GetWindowRect(hwnd, &windowRect);
  2677. SetCapture(hwnd);
  2678. resizer->Start(&pt, playback->GetVideoWidth(), playback->GetVideoHeight());
  2679. }
  2680. else {
  2681. action = ACTION_NONE;
  2682. }
  2683. }
  2684. if(action == ACTION_NONE) {
  2685. /*
  2686.  * 移动窗口
  2687.  */
  2688. action = ACTION_MOVING;
  2689. moveX = xPos;
  2690. moveY = yPos;
  2691. GetWindowRect(hwnd, &windowRect);
  2692. SetCapture(hwnd);
  2693. }
  2694. if(action == ACTION_VOLUME_CURSOR || action == ACTION_PROGRESS_CURSOR) {
  2695. moveX = xPos;
  2696. SetCapture(hwnd);
  2697. }
  2698. }
  2699. break;
  2700. case WM_LBUTTONUP:
  2701. skin->SetActionEnd(hwnd, action);
  2702. switch(action) {
  2703. case ACTION_MENU:
  2704. HMENU menu;
  2705. POINT pt;
  2706. pt.x = pt.y = 0;
  2707. ClientToScreen(hwnd, &pt);
  2708. xPos = pt.x + LOWORD(lParam); 
  2709. yPos = pt.y + HIWORD(lParam);
  2710. menu = GetSubMenu(popupMenu, 0);
  2711. TrackPopupMenu( menu, 0, xPos, yPos, 0, hwnd, NULL);
  2712. break;
  2713. case ACTION_CLOSE:
  2714. Quit();
  2715. break;
  2716. case ACTION_MINIMIZE:
  2717. ShowWindow(hwnd, SW_MINIMIZE);
  2718. break;
  2719. case ACTION_STOP:
  2720. playback->Stop(TRUE);
  2721. break;
  2722. case ACTION_PLAY:
  2723. if(playback->HasVideo() || playback->HasAudio()) {
  2724. if(playback->IsPaused()) {
  2725. playback->Pause();
  2726. }
  2727. else {
  2728. playback->Play();
  2729. if(playback->IsOverlay()) {
  2730. RECT rect;
  2731. GetClientRect(hwnd, &rect);
  2732. InvalidateRect(hwnd, &rect, TRUE);
  2733.   UpdateWindow(hwnd);
  2734. }
  2735. }
  2736. }
  2737. else {
  2738. /*
  2739.  * 装载文件
  2740.  */
  2741. FilesOpen(hwnd);
  2742. }
  2743. break;
  2744. case ACTION_PAUSE:
  2745. if(playback->HasVideo() || playback->HasAudio()) {
  2746. if(playback->IsPaused()) {
  2747. playback->NextFrame();
  2748. }
  2749. else {
  2750. playback->Pause();
  2751. }
  2752. }
  2753. break;
  2754. case ACTION_FORWARD:
  2755. playback->FastForward();
  2756. break;
  2757. case ACTION_REWIND:
  2758. playback->Rewind();
  2759. break;
  2760. case ACTION_LOAD:
  2761. {
  2762. FilesOpen(hwnd);
  2763. }
  2764. break;
  2765. case ACTION_PROGRESS_CURSOR:
  2766. ReleaseCapture();
  2767. playback->Seek(skin->GetProgress());
  2768. break;
  2769. case ACTION_VOLUME_CURSOR:
  2770. ReleaseCapture();
  2771. playback->SetVolume(skin->GetVolume());
  2772. break;
  2773. case ACTION_VOLUME_BAR:
  2774. moveX = LOWORD(lParam); 
  2775. skin->SetVolumeCursorX(hwnd, moveX);
  2776. playback->SetVolume(skin->GetVolume());
  2777. break;
  2778. case ACTION_PROGRESS_BAR:
  2779. moveX = LOWORD(lParam); 
  2780. skin->SetProgressCursorX(hwnd, moveX);
  2781. playback->Seek(skin->GetProgress());
  2782. break;
  2783. case ACTION_NONE:
  2784. default:
  2785. break;
  2786. }
  2787. if(action == ACTION_MOVING) {
  2788. ReleaseCapture();
  2789. RECT rect;
  2790. GetWindowRect(hwnd, &rect);
  2791. SetWindowPos(hwnd, HWND_TOPMOST, rect.left, rect.top, 
  2792.  rect.right - rect.left, rect.bottom - rect.top, 
  2793.  SWP_SHOWWINDOW | SWP_NOZORDER | SWP_NOACTIVATE);
  2794. GetWindowRect(hwnd, &windowRect);
  2795. if(playback->IsPlaying()) {
  2796. GetClientRect(hwnd, &rect);
  2797. InvalidateRect(hwnd, &rect, TRUE);
  2798.   UpdateWindow(hwnd);
  2799. }
  2800. }
  2801. if(action == ACTION_RESIZE) {
  2802. POINT *pt;
  2803. pt = resizer->GetLastPoint();
  2804. ReleaseCapture();
  2805. resizer->Stop();
  2806. MoveWindow( hwnd, windowRect.left, 
  2807. windowRect.top, 
  2808. windowRect.right + (pt->x - moveX) - windowRect.left, 
  2809. windowRect.bottom + (pt->y - moveY) - windowRect.top, TRUE);
  2810. GetWindowRect(hwnd, &windowRect);
  2811. moveX = pt->x;
  2812. moveY = pt->y;
  2813. playback->SetVideoRect(skin->GetVideoRect());
  2814. }
  2815. action = ACTION_NONE;
  2816. break;
  2817. case WM_MOUSEMOVE:
  2818. count = 0;
  2819. ShowCursor(1);
  2820. showing_cursor = 1;
  2821. if(action == ACTION_MOVING) {
  2822. RECT   r;
  2823. POINT pt;
  2824. xPos = LOWORD(lParam); 
  2825. yPos = HIWORD(lParam);
  2826. GetClientRect(hwnd, &r);
  2827. pt.x = xPos;
  2828. pt.y = yPos;
  2829. ClientToScreen(hwnd, &pt);
  2830. MoveWindow( hwnd, pt.x - moveX, 
  2831. pt.y - moveY, 
  2832. windowRect.right - windowRect.left, 
  2833. windowRect.bottom - windowRect.top, TRUE);
  2834. if(playback->IsPaused()) {
  2835. playback->MaintainImage();
  2836. }
  2837. }
  2838. if(action == ACTION_RESIZE) {
  2839. POINT pt;
  2840. pt.x = LOWORD(lParam);
  2841. pt.y = HIWORD(lParam);
  2842. if(playback->HasVideo()) {
  2843. resizer->Draw(hwnd, &pt, options.aspect_ratio);
  2844. }
  2845. else {
  2846. resizer->Draw(hwnd, &pt, ASPECT_RATIO_FREE);
  2847. }
  2848. }
  2849. if(action == ACTION_VOLUME_CURSOR) {
  2850. moveX = LOWORD(lParam); 
  2851. skin->SetVolumeCursorX(hwnd, moveX);
  2852. playback->SetVolume(skin->GetVolume());
  2853. }
  2854. if(action == ACTION_PROGRESS_CURSOR) {
  2855. moveX = LOWORD(lParam); 
  2856. skin->SetProgressCursorX(hwnd, moveX);
  2857. }
  2858. break;
  2859. case WM_RBUTTONDOWN:
  2860. HMENU menu;
  2861. POINT pt1;
  2862. int   x, y;
  2863. pt1.x = pt1.y = 0;
  2864. ClientToScreen(hwnd, &pt1);
  2865. x = pt1.x + LOWORD(lParam); 
  2866. y = pt1.y + HIWORD(lParam);
  2867. menu = GetSubMenu(popupMenu, 0);
  2868. TrackPopupMenu( menu, 0, x, y, 0, hwnd, NULL);
  2869. break;
  2870. case WM_SIZE:
  2871. POINT pt2;
  2872. RECT  clientRect, windowRect;
  2873. POINT other_pt;
  2874. GetClientRect(hwnd, &clientRect);
  2875. GetWindowRect(hwnd, &windowRect);
  2876. other_pt.x = clientRect.left;
  2877. other_pt.y = clientRect.top;
  2878. ClientToScreen(hwnd, &other_pt);
  2879. pt2.x = clientRect.right;
  2880. pt2.y = clientRect.bottom;
  2881. ClientToScreen(hwnd, &pt2);
  2882. if(!compact_mode) {
  2883.     SetWindowRgn(hwnd, CreateRectRgn( other_pt.x  - windowRect.left, 
  2884.      other_pt.y  - windowRect.top,
  2885.   (windowRect.right - windowRect.left) - (windowRect.right - pt2.x),
  2886.   (windowRect.bottom - windowRect.top) - (windowRect.bottom - pt2.y)), TRUE); 
  2887. }
  2888. else {
  2889. SetWindowRgn(hwnd, CreateRectRgn( 0, 
  2890.      0,
  2891.   (windowRect.right - windowRect.left),
  2892.   (windowRect.bottom - windowRect.top)), TRUE); 
  2893. }
  2894. if(compact_mode)
  2895. playback->SetVideoRect(skin->GetVideoRect());
  2896. break;
  2897. case WM_PAINT:
  2898. skin->UpdateSize(hwnd);
  2899. skin->Display(hwnd, playback);
  2900. if(playback->IsPaused()) {
  2901. playback->MaintainImage();
  2902. }
  2903. return 0;
  2904. break;
  2905. case WM_DROPFILES:
  2906. char lpFilename[512];
  2907. if(DragQueryFile( (HDROP) wParam, 0, lpFilename, 512) > 0)  {
  2908. playlist->Reset();
  2909. playlist->AddItem(lpFilename);
  2910. OpenFileForPlaying(hwnd);
  2911. }
  2912. break;
  2913. }
  2914.   return DefWindowProc(hwnd, Message, wParam, lParam);
  2915. }