fixed up , and added more functionality

This commit is contained in:
rods%netscape.com 1999-03-23 21:26:41 +00:00
Родитель 42edd3c5f4
Коммит a12004d678
5 изменённых файлов: 312 добавлений и 172 удалений

Просмотреть файл

@ -25,11 +25,18 @@
#include "nsIClipboardOwner.h"
#include "nsIDataFlavor.h"
#include "nsIWidget.h"
#include "nsIComponentManager.h"
#include "nsWidgetsCID.h"
#include "DDCOMM.h"
// interface definitions
static NS_DEFINE_IID(kIDataFlavorIID, NS_IDATAFLAVOR_IID);
static NS_DEFINE_IID(kIWidgetIID, NS_IWIDGET_IID);
static NS_DEFINE_IID(kWindowCID, NS_WINDOW_CID);
NS_IMPL_ADDREF(nsClipboard)
NS_IMPL_RELEASE(nsClipboard)
@ -41,8 +48,15 @@ NS_IMPL_RELEASE(nsClipboard)
nsClipboard::nsClipboard()
{
NS_INIT_REFCNT();
mTransferable = nsnull;
mDataObj = nsnull;
mClipboardOwner = nsnull;
mTransferable = nsnull;
mDataObj = nsnull;
mIgnoreEmptyNotification = PR_FALSE;
// Create a Native window for the shell container...
//nsresult rv = nsComponentManager::CreateInstance(kWindowCID, nsnull, kIWidgetIID, (void**)&mWindow);
//mWindow->Show(PR_FALSE);
//mWindow->Resize(1,1,PR_FALSE);
}
//-------------------------------------------------------------------------
@ -52,9 +66,13 @@ nsClipboard::nsClipboard()
//-------------------------------------------------------------------------
nsClipboard::~nsClipboard()
{
NS_IF_RELEASE(mWindow);
EmptyClipboard();
if (nsnull != mDataObj) {
mDataObj->Release();
}
}
/**
@ -89,26 +107,35 @@ nsresult nsClipboard::QueryInterface(const nsIID& aIID, void** aInstancePtr)
*/
NS_IMETHODIMP nsClipboard::SetTransferable(nsITransferable * aTransferable, nsIClipboardOwner * anOwner)
{
if (nsnull != mClipboardOwner) {
mClipboardOwner->LosingOwnership(mTransferable);
NS_RELEASE(mClipboardOwner);
if (aTransferable == mTransferable && anOwner == mClipboardOwner) {
return NS_OK;
}
EmptyClipboard();
mClipboardOwner = anOwner;
if (nsnull != anOwner) {
NS_ADDREF(mClipboardOwner);
}
if (nsnull != mTransferable) {
NS_RELEASE(mTransferable);
}
mTransferable = aTransferable;
if (nsnull == mTransferable) {
return NS_OK;
if (nsnull != mTransferable) {
NS_ADDREF(mTransferable);
}
NS_ADDREF(mTransferable);
return NS_OK;
}
/**
* Gets the transferable object
*
*/
NS_IMETHODIMP nsClipboard::GetTransferable(nsITransferable ** aTransferable)
{
*aTransferable = mTransferable;
if (nsnull != mTransferable) {
NS_ADDREF(mTransferable);
}
return NS_OK;
}
@ -119,6 +146,8 @@ NS_IMETHODIMP nsClipboard::SetTransferable(nsITransferable * aTransferable, nsIC
*/
NS_IMETHODIMP nsClipboard::SetClipboard()
{
mIgnoreEmptyNotification = PR_TRUE;
// make sure we have a good transferable
if (nsnull == mTransferable) {
return NS_ERROR_FAILURE;
@ -182,6 +211,8 @@ NS_IMETHODIMP nsClipboard::SetClipboard()
IDataObject * ido = (IDataObject *)mDataObj;
::OleSetClipboard(ido);
mIgnoreEmptyNotification = PR_FALSE;
return NS_OK;
}
@ -189,14 +220,15 @@ NS_IMETHODIMP nsClipboard::SetClipboard()
*
*
*/
static nsresult GetNativeDataOffClipboard(UINT aFormat, void ** aData, PRUint32 * aLen)
static nsresult GetNativeDataOffClipboard(nsIWidget * aWindow, UINT aFormat, void ** aData, PRUint32 * aLen)
{
HGLOBAL hglb;
LPSTR lpStr;
nsresult result = NS_ERROR_FAILURE;
DWORD dataSize;
if (::OpenClipboard(NULL)) { // Just Grab TEXT for now, later we will grab HTML, XIF, etc.
HWND nativeWin = nsnull;//(HWND)aWindow->GetNativeData(NS_NATIVE_WINDOW);
if (::OpenClipboard(nativeWin)) {
hglb = ::GetClipboardData(aFormat);
if (hglb != NULL) {
lpStr = (LPSTR)::GlobalLock(hglb);
@ -214,12 +246,55 @@ static nsresult GetNativeDataOffClipboard(UINT aFormat, void ** aData, PRUint32
*aData = data;
result = NS_OK;
} else {
*aData = nsnull;
*aLen = 0;
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
// Display the string.
MessageBox( NULL, (const char *)lpMsgBuf, "GetLastError", MB_OK|MB_ICONINFORMATION );
// Free the buffer.
LocalFree( lpMsgBuf );
}
::CloseClipboard();
}
return NS_OK;
}
/**
*
*
*/
static UINT GetFormat(const nsString & aMimeStr)
{
UINT format = 0;
if (aMimeStr.Equals(kTextMime)) {
format = CF_TEXT;
} else if (aMimeStr.Equals(kUnicodeMime)) {
format = CF_UNICODETEXT;
} else if (aMimeStr.Equals(kImageMime)) {
format = CF_BITMAP;
} else {
char * str = aMimeStr.ToNewCString();
format = ::RegisterClipboardFormat(str);
delete[] str;
}
return format;
}
/**
*
*
@ -243,24 +318,12 @@ NS_IMETHODIMP nsClipboard::GetClipboard()
if (NS_OK == supports->QueryInterface(kIDataFlavorIID, (void **)&df)) {
nsString mime;
df->GetMimeType(mime);
UINT format;
UINT format = GetFormat(mime);
void * data;
PRUint32 dataLen;
if (mime.Equals(kTextMime)) {
format = CF_TEXT;
} else if (mime.Equals(kUnicodeMime)) {
format = CF_UNICODETEXT;
} else if (mime.Equals(kImageMime)) {
format = CF_BITMAP;
} else {
char * str = mime.ToNewCString();
format = ::RegisterClipboardFormat(str);
delete[] str;
}
if (NS_OK == GetNativeDataOffClipboard(format, &data, &dataLen)) {
if (NS_OK == GetNativeDataOffClipboard(mWindow, format, &data, &dataLen)) {
mTransferable->SetTransferData(df, data, dataLen);
//NS_RELEASE(df);
//NS_RELEASE(supports);
@ -280,9 +343,121 @@ NS_IMETHODIMP nsClipboard::GetClipboard()
*/
NS_IMETHODIMP nsClipboard::IsDataFlavorSupported(nsIDataFlavor * aDataFlavor)
{
return NS_ERROR_FAILURE;
// make sure we have a good transferable
if (nsnull == mTransferable) {
return NS_ERROR_FAILURE;
}
return mTransferable->IsDataFlavorSupported(aDataFlavor);
}
/**
*
*
*/
NS_IMETHODIMP nsClipboard::EmptyClipboard()
{
if (mIgnoreEmptyNotification) {
return NS_OK;
}
if (nsnull != mClipboardOwner) {
mClipboardOwner->LosingOwnership(mTransferable);
NS_RELEASE(mClipboardOwner);
}
if (nsnull != mTransferable) {
NS_RELEASE(mTransferable);
}
return NS_OK;
}
/**
*
*
*/
static void PlaceDataOnClipboard(PRUint32 aFormat, char * aData, int aLength)
{
HGLOBAL hGlobalMemory;
PSTR pGlobalMemory;
PRInt32 size = aLength + 1;
if (aLength) {
// Copy text to Global Memory Area
hGlobalMemory = (HGLOBAL)::GlobalAlloc(GHND, size);
if (hGlobalMemory != NULL) {
pGlobalMemory = (PSTR) ::GlobalLock(hGlobalMemory);
int i;
char * s = aData;
PRInt32 len = aLength;
for (i=0;i< len;i++) {
*pGlobalMemory++ = *s++;
}
// Put data on Clipboard
::GlobalUnlock(hGlobalMemory);
::SetClipboardData(aFormat, hGlobalMemory);
}
}
}
/**
*
*
*/
NS_IMETHODIMP nsClipboard::ForceDataToClipboard()
{
// make sure we have a good transferable
if (nsnull == mTransferable) {
return NS_ERROR_FAILURE;
}
HWND nativeWin = nsnull;//(HWND)mWindow->GetNativeData(NS_NATIVE_WINDOW);
::OpenClipboard(nativeWin);
::EmptyClipboard();
// Get the transferable list of data flavors
nsISupportsArray * dfList;
mTransferable->GetTransferDataFlavors(&dfList);
// Walk through flavors and see which flavor is on the clipboard them on the native clipboard,
PRUint32 i;
for (i=0;i<dfList->Count();i++) {
nsIDataFlavor * df;
nsISupports * supports = dfList->ElementAt(i);
if (NS_OK == supports->QueryInterface(kIDataFlavorIID, (void **)&df)) {
nsString mime;
df->GetMimeType(mime);
UINT format = GetFormat(mime);
void * data;
PRUint32 dataLen;
mTransferable->GetTransferData(df, &data, &dataLen);
if (nsnull != data) {
PlaceDataOnClipboard(format, (char *)data, dataLen);
}
NS_RELEASE(df);
}
NS_RELEASE(supports);
}
::CloseClipboard();
return NS_OK;
}
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
// make the IDataObject
/*IDataObject * dataObj = NULL;
@ -302,3 +477,83 @@ NS_IMETHODIMP nsClipboard::IsDataFlavorSupported(nsIDataFlavor * aDataFlavor)
if (FAILED(ret)) {
//return ret;
}*/
#if 0
NS_IMETHODIMP nsTransferable::SetNativeClipboard()
{
::OleFlushClipboard();
if (!mStrCache) {
return NS_OK;
}
char * str = mStrCache->ToNewCString();
#if 0
PlaceStringOnClipboard(CF_TEXT, str, mStrCache->Length());
::CloseClipboard();
#else
if (mDataObj) {
mDataObj->Release();
}
// make the IDataObject
/*IDataObject * dataObj = NULL;
IClassFactory * pCF = NULL;
HRESULT hr = ::CoGetClassObject(CLSID_CfDataObj, CLSCTX_INPROC_SERVER, NULL, IID_IClassFactory, (void **)&pCF);
if (REGDB_E_CLASSNOTREG == hr) {
return hr;
}
//hresult = pCF->CreateInstance(pUnkOuter, riid, ppvObj)
pCF->Release();
HRESULT ret = ::CoCreateInstance(CLSID_CfDataObj, NULL, CLSCTX_INPROC_SERVER, IID_IDataObject, (void **)&dataObj);
if (REGDB_E_CLASSNOTREG == ret) {
//return ret;
}
if (FAILED(ret)) {
//return ret;
}*/
mDataObj = new nsDataObj();
mDataObj->AddRef();
mDataObj->SetText(*mStrCache);
PRUint32 i;
for (i=0;i<mDFList->Count();i++) {
nsIDataFlavor * df;
nsISupports * supports = mDFList->ElementAt(i);
if (NS_OK == supports->QueryInterface(kIDataFlavorIID, (void **)&df)) {
nsString mime;
df->GetMimeType(mime);
UINT format;
if (mime.Equals(kTextMime)) {
format = CF_TEXT;
} else {
char * str = mime.ToNewCString();
UINT format = ::RegisterClipboardFormat(str);
delete[] str;
}
FORMATETC fe;
SET_FORMATETC(fe, format, 0, DVASPECT_CONTENT, 0, TYMED_HGLOBAL);
mDataObj->AddDataFlavor(df, &fe);
NS_RELEASE(df);
}
NS_RELEASE(supports);
}
IDataObject * ido = (IDataObject *)mDataObj;
::OleSetClipboard(ido);
#endif
delete[] str;
return NS_OK;
}
#endif

Просмотреть файл

@ -25,6 +25,7 @@
class nsITransferable;
class nsDataObj;
class nsIClipboardOwner;
class nsIWidget;
/**
* Native Win32 Clipboard wrapper
@ -43,18 +44,23 @@ public:
// nsIClipboard
NS_IMETHOD SetTransferable(nsITransferable * aTransferable, nsIClipboardOwner * anOwner);
NS_IMETHOD GetTransferable(nsITransferable ** aTransferable);
NS_IMETHOD GetClipboard();
NS_IMETHOD SetClipboard();
NS_IMETHOD IsDataFlavorSupported(nsIDataFlavor * aDataFlavor);
NS_IMETHOD EmptyClipboard();
NS_IMETHOD ForceDataToClipboard();
protected:
PRBool mIgnoreEmptyNotification;
nsIClipboardOwner * mClipboardOwner;
nsITransferable * mTransferable;
nsITransferable * mTransferable;
nsIWidget * mWindow;
nsDataObj * mDataObj;
nsDataObj * mDataObj;
};

Просмотреть файл

@ -30,8 +30,8 @@ static NS_DEFINE_IID(kIDataFlavorIID, NS_IDATAFLAVOR_IID);
ULONG nsDataObjClassFactory::g_cLock = 0;
ULONG nsDataObj::g_cRef = 0;
EXTERN_C GUID CDECL CLSID_nsDataObj;// =
// { 0x1bba7640, 0xdf52, 0x11cf, { 0x82, 0x7b, 0, 0xa0, 0x24, 0x3a, 0xe5, 0x05 } };
EXTERN_C GUID CDECL CLSID_nsDataObj =
{ 0x1bba7640, 0xdf52, 0x11cf, { 0x82, 0x7b, 0, 0xa0, 0x24, 0x3a, 0xe5, 0x05 } };
/*
* class nsDataObjClassFactory

Просмотреть файл

@ -147,10 +147,6 @@ NS_IMETHODIMP nsTransferable::GetTransferData(nsIDataFlavor * aDataFlavor, void
mDataPtr = (void *)str;
*aData = mDataPtr;
//mDataPtr = (void *)new char[*aDataLen];
//memcpy(*mDataPtr, str, *aDataLen);
//delete[] str;
} else if (mimeInQuestion.Equals(kHTMLMime)) {
}
@ -164,6 +160,10 @@ NS_IMETHODIMP nsTransferable::GetTransferData(nsIDataFlavor * aDataFlavor, void
*/
NS_IMETHODIMP nsTransferable::SetTransferData(nsIDataFlavor * aDataFlavor, void * aData, PRUint32 aDataLen)
{
if (aData == nsnull) {
return NS_OK;
}
nsAutoString mimeInQuestion;
aDataFlavor->GetMimeType(mimeInQuestion);
@ -208,122 +208,6 @@ NS_IMETHODIMP nsTransferable::GetTransferString(nsString & aStr)
return NS_OK;
}
#if 0
static void PlaceStringOnClipboard(PRUint32 aFormat, char* aData, int aLength)
{
HGLOBAL hGlobalMemory;
PSTR pGlobalMemory;
PRInt32 size = aLength + 1;
if (aLength) {
// Copy text to Global Memory Area
hGlobalMemory = (HGLOBAL)::GlobalAlloc(GHND, size);
if (hGlobalMemory != NULL) {
pGlobalMemory = (PSTR) ::GlobalLock(hGlobalMemory);
int i;
char * s = aData;
PRInt32 len = aLength;
for (i=0;i< len;i++) {
*pGlobalMemory++ = *s++;
}
// Put data on Clipboard
::GlobalUnlock(hGlobalMemory);
::SetClipboardData(aFormat, hGlobalMemory);
}
}
}
#endif
/**
*
*
*/
NS_IMETHODIMP nsTransferable::SetNativeClipboard()
{
#if 0
::OleFlushClipboard();
if (!mStrCache) {
return NS_OK;
}
char * str = mStrCache->ToNewCString();
#if 0
::OpenClipboard(NULL);
::EmptyClipboard();
PlaceStringOnClipboard(CF_TEXT, str, mStrCache->Length());
::CloseClipboard();
#else
if (mDataObj) {
mDataObj->Release();
}
// make the IDataObject
/*IDataObject * dataObj = NULL;
IClassFactory * pCF = NULL;
HRESULT hr = ::CoGetClassObject(CLSID_CfDataObj, CLSCTX_INPROC_SERVER, NULL, IID_IClassFactory, (void **)&pCF);
if (REGDB_E_CLASSNOTREG == hr) {
return hr;
}
//hresult = pCF->CreateInstance(pUnkOuter, riid, ppvObj)
pCF->Release();
HRESULT ret = ::CoCreateInstance(CLSID_CfDataObj, NULL, CLSCTX_INPROC_SERVER, IID_IDataObject, (void **)&dataObj);
if (REGDB_E_CLASSNOTREG == ret) {
//return ret;
}
if (FAILED(ret)) {
//return ret;
}*/
mDataObj = new nsDataObj();
mDataObj->AddRef();
mDataObj->SetText(*mStrCache);
PRUint32 i;
for (i=0;i<mDFList->Count();i++) {
nsIDataFlavor * df;
nsISupports * supports = mDFList->ElementAt(i);
if (NS_OK == supports->QueryInterface(kIDataFlavorIID, (void **)&df)) {
nsString mime;
df->GetMimeType(mime);
UINT format;
if (mime.Equals(kTextMime)) {
format = CF_TEXT;
} else {
char * str = mime.ToNewCString();
UINT format = ::RegisterClipboardFormat(str);
delete[] str;
}
FORMATETC fe;
SET_FORMATETC(fe, format, 0, DVASPECT_CONTENT, 0, TYMED_HGLOBAL);
mDataObj->AddDataFlavor(df, &fe);
NS_RELEASE(df);
}
NS_RELEASE(supports);
}
IDataObject * ido = (IDataObject *)mDataObj;
::OleSetClipboard(ido);
#endif
delete[] str;
#endif
return NS_OK;
}
/**
*
*
@ -339,22 +223,19 @@ NS_IMETHODIMP nsTransferable::AddDataFlavor(const nsString & aMimeType, const ns
df->Init(aMimeType, aHumanPresentableName);
mDFList->AppendElement(df);
/*FORMATETC fe;
if (aMimeType.Equals(kTextMime)) {
SET_FORMATETC(fe, CF_TEXT, 0, DVASPECT_CONTENT, 0, TYMED_HGLOBAL);
m_getFormats[m_numGetFormats++] = fe;
SET_FORMATETC(fe, CF_TEXT, 0, DVASPECT_CONTENT, 0, TYMED_HGLOBAL);
m_setFormats[m_numSetFormats++] = fe;
} else {
nsDataFlavor * ndf = (nsDataFlavor *)df;
SET_FORMATETC(fe, ndf->GetFormat(), 0, DVASPECT_CONTENT, 0, TYMED_HGLOBAL);
m_getFormats[m_numGetFormats++] = fe;
SET_FORMATETC(fe, ndf->GetFormat(), 0, DVASPECT_CONTENT, 0, TYMED_HGLOBAL);
m_setFormats[m_numSetFormats++] = fe;
}*/
return rv;
}
/**
*
*
*/
NS_IMETHODIMP nsTransferable::IsLargeDataSet()
{
if (mStrCache) {
return (mStrCache->Length() > 1024?NS_OK:NS_ERROR_FAILURE);
}
return NS_ERROR_FAILURE;
}

Просмотреть файл

@ -25,8 +25,6 @@ class nsISupportsArray;
class nsIDataFlavor;
class nsDataObj;
#define MAX_FORMATS 32
/**
* Native Win32 Transferable wrapper
*/
@ -52,7 +50,7 @@ public:
NS_IMETHOD GetTransferString(nsString & aStr);
NS_IMETHOD AddDataFlavor(const nsString & aMimeType, const nsString & aHumanPresentableName);
NS_IMETHOD SetNativeClipboard();
NS_IMETHOD IsLargeDataSet();
// Used for native implementation
nsDataObj * GetDataObj() { return mDataObj; }