1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2003 VideoLAN
5 * $Id: win32_factory.cpp,v 1.1 2004/01/03 23:31:34 asmax Exp $
7 * Authors: Cyril Deguet <asmax@via.ecp.fr>
8 * Olivier Teulière <ipkiss@via.ecp.fr>
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.
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.
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., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
23 *****************************************************************************/
27 #include "win32_factory.hpp"
28 #include "win32_graphics.hpp"
29 #include "win32_timer.hpp"
30 #include "win32_window.hpp"
31 #include "win32_tooltip.hpp"
32 #include "win32_loop.hpp"
35 LRESULT CALLBACK Win32Proc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
37 // Get pointer to thread info: should only work with the parent window
38 intf_thread_t *p_intf = (intf_thread_t *)GetWindowLongPtr( hwnd,
41 // If doesn't exist, treat windows message normally
42 if( p_intf == NULL || p_intf->p_sys->p_osFactory == NULL )
44 return DefWindowProc( hwnd, uMsg, wParam, lParam );
47 // Here we know we are getting a message for the parent window, since it is
48 // the only one to store p_intf...
49 // Yes, it is a kludge :)
51 //Win32Factory *pFactory = (Win32Factory*)Win32Factory::instance( p_intf );
52 //msg_Err( p_intf, "Parent window %p %p %u %i\n", 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 )
57 if( uMsg == WM_SYSCOMMAND )
59 // If closing parent window
60 if( wParam == SC_CLOSE )
62 Win32Loop *pLoop = (Win32Loop*)Win32Loop::instance( p_intf );
68 msg_Err( p_intf, "WM_SYSCOMMAND %i", wParam );
70 // if( (Event *)wParam != NULL )
71 // ( (Event *)wParam )->SendEvent();
76 // If hwnd does not match any window or message not processed
77 return DefWindowProc( hwnd, uMsg, wParam, lParam );
81 Win32Factory::Win32Factory( intf_thread_t *pIntf ):
82 OSFactory( pIntf ), TransparentBlt( NULL ),
83 SetLayeredWindowAttributes( NULL )
89 bool Win32Factory::init()
91 // Get instance handle
92 m_hInst = GetModuleHandle( NULL );
95 msg_Err( getIntf(), "Cannot get module handle" );
98 // Create window class
99 WNDCLASS skinWindowClass;
100 skinWindowClass.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS;
101 skinWindowClass.lpfnWndProc = (WNDPROC) Win32Proc;
102 skinWindowClass.lpszClassName = "SkinWindowClass";
103 skinWindowClass.lpszMenuName = NULL;
104 skinWindowClass.cbClsExtra = 0;
105 skinWindowClass.cbWndExtra = 0;
106 skinWindowClass.hbrBackground = HBRUSH (COLOR_WINDOW);
107 skinWindowClass.hCursor = LoadCursor( NULL , IDC_ARROW );
108 skinWindowClass.hIcon = LoadIcon( m_hInst, "VLC_ICON" );
109 skinWindowClass.hInstance = m_hInst;
111 // Register class and check it
112 if( !RegisterClass( &skinWindowClass ) )
116 // Check why it failed. If it's because the class already exists
117 // then fine, otherwise return with an error.
118 if( !GetClassInfo( m_hInst, "SkinWindowClass", &wndclass ) )
120 msg_Err( getIntf(), "Cannot register window class" );
126 m_hParentWindow = CreateWindowEx( WS_EX_APPWINDOW, "SkinWindowClass",
127 "VLC Media Player", WS_SYSMENU, 0, 0, 0, 0, 0, 0,
129 if( m_hParentWindow == NULL )
131 msg_Err( getIntf(), "Cannot create parent window" );
135 // We do it this way otherwise CreateWindowEx will fail
136 // if WS_EX_LAYERED is not supported
137 SetWindowLongPtr( m_hParentWindow, GWL_EXSTYLE,
138 GetWindowLong( m_hParentWindow, GWL_EXSTYLE )
141 // Store with it a pointer to the interface thread
142 SetWindowLongPtr( m_hParentWindow, GWLP_USERDATA, (LONG_PTR)getIntf() );
143 ShowWindow( m_hParentWindow, SW_SHOW );
145 // Initialize the OLE library (for drag & drop)
146 OleInitialize( NULL );
148 // We dynamically load msimg32.dll to get a pointer to TransparentBlt()
149 m_hMsimg32 = LoadLibrary( "msimg32.dll" );
152 (BOOL (WINAPI*)(HDC, int, int, int, int,
153 HDC, int, int, int, int, unsigned int))
154 GetProcAddress( m_hMsimg32, "TransparentBlt" ) ) )
156 TransparentBlt = NULL;
157 msg_Dbg( getIntf(), "Couldn't find TransparentBlt(), "
158 "falling back to BitBlt()" );
161 // Idem for user32.dll and SetLayeredWindowAttributes()
162 m_hUser32 = LoadLibrary( "user32.dll" );
164 !( SetLayeredWindowAttributes =
165 (BOOL (WINAPI *)(HWND, COLORREF, BYTE, DWORD))
166 GetProcAddress( m_hUser32, "SetLayeredWindowAttributes" ) ) )
168 SetLayeredWindowAttributes = NULL;
169 msg_Dbg( getIntf(), "Couldn't find SetLayeredWindowAttributes()" );
177 Win32Factory::~Win32Factory()
179 // Uninitialize the OLE library
182 // Unload msimg32.dll and user32.dll
184 FreeLibrary( m_hMsimg32 );
186 FreeLibrary( m_hUser32 );
190 OSGraphics *Win32Factory::createOSGraphics( int width, int height )
192 return new Win32Graphics( getIntf(), width, height );
196 OSLoop *Win32Factory::getOSLoop()
198 return Win32Loop::instance( getIntf() );
202 void Win32Factory::destroyOSLoop()
204 Win32Loop::destroy( getIntf() );
208 OSTimer *Win32Factory::createOSTimer( const Callback &rCallback )
210 return new Win32Timer( getIntf(), rCallback, m_hParentWindow );
214 OSWindow *Win32Factory::createOSWindow( GenericWindow &rWindow, bool dragDrop,
217 return new Win32Window( getIntf(), rWindow, m_hInst, m_hParentWindow,
218 dragDrop, playOnDrop );
222 OSTooltip *Win32Factory::createOSTooltip()
224 return new Win32Tooltip( getIntf(), m_hInst, m_hParentWindow );
228 const string Win32Factory::getDirSeparator() const
234 int Win32Factory::getScreenWidth() const
236 return GetSystemMetrics(SM_CXSCREEN);
241 int Win32Factory::getScreenHeight() const
243 return GetSystemMetrics(SM_CYSCREEN);
247 Rect Win32Factory::getWorkArea() const
250 SystemParametersInfo( SPI_GETWORKAREA, 0, &r, 0 );
251 // Fill a Rect object
252 Rect rect( r.left, r.top, r.right, r.bottom );
257 void Win32Factory::getMousePos( int &rXPos, int &rYPos ) const
260 GetCursorPos( &mousePos );
266 void Win32Factory::rmDir( const string &rPath )
268 WIN32_FIND_DATA find;
270 string findFiles = rPath + "\\*";
271 HANDLE handle = FindFirstFile( findFiles.c_str(), &find );
273 while( handle != INVALID_HANDLE_VALUE )
275 // If file is neither "." nor ".."
276 if( strcmp( find.cFileName, "." ) && strcmp( find.cFileName, ".." ) )
279 file = rPath + "\\" + (string)find.cFileName;
281 // If file is a directory, delete it recursively
282 if( find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
286 // Else, it is a file so simply delete it
289 DeleteFile( file.c_str() );
293 // If no more file in directory, exit while
294 if( !FindNextFile( handle, &find ) )
298 // Now directory is empty so can be removed
300 RemoveDirectory( rPath.c_str() );