diff options
Diffstat (limited to 'plugins/FloatingContacts/src/filedrop.cpp')
| -rw-r--r-- | plugins/FloatingContacts/src/filedrop.cpp | 368 | 
1 files changed, 368 insertions, 0 deletions
diff --git a/plugins/FloatingContacts/src/filedrop.cpp b/plugins/FloatingContacts/src/filedrop.cpp new file mode 100644 index 0000000000..473c7a6814 --- /dev/null +++ b/plugins/FloatingContacts/src/filedrop.cpp @@ -0,0 +1,368 @@ +#include "stdhdr.h"
 +
 +static	void	ProcessDroppedItems	( char **ppDroppedItems, int nCount, char **ppFiles );
 +static	int		CountDroppedFiles	( char **ppDroppedItems, int nCount  );
 +static	BOOL	OnDropFiles			( HDROP hDrop, ThumbInfo *pThumb );
 +
 +HRESULT STDMETHODCALLTYPE CDropTarget::QueryInterface(REFIID riid,LPVOID *ppvObj)
 +{
 +	if ( IsEqualIID( riid, IID_IDropTarget )) 
 +	{
 +		*ppvObj = this;
 +		this->AddRef();
 +		return S_OK;
 +	}
 +	
 +	*ppvObj = NULL;
 +
 +	return ( E_NOINTERFACE );
 +}
 +
 +ULONG STDMETHODCALLTYPE CDropTarget::AddRef( )
 +{
 +	return ++this->refCount;
 +}
 +
 +ULONG STDMETHODCALLTYPE CDropTarget::Release( )
 +{
 +	int res = --this->refCount;
 +	if (!res) delete this;
 +	return res;
 +}
 +
 +
 +HRESULT STDMETHODCALLTYPE CDropTarget::DragOver( DWORD fKeyState, POINTL pt, DWORD *pdwEffect )
 +{
 +	*pdwEffect = 0;
 +	
 +	if ( hwndCurDrag == NULL ) 
 +	{
 +		*pdwEffect = DROPEFFECT_NONE;
 +	}
 +	else
 +	{
 +		*pdwEffect |= DROPEFFECT_COPY;
 +	}
 +	return S_OK;
 +}
 +
 +
 +HRESULT STDMETHODCALLTYPE CDropTarget::DragEnter( IDataObject *pData, DWORD fKeyState, POINTL pt, DWORD *pdwEffect)
 +{
 +	HWND		hwnd	 =  NULL;
 +	POINT		shortPt;
 +	FORMATETC	feFile	 =  { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
 +	FORMATETC	feText	 =  { CF_TEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
 +	ThumbInfo *pThumb;
 +
 +	if ( S_OK == pData->QueryGetData( &feFile ) ||
 +		 S_OK == pData->QueryGetData( &feText ))
 +	{
 +		shortPt.x	 =  pt.x; 
 +		shortPt.y	 =  pt.y;
 +		
 +		hwnd = WindowFromPoint( shortPt );
 +		
 +		if ( pThumb = thumbList.FindThumb( hwnd ))
 +		{
 +			hwndCurDrag = hwnd;
 +			pThumb->ThumbSelect( TRUE );
 +		}
 +	}
 +
 +	return DragOver( fKeyState, pt, pdwEffect);
 +}
 +
 +
 +HRESULT STDMETHODCALLTYPE CDropTarget::DragLeave( )
 +{
 +	ThumbInfo *pThumb = thumbList.FindThumb( hwndCurDrag );
 +
 +	if ( NULL != pThumb )
 +	{
 +		pThumb->ThumbDeselect( TRUE );
 +	}
 +
 +	hwndCurDrag = NULL;
 +	
 +	return S_OK;
 +}
 +
 +
 +HRESULT STDMETHODCALLTYPE CDropTarget::Drop( IDataObject *pData,DWORD fKeyState,POINTL pt,DWORD *pdwEffect)
 +{
 +	FORMATETC	fe		 =  { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
 +	STGMEDIUM	stg;
 +	HDROP		hDrop		 =  NULL;
 +	ThumbInfo	*pThumb		 =  NULL;
 +	char		*pText		 =  NULL;
 +	BOOL		bFormatText = FALSE;
 +
 +	*pdwEffect = DROPEFFECT_NONE;
 +	
 +
 +	if ( hwndCurDrag == NULL ) return( S_OK );
 +
 +	pThumb	 =  (ThumbInfo*)GetWindowLongPtr( hwndCurDrag, GWLP_USERDATA );
 +	if ( pThumb == NULL ) return( S_OK );
 +
 +	if ( S_OK != pData->GetData( &fe,&stg ))
 +	{
 +		fe.cfFormat = CF_TEXT;
 +
 +		if ( S_OK != pData->GetData( &fe,&stg ))
 +		{
 +			return( S_OK );
 +		}
 +		else
 +		{
 +			bFormatText = TRUE;
 +		}
 +	}
 +		
 +	
 +
 +	if ( !bFormatText )
 +	{
 +		hDrop	 =  (HDROP)stg.hGlobal;
 +		
 +		if ( hDrop != NULL )
 +		{
 +			OnDropFiles( hDrop, pThumb );
 +		}
 +	}
 +	else
 +	{
 +		pText = (char*)GlobalLock( stg.hGlobal );
 +
 +		if ( pText != NULL  )
 +		{
 +			SendMsgDialog( hwndCurDrag, pText );
 +			GlobalUnlock( stg.hGlobal );
 +		}
 +	}
 +
 +	if ( stg.pUnkForRelease != NULL )
 +	{
 +		stg.pUnkForRelease->Release( );
 +	}
 +	else 
 +	{
 +		GlobalFree( stg.hGlobal );
 +	}
 +
 +	DragLeave( );
 +	
 +	return S_OK;
 +}
 +
 +///////////////////////////////////////////////////////
 +// Send files processing
 +
 +BOOL OnDropFiles( HDROP hDrop, ThumbInfo *pThumb )
 +{
 +	BOOL	bSuccess			 =  FALSE;
 +	UINT	nFilesCount			 =  0;
 +	UINT	iItem				 =  0;
 +	char	**ppFiles			 =  NULL;	
 +	char	**ppDroppedItems	 =  NULL;
 +	UINT	nDroppedItemsCount	 =  0;
 +	char	szFilename[ MAX_PATH ];
 +	
 +
 +	nDroppedItemsCount = DragQueryFile( hDrop, 0xFFFFFFFF, NULL, 0 );
 +
 +	ppDroppedItems = ( char** )malloc( sizeof(char*)*( nDroppedItemsCount + 1 ));
 +	
 +	if ( ppDroppedItems == NULL )
 +	{
 +		return( FALSE );
 +	}
 +
 +	ppDroppedItems[ nDroppedItemsCount ] = NULL;
 +	
 +	for ( iItem = 0; iItem < nDroppedItemsCount; ++iItem ) 
 +	{
 +		DragQueryFileA( hDrop, iItem, szFilename, sizeof( szFilename ));
 +		ppDroppedItems[ iItem ] = _strdup( szFilename );
 +	}
 +	
 +	nFilesCount = CountDroppedFiles( ppDroppedItems, nDroppedItemsCount );
 +	
 +	ppFiles = ( char** )malloc( sizeof( char *)* ( nFilesCount+1 ));
 +	
 +	if ( ppFiles == NULL )
 +	{
 +		return( FALSE );
 +	}
 +	
 +	ppFiles[ nFilesCount] = NULL;
 +
 +	ProcessDroppedItems( ppDroppedItems, nDroppedItemsCount, ppFiles );
 +
 +	bSuccess = (BOOL)CallService( MS_CLIST_CONTACTFILESDROPPED, (WPARAM)pThumb->hContact, (LPARAM)ppFiles ); 
 +
 +	// Cleanup
 +	for ( iItem = 0; ppDroppedItems[ iItem ]; ++iItem ) 
 +	{
 +		free( ppDroppedItems[ iItem ] );
 +	}
 +
 +	free( ppDroppedItems );
 +
 +	for ( iItem = 0; iItem < nFilesCount ; ++iItem ) 
 +	{
 +		free( ppFiles[ iItem ] );
 +	}
 +
 +	free( ppFiles );
 +
 +	return( bSuccess );
 +}
 +
 +
 +static int CountFiles( char *szItem )
 +{
 +	int nCount = 0;
 +	WIN32_FIND_DATAA	fd;
 +	
 +	HANDLE hFind = FindFirstFileA( szItem, &fd );
 +
 +	if ( hFind != INVALID_HANDLE_VALUE )
 +	{
 +		do
 +		{
 +			if ( fd.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY )
 +			{
 +				// Skip parent directories
 +				if ( ( 0 != strcmp( fd.cFileName, "." )) &&
 +					 ( 0 != strcmp( fd.cFileName, ".." )) )
 +				{
 +					char szDirName[ MAX_PATH ];
 +					strncpy( szDirName, szItem, MAX_PATH - 1 );
 +
 +					if ( NULL != strstr( szItem, "*.*" ))
 +					{
 +						sprintf( szDirName + strlen( szDirName ) - 3, "%s\0", fd.cFileName );
 +					}
 +					
 +					++nCount;
 +					strcat( szDirName, "\\*.*" );
 +					nCount += CountFiles( szDirName );
 +				}
 +			}
 +			else
 +			{
 +				++nCount;
 +			}
 +		}
 +		while( FALSE != FindNextFileA( hFind, &fd ));
 +	}
 +
 +	return( nCount );
 +}
 +
 +
 +
 +static void SaveFiles( char *szItem, char **ppFiles, int *pnCount )
 +{
 +	
 +	WIN32_FIND_DATAA	fd;
 +
 +	HANDLE hFind = FindFirstFileA( szItem, &fd );
 +
 +	if ( hFind != INVALID_HANDLE_VALUE )
 +	{
 +		do
 +		{
 +			if ( fd.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY )
 +			{
 +				// Skip parent directories
 +				if ( ( 0 != strcmp( fd.cFileName, "." )) &&
 +					 ( 0 != strcmp( fd.cFileName, ".." )) )
 +				{
 +					char szDirName[ MAX_PATH ];
 +					strncpy( szDirName, szItem, MAX_PATH - 1 );
 +
 +					if ( NULL != strstr( szItem, "*.*" ))
 +					{
 +						sprintf( szDirName + strlen( szDirName ) - 3, "%s\0", fd.cFileName );
 +					}
 +					
 +					ppFiles[ *pnCount ] = _strdup( szDirName );
 +					++( *pnCount );
 +
 +					strcat( szDirName, "\\*.*" );
 +					SaveFiles( szDirName, ppFiles, pnCount );
 +					
 +				}
 +			}
 +			else
 +			{
 +				int	 nSize = sizeof(char) * ( strlen( szItem ) + strlen( fd.cFileName ) + sizeof( char ));
 +				char *szFile = (char*) malloc( nSize ) ;
 +				
 +				strncpy( szFile, szItem, nSize - 1 ); 
 +				
 +				if ( NULL != strstr( szFile, "*.*" ))
 +				{
 +					szFile[ strlen( szFile ) - 3 ] = '\0';
 +					strncat( szFile, fd.cFileName, MAX_PATH - 1 );
 +				}
 +								
 +				ppFiles[ *pnCount ] = szFile;
 +				++( *pnCount );
 +			}
 +		}
 +		while( FALSE != FindNextFileA( hFind, &fd ));
 +	}
 +}
 +
 +
 +static void ProcessDroppedItems( char **ppDroppedItems, int nCount, char **ppFiles  )
 +{
 +	int i;
 +	int fileCount = 0;
 +
 +	for ( i = 0; i < nCount; ++i )
 +	{
 +		SaveFiles( ppDroppedItems[ i ], ppFiles, &fileCount );
 +	}
 +}
 +
 +
 +static int CountDroppedFiles( char **ppDroppedItems, int nCount  )
 +{
 +	int fileCount = 0;
 +	int i;
 +	
 +	for ( i = 0; i < nCount; ++i )
 +	{
 +		fileCount += CountFiles( ppDroppedItems[ i ] );
 +	}
 +
 +	return( fileCount );
 +}
 +
 +
 +///////////////////////////////////////////////////////////////////////////////
 +// Init/destroy
 +void InitFileDropping()
 +{
 +	OleInitialize( NULL );
 +}
 +
 +void FreeFileDropping(void)
 +{
 +	OleUninitialize();
 +}
 +
 +void RegisterFileDropping( HWND hwnd, CDropTarget* pdropTarget )
 +{
 +	RegisterDragDrop( hwnd, (IDropTarget*)pdropTarget );
 +}
 +
 +void UnregisterFileDropping( HWND hwnd )
 +{
 +	RevokeDragDrop( hwnd );
 +}
  | 
