win32_factory.cpp
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:13k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * win32_factory.cpp
  3.  *****************************************************************************
  4.  * Copyright (C) 2003 the VideoLAN team
  5.  * $Id: 47d4556c90c21e65b974f02dfdafa542f7ef98f1 $
  6.  *
  7.  * Authors: Cyril Deguet     <asmax@via.ecp.fr>
  8.  *          Olivier Teulière <ipkiss@via.ecp.fr>
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 2 of the License, or
  13.  * (at your option) any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to the Free Software
  22.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  23.  *****************************************************************************/
  24. #ifdef WIN32_SKINS
  25. #include "win32_factory.hpp"
  26. #include "win32_graphics.hpp"
  27. #include "win32_timer.hpp"
  28. #include "win32_window.hpp"
  29. #include "win32_tooltip.hpp"
  30. #include "win32_popup.hpp"
  31. #include "win32_loop.hpp"
  32. #include "../src/theme.hpp"
  33. #include "../src/window_manager.hpp"
  34. #include "../commands/cmd_dialogs.hpp"
  35. #include "../commands/cmd_minimize.hpp"
  36. // Custom message for the notifications of the system tray
  37. #define MY_WM_TRAYACTION (WM_APP + 1)
  38. LRESULT CALLBACK Win32Proc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
  39. {
  40.     // Get pointer to thread info: should only work with the parent window
  41.     intf_thread_t *p_intf = (intf_thread_t *)GetWindowLongPtr( hwnd,
  42.         GWLP_USERDATA );
  43.     // If doesn't exist, treat windows message normally
  44.     if( p_intf == NULL || p_intf->p_sys->p_osFactory == NULL )
  45.     {
  46.         return DefWindowProc( hwnd, uMsg, wParam, lParam );
  47.     }
  48.     // Here we know we are getting a message for the parent window, since it is
  49.     // the only one to store p_intf...
  50.     // Yes, it is a kludge :)
  51. //Win32Factory *pFactory = (Win32Factory*)Win32Factory::instance( p_intf );
  52. //msg_Err( p_intf, "Parent window %p %p %u %in", pFactory->m_hParentWindow, hwnd, uMsg, wParam );
  53.     // If Window is parent window
  54.     // XXX: this test isn't needed, see the kludge above...
  55. //    if( hwnd == pFactory->m_hParentWindow )
  56.     {
  57.         if( uMsg == WM_SYSCOMMAND )
  58.         {
  59.             // If closing parent window
  60.             if( wParam == SC_CLOSE )
  61.             {
  62.                 Win32Loop *pLoop = (Win32Loop*)Win32Loop::instance( p_intf );
  63.                 pLoop->exit();
  64.                 return 0;
  65.             }
  66.             else
  67.             {
  68.                 msg_Dbg( p_intf, "WM_SYSCOMMAND %i", wParam );
  69.             }
  70.         }
  71.         // Handle systray notifications
  72.         else if( uMsg == MY_WM_TRAYACTION )
  73.         {
  74.             if( (UINT)lParam == WM_LBUTTONDOWN )
  75.             {
  76.                 p_intf->p_sys->p_theme->getWindowManager().raiseAll();
  77.             }
  78.             else if( (UINT)lParam == WM_RBUTTONDOWN )
  79.             {
  80.                 CmdDlgShowPopupMenu aCmdPopup( p_intf );
  81.                 aCmdPopup.execute();
  82.             }
  83.             else if( (UINT)lParam == WM_LBUTTONDBLCLK )
  84.             {
  85.                 CmdRestore aCmdRestore( p_intf );
  86.                 aCmdRestore.execute();
  87.             }
  88.         }
  89.     }
  90.     // If hwnd does not match any window or message not processed
  91.     return DefWindowProc( hwnd, uMsg, wParam, lParam );
  92. }
  93. Win32Factory::Win32Factory( intf_thread_t *pIntf ):
  94.     OSFactory( pIntf ), TransparentBlt( NULL ), AlphaBlend( NULL ),
  95.     SetLayeredWindowAttributes( NULL ), m_hParentWindow( NULL ),
  96.     m_dirSep( "\" )
  97. {
  98.     // see init()
  99. }
  100. bool Win32Factory::init()
  101. {
  102.     // Get instance handle
  103.     m_hInst = GetModuleHandle( NULL );
  104.     if( m_hInst == NULL )
  105.     {
  106.         msg_Err( getIntf(), "Cannot get module handle" );
  107.     }
  108.     // Create window class
  109.     WNDCLASS skinWindowClass;
  110.     skinWindowClass.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS;
  111.     skinWindowClass.lpfnWndProc = (WNDPROC) Win32Proc;
  112.     skinWindowClass.lpszClassName = _T("SkinWindowClass");
  113.     skinWindowClass.lpszMenuName = NULL;
  114.     skinWindowClass.cbClsExtra = 0;
  115.     skinWindowClass.cbWndExtra = 0;
  116.     skinWindowClass.hbrBackground = NULL;
  117.     skinWindowClass.hCursor = LoadCursor( NULL , IDC_ARROW );
  118.     skinWindowClass.hIcon = LoadIcon( m_hInst, _T("VLC_ICON") );
  119.     skinWindowClass.hInstance = m_hInst;
  120.     // Register class and check it
  121.     if( !RegisterClass( &skinWindowClass ) )
  122.     {
  123.         WNDCLASS wndclass;
  124.         // Check why it failed. If it's because the class already exists
  125.         // then fine, otherwise return with an error.
  126.         if( !GetClassInfo( m_hInst, _T("SkinWindowClass"), &wndclass ) )
  127.         {
  128.             msg_Err( getIntf(), "cannot register window class" );
  129.             return false;
  130.         }
  131.     }
  132.     // Create Window
  133.     m_hParentWindow = CreateWindowEx( WS_EX_TOOLWINDOW, _T("SkinWindowClass"),
  134.         _T("VLC media player"), WS_SYSMENU|WS_POPUP,
  135.         -200, -200, 0, 0, 0, 0, m_hInst, 0 );
  136.     if( m_hParentWindow == NULL )
  137.     {
  138.         msg_Err( getIntf(), "cannot create parent window" );
  139.         return false;
  140.     }
  141.     // Store with it a pointer to the interface thread
  142.     SetWindowLongPtr( m_hParentWindow, GWLP_USERDATA, (LONG_PTR)getIntf() );
  143.     // We do it this way otherwise CreateWindowEx will fail
  144.     // if WS_EX_LAYERED is not supported
  145.     SetWindowLongPtr( m_hParentWindow, GWL_EXSTYLE,
  146.                       GetWindowLong( m_hParentWindow, GWL_EXSTYLE ) |
  147.                       WS_EX_LAYERED );
  148.     ShowWindow( m_hParentWindow, SW_SHOW );
  149.     // Initialize the systray icon
  150.     m_trayIcon.cbSize = sizeof( NOTIFYICONDATA );
  151.     m_trayIcon.hWnd = m_hParentWindow;
  152.     m_trayIcon.uID = 42;
  153.     m_trayIcon.uFlags = NIF_ICON|NIF_TIP|NIF_MESSAGE;
  154.     m_trayIcon.uCallbackMessage = MY_WM_TRAYACTION;
  155.     m_trayIcon.hIcon = LoadIcon( m_hInst, _T("VLC_ICON") );
  156.     strcpy( m_trayIcon.szTip, "VLC media player" );
  157.     // Show the systray icon if needed
  158.     if( config_GetInt( getIntf(), "skins2-systray" ) )
  159.     {
  160.         addInTray();
  161.     }
  162.     // Show the task in the task bar if needed
  163.     if( config_GetInt( getIntf(), "skins2-taskbar" ) )
  164.     {
  165.         addInTaskBar();
  166.     }
  167.     // Initialize the OLE library (for drag & drop)
  168.     OleInitialize( NULL );
  169.     // We dynamically load msimg32.dll to get a pointer to TransparentBlt()
  170.     m_hMsimg32 = LoadLibrary( _T("msimg32.dll") );
  171.     if( !m_hMsimg32 ||
  172.         !( TransparentBlt =
  173.             (BOOL (WINAPI*)(HDC, int, int, int, int,
  174.                             HDC, int, int, int, int, unsigned int))
  175.             GetProcAddress( m_hMsimg32, _T("TransparentBlt") ) ) )
  176.     {
  177.         TransparentBlt = NULL;
  178.         msg_Dbg( getIntf(), "couldn't find TransparentBlt(), "
  179.                  "falling back to BitBlt()" );
  180.     }
  181.     if( !m_hMsimg32 ||
  182.         !( AlphaBlend =
  183.             (BOOL (WINAPI*)( HDC, int, int, int, int, HDC, int, int,
  184.                               int, int, BLENDFUNCTION ))
  185.             GetProcAddress( m_hMsimg32, _T("AlphaBlend") ) ) )
  186.     {
  187.         AlphaBlend = NULL;
  188.         msg_Dbg( getIntf(), "couldn't find AlphaBlend()" );
  189.     }
  190.     // Idem for user32.dll and SetLayeredWindowAttributes()
  191.     m_hUser32 = LoadLibrary( _T("user32.dll") );
  192.     if( !m_hUser32 ||
  193.         !( SetLayeredWindowAttributes =
  194.             (BOOL (WINAPI *)(HWND, COLORREF, BYTE, DWORD))
  195.             GetProcAddress( m_hUser32, _T("SetLayeredWindowAttributes") ) ) )
  196.     {
  197.         SetLayeredWindowAttributes = NULL;
  198.         msg_Dbg( getIntf(), "couldn't find SetLayeredWindowAttributes()" );
  199.     }
  200.     // Initialize the resource path
  201.     char *datadir = config_GetUserDataDir();
  202.     m_resourcePath.push_back( (string)datadir + "\skins" );
  203.     free( datadir );
  204.     m_resourcePath.push_back( (string)config_GetDataDir() +
  205.                               "\skins" );
  206.     m_resourcePath.push_back( (string)config_GetDataDir() +
  207.                               "\skins2" );
  208.     m_resourcePath.push_back( (string)config_GetDataDir() +
  209.                               "\share\skins" );
  210.     m_resourcePath.push_back( (string)config_GetDataDir() +
  211.                               "\share\skins2" );
  212.     // All went well
  213.     return true;
  214. }
  215. Win32Factory::~Win32Factory()
  216. {
  217.     // Uninitialize the OLE library
  218.     OleUninitialize();
  219.     // Remove the systray icon
  220.     removeFromTray();
  221.     if( m_hParentWindow ) DestroyWindow( m_hParentWindow );
  222.     // Unload msimg32.dll and user32.dll
  223.     if( m_hMsimg32 )
  224.         FreeLibrary( m_hMsimg32 );
  225.     if( m_hUser32 )
  226.         FreeLibrary( m_hUser32 );
  227. }
  228. OSGraphics *Win32Factory::createOSGraphics( int width, int height )
  229. {
  230.     return new Win32Graphics( getIntf(), width, height );
  231. }
  232. OSLoop *Win32Factory::getOSLoop()
  233. {
  234.     return Win32Loop::instance( getIntf() );
  235. }
  236. void Win32Factory::destroyOSLoop()
  237. {
  238.     Win32Loop::destroy( getIntf() );
  239. }
  240. void Win32Factory::minimize()
  241. {
  242.     /* Make sure no tooltip is visible first */
  243.     getIntf()->p_sys->p_theme->getWindowManager().hideTooltip();
  244.     ShowWindow( m_hParentWindow, SW_MINIMIZE );
  245. }
  246. void Win32Factory::restore()
  247. {
  248.     ShowWindow( m_hParentWindow, SW_RESTORE );
  249. }
  250. void Win32Factory::addInTray()
  251. {
  252.     Shell_NotifyIcon( NIM_ADD, &m_trayIcon );
  253. }
  254. void Win32Factory::removeFromTray()
  255. {
  256.     Shell_NotifyIcon( NIM_DELETE, &m_trayIcon );
  257. }
  258. void Win32Factory::addInTaskBar()
  259. {
  260.     ShowWindow( m_hParentWindow, SW_HIDE );
  261.     SetWindowLongPtr( m_hParentWindow, GWL_EXSTYLE,
  262.                       WS_EX_LAYERED|WS_EX_APPWINDOW );
  263.     ShowWindow( m_hParentWindow, SW_SHOW );
  264. }
  265. void Win32Factory::removeFromTaskBar()
  266. {
  267.     ShowWindow( m_hParentWindow, SW_HIDE );
  268.     SetWindowLongPtr( m_hParentWindow, GWL_EXSTYLE,
  269.                       WS_EX_LAYERED|WS_EX_TOOLWINDOW );
  270.     ShowWindow( m_hParentWindow, SW_SHOW );
  271. }
  272. OSTimer *Win32Factory::createOSTimer( CmdGeneric &rCmd )
  273. {
  274.     return new Win32Timer( getIntf(), rCmd, m_hParentWindow );
  275. }
  276. OSWindow *Win32Factory::createOSWindow( GenericWindow &rWindow, bool dragDrop,
  277.                                         bool playOnDrop, OSWindow *pParent )
  278. {
  279.     return new Win32Window( getIntf(), rWindow, m_hInst, m_hParentWindow,
  280.                             dragDrop, playOnDrop, (Win32Window*)pParent );
  281. }
  282. OSTooltip *Win32Factory::createOSTooltip()
  283. {
  284.     return new Win32Tooltip( getIntf(), m_hInst, m_hParentWindow );
  285. }
  286. OSPopup *Win32Factory::createOSPopup()
  287. {
  288.     // XXX FIXME: this way of getting the handle really sucks!
  289.     // In fact, the clean way would be to have in Builder::addPopup() a call
  290.     // to pPopup->associateToWindow() (to be written)... but the problem is
  291.     // that there is no way to access the OS-dependent window handle from a
  292.     // GenericWindow (we cannot even access the OSWindow).
  293.     if( m_windowMap.begin() == m_windowMap.end() )
  294.     {
  295.         msg_Err( getIntf(), "no window has been created before the popup!" );
  296.         return NULL;
  297.     }
  298.     return new Win32Popup( getIntf(), m_windowMap.begin()->first );
  299. }
  300. int Win32Factory::getScreenWidth() const
  301. {
  302.     return GetSystemMetrics(SM_CXSCREEN);
  303. }
  304. int Win32Factory::getScreenHeight() const
  305. {
  306.     return GetSystemMetrics(SM_CYSCREEN);
  307. }
  308. SkinsRect Win32Factory::getWorkArea() const
  309. {
  310.     RECT r;
  311.     SystemParametersInfo( SPI_GETWORKAREA, 0, &r, 0 );
  312.     // Fill a Rect object
  313.     return  SkinsRect( r.left, r.top, r.right, r.bottom );
  314. }
  315. void Win32Factory::getMousePos( int &rXPos, int &rYPos ) const
  316. {
  317.     POINT mousePos;
  318.     GetCursorPos( &mousePos );
  319.     rXPos = mousePos.x;
  320.     rYPos = mousePos.y;
  321. }
  322. void Win32Factory::changeCursor( CursorType_t type ) const
  323. {
  324.     LPCTSTR id;
  325.     switch( type )
  326.     {
  327.         case kDefaultArrow:
  328.             id = IDC_ARROW;
  329.             break;
  330.         case kResizeNWSE:
  331.             id = IDC_SIZENWSE;
  332.             break;
  333.         case kResizeNS:
  334.             id = IDC_SIZENS;
  335.             break;
  336.         case kResizeWE:
  337.             id = IDC_SIZEWE;
  338.             break;
  339.         case kResizeNESW:
  340.             id = IDC_SIZENESW;
  341.             break;
  342.         default:
  343.             id = IDC_ARROW;
  344.             break;
  345.     }
  346.     HCURSOR hCurs = LoadCursor( NULL, id );
  347.     SetCursor( hCurs );
  348. }
  349. void Win32Factory::rmDir( const string &rPath )
  350. {
  351.     WIN32_FIND_DATA find;
  352.     string file;
  353.     string findFiles = rPath + "\*";
  354.     HANDLE handle    = FindFirstFile( findFiles.c_str(), &find );
  355.     while( handle != INVALID_HANDLE_VALUE )
  356.     {
  357.         // If file is neither "." nor ".."
  358.         if( strcmp( find.cFileName, "." ) && strcmp( find.cFileName, ".." ) )
  359.         {
  360.             // Set file name
  361.             file = rPath + "\" + (string)find.cFileName;
  362.             // If file is a directory, delete it recursively
  363.             if( find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
  364.             {
  365.                 rmDir( file );
  366.             }
  367.             // Else, it is a file so simply delete it
  368.             else
  369.             {
  370.                 DeleteFile( file.c_str() );
  371.             }
  372.         }
  373.         // If no more file in directory, exit while
  374.         if( !FindNextFile( handle, &find ) )
  375.             break;
  376.     }
  377.     // Now directory is empty so can be removed
  378.     FindClose( handle );
  379.     RemoveDirectory( rPath.c_str() );
  380. }
  381. #endif