Back to index

lightning-sunbird  0.9+nobinonly
clipboard.cpp
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is WinCE Shunt
00015  *
00016  * The Initial Developer of the Original Code is 
00017  * Douglas F. Turner II  <dougt@meer.net>
00018  * Portions created by the Initial Developer are Copyright (C) 2005
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *
00023  * Alternatively, the contents of this file may be used under the terms of
00024  * either the GNU General Public License Version 2 or later (the "GPL"), or
00025  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00026  * in which case the provisions of the GPL or the LGPL are applicable instead
00027  * of those above. If you wish to allow use of your version of this file only
00028  * under the terms of either the GPL or the LGPL, and not to allow others to
00029  * use your version of this file under the terms of the MPL, indicate your
00030  * decision by deleting the provisions above and replace them with the notice
00031  * and other provisions required by the GPL or the LGPL. If you do not delete
00032  * the provisions above, a recipient may use your version of this file under
00033  * the terms of any one of the MPL, the GPL or the LGPL.
00034  *
00035  * ***** END LICENSE BLOCK ***** */
00036 
00037 #include "mozce_internal.h"
00038 
00039 extern "C" {
00040 #if 0
00041 }
00042 #endif
00043 
00044 static IDataObject* gDataObject = NULL;
00045 static HWND gClipboardWND = NULL; /* we may need to free this */
00046 
00047 void oleSetup()
00048 {
00049   if (gClipboardWND)
00050     return;
00051   
00052   WNDCLASS wndclass;
00053   ZeroMemory( &wndclass, sizeof(WNDCLASS));
00054   
00055   
00056   wndclass.style          = CS_GLOBALCLASS;
00057   wndclass.lpfnWndProc    = DefWindowProc;
00058   wndclass.lpszClassName  = L"OLE_CLIPBOARD";
00059   
00060   RegisterClass(&wndclass);
00061   
00062   gClipboardWND = CreateWindow(L"OLE_Clipboard",
00063                          0,
00064                          0,
00065                          CW_USEDEFAULT, CW_USEDEFAULT,
00066                          CW_USEDEFAULT, CW_USEDEFAULT,
00067                          0,
00068                          0,
00069                          0,
00070                          0);
00071 }
00072 
00073 class ClipDataObj : public IDataObject
00074 {
00075 public:
00076   ClipDataObj()
00077   {
00078     mRefCnt = 0;
00079   } 
00080   
00081   ~ClipDataObj()
00082   {  
00083   }
00084   
00085   STDMETHODIMP_(ULONG) AddRef()
00086   {
00087     mRefCnt++; 
00088     return mRefCnt; 
00089   }
00090   
00091   STDMETHODIMP QueryInterface(REFIID iid, void **ppvObject)
00092   {
00093     // check to see what interface has been requested
00094     if(iid == IID_IDataObject || iid == IID_IUnknown)
00095     {
00096       AddRef();
00097       *ppvObject = this;
00098       return S_OK;
00099     }
00100     else
00101     {
00102       *ppvObject = 0;
00103       return E_NOINTERFACE;
00104     }
00105   }
00106   
00107   STDMETHODIMP_(ULONG) Release()
00108   {
00109     mRefCnt--;
00110     if (mRefCnt == 0)
00111     {
00112       delete this;
00113       return 0;
00114     }
00115     
00116     return mRefCnt;
00117   }
00118   
00119   STDMETHODIMP GetData      (FORMATETC *pFormatEtc, STGMEDIUM *pMedium)
00120   {
00121     
00122     oleSetup();
00123     
00124     BOOL b = OpenClipboard(gClipboardWND);
00125     
00126     if (!b)
00127       return E_FAIL;
00128     
00129     HANDLE hData = GetClipboardData(pFormatEtc->cfFormat);
00130     
00131     LPVOID src = GlobalLock(hData);
00132     if(src) {
00133       ULONG  size  = GlobalSize(hData);
00134       HANDLE hDest = GlobalAlloc(GHND, size);
00135       LPVOID dest  = GlobalLock(hDest);
00136       memcpy(dest, src, size);
00137       
00138       GlobalUnlock(hDest);
00139       GlobalUnlock(hData);
00140       
00141       hData = hDest;
00142     }
00143     
00144     pMedium->tymed = (hData == 0) ? TYMED_NULL : TYMED_HGLOBAL;
00145     pMedium->hGlobal = (HGLOBAL)hData;
00146     pMedium->pUnkForRelease = NULL;
00147     
00148     return S_OK;
00149   }
00150   
00151   STDMETHODIMP GetDataHere (LPFORMATETC pFE, LPSTGMEDIUM pSTM)
00152   {
00153     return DATA_E_FORMATETC;
00154   }
00155   
00156   STDMETHODIMP QueryGetData (LPFORMATETC pFE)
00157   {
00158     return S_OK;
00159   }
00160   
00161   STDMETHODIMP GetCanonicalFormatEtc (LPFORMATETC pFE, LPFORMATETC pCanonFE)
00162   {
00163     pFE->ptd = NULL;
00164     return E_NOTIMPL;
00165   }
00166   
00167   STDMETHODIMP SetData      (LPFORMATETC pFE, LPSTGMEDIUM pSTM, BOOL release)
00168   {
00169     return E_NOTIMPL;
00170   }
00171   
00172   STDMETHODIMP EnumFormatEtc       (DWORD dwDirection, LPENUMFORMATETC* ppEnum)
00173   {
00174     return E_NOTIMPL;
00175   }
00176   
00177   STDMETHODIMP DAdvise      (LPFORMATETC pFE, DWORD flags, LPADVISESINK pAdvise, DWORD* pConn)
00178   {
00179     return OLE_E_ADVISENOTSUPPORTED;
00180   }
00181   
00182   STDMETHODIMP DUnadvise (DWORD pConn)
00183   {
00184     return OLE_E_ADVISENOTSUPPORTED;
00185   }
00186   
00187   STDMETHODIMP EnumDAdvise (LPENUMSTATDATA *ppEnum)
00188   {
00189     return OLE_E_ADVISENOTSUPPORTED;
00190   }
00191 private:
00192   LONG    mRefCnt;
00193 };
00194 
00195 
00196 
00197 MOZCE_SHUNT_API HRESULT mozce_OleSetClipboard(IDataObject * pDataObj)
00198 {
00199   MOZCE_PRECHECK
00200     
00201        oleSetup();
00202   
00203   if (gDataObject)
00204     gDataObject->Release();
00205   
00206   gDataObject = pDataObj;
00207   
00208   if (pDataObj) 
00209   {
00210     BOOL b = OpenClipboard(gClipboardWND);
00211     
00212     if (!b)
00213       return E_FAIL;
00214     
00215     EmptyClipboard();
00216     
00217     pDataObj->AddRef();
00218     
00219     IEnumFORMATETC* enumerator = NULL;
00220     pDataObj->EnumFormatEtc(DATADIR_GET, &enumerator);
00221     if (!enumerator)
00222       return S_OK;
00223     
00224     FORMATETC etc;
00225     
00226     while (S_OK == enumerator->Next(1, &etc, NULL))
00227     {
00228       if ( etc.tymed == TYMED_HGLOBAL )
00229       {
00230 
00231               STGMEDIUM medium;
00232               pDataObj->GetData(&etc, &medium);
00233         SetClipboardData( etc.cfFormat, medium.hGlobal);
00234       }
00235     }
00236     
00237     enumerator->Release();
00238     
00239     CloseClipboard();
00240     
00241   }
00242   return S_OK;
00243 }
00244 
00245 MOZCE_SHUNT_API HRESULT mozce_OleGetClipboard(IDataObject ** pDataObj)
00246 {
00247   MOZCE_PRECHECK
00248     oleSetup();
00249   
00250   if (pDataObj)
00251     *pDataObj = gDataObject;
00252   
00253   if (!*pDataObj)
00254   {
00255     *pDataObj = new ClipDataObj();
00256     if (!*pDataObj)
00257       return E_FAIL;
00258 
00259     gDataObject = *pDataObj;
00260   }
00261   
00262   (*pDataObj)->AddRef();
00263   return S_OK;
00264 }
00265 
00266 MOZCE_SHUNT_API HRESULT mozce_OleFlushClipboard()
00267 {
00268   MOZCE_PRECHECK
00269     oleSetup();
00270   
00271   mozce_OleSetClipboard(NULL);
00272   return S_OK;
00273 }
00274 
00275 
00276 MOZCE_SHUNT_API BOOL mozce_IsClipboardFormatAvailable(UINT format)
00277 {
00278   if (gClipboardWND)
00279   {
00280     BOOL b = OpenClipboard(gClipboardWND);
00281     if (!b)
00282       return E_FAIL;
00283     
00284     IEnumFORMATETC* enumerator = NULL;
00285     gDataObject->EnumFormatEtc(DATADIR_GET, &enumerator);
00286     if (!enumerator)
00287       return S_OK;
00288     
00289     FORMATETC etc;
00290     
00291     while (S_OK == enumerator->Next(1, &etc, NULL))
00292     {
00293       if ( etc.cfFormat == format)
00294       {
00295         enumerator->Release();
00296         CloseClipboard();
00297         return true;
00298       }
00299     }
00300     enumerator->Release();
00301     CloseClipboard();
00302   }
00303   
00304   return IsClipboardFormatAvailable(format);
00305 }
00306 
00307 #if 0
00308 {
00309 #endif
00310 } /* extern "C" */