mirror of
https://github.com/nillerusr/source-engine.git
synced 2024-12-22 14:16:50 +00:00
170 lines
3.5 KiB
C++
170 lines
3.5 KiB
C++
//========= Copyright Valve Corporation, All rights reserved. ============//
|
|
//
|
|
// Purpose:
|
|
//
|
|
//=============================================================================
|
|
|
|
#include "clipboardmanager.h"
|
|
#include "datamodel.h"
|
|
#include "tier1/KeyValues.h"
|
|
|
|
#ifdef _WIN32
|
|
#define USE_WINDOWS_CLIPBOARD
|
|
#endif
|
|
|
|
#if defined( USE_WINDOWS_CLIPBOARD )
|
|
#include <windows.h>
|
|
#endif
|
|
|
|
CClipboardManager::CClipboardManager( ) :
|
|
m_pfnCleanup( NULL )
|
|
{
|
|
}
|
|
|
|
CClipboardManager::~CClipboardManager()
|
|
{
|
|
EmptyClipboard( false );
|
|
}
|
|
|
|
void CClipboardManager::EmptyClipboard( bool bClearWindowsClipboard )
|
|
{
|
|
// Call optional cleanup function if there is one...
|
|
if ( m_pfnCleanup )
|
|
{
|
|
m_pfnCleanup->ReleaseClipboardData( m_Data );
|
|
}
|
|
int c = m_Data.Count();
|
|
for ( int i = 0; i < c; ++i )
|
|
{
|
|
m_Data[ i ]->deleteThis();
|
|
}
|
|
m_Data.RemoveAll();
|
|
m_pfnCleanup = NULL;
|
|
|
|
#if defined( USE_WINDOWS_CLIPBOARD )
|
|
if ( bClearWindowsClipboard )
|
|
{
|
|
if ( ::OpenClipboard( ::GetDesktopWindow() ) )
|
|
{
|
|
::EmptyClipboard();
|
|
::CloseClipboard();
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void CClipboardManager::SetClipboardData( CUtlVector< KeyValues * >& data, IClipboardCleanup *pfnOptionalCleanuFunction )
|
|
{
|
|
EmptyClipboard( true );
|
|
m_Data = data;
|
|
m_pfnCleanup = pfnOptionalCleanuFunction;
|
|
|
|
#if defined( USE_WINDOWS_CLIPBOARD )
|
|
if ( m_Data.Count() >= 0 )
|
|
{
|
|
// Only stick the first item's data into the clipboard
|
|
char const *text = m_Data[ 0 ]->GetString( "text", "" );
|
|
if ( text && text[ 0 ] )
|
|
{
|
|
int textLen = Q_strlen( text );
|
|
|
|
if ( ::OpenClipboard( ::GetDesktopWindow() ) )
|
|
{
|
|
HANDLE hmem = ::GlobalAlloc(GMEM_MOVEABLE, textLen + 1);
|
|
if (hmem)
|
|
{
|
|
void *ptr = ::GlobalLock( hmem );
|
|
if ( ptr )
|
|
{
|
|
Q_memset( ptr, 0, textLen + 1 );
|
|
Q_memcpy( ptr, text, textLen );
|
|
::GlobalUnlock( hmem );
|
|
|
|
::SetClipboardData( CF_TEXT, hmem );
|
|
}
|
|
}
|
|
::CloseClipboard();
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void CClipboardManager::AddToClipboardData( KeyValues *add )
|
|
{
|
|
m_Data.AddToTail( add );
|
|
#if defined( USE_WINDOWS_CLIPBOARD )
|
|
if ( m_Data.Count() >= 0 )
|
|
{
|
|
// Only stick the first item's data into the clipboard
|
|
char const *text = m_Data[ 0 ]->GetString( "text", "" );
|
|
if ( text && text[ 0 ] )
|
|
{
|
|
int textLen = Q_strlen( text );
|
|
|
|
|
|
if ( ::OpenClipboard( ::GetDesktopWindow() ) )
|
|
{
|
|
::EmptyClipboard();
|
|
|
|
HANDLE hmem = ::GlobalAlloc(GMEM_MOVEABLE, textLen + 1);
|
|
if (hmem)
|
|
{
|
|
void *ptr = ::GlobalLock( hmem );
|
|
if ( ptr )
|
|
{
|
|
Q_memset( ptr, 0, textLen + 1 );
|
|
Q_memcpy( ptr, text, textLen );
|
|
::GlobalUnlock( hmem );
|
|
|
|
::SetClipboardData( CF_TEXT, hmem );
|
|
}
|
|
}
|
|
::CloseClipboard();
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void CClipboardManager::GetClipboardData( CUtlVector< KeyValues * >& data )
|
|
{
|
|
data.RemoveAll();
|
|
data = m_Data;
|
|
#if defined( USE_WINDOWS_CLIPBOARD )
|
|
if ( data.Count() == 0 )
|
|
{
|
|
// See if windows has some text since we didn't have any internally
|
|
if ( ::OpenClipboard( ::GetDesktopWindow() ) )
|
|
{
|
|
HANDLE hmem = ::GetClipboardData( CF_TEXT );
|
|
if ( hmem )
|
|
{
|
|
int len = GlobalSize( hmem );
|
|
if ( len > 0 )
|
|
{
|
|
void *ptr = GlobalLock(hmem);
|
|
if ( ptr )
|
|
{
|
|
char buf[ 8192 ];
|
|
len = min( len, 8191 );
|
|
Q_memcpy( buf, ( char * )ptr, len );
|
|
buf[ 8191 ] = 0;
|
|
GlobalUnlock(hmem);
|
|
|
|
KeyValues *newData = new KeyValues( "ClipBoard", "text", buf );
|
|
data.AddToTail( newData );
|
|
}
|
|
}
|
|
}
|
|
::CloseClipboard();
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
bool CClipboardManager::HasClipboardData() const
|
|
{
|
|
return m_Data.Count() > 0 ? true : false;
|
|
}
|