Main.cpp
上传用户:lusi_8715
上传日期:2007-01-08
资源大小:199k
文件大小:47k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /**************************************************************************************
  2.  *                                                                                    *
  3.  * This application contains code from OpenDivX and is released as a "Larger Work"    *
  4.  * under that license. Consistant with that license, this application is released     *
  5.  * under the GNU General Public License.                                              *
  6.  *                                                                                    *
  7.  * The OpenDivX license can be found at: http://www.projectmayo.com/opendivx/docs.php *
  8.  * The GPL can be found at: http://www.gnu.org/copyleft/gpl.html                      *
  9.  *                                                                                    *
  10.  * Copyright (c) 2001 - Project Mayo                                                  *
  11.  *                                                                                    *
  12.  * Authors: Damien Chavarria <adrc at projectmayo.com>                                *
  13.  *                                                                                    *
  14.  **************************************************************************************/
  15. #include "debug.h"
  16. #include "Skin.h"
  17. #include "Playback.h"
  18. #include "Playlist.h"
  19. #include "DirDialog.h"
  20. #include "SkinList.h"
  21. #include "Resizer.h"
  22. #ifdef WIN32
  23. #include "../build/win32/ressources.h"
  24. #include "../build/win32/resource.h"
  25. #endif
  26. #include <math.h>
  27. #include <commctrl.h>
  28. #include <windows.h>
  29. #include <windowsx.h>
  30. /*
  31.  * Intervals for the timers
  32.  */
  33. #define TIMER_ID     1
  34. #define TIMER_RATE 100
  35. /*
  36.  * Variables
  37.  *
  38.  * Please regroup that in a struct...
  39.  *
  40.  *
  41.  */
  42. DWORD anonymous;
  43. HWND  hwndDisplay;
  44. #ifdef _DEBUG__
  45. FILE *debug_file;
  46. #endif
  47. int       action  = ACTION_NONE;
  48. DWORD     count = 0;
  49. DWORD     use_subtitles         = 1;
  50. DWORD     no_resize             = 0;
  51. char      skinPath[256];
  52. UINT      uTimerID;
  53. RECT      clientRect;
  54. RECT      windowRect, fullwindowRect;
  55. int       moveX = 0, moveY = 0;
  56. Skin     *skin;
  57. Playback *playback;
  58. Playlist *playlist;
  59. CDirDialog *dirChooser;
  60. SkinList   *skinList;
  61. Resizer   *resizer;
  62. char      Name[] = "The "Playa"";
  63. char     *RecentFiles[5];
  64. HWND      hwnd, about, urlW = NULL;
  65. HMENU     popupMenu;
  66. HACCEL    hAccel;
  67. POINT     pt2;
  68. POINT     oldPt;
  69. HINSTANCE hInstance;
  70. int showing_cursor;
  71. options_t options, tmpOptions;
  72. /*
  73.  * needed definitions
  74.  */
  75. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
  76. void OpenFileForPlaying(HWND hwnd, char *filename, int type);
  77. /*
  78.  * Save and load options
  79.  */
  80. void LoadOptions() {
  81. HKEY     key;
  82. DWORD created, size;
  83. LONG     result;
  84. DWORD  type, i;
  85. char      file[256], name[5];
  86. /*
  87.  * Put the default options
  88.  *
  89.  */
  90. options.change_fullscreen_res = 0;
  91. options.loop                  = 1;
  92. options.maintain_aspect_ratio = 1;
  93. options.on_top                = 1;
  94. options.use_bilinear          = 0;
  95. /*
  96.  * Init the recent file list 
  97.  */
  98. for(i=0; i < 5; i++) {
  99. RecentFiles[i] = NULL;
  100. }
  101. /*
  102.  * Open the registry key
  103.  */
  104. result = RegCreateKeyEx(HKEY_CURRENT_USER, "Software\DivXNetworks\ThePlaya",
  105.                   0, "CONFIG", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 
  106. NULL, &key, &created);
  107. if(result != ERROR_SUCCESS) {
  108. MessageBox(NULL, "Couldn't load options", "", MB_OK);
  109. return;
  110. }
  111. switch(created) {
  112. case REG_CREATED_NEW_KEY:
  113. /*
  114.  * First time launch (we keep the default)
  115.  * 
  116.  */
  117. break;
  118. case REG_OPENED_EXISTING_KEY:
  119. /*
  120.  * We can read the values
  121.    */
  122. size = 4;
  123. result = RegQueryValueEx(key, "UseBilinear", 0, &type, (BYTE *)&options.use_bilinear, &size);
  124. size = 4;
  125. result = RegQueryValueEx(key, "MaintainAspectRatio", 0, &type, (BYTE *)&options.maintain_aspect_ratio, &size);
  126. size = 4;
  127. result = RegQueryValueEx(key, "ChangeFullscreenRes", 0, &type, (BYTE *)&options.change_fullscreen_res, &size);
  128. size = 4;
  129. result = RegQueryValueEx(key, "UseSubtitles", 0, &type, (BYTE *)&use_subtitles, &size);
  130. size = 4;
  131. result = RegQueryValueEx(key, "Loop", 0, &type, (BYTE *)&options.loop, &size);
  132. size = 4;
  133. result = RegQueryValueEx(key, "OnTop", 0, &type, (BYTE *)&options.on_top, &size);
  134. size = 256;
  135. result = RegQueryValueEx(key, "SkinPath", 0, &type, (BYTE *)skinPath, &size);
  136. /*
  137.  * And the recent files
  138.  */
  139. for(i=0; i < 5; i++) {
  140. sprintf(name, "File%d", i+1);
  141. size = 256;
  142. result = RegQueryValueEx(key, name, 0, &type, (BYTE *)&file, &size);
  143. if(result == ERROR_SUCCESS) {
  144. RecentFiles[i] = (char *) malloc(size);
  145. strncpy(RecentFiles[i], file, size);
  146. }
  147. }
  148. break;
  149. default:
  150. break;
  151. }
  152. RegCloseKey(key);
  153. }
  154. void SaveOptions() {
  155. HKEY     key;
  156. LONG     result;
  157. DWORD created, i;
  158. char      name[5];
  159. /*
  160.  * Try to open the registry key
  161.  */
  162. result = RegCreateKeyEx(HKEY_CURRENT_USER, "Software\DivXNetworks\ThePlaya",
  163.               0, "CONFIG", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 
  164.               NULL, &key, &created);
  165. if(result != ERROR_SUCCESS) {
  166. MessageBox(NULL, "Couldn't save options", "", MB_OK);
  167. RegCloseKey(key);
  168. return;
  169. }
  170. RegSetValueEx(key, "UseBilinear", 0, REG_DWORD, (BYTE *) &options.use_bilinear, 4);
  171. RegSetValueEx(key, "MaintainAspectRatio", 0, REG_DWORD, (BYTE *) &options.maintain_aspect_ratio, 4);
  172. RegSetValueEx(key, "ChangeFullscreenRes", 0, REG_DWORD, (BYTE *) &options.change_fullscreen_res, 4);
  173. RegSetValueEx(key, "UseSubtitles", 0, REG_DWORD, (BYTE *) &use_subtitles, 4);
  174. RegSetValueEx(key, "Loop", 0, REG_DWORD, (BYTE *) &options.loop, 4);
  175. RegSetValueEx(key, "OnTop", 0, REG_DWORD, (BYTE *) &options.on_top, 4);
  176. if(strcmp(skinPath, "Default") != 0)
  177. RegSetValueEx(key, "SkinPath", 0, REG_SZ, (BYTE *) skinPath, strlen(skinPath));
  178. else 
  179. RegSetValueEx(key, "SkinPath", 0, REG_SZ, (BYTE *) "Default", strlen("Default"));
  180. /*
  181.  * The recent file list
  182.  */
  183. for(i=0; i < 5; i++) {
  184. if(RecentFiles[i] != NULL) {
  185. sprintf(name, "File%d", i+1);
  186. RegSetValueEx(key, name, 0, REG_SZ, 
  187.       (BYTE *) RecentFiles[i], strlen(RecentFiles[i]));
  188. }
  189. }
  190. RegCloseKey(key);
  191. }
  192. void Cleanup()
  193. {
  194. DWORD i;
  195. for(i=0; i < 5; i++) {
  196. if(RecentFiles[i] != NULL) {
  197. free(RecentFiles[i]);
  198. }
  199. }
  200. DestroyMenu(popupMenu);
  201. delete playback;
  202. delete skinList;
  203. delete resizer;
  204. delete playlist;
  205. }
  206. /*******************************************************************************************/
  207. static BOOL APIENTRY PreferencesGeneralDlgProc( HWND hDlg, UINT message, UINT wParam, LONG lParam) {
  208. switch(message) {
  209. case WM_INITDIALOG:
  210. SetWindowPos(hDlg, HWND_TOP, 15, 35, 0, 0, SWP_NOSIZE);
  211.     CheckDlgButton(hDlg, IDC_CHECK_LOOP, tmpOptions.loop);
  212.     CheckDlgButton(hDlg, IDC_CHECK_ON_TOP, tmpOptions.on_top);
  213. return TRUE;
  214.   case WM_COMMAND:
  215.         switch (wParam)
  216. {
  217. case IDC_CHECK_LOOP:
  218. tmpOptions.loop = tmpOptions.loop ? 0 : 1;
  219. break;
  220. case IDC_CHECK_ON_TOP:
  221. tmpOptions.on_top = tmpOptions.on_top ? 0 : 1;
  222. break;
  223. }
  224. case WM_DESTROY:
  225. return TRUE;
  226. }
  227. return FALSE;
  228. }
  229. static BOOL APIENTRY PreferencesVideoDlgProc( HWND hDlg, UINT message, UINT wParam, LONG lParam) {
  230. switch(message) {
  231. case WM_INITDIALOG:
  232. SetWindowPos(hDlg, HWND_TOP, 15, 35, 0, 0, SWP_NOSIZE);
  233. CheckDlgButton(hDlg, IDC_CHECK_MAINTAIN, tmpOptions.maintain_aspect_ratio);
  234.     CheckDlgButton(hDlg, IDC_CHECK_BILINEAR, tmpOptions.use_bilinear);
  235.     CheckDlgButton(hDlg, IDC_CHECK_CHANGE_RES, !tmpOptions.change_fullscreen_res);
  236. return TRUE;
  237. case WM_COMMAND:
  238. switch (wParam)
  239. {
  240. case IDC_CHECK_MAINTAIN:
  241. tmpOptions.maintain_aspect_ratio = tmpOptions.maintain_aspect_ratio ? 0 : 1;
  242. break;
  243. case IDC_CHECK_BILINEAR:
  244. tmpOptions.use_bilinear = tmpOptions.use_bilinear ? 0 : 1;
  245. break;
  246. case IDC_CHECK_CHANGE_RES:
  247. tmpOptions.change_fullscreen_res = tmpOptions.change_fullscreen_res ? 0 : 1;
  248. break;
  249. }
  250. case WM_DESTROY:
  251. return TRUE;
  252. }
  253. return FALSE;
  254. }
  255. /*
  256.  * List of the preferences tab
  257.  *
  258.  */
  259. static struct prefsTabs {
  260. LPTSTR rsrc;
  261. char *name;
  262. DLGPROC dProc;
  263. } tabs[]={
  264. { MAKEINTRESOURCE(IDD_PREFS_GENERAL), "General", PreferencesGeneralDlgProc},
  265. { MAKEINTRESOURCE(IDD_PREFS_VIDEO), "Video", PreferencesVideoDlgProc },
  266. };
  267. /*
  268.  * Main preferences DlgProc
  269.  *
  270.  */
  271. static BOOL APIENTRY PreferencesDlgProc( HWND hDlg, UINT message, UINT wParam, LONG lParam) {
  272. DWORD i;
  273. switch(message) {
  274. case WM_INITDIALOG:
  275. {
  276. HWND tab = GetDlgItem(hDlg, IDC_TAB);
  277. memcpy(&tmpOptions, &options, sizeof(options_t));
  278. for(i = 0; i < (sizeof tabs/sizeof tabs[0]); i++) {
  279. TC_ITEM ti;
  280. ti.mask = TCIF_TEXT;
  281. ti.pszText = tabs[i].name;
  282. TabCtrl_InsertItem(tab, i, &ti);
  283. }
  284. hwndDisplay = CreateDialogParam(hInstance, tabs[0].rsrc, hDlg, tabs[0].dProc, (LPARAM)NULL);
  285. ShowWindow(hwndDisplay, SW_SHOW);
  286. return TRUE;
  287. }
  288. case WM_NOTIFY: {
  289. NMHDR *nm = (LPNMHDR)lParam;
  290. switch(nm->code) {
  291. case TCN_SELCHANGE:
  292. {
  293. int iTab = TabCtrl_GetCurSel(nm->hwndFrom);
  294. if (iTab>=0) {
  295. if (hwndDisplay) DestroyWindow(hwndDisplay);
  296. hwndDisplay = CreateDialogParam(hInstance, tabs[iTab].rsrc, hDlg, tabs[iTab].dProc, NULL);
  297. }
  298. ShowWindow(hwndDisplay, SW_SHOW);
  299. }
  300. return TRUE;
  301. }
  302. }break;
  303.   case WM_COMMAND:
  304.         switch (wParam)
  305. {
  306.   case IDC_PREFS_OK:
  307.   /*
  308.    * Save the options changes
  309.    */
  310.   memcpy(&options, &tmpOptions, sizeof(options_t));
  311.   /*
  312.    * And apply them
  313.    */
  314.   CheckMenuItem(popupMenu, (UINT)ID_BILINEAR,     options.use_bilinear ? MF_CHECKED : MF_UNCHECKED);
  315.   CheckMenuItem(popupMenu, (UINT)ID_ASPECT_RATIO, options.maintain_aspect_ratio ? MF_CHECKED : MF_UNCHECKED);
  316.   CheckMenuItem(popupMenu, (UINT)ID_LOOP, options.loop ? MF_CHECKED : MF_UNCHECKED);
  317.      CheckMenuItem(popupMenu, (UINT)ID_ON_TOP, options.on_top ? MF_CHECKED : MF_UNCHECKED);
  318.   playback->SetBilinear(options.use_bilinear);
  319.   playback->SetChangeFullscreenRes(options.change_fullscreen_res);
  320.   playback->SetLoop(options.loop);
  321.   /*
  322.    * And end the dialog
  323.    */
  324.   
  325.   EndDialog(hDlg, TRUE);
  326.   return TRUE;
  327.   break;
  328.   case IDC_PREFS_CANCEL:
  329.   EndDialog(hDlg, TRUE);
  330.   break;
  331.   default:
  332.   return 0;
  333. }
  334. break;
  335. case WM_DESTROY:
  336. return TRUE;
  337. }
  338. return FALSE;
  339. }
  340. /*******************************************************************************************/
  341. /*
  342.  * Properties dialog box message function
  343.  *
  344.  */
  345. int APIENTRY PropDlgProc (HWND hDlg, WORD wMsg, LONG wParam, LONG lParam)
  346. {
  347.   switch (wMsg)
  348.     {
  349.       case WM_INITDIALOG:
  350.   char freq[20];
  351.   char channels[2];
  352.   char video_size[20];
  353.   char duration[20];
  354.   char total_size[50];
  355.   DWORD time, hours, minutes, seconds;
  356.   _ultoa(playback->audioCodec->GetFormat()->nSamplesPerSec, freq, 10);
  357.   _ultoa(playback->audioCodec->GetFormat()->nChannels, channels, 10);
  358.   sprintf(video_size, "%dx%d", playback->decaps->Width(), playback->decaps->Height());
  359.   sprintf(total_size, "%d bytes", playback->decaps->input->getSize());
  360.   time = playback->decaps->TotalFrames()/playback->decaps->FrameRate();
  361.   hours   = time/3600;
  362.   minutes = (time - hours*3600)/60;
  363.   seconds = (time - hours*3600 - minutes*60)/60;
  364.   sprintf(duration, "%.2d:%.2d:%.2d", hours, minutes, seconds);
  365.   SetWindowText(GetDlgItem(hDlg, IDC_STATIC_FILENAME), playback->decaps->input->getFilename());
  366.   SetWindowText(GetDlgItem(hDlg, IDC_STATIC_FILE_TYPE), playback->decaps->input->http ? "HTTP Download" : "Local File.");
  367.   SetWindowText(GetDlgItem(hDlg, IDC_STATIC_FILE_SIZE), total_size);
  368.   SetWindowText(GetDlgItem(hDlg, IDC_STATIC_DURATION), duration);
  369.   SetWindowText(GetDlgItem(hDlg, IDC_STATIC_VIDEO_CODEC), playback->videoBuffer->codec->GetCodecName());
  370.   SetWindowText(GetDlgItem(hDlg, IDC_STATIC_VIDEO_SIZE), video_size);
  371.   switch(playback->videoBuffer->codec->GetVideoMode()) {
  372.   case VIDEO_MODE_RGB16:
  373.   SetWindowText(GetDlgItem(hDlg, IDC_STATIC_VIDEO_MODE), "16 bpp");
  374.   break;
  375.   case VIDEO_MODE_RGB24:
  376.   SetWindowText(GetDlgItem(hDlg, IDC_STATIC_VIDEO_MODE), "24 bpp");
  377.   break;
  378.   case VIDEO_MODE_RGB32:
  379.   SetWindowText(GetDlgItem(hDlg, IDC_STATIC_VIDEO_MODE), "32 bpp");
  380.   break;
  381.   }
  382.   if(playback->audioRenderer != NULL) {
  383.      
  384.   SetWindowText(GetDlgItem(hDlg, IDC_STATIC_AUDIO_CODEC), playback->audioCodec->GetCodecName());
  385.   SetWindowText(GetDlgItem(hDlg, IDC_STATIC_AUDIO_FREQUENCY), freq);
  386.   SetWindowText(GetDlgItem(hDlg, IDC_STATIC_AUDIO_CHANNELS), channels);
  387.   }
  388.   else {
  389.   SetWindowText(GetDlgItem(hDlg, IDC_STATIC_AUDIO_CODEC),     "Not Available");
  390.   SetWindowText(GetDlgItem(hDlg, IDC_STATIC_AUDIO_FREQUENCY), "Not Available");
  391.   SetWindowText(GetDlgItem(hDlg, IDC_STATIC_AUDIO_CHANNELS),  "Not Available");
  392.   }
  393.   return (0);
  394. break;
  395.       case WM_SYSCOMMAND:
  396.         if (wParam == SC_CLOSE)
  397.           {
  398.           EndDialog (hDlg, TRUE);
  399.           return (TRUE);
  400.           }
  401.         break;
  402.   case WM_COMMAND:
  403.         switch (wParam)
  404. {
  405.   case IDB_PROPERTIES_OK:
  406.   EndDialog(hDlg, TRUE);
  407.   return TRUE;
  408.   break;
  409.   default:
  410.   return 0;
  411. }
  412. break;
  413. }
  414.   return FALSE;
  415. }
  416. /*
  417.  * About dialog box message function
  418.  *
  419.  */
  420. int APIENTRY AboutDlgProc (HWND hDlg, WORD wMsg, LONG wParam, LONG lParam)
  421. {
  422.   int first = 0;
  423.   switch (wMsg)
  424.     {
  425.       case WM_INITDIALOG:
  426.         return (0);
  427. break;
  428.       case WM_SYSCOMMAND:
  429.         if (wParam == SC_CLOSE)
  430.           {
  431.           EndDialog (hDlg, TRUE);
  432.           return (TRUE);
  433.           }
  434.         break;
  435.   case WM_COMMAND:
  436.         switch (wParam)
  437. {
  438.   case IDB_ABOUT_OK:
  439.   EndDialog(hDlg, TRUE);
  440.   return TRUE;
  441.   break;
  442.   default:
  443.   return 0;
  444. }
  445. break;
  446. }
  447.   return FALSE;
  448. }
  449. /*
  450.  * Buffering dialog box message function
  451.  *
  452.  */
  453. DWORD WINAPI OpenHTTPThreadFunc( LPVOID lpData)
  454. {
  455. char *url;
  456. url = (char *) lpData;
  457. OpenFileForPlaying(hwnd, url, INPUT_TYPE_HTTP);
  458. return 0;
  459. }
  460. int APIENTRY BuffDlgProc (HWND hDlg, WORD wMsg, LONG wParam, LONG lParam)
  461. {
  462.   DWORD id = 0;
  463.   switch (wMsg)
  464.     {
  465.       case WM_INITDIALOG:
  466.   SetTimer(hDlg, 0xF8, 100, NULL);
  467.   urlW = hDlg;
  468.   return (0);
  469. break;
  470.       case WM_SYSCOMMAND:
  471.         if (wParam == SC_CLOSE)
  472.           {
  473. urlW = NULL;
  474.             EndDialog (hDlg, TRUE);
  475.             return (TRUE);
  476.           }
  477.         break;
  478.   case WM_COMMAND:
  479.         switch (wParam)
  480. {
  481.   case IDB_ABOUT_OK:
  482.   EndDialog(hDlg, TRUE);
  483.   return TRUE;
  484.   break;
  485.   default:
  486.   return 0;
  487. }
  488. break;
  489.   case WM_TIMER:
  490.   if(playback) {
  491.   DWORD progress = playback->GetBufferingState();
  492.   SendMessage(GetDlgItem(hDlg, IDC_PROGRESS), PBM_SETPOS, (WPARAM) progress, 0);
  493.   if(progress == 100) {
  494.   EndDialog(hDlg, TRUE);
  495.   return TRUE;
  496.   }
  497.   }
  498.   break;
  499. }
  500.   return FALSE;
  501. }
  502. /*
  503.  * Skin Browser Message Function
  504.  *
  505.  */
  506. int APIENTRY SkinBrowserDlgProc (HWND hDlg, WORD wMsg, LONG wParam, LONG lParam)
  507. {
  508.   int first = 0;
  509.   switch (wMsg)
  510.     {
  511.       case WM_INITDIALOG:
  512.   int nItem, i;
  513.   
  514.   /*
  515.    * Init the list of skins
  516.    */
  517.   SendMessage(GetDlgItem(hDlg, IDC_SKIN_LIST), LB_ADDSTRING, 0, (LONG) "[Default Skin]");
  518.   SendMessage(GetDlgItem(hDlg, IDC_SKIN_LIST), LB_SETCURSEL, 0, 0); 
  519.   
  520.   if(skinList->skinsDir != NULL) {
  521.   SendMessage(GetDlgItem(hDlg, IDC_COMBO_DIR), CB_ADDSTRING, 0, (LONG)skinList->skinsDir);
  522.       SendMessage(GetDlgItem(hDlg, IDC_COMBO_DIR), CB_SETCURSEL, 0, 0);
  523.   }
  524.   skinList->Scan();
  525.   for(i=0; i < skinList->getNumberOfSkins(); i++) {
  526.   
  527.   SendMessage(GetDlgItem(hDlg, IDC_SKIN_LIST), LB_ADDSTRING, 0, (LONG) skinList->getSkinInfo(i)->name);
  528.   if(strcmp(skinList->getSkinInfo(i)->directory, skinPath) == 0) {
  529.   SendMessage(GetDlgItem(hDlg, IDC_SKIN_LIST), LB_SETCURSEL, 0, 0); 
  530.   }
  531.   }
  532.   return (0);
  533. break;
  534.       case WM_SYSCOMMAND:
  535.         if (wParam == SC_CLOSE)
  536.           {
  537.           EndDialog (hDlg, TRUE);
  538.           return (TRUE);
  539.           }
  540.         break;
  541.   case WM_COMMAND:
  542.     switch (LOWORD(wParam))  {
  543.   
  544.           case IDC_SKIN_LIST: 
  545.               
  546.   switch (HIWORD(wParam)) { 
  547.                   
  548.   case LBN_SELCHANGE:
  549.   
  550.   int nItem;
  551.   nItem = SendMessage(GetDlgItem(hDlg, IDC_SKIN_LIST), LB_GETCURSEL, 0, 0); 
  552.   if(nItem < skinList->getNumberOfSkins()) {
  553.   
  554.   RECT rect;
  555.   skin->Load(skinList->getSkinInfo(nItem)->directory, hwnd);
  556.   strcpy(skinPath, skinList->getSkinInfo(nItem)->directory);
  557.   GetClientRect(hwnd, &rect);
  558.   InvalidateRect(hwnd, &rect, TRUE); 
  559.     UpdateWindow(hwnd);
  560.   }
  561.   else {
  562.   
  563.   RECT rect;
  564.   skin->LoadDefault(hInstance, hwnd);
  565.   strcpy(skinPath, "Default");
  566.   GetClientRect(hwnd, &rect);
  567.   InvalidateRect(hwnd, &rect, TRUE); 
  568.     UpdateWindow(hwnd);
  569.   }
  570.   break;
  571.   }
  572. }
  573.         switch (wParam)
  574. {
  575.   case IDB_SKINS_OK:
  576.   EndDialog(hDlg, TRUE);
  577.   return TRUE;
  578.   break;
  579.   
  580.   case ID_SKINS_CANCEL:
  581.   EndDialog(hDlg, TRUE);
  582.   return TRUE;
  583.   break;
  584.   case IDC_CHANGE_DIR:
  585.   dirChooser = new CDirDialog();
  586.   if(dirChooser->DoBrowse()) {
  587. skinList->SetDir(dirChooser->m_strPath);
  588. SendMessage(GetDlgItem(hDlg, IDC_COMBO_DIR), CB_RESETCONTENT, 0, 0);
  589. SendMessage(GetDlgItem(hDlg, IDC_SKIN_LIST), LB_RESETCONTENT, 0, 0);
  590. SendMessage(GetDlgItem(hDlg, IDC_SKIN_LIST), LB_ADDSTRING, 0, (LONG) "[Default Skin]");
  591. SendMessage(GetDlgItem(hDlg, IDC_SKIN_LIST), LB_SETCURSEL, 0, 0); 
  592. if(skinList->skinsDir != NULL) {
  593.   SendMessage(GetDlgItem(hDlg, IDC_COMBO_DIR), CB_ADDSTRING, 0, (LONG)skinList->skinsDir);
  594.       SendMessage(GetDlgItem(hDlg, IDC_COMBO_DIR), CB_SETCURSEL, 0, 0);
  595.   }
  596.   skinList->Scan();
  597.   for(i=0; i < skinList->getNumberOfSkins(); i++) {
  598.   
  599.   SendMessage(GetDlgItem(hDlg, IDC_SKIN_LIST), LB_ADDSTRING, 0, (LONG) skinList->getSkinInfo(i)->name);
  600.   if(strcmp(skinList->getSkinInfo(i)->directory, skinPath) == 0) {
  601.   SendMessage(GetDlgItem(hDlg, IDC_SKIN_LIST), LB_SETCURSEL, 0, 0); 
  602.   }
  603.   }
  604.   }
  605.   break;
  606.   default:
  607.   return 0;
  608. }
  609. break;
  610. }
  611.   return FALSE;
  612. }
  613. /*
  614.  * Open URL dialog box message function
  615.  *
  616.  */
  617. int APIENTRY UrlDlgProc (HWND hDlg, WORD wMsg, LONG wParam, LONG lParam)
  618. {
  619.   switch (wMsg)
  620.     {
  621.       case WM_INITDIALOG:
  622.   SendMessage(GetDlgItem(hDlg, IDC_RADIO_HTTP), BM_SETCHECK, BST_CHECKED, 0);
  623.   EnableWindow(GetDlgItem(hDlg, IDC_STATIC_FTP_USERNAME), FALSE);
  624.   EnableWindow(GetDlgItem(hDlg, IDC_STATIC_FTP_PASSWORD), FALSE);
  625.   EnableWindow(GetDlgItem(hDlg, IDC_CHECK_ANONYMOUS),     FALSE);
  626.   EnableWindow(GetDlgItem(hDlg, IDC_STATIC_FTP_SERVER),   FALSE);
  627.   EnableWindow(GetDlgItem(hDlg, IDC_COMBO_FTP),           FALSE);
  628.   EnableWindow(GetDlgItem(hDlg, IDC_EDIT_USERNAME),       FALSE);
  629.   EnableWindow(GetDlgItem(hDlg, IDC_EDIT_PASSWORD),       FALSE);
  630.   return (0);
  631. break;
  632.       case WM_SYSCOMMAND:
  633.         if (wParam == SC_CLOSE) {
  634.             EndDialog (hDlg, TRUE);
  635.             return (TRUE);
  636.         }
  637.         break;
  638.   case WM_COMMAND:
  639.         switch (wParam)
  640. {
  641. case IDC_RADIO_HTTP:
  642.     EnableWindow(GetDlgItem(hDlg, IDC_STATIC_FTP_USERNAME), FALSE);
  643.     EnableWindow(GetDlgItem(hDlg, IDC_STATIC_FTP_PASSWORD), FALSE);
  644.     EnableWindow(GetDlgItem(hDlg, IDC_CHECK_ANONYMOUS),     FALSE);
  645.     EnableWindow(GetDlgItem(hDlg, IDC_STATIC_FTP_SERVER),   FALSE);
  646.     EnableWindow(GetDlgItem(hDlg, IDC_COMBO_FTP),           FALSE);
  647.     EnableWindow(GetDlgItem(hDlg, IDC_EDIT_USERNAME),       FALSE);
  648.     EnableWindow(GetDlgItem(hDlg, IDC_EDIT_PASSWORD),       FALSE);
  649.     EnableWindow(GetDlgItem(hDlg, IDC_COMBO_HTTP),  TRUE);
  650.     EnableWindow(GetDlgItem(hDlg, IDC_STATIC_HTTP), TRUE);
  651. break;
  652. case IDC_RADIO_FTP:
  653.     EnableWindow(GetDlgItem(hDlg, IDC_CHECK_ANONYMOUS),     TRUE);
  654.     EnableWindow(GetDlgItem(hDlg, IDC_STATIC_FTP_SERVER),   TRUE);
  655.     EnableWindow(GetDlgItem(hDlg, IDC_COMBO_FTP),    TRUE);
  656.     EnableWindow(GetDlgItem(hDlg, IDC_COMBO_HTTP),  FALSE);
  657.     EnableWindow(GetDlgItem(hDlg, IDC_STATIC_HTTP), FALSE);
  658. anonymous = 1;
  659.     CheckDlgButton(hDlg, IDC_CHECK_ANONYMOUS, TRUE);
  660. break;
  661. case IDC_CHECK_ANONYMOUS:
  662. anonymous = anonymous ? 0 : 1;
  663. if(anonymous) {
  664.     EnableWindow(GetDlgItem(hDlg, IDC_STATIC_FTP_USERNAME), FALSE);
  665.     EnableWindow(GetDlgItem(hDlg, IDC_STATIC_FTP_PASSWORD), FALSE);
  666.     EnableWindow(GetDlgItem(hDlg, IDC_EDIT_USERNAME),       FALSE);
  667.     EnableWindow(GetDlgItem(hDlg, IDC_EDIT_PASSWORD),       FALSE);
  668. }
  669. else {
  670.     EnableWindow(GetDlgItem(hDlg, IDC_STATIC_FTP_USERNAME), TRUE);
  671.     EnableWindow(GetDlgItem(hDlg, IDC_STATIC_FTP_PASSWORD), TRUE);
  672.     EnableWindow(GetDlgItem(hDlg, IDC_EDIT_USERNAME),       TRUE);
  673.     EnableWindow(GetDlgItem(hDlg, IDC_EDIT_PASSWORD),       TRUE);
  674. }
  675. break;
  676. case IDB_URL_OK:
  677. DWORD http;
  678. EndDialog(hDlg, TRUE);
  679. if(SendMessage(GetDlgItem(hDlg, IDC_RADIO_HTTP), BM_GETCHECK, 0, 0) == BST_CHECKED) {
  680. char  *url;
  681. DWORD id, size;
  682. /*
  683.  * HTTP
  684.  */
  685. url = (char *) malloc(256);
  686. size = SendMessage(GetDlgItem(hDlg, IDC_COMBO_HTTP), EM_GETLINE, 0, (LONG)(LPVOID)url);
  687. *(url + size) = '';
  688. if(strstr(url, "http://") != NULL) {
  689. CreateThread( NULL, 0, OpenHTTPThreadFunc, (LPVOID) url, 0, &id );
  690. DialogBox (hInstance, (LPCSTR)MAKEINTRESOURCE(IDD_BUFFERING),
  691.       hwnd, (DLGPROC)BuffDlgProc);
  692. return 0;
  693. }
  694. }
  695. else {
  696. char  *url;
  697. DWORD id, size;
  698. /*
  699.  * FTP
  700.  */
  701. url = (char *) malloc(256);
  702. size = SendMessage(GetDlgItem(hDlg, IDC_COMBO_FTP), EM_GETLINE, 0, (LONG)(LPVOID)url);
  703. *(url + size) = '';
  704. if(strstr(url, "ftp://") != NULL) {
  705. if(anonymous) {
  706. CreateThread( NULL, 0, OpenHTTPThreadFunc, (LPVOID) url, 0, &id );
  707. DialogBox (hInstance, (LPCSTR)MAKEINTRESOURCE(IDD_BUFFERING),
  708.       hwnd, (DLGPROC)BuffDlgProc);
  709. return 0;
  710. }
  711. else {
  712. /*
  713.  * Not implemented yet.
  714.  *
  715.  */
  716. }
  717. }
  718. }
  719.   
  720. return TRUE;
  721. break;
  722. case IDB_URL_CANCEL:
  723. EndDialog(hDlg, TRUE);
  724. return TRUE;
  725. break;
  726. default:
  727.   return 0;
  728. }
  729. break;
  730. }
  731.   return FALSE;
  732. }
  733. /*
  734.  * Main function
  735.  */
  736. int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow)
  737. POINT pt;
  738.     MSG Msg;
  739.     WNDCLASS W;
  740. DWORD i;
  741. hInstance = hInst;
  742. oldPt.x = 0;
  743. oldPt.y = 0;
  744. showing_cursor = 1;
  745. /*
  746.  * Open the log file
  747.  */
  748. #ifdef _DEBUG_
  749. debug_file = fopen("c:\playa.txt", "wt");
  750. #endif
  751. /*
  752.  * Load the options
  753.  *
  754.  */
  755.     strcpy(skinPath, "Default");
  756. LoadOptions();
  757. /*
  758.      * init the video subsystem 
  759.      *
  760.      */
  761.    playback = new Playback();
  762.    playlist = new Playlist();
  763.    skinList = new SkinList();
  764.    resizer  = new Resizer();
  765.    playback->SetLoop(options.loop);
  766.    clientRect.left   = 0;
  767.    clientRect.right  = DEFAULT_SKIN_WIDTH;
  768.    clientRect.top    = 0;
  769.    clientRect.bottom = DEFAULT_SKIN_HEIGHT;
  770.    
  771.    windowRect.left   = 0;
  772.    windowRect.right  = DEFAULT_SKIN_WIDTH;
  773.    windowRect.top    = 0;
  774.    windowRect.bottom = DEFAULT_SKIN_HEIGHT;
  775.    AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW, 0);
  776.    /*
  777.     * Window Class
  778.     */
  779.    memset(&W, 0, sizeof(WNDCLASS));
  780.    
  781.    W.style         = CS_HREDRAW | CS_VREDRAW | CS_PARENTDC;
  782.    W.lpfnWndProc   = WndProc;
  783.    W.hInstance     = hInst;
  784.    W.hbrBackground = (HBRUSH)(0);
  785.    W.hCursor       = LoadCursor(hInst, MAKEINTRESOURCE(IDC_CURSOR1));
  786.    W.hIcon         = LoadIcon(hInst, MAKEINTRESOURCE(IDB_ICON));
  787.    W.lpszClassName = Name;
  788.    W.lpszMenuName  = NULL;
  789.    RegisterClass(&W);
  790.    /*
  791.     * Load the menu and change 
  792. * it for recent file list
  793.     */
  794.    HMENU             menu;
  795.    MENUITEMINFO itemInfo;
  796.    popupMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_MENU1));
  797.    menu = GetSubMenu(popupMenu, 0);
  798.    menu = GetSubMenu(menu, 5);
  799.    
  800.    if(RecentFiles[0] != NULL) {
  801.    RemoveMenu(menu, 0, MF_BYPOSITION);
  802.    
  803. /*
  804.  * Now add the files
  805.  */
  806.    
  807.    for(i=0; i < 5; i++) {
  808.    
  809.    if(RecentFiles[i] != NULL) {
  810.    itemInfo.cbSize = sizeof(MENUITEMINFO);
  811.    itemInfo.fMask  = MIIM_DATA | MIIM_TYPE | MIIM_ID;
  812.    itemInfo.fType  = MFT_STRING;
  813.    itemInfo.dwTypeData = RecentFiles[i];
  814.    itemInfo.cch = strlen(RecentFiles[i]);
  815.    itemInfo.wID = ID_RECENT_FILE1 + i;
  816.    
  817.    InsertMenuItem(menu, GetMenuItemCount(menu), TRUE, &itemInfo);
  818. }
  819.    }
  820.    }
  821.    /*
  822.     * Create the main window
  823.     *
  824.     */
  825.    hwnd = CreateWindow( Name, Name, WS_OVERLAPPEDWINDOW, 100, 30, 
  826. windowRect.right - windowRect.left, 
  827. windowRect.bottom - windowRect.top, 
  828. NULL, NULL, hInst, NULL);
  829.    
  830.    /*
  831.     * Set the window Rgn
  832.     *
  833.     */
  834. GetClientRect(hwnd, &clientRect);
  835. GetWindowRect(hwnd, &windowRect);
  836. pt.x = clientRect.left;
  837. pt.y = clientRect.top;
  838. ClientToScreen(hwnd, &pt);
  839. pt2.x = clientRect.right;
  840. pt2.y = clientRect.bottom;
  841. ClientToScreen(hwnd, &pt2);
  842. SetWindowRgn(hwnd, CreateRectRgn( pt.x  - windowRect.left, 
  843.      pt.y  - windowRect.top,
  844.   (windowRect.right - windowRect.left) - (windowRect.right - pt2.x),
  845.   (windowRect.bottom - windowRect.top) - (windowRect.bottom - pt2.y)), TRUE); 
  846.    /*
  847.     * Register for Drag n' Drop
  848.     */
  849.    DragAcceptFiles(hwnd, TRUE);
  850.    /*
  851.     * And Start TIMER
  852.     *
  853.     */
  854. SetTimer(hwnd, TIMER_ID, TIMER_RATE, NULL);
  855. /*
  856.  * Load Accelerators
  857.  */
  858. hAccel = LoadAccelerators(hInst, MAKEINTRESOURCE(IDR_ACCELERATOR));
  859. /*
  860.  * Set the icon
  861.  */
  862. SetClassLong(hwnd, GCL_HICON, (LONG) LoadIcon(hInst, MAKEINTRESOURCE(IDB_ICON))); 
  863.  
  864. /*
  865.  * Menu items 
  866.  */
  867. CheckMenuItem(popupMenu, (UINT)ID_BILINEAR,     options.use_bilinear ? MF_CHECKED : MF_UNCHECKED);
  868. CheckMenuItem(popupMenu, (UINT)ID_ASPECT_RATIO, options.maintain_aspect_ratio ? MF_CHECKED : MF_UNCHECKED);
  869. CheckMenuItem(popupMenu, (UINT)ID_LOOP, options.loop ? MF_CHECKED : MF_UNCHECKED);
  870. CheckMenuItem(popupMenu, (UINT)ID_ON_TOP, options.on_top ? MF_CHECKED : MF_UNCHECKED);
  871.    /*
  872.     * Loads the skin
  873.     *
  874.     */
  875.    skin = new Skin(hInst, hwnd);
  876.    if(strcmp(skinPath, "Default") == 0) {
  877.    skin->LoadDefault(hInst, hwnd);
  878.    }
  879.    else {
  880.    skin->Load(skinPath, hwnd);
  881.    }
  882.    /*
  883.     * now The buttons
  884.     */
  885. ShowWindow(hwnd, nCmdShow);
  886. UpdateWindow(hwnd);
  887. GetWindowRect(hwnd, &windowRect);
  888. if(options.on_top)
  889. SetWindowPos(hwnd, (HWND) -1,  windowRect.left, windowRect.top, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, TRUE);
  890.    while (TRUE)
  891.     {
  892.    /*
  893. * Get the messages
  894. */
  895.    if (!GetMessage(&Msg, NULL, 0, 0))
  896. return (int) Msg.wParam;
  897. if (!TranslateAccelerator(hwnd, hAccel, &Msg)) {
  898. TranslateMessage(&Msg); 
  899. DispatchMessage(&Msg); 
  900. else {
  901.            
  902. TranslateMessage(&Msg);
  903.        DispatchMessage(&Msg);
  904. }
  905.    }
  906.    return Msg.wParam;
  907. }
  908. /*
  909.  * Opens a specified file for playing
  910.  */
  911. void OpenFileForPlaying(HWND hwnd, char *filename, int type) {
  912. skin->Display(hwnd, playback);
  913. RECT rect, windowrect;
  914. playback->Close();
  915. if(playback->Open(filename, type, hwnd)) {
  916. /*
  917.  * First resize the window
  918.  */
  919. if(playback->OK()) {
  920. DWORD i;
  921. GetWindowRect(hwnd, &windowrect); 
  922. rect.left   = windowrect.left;
  923. rect.top    = windowrect.top;
  924. rect.right  = playback->Width() + 15;
  925. rect.bottom = playback->Height() + 115 + 22 + (playback->has_subtitles && use_subtitles ? 50 : 0);
  926. MoveWindow( hwnd, rect.left, rect.top, rect.right, rect.bottom, TRUE);
  927. /*
  928.  * Update flags
  929.  */
  930. playback->SetBilinear(options.use_bilinear);
  931. playback->SetChangeFullscreenRes(options.change_fullscreen_res);
  932. playback->SetUseSubtitles(use_subtitles);
  933. /*
  934.  * Update recent file list
  935.  */
  936. DWORD insert = 1;
  937. for(i=0; i < 5; i++) {
  938. if(RecentFiles[i] != NULL && strcmp(RecentFiles[i], filename) == 0) {
  939. insert = 0;
  940. }
  941. }
  942. if(insert && strstr(filename, "http://") == NULL && strstr(filename, "ftp://") == NULL) {
  943. for(i=4; i > 0; i--) {
  944. RecentFiles[i] = RecentFiles[i - 1];
  945. }
  946. RecentFiles[0] = (char *) malloc(strlen(filename) + 1);
  947. strncpy(RecentFiles[0], filename, strlen(filename));
  948. RecentFiles[0][strlen(filename)] = '';
  949. }
  950. /*
  951.  * And update the menu
  952.  */
  953. HMENU menu, sub;
  954. menu = GetSubMenu(popupMenu, 0);
  955. /*
  956.  * The subtitles and Properties menus
  957.  */
  958. EnableMenuItem(menu, (UINT)ID_PROPERTIES, MF_ENABLED);
  959. if(playback->has_subtitles) {
  960. sub = GetSubMenu(menu, 17);
  961. RemoveMenu(sub, 0, MF_BYPOSITION);
  962. MENUITEMINFO subitemInfo;
  963.     subitemInfo.cbSize = sizeof(MENUITEMINFO);
  964. subitemInfo.fMask  = MIIM_DATA | MIIM_TYPE | MIIM_ID;
  965. subitemInfo.fType  = MFT_STRING;
  966. subitemInfo.dwTypeData = "Use Subtitles";
  967. subitemInfo.cch = 13;
  968. subitemInfo.wID = ID_SUBTITLES;
  969.    
  970.     InsertMenuItem(sub, 0, TRUE, &subitemInfo);
  971.     CheckMenuItem(sub, (UINT)ID_SUBTITLES, use_subtitles ? MF_CHECKED : MF_UNCHECKED);
  972. }
  973. else {
  974. sub = GetSubMenu(menu, 17);
  975. RemoveMenu(sub, 0, MF_BYPOSITION);
  976. MENUITEMINFO subitemInfo;
  977.     subitemInfo.cbSize = sizeof(MENUITEMINFO);
  978. subitemInfo.fMask  = MIIM_DATA | MIIM_TYPE | MIIM_ID;
  979. subitemInfo.fType  = MFT_STRING;
  980. subitemInfo.dwTypeData = "None Available";
  981. subitemInfo.cch = 14;
  982. subitemInfo.wID = ID_NONE_SUB;
  983.    
  984.     InsertMenuItem(sub, 0, TRUE, &subitemInfo);
  985. EnableMenuItem(sub, (UINT)ID_NONE_SUB, MF_GRAYED);
  986. }
  987. /*
  988.  * And the recent file list
  989.  */
  990. menu = GetSubMenu(menu, 5);
  991. if(RecentFiles[0] != NULL) {
  992. DWORD count;
  993. MENUITEMINFO itemInfo;
  994. count = GetMenuItemCount(menu);
  995. for(i=0; i < count; i++) {
  996. RemoveMenu(menu, 0, MF_BYPOSITION);
  997. }
  998. /*
  999.  * Now add the files
  1000.  */
  1001.    
  1002.     for(i=0; i < 5; i++) {
  1003.    
  1004.    if(RecentFiles[i] != NULL) {
  1005.   itemInfo.cbSize = sizeof(MENUITEMINFO);
  1006.   itemInfo.fMask  = MIIM_DATA | MIIM_TYPE | MIIM_ID;
  1007.   itemInfo.fType  = MFT_STRING;
  1008.   itemInfo.dwTypeData = RecentFiles[i];
  1009.   itemInfo.cch = strlen(RecentFiles[i]);
  1010.   itemInfo.wID = ID_RECENT_FILE1 + i;
  1011.    
  1012.   InsertMenuItem(menu, GetMenuItemCount(menu), TRUE, &itemInfo);
  1013.    }
  1014.    }
  1015. }
  1016. /*
  1017.    * Then play
  1018.  */
  1019. playback->Play();
  1020. }
  1021. }
  1022. else {
  1023. /*
  1024.  * File couldn't be opened
  1025.  * so we may have to close the
  1026.  * buffering window...
  1027.  */
  1028. if(urlW != NULL) {
  1029. EndDialog(urlW, 0);
  1030. urlW = NULL;
  1031. }
  1032. MessageBox(NULL, "The location you selected could not be opened", "Error", MB_OK);
  1033. }
  1034. }
  1035. /*
  1036.  * Opens a file:
  1037.  */
  1038. void fileOpen(HWND hwnd)
  1039. {
  1040. OPENFILENAME ofn;
  1041. char szFile[260];
  1042. /*
  1043.  * shows a file selector
  1044.  */
  1045. ZeroMemory(&ofn, sizeof(OPENFILENAME));
  1046.     ZeroMemory(szFile, 260);
  1047. ofn.lStructSize = sizeof(OPENFILENAME);
  1048. ofn.hwndOwner = hwnd;
  1049. ofn.lpstrFile = szFile;
  1050. ofn.nMaxFile = sizeof(szFile);
  1051. ofn.lpstrFilter = "All*.*AVI Files*.AVI";
  1052. ofn.nFilterIndex = 2;
  1053. ofn.lpstrFileTitle = "";
  1054. ofn.nMaxFileTitle = 0;
  1055. ofn.lpstrInitialDir = NULL;
  1056. ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
  1057. if (GetOpenFileName(&ofn) == TRUE) {
  1058. OpenFileForPlaying(hwnd, ofn.lpstrFile, INPUT_TYPE_FILE);
  1059. }
  1060. }
  1061. /*
  1062.  * Handles events
  1063.  */
  1064. LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
  1065. int xPos, yPos;
  1066. switch(Message) {
  1067. case WM_DESTROY:
  1068. #ifdef _DEBUG__
  1069. fclose(debug_file);
  1070. #endif
  1071. SaveOptions();
  1072. playback->Close();
  1073. Cleanup();
  1074. PostQuitMessage(0);
  1075. return TRUE;
  1076. break;
  1077. case WM_SYSCOMMAND:
  1078.         
  1079. if (wParam == SC_CLOSE)
  1080.           {
  1081. #ifdef _DEBUG__
  1082. fclose(debug_file);
  1083. #endif
  1084. SaveOptions();
  1085. playback->Close();
  1086. Cleanup();
  1087. PostQuitMessage(0);
  1088. return (TRUE);
  1089.           }
  1090.         break;
  1091. case WM_COMMAND :
  1092.     
  1093. switch(LOWORD(wParam)) {
  1094. case ID_SUBTITLES:
  1095. RECT  wrect;
  1096. HMENU menu;
  1097. menu = GetSubMenu(popupMenu, 0);
  1098. menu = GetSubMenu(menu, 17);
  1099. if(playback != NULL) {
  1100. GetWindowRect(hwnd, &wrect);
  1101. if(use_subtitles) {
  1102. use_subtitles = 0;
  1103. wrect.bottom -= 50;
  1104. MoveWindow(hwnd, wrect.left, wrect.top, wrect.right - wrect.left, wrect.bottom - wrect.top, TRUE);
  1105. CheckMenuItem(menu, (UINT)ID_SUBTITLES, MF_UNCHECKED);
  1106. playback->SetUseSubtitles(use_subtitles);
  1107. }
  1108. else {
  1109. use_subtitles = 1;
  1110. wrect.bottom += 50;
  1111. CheckMenuItem(menu, (UINT)ID_SUBTITLES, MF_CHECKED);
  1112. MoveWindow(hwnd, wrect.left, wrect.top, wrect.right - wrect.left, wrect.bottom - wrect.top, TRUE);
  1113. playback->SetUseSubtitles(use_subtitles);
  1114. }
  1115. }
  1116. break;
  1117. case ID_RECENT_FILE1:
  1118. OpenFileForPlaying(hwnd, RecentFiles[0], INPUT_TYPE_FILE);
  1119. break;
  1120. case ID_RECENT_FILE2:
  1121. OpenFileForPlaying(hwnd, RecentFiles[1], INPUT_TYPE_FILE);
  1122. break;
  1123. case ID_RECENT_FILE3:
  1124. OpenFileForPlaying(hwnd, RecentFiles[2], INPUT_TYPE_FILE);
  1125. break;
  1126. case ID_RECENT_FILE4:
  1127. OpenFileForPlaying(hwnd, RecentFiles[3], INPUT_TYPE_FILE);
  1128. break;
  1129. case ID_RECENT_FILE5:
  1130. OpenFileForPlaying(hwnd, RecentFiles[4], INPUT_TYPE_FILE);
  1131. break;
  1132. case ID_MENU_ABOUT:
  1133.             DialogBox (hInstance, (LPCSTR)MAKEINTRESOURCE(IDD_ABOUT_DIALOG),
  1134.                         hwnd, (DLGPROC)AboutDlgProc);
  1135. break;
  1136. case ID_SKIN_BROWSER:
  1137.             DialogBox (hInstance, (LPCSTR)MAKEINTRESOURCE(IDD_SKIN_BROWSER),
  1138.                              hwnd, (DLGPROC)SkinBrowserDlgProc);
  1139. break;
  1140. case ID_MENU_OPTIONS:
  1141.             DialogBox (hInstance, (LPCSTR)MAKEINTRESOURCE(IDD_PREFS),
  1142.                              hwnd, (DLGPROC)PreferencesDlgProc);
  1143. break;
  1144. case ID_OPEN_URL:
  1145.             DialogBox (hInstance, (LPCSTR)MAKEINTRESOURCE(IDD_URL_DIALOG),
  1146.                              hwnd, (DLGPROC)UrlDlgProc);
  1147. break;
  1148. case ID_PROPERTIES:
  1149. DialogBox (hInstance, (LPCSTR)MAKEINTRESOURCE(IDD_PROPERTIES),
  1150.                        hwnd, (DLGPROC)PropDlgProc);
  1151. break;
  1152. case ID_OPEN_FILE:
  1153. fileOpen(hwnd);
  1154. break;
  1155. case ID_ON_TOP:
  1156. RECT r;
  1157. options.on_top = options.on_top == 1 ? 0 : 1;
  1158. CheckMenuItem(popupMenu, (UINT)wParam, options.on_top ? MF_CHECKED : MF_UNCHECKED);
  1159. GetWindowRect(hwnd, &r);
  1160. SetWindowPos(hwnd, options.on_top ? (HWND) -1 : (HWND) 1,  r.left, r.top, r.right - r.left, r.bottom - r.top, TRUE);
  1161. if(!options.on_top)
  1162. SetWindowPos(hwnd, HWND_TOP,  r.left, r.top, r.right - r.left, r.bottom - r.top, TRUE);
  1163. break;
  1164. case ID_LOOP:
  1165. options.loop = options.loop == 1 ? 0 : 1;
  1166. CheckMenuItem(popupMenu, (UINT)wParam, options.loop ? MF_CHECKED : MF_UNCHECKED);
  1167. playback->SetLoop(options.loop);
  1168. break;
  1169. case ID_PREVIOUS:
  1170. playback->Rewind();
  1171. break;
  1172. case ID_STOP:
  1173. playback->Stop(TRUE);
  1174. break;
  1175. case ID_PLAY:
  1176. if(playback->OK()) {
  1177. if(playback->isPaused()) {
  1178. playback->Pause();
  1179. }
  1180. else {
  1181. playback->Play();
  1182. }
  1183. }
  1184. else {
  1185. /*
  1186.  * Load files
  1187.  */
  1188. fileOpen(hwnd);
  1189. }
  1190. break;
  1191. case ID_PAUSE:
  1192. if(playback->OK()) {
  1193. playback->Pause();
  1194. }
  1195. break;
  1196. case ID_NEXT:
  1197. playback->FastForward();
  1198. break;
  1199. case ID_EXIT:
  1200. SaveOptions();
  1201.     DestroyWindow(hwnd);
  1202. break;
  1203. case ID_FULLSCREEN:
  1204. GetWindowRect(hwnd, &fullwindowRect);
  1205. count          = 0;
  1206. showing_cursor = 1;
  1207. playback->SetChangeFullscreenRes(options.change_fullscreen_res);
  1208. playback->Fullscreen(TRUE);
  1209. break;
  1210. case ID_ORIGINAL_SIZE:
  1211. if(playback->isPlaying()) {
  1212. RECT src;
  1213. GetWindowRect(hwnd, &windowRect);
  1214. src.left    = 0;
  1215. src.right   = playback->Width() + 7;
  1216. src.top     = 0;
  1217. src.bottom  = playback->Height() + 110;
  1218. AdjustWindowRect(&src, WS_OVERLAPPEDWINDOW, 0);
  1219. MoveWindow( hwnd, windowRect.left, 
  1220. windowRect.top, 
  1221. src.right - src.left, 
  1222. src.bottom - src.top, TRUE);
  1223. }
  1224. break;
  1225. case ID_HALF_SIZE:
  1226. if(playback->isPlaying()) {
  1227. RECT src;
  1228. GetWindowRect(hwnd, &windowRect);
  1229. src.left    = 0;
  1230. src.right   = playback->Width()/2 + 7;
  1231. src.top     = 0;
  1232. src.bottom  = playback->Height()/2 + 110;
  1233. AdjustWindowRect(&src, WS_OVERLAPPEDWINDOW, 0);
  1234. MoveWindow( hwnd, windowRect.left, 
  1235. windowRect.top, 
  1236. src.right - src.left, 
  1237. src.bottom - src.top, TRUE);
  1238. }
  1239. break;
  1240. case ID_DOUBLE_SIZE:
  1241. if(playback->isPlaying()) {
  1242. RECT src;
  1243. GetWindowRect(hwnd, &windowRect);
  1244. src.left    = 0;
  1245. src.right   = playback->Width()*2 + 7;
  1246. src.top     = 0;
  1247. src.bottom  = playback->Height()*2 + 110;
  1248. AdjustWindowRect(&src, WS_OVERLAPPEDWINDOW, 0);
  1249. MoveWindow( hwnd, windowRect.left, 
  1250. windowRect.top, 
  1251. src.right - src.left, 
  1252. src.bottom - src.top, TRUE);
  1253. }
  1254. break;
  1255. case ID_BILINEAR:
  1256. options.use_bilinear = options.use_bilinear == 1 ? 0 : 1;
  1257. CheckMenuItem(popupMenu, (UINT)wParam, options.use_bilinear ? MF_CHECKED : MF_UNCHECKED);
  1258. playback->SetBilinear(options.use_bilinear);
  1259. break;
  1260. case ID_ASPECT_RATIO:
  1261. options.maintain_aspect_ratio = options.maintain_aspect_ratio == 1 ? 0 : 1;
  1262. CheckMenuItem(popupMenu, (UINT)wParam, options.maintain_aspect_ratio ? MF_CHECKED : MF_UNCHECKED);
  1263. break;
  1264. }
  1265. break;
  1266. /*
  1267.  * Timer
  1268.  *
  1269.  */
  1270. case WM_TIMER:
  1271. if(playback && playback->isPlaying() && !playback->fullscreen) {
  1272. if(action != ACTION_PROGRESS_CURSOR) {
  1273. skin->SetProgressValue(hwnd, playback->GetProgress());
  1274. }
  1275. /*
  1276.  * Do time display here
  1277.  */
  1278. }
  1279. if(playback->isInFullscreen() && showing_cursor) {
  1280. count++;
  1281. /*
  1282.  * We wait for 2 secs
  1283.  */ 
  1284. if(count >= 20) {
  1285. ShowCursor(0);
  1286. showing_cursor = 0;
  1287. }
  1288. }
  1289. break;
  1290. /*
  1291.  * Key Press
  1292.  *
  1293.  */
  1294. case WM_KEYUP:
  1295. switch(wParam) {
  1296. case VK_ESCAPE:
  1297. if(playback->fullscreen) {
  1298. RECT rect;
  1299. playback->Fullscreen(FALSE);
  1300. ShowCursor(1);
  1301. /*
  1302.  * We need to resize the window to it's original size
  1303.  */
  1304. MoveWindow(hwnd, fullwindowRect.left, fullwindowRect.top, fullwindowRect.right - fullwindowRect.left, 
  1305.    fullwindowRect.bottom - fullwindowRect.top, TRUE);
  1306. GetClientRect(hwnd, &rect);
  1307. InvalidateRect(hwnd, &rect, TRUE); 
  1308.   UpdateWindow(hwnd);
  1309. Sleep(100);
  1310. GetClientRect(hwnd, &rect);
  1311. InvalidateRect(hwnd, &rect, TRUE); 
  1312.   UpdateWindow(hwnd);
  1313. }
  1314. break;
  1315. default:
  1316. break;
  1317. }
  1318. break;
  1319. case WM_LBUTTONDOWN:
  1320. xPos = LOWORD(lParam); 
  1321. yPos = HIWORD(lParam);
  1322. action = skin->GetAction(xPos, yPos);
  1323. skin->SetActionStart(hwnd, action);
  1324. if(action == ACTION_RESIZE) {
  1325. POINT pt;
  1326. pt.x = xPos;
  1327. pt.y = yPos;
  1328. ClientToScreen(hwnd, &pt);
  1329. moveX = pt.x;
  1330. moveY = pt.y;
  1331. GetWindowRect(hwnd, &windowRect);
  1332. SetCapture(hwnd);
  1333. resizer->Start(&pt);
  1334. }
  1335. if(action == ACTION_NONE) {
  1336. /*
  1337.  * We are moving the window
  1338.  */
  1339. action = ACTION_MOVING;
  1340. moveX = xPos;
  1341. moveY = yPos;
  1342. GetWindowRect(hwnd, &windowRect);
  1343. SetCapture(hwnd);
  1344. if(!playback->isPaused())
  1345. playback->Pause();
  1346. }
  1347. if(action == ACTION_VOLUME_CURSOR || action == ACTION_PROGRESS_CURSOR) {
  1348. moveX = xPos;
  1349. }
  1350. break;
  1351. case WM_LBUTTONUP:
  1352. skin->SetActionEnd(hwnd, action);
  1353. switch(action) {
  1354. case ACTION_MENU:
  1355. HMENU menu;
  1356. POINT pt;
  1357. pt.x = pt.y = 0;
  1358. ClientToScreen(hwnd, &pt);
  1359. xPos = pt.x + LOWORD(lParam); 
  1360. yPos = pt.y + HIWORD(lParam);
  1361. menu = GetSubMenu(popupMenu, 0);
  1362. TrackPopupMenu( menu, 0, xPos, yPos, 0, hwnd, NULL);
  1363. break;
  1364. case ACTION_CLOSE:
  1365. SaveOptions();
  1366. PostQuitMessage(0);
  1367. break;
  1368. case ACTION_MINIMIZE:
  1369. ShowWindow(hwnd, SW_MINIMIZE);
  1370. break;
  1371. case ACTION_STOP:
  1372. playback->Stop(TRUE);
  1373. break;
  1374. case ACTION_PLAY:
  1375. if(playback->OK()) {
  1376. if(playback->isPaused()) {
  1377. playback->Pause();
  1378. }
  1379. else {
  1380. playback->Play();
  1381. }
  1382. }
  1383. else {
  1384. /*
  1385.  * Load files
  1386.  */
  1387. fileOpen(hwnd);
  1388. }
  1389. break;
  1390. case ACTION_PAUSE:
  1391. if(playback->OK()) {
  1392. if(playback->isPaused()) {
  1393. playback->NextFrame();
  1394. }
  1395. else {
  1396. playback->Pause();
  1397. }
  1398. }
  1399. break;
  1400. case ACTION_FORWARD:
  1401. playback->FastForward();
  1402. break;
  1403. case ACTION_REWIND:
  1404. playback->Rewind();
  1405. break;
  1406. case ACTION_LOAD:
  1407. {
  1408. fileOpen(hwnd);
  1409. }
  1410. break;
  1411. case ACTION_PROGRESS_CURSOR:
  1412. playback->Seek(skin->GetProgress());
  1413. break;
  1414. case ACTION_VOLUME_CURSOR:
  1415. playback->SetVolume(skin->GetVolume());
  1416. break;
  1417. case ACTION_VOLUME_BAR:
  1418. moveX = LOWORD(lParam); 
  1419. skin->SetVolumeCursorX(hwnd, moveX);
  1420. playback->SetVolume(skin->GetVolume());
  1421. break;
  1422. case ACTION_PROGRESS_BAR:
  1423. moveX = LOWORD(lParam); 
  1424. skin->SetProgressCursorX(hwnd, moveX);
  1425. playback->Seek(skin->GetProgress());
  1426. break;
  1427. case ACTION_NONE:
  1428. default:
  1429. break;
  1430. }
  1431. if(action == ACTION_MOVING) {
  1432. ReleaseCapture();
  1433. RECT rect;
  1434. GetWindowRect(hwnd, &rect);
  1435. SetWindowPos(hwnd, HWND_TOPMOST, rect.left, rect.top, 
  1436.  rect.right - rect.left, rect.bottom - rect.top, 
  1437.  SWP_SHOWWINDOW | SWP_NOZORDER | SWP_NOACTIVATE);
  1438. if(playback->isPaused())
  1439. playback->Pause();
  1440. if(playback->isPlaying()) {
  1441. GetClientRect(hwnd, &rect);
  1442. InvalidateRect(hwnd, &rect, TRUE); 
  1443.   UpdateWindow(hwnd);
  1444. }
  1445. }
  1446. if(action == ACTION_RESIZE) {
  1447. POINT pt;
  1448. ReleaseCapture();
  1449. resizer->Stop();
  1450. xPos = LOWORD(lParam);
  1451. yPos = HIWORD(lParam);
  1452. pt.x = xPos;
  1453. pt.y = yPos;
  1454. if(xPos > 32768 || yPos > 32768)
  1455. return 0;
  1456. ClientToScreen(hwnd, &pt);
  1457. if(windowRect.right + (pt.x - moveX) - windowRect.left >= skin->DefaultWidth() &&
  1458.    windowRect.bottom + (pt.y - moveY) - windowRect.top >= skin->DefaultHeight()) {
  1459. MoveWindow( hwnd, windowRect.left, 
  1460. windowRect.top, 
  1461. windowRect.right + (pt.x - moveX) - windowRect.left, 
  1462. windowRect.bottom + (pt.y - moveY) - windowRect.top, TRUE);
  1463. }
  1464. else {
  1465. RECT r;
  1466. r.left   = 0;
  1467. r.right  = DEFAULT_SKIN_WIDTH;
  1468. r.top    = 0;
  1469. r.bottom = DEFAULT_SKIN_HEIGHT;
  1470. AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW, FALSE);
  1471. if(windowRect.right + (pt.x - moveX) - windowRect.left >= skin->DefaultWidth()) {
  1472. MoveWindow( hwnd, windowRect.left, 
  1473. windowRect.top, 
  1474. windowRect.right + (pt.x - moveX) - windowRect.left, 
  1475. r.bottom - r.top + 2, TRUE);
  1476. }
  1477. else {
  1478. if(windowRect.bottom + (pt.y - moveY) - windowRect.top >= skin->DefaultHeight()) {
  1479. MoveWindow( hwnd, windowRect.left, 
  1480. windowRect.top, 
  1481. r.right - r.left + 2, 
  1482. windowRect.bottom + (pt.y - moveY) - windowRect.top, TRUE);
  1483. }
  1484. else {
  1485. MoveWindow( hwnd, windowRect.left, 
  1486. windowRect.top, 
  1487. r.right - r.left + 2, 
  1488. r.bottom - r.top + 2, TRUE);
  1489. }
  1490. }
  1491. }
  1492. moveX = pt.x;
  1493. moveY = pt.y;
  1494. }
  1495. action = ACTION_NONE;
  1496. break;
  1497. case WM_MOUSEMOVE:
  1498. count = 0;
  1499. if(playback->isInFullscreen() && !showing_cursor) {
  1500. ShowCursor(1);
  1501. showing_cursor = 1;
  1502. }
  1503. if(action == ACTION_MOVING) {
  1504. RECT   r;
  1505. POINT pt;
  1506. xPos = LOWORD(lParam); 
  1507. yPos = HIWORD(lParam);
  1508. GetClientRect(hwnd, &r);
  1509. if(xPos > 16768) {
  1510. xPos = 1;
  1511. }
  1512. else {
  1513. if(xPos >= (r.right - r.left))
  1514. xPos = r.right - r.left - 1;
  1515. }
  1516. if(yPos > 16768) {
  1517. yPos = 1;
  1518. }
  1519. else {
  1520. if(yPos >= (r.bottom - r.top))
  1521. yPos = r.bottom - r.top - 1;
  1522. }
  1523. pt.x = xPos;
  1524. pt.y = yPos;
  1525. ClientToScreen(hwnd, &pt);
  1526. MoveWindow( hwnd, pt.x - moveX, 
  1527. pt.y - moveY - 22, 
  1528. windowRect.right - windowRect.left, 
  1529. windowRect.bottom - windowRect.top, TRUE);
  1530. }
  1531. if(action == ACTION_RESIZE) {
  1532. POINT pt;
  1533. pt.x = LOWORD(lParam);
  1534. pt.y = HIWORD(lParam);
  1535. resizer->Draw(hwnd, &pt);
  1536.   
  1537. }
  1538. if(action == ACTION_VOLUME_CURSOR) {
  1539. moveX = LOWORD(lParam); 
  1540. skin->SetVolumeCursorX(hwnd, moveX);
  1541. playback->SetVolume(skin->GetVolume());
  1542. }
  1543. if(action == ACTION_PROGRESS_CURSOR) {
  1544. moveX = LOWORD(lParam); 
  1545. skin->SetProgressCursorX(hwnd, moveX);
  1546. }
  1547. break;
  1548. case WM_RBUTTONDOWN:
  1549. if(!playback->fullscreen) {
  1550. HMENU menu;
  1551. POINT pt1;
  1552. int   x, y;
  1553. pt1.x = pt1.y = 0;
  1554. ClientToScreen(hwnd, &pt1);
  1555. x = pt1.x + LOWORD(lParam); 
  1556. y = pt1.y + HIWORD(lParam);
  1557. menu = GetSubMenu(popupMenu, 0);
  1558. TrackPopupMenu( menu, 0, x, y, 0, hwnd, NULL);
  1559. }
  1560. break;
  1561. case WM_SIZE:
  1562. RECT  clientRect, windowRect;
  1563. POINT other_pt;
  1564. GetClientRect(hwnd, &clientRect);
  1565. GetWindowRect(hwnd, &windowRect);
  1566. other_pt.x = clientRect.left;
  1567. other_pt.y = clientRect.top;
  1568. ClientToScreen(hwnd, &other_pt);
  1569. pt2.x = clientRect.right;
  1570. pt2.y = clientRect.bottom;
  1571. ClientToScreen(hwnd, &pt2);
  1572.     SetWindowRgn(hwnd, CreateRectRgn( other_pt.x  - windowRect.left, 
  1573.      other_pt.y  - windowRect.top,
  1574.   (windowRect.right - windowRect.left) - (windowRect.right - pt2.x),
  1575.   (windowRect.bottom - windowRect.top) - (windowRect.bottom - pt2.y)), TRUE); 
  1576. break;
  1577. case WM_PAINT:
  1578. skin->UpdateSize(hwnd);
  1579. skin->Display(hwnd, playback);
  1580. return 0;
  1581. break;
  1582. case WM_DROPFILES:
  1583. char lpFilename[256];
  1584. if(DragQueryFile( (HDROP) wParam, 0, lpFilename, 256) > 0)  {
  1585. OpenFileForPlaying(hwnd, lpFilename, INPUT_TYPE_FILE);
  1586. }
  1587. break;
  1588. }
  1589.   return DefWindowProc(hwnd, Message, wParam, lParam);
  1590. }