summaryrefslogtreecommitdiff
path: root/plugins/FloatingContacts/src/filedrop.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/FloatingContacts/src/filedrop.cpp')
-rw-r--r--plugins/FloatingContacts/src/filedrop.cpp368
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 );
+}