#include <clipext.h>
Public Member Functions | |
BOOL | IsOurs () const |
ExternalClipboard () | |
constructor | |
virtual | ~ExternalClipboard () |
Destructor. Cleans up our lists and wotnot. | |
void | CheckKeepClipboardOnExit (void) |
Called once on exit to check if the user wants the contents of the clipboard to be available after camelot is gone. This is supposed to be done when RenderAllFormats is called, but this happens after the main frame window has departed, so we want someone to call this method sometime between the last document being closed and the main frame being removed. | |
void | DestroyClipboard (void) |
Destroys the external and internal clipboards. | |
void | RenderFormat (UINT32 ClipboardFormat) |
"Renders" the given format to the clipboard (i.e. exports the internal clipboard to the windows clipboard using the specified mapping) | |
void | RenderFormat (ClipboardMapping *Info) |
"Renders" the given format to the clipboard (i.e. exports the internal clipboard to the windows clipboard using the specified mapping) | |
void | RenderAllFormats (void) |
Renders all available formats onto the windows clipboard Called when WM_RENDER_ALL_FORMATS is received (if the application quits when it owns the clipboard). | |
void | WindowsClipboardHasChanged (void) |
Destroys the internal clipboard. | |
BOOL | UnlinkTempClipboard () |
Delete the temporary clipboard and return any static pointers to normal. | |
Static Public Member Functions | |
static BOOL | Init (void) |
Initialises the ExternalClipboard ready for operation. | |
static void | Deinit (void) |
De-Initialises the ExternalClipboard when you're shutting down. | |
static void | RegisterDataType (ClipboardMapping *TypeInfo) |
Called by filters to add import/export mappings to the external clipboard. Each mapping indicates which filter to call in order to convert data between a particular internal and external clipboard format. | |
static void | PrepareForShutdown (void) |
static BOOL | CanImport (UINT32 WindowsFormat) |
Determines if there is an import mapping that can cope with the given format. | |
static void | GetExternalFormatName (UINT32 ExternalFormat, String_64 *Result) |
To get the textual description of a clipboard format. | |
static ExternalClipboard * | GetExternalClipboard (void) |
Finds the external clipboard. Only really of any use to the InternalClipboard and the main window which has to pass events to the ExternalClipboard. | |
static ExternalClipboard * | LinkTempClipboard () |
Create a new temporary clipboard document and point the statics at it. | |
static void | UpdateSystemClipboard (BOOL fState) |
Protected Member Functions | |
BOOL | PrepareForCopy (void) |
To ready the clipboard for a cut/copy operation (copy data TO the clipboard). This will interact with the external clipboard in order to claim the global clipboard, and readies the clipboard for use. | |
BOOL | CopyCompleted (void) |
Tells the ExternalClipboard that you have finished copying data to it. This interacts with the external clipboard in order to make the new data available to the outside world. | |
BOOL | PrepareForPaste (void) |
To ready the clipboard for a paste operation (copy data FROM the clipboard). This may interact with the external clipboard in order to provide the necessary data. | |
BOOL | PasteCompleted (void) |
Tells the ExternalClipboard that you have finished copying data from it. This provides interaction with the external clipboard. | |
Static Protected Member Functions | |
static BOOL | IsEmpty (void) |
To ready the clipboard for a cut/copy operation (copy data TO the clipboard). This will interact with the external clipboard in order to claim the global clipboard, and readies the clipboard for use. | |
static void | DescribeContents (String_64 *Result) |
To get the textual description of the clipboard format which will be pasted if a paste operation is to be applied now. | |
static CWnd * | GetOwnerWindow (void) |
Finds the main window of camelot, which is used to handle all communications between us and Windows regardingthe clipboard. | |
Protected Attributes | |
List | Mappings |
BOOL | KeepFormatsOnExit |
Static Protected Attributes | |
static ExternalClipboard * | pInstance = NULL |
Static Private Attributes | |
static BOOL | m_fUpdateSystemClipboard = TRUE |
Friends | |
class | InternalClipboard |
class | CMainFrame |
class | OpClipboardImport |
class | PasteSpecialDlg |
class | ScreenCamView |
Definition at line 138 of file clipext.h.
|
constructor
Definition at line 215 of file clipext.cpp. 00216 { 00217 if (pInstance == NULL) 00218 pInstance = this; 00219 else 00220 { 00221 ERROR3("Oy! You can't have more than one instance of the ExternalClipboard!"); 00222 } 00223 00224 KeepFormatsOnExit = TRUE; 00225 00226 #if (_OLE_VER >= 0x200) 00227 m_fIgnoreChange = FALSE; 00228 #endif 00229 }
|
|
Destructor. Cleans up our lists and wotnot.
Definition at line 244 of file clipext.cpp. 00245 { 00246 Mappings.DeleteAll(); 00247 00248 if (pInstance == this) 00249 pInstance = NULL; 00250 else 00251 { 00252 ERROR3("Oy! You can't have more than one instance of the ExternalClipboard!"); 00253 } 00254 }
|
|
Determines if there is an import mapping that can cope with the given format.
Definition at line 642 of file clipext.cpp. 00643 { 00644 if (pInstance == NULL) 00645 return(FALSE); 00646 00647 ClipboardMapping *Mapping = (ClipboardMapping *) pInstance->Mappings.GetHead(); 00648 while (Mapping != NULL) 00649 { 00650 if (Mapping->Type != CLIPMAP_EXPORTONLY && Mapping->ExternalDataType == WindowsFormat) 00651 return(TRUE); 00652 00653 Mapping = (ClipboardMapping *) pInstance->Mappings.GetNext(Mapping); 00654 } 00655 00656 return(FALSE); 00657 }
|
|
Called once on exit to check if the user wants the contents of the clipboard to be available after camelot is gone. This is supposed to be done when RenderAllFormats is called, but this happens after the main frame window has departed, so we want someone to call this method sometime between the last document being closed and the main frame being removed.
The user may not be asked at all (e.g. if we don't own the clipboard)
Definition at line 542 of file clipext.cpp. 00543 { 00544 if (InternalClipboard::IsEmpty(FALSE)) // No clipboard! 00545 return; 00546 00547 // Do we own the clipboard? 00548 if (!IsOurs()) return; 00549 00550 // OK, Now let's determine just how complicated the data is. If it looks like it 00551 // will take an INT32 time or a lot of memory to leave it on the CB, then we'll 00552 // ask the user - if not, we'll just stay quiet about it and lump it all onto 00553 // the CB without asking permission. 00554 // This is done with a very rough guide: A node count of the clipboard content, 00555 // modified slightly to take account of the fact that blends and grad fills usually 00556 // cause a lot more output (in WMF format etc). 00557 Node *pRoot = InternalClipboard::GetInsertionLayer(); 00558 if (pRoot == NULL) 00559 { 00560 KeepFormatsOnExit = TRUE; 00561 return; 00562 } 00563 00564 Node *pNode = pRoot->FindFirstDepthFirst(); 00565 INT32 RoughNodeCount = 0; 00566 00567 while (pNode != NULL && RoughNodeCount < KeepClipboardThreshold) 00568 { 00569 if (pNode->IsAVisibleTextNode()) 00570 { 00571 RoughNodeCount += 1; // Text chars export small, so count as 1 00572 } 00573 else if (IS_A(pNode, NodeBlend)) 00574 { 00575 // Each blend step counts as another 8 00576 RoughNodeCount += 128 * (((NodeBlend *)pNode)->GetNumBlendSteps()); 00577 } 00578 else if (pNode->IsAnAttribute()) 00579 { 00580 // Each fill counts as 64 (in case it's a grad fill) 00581 if (pNode->IsKindOf(CC_RUNTIME_CLASS(AttrFillGeometry))) 00582 RoughNodeCount += 64; 00583 } 00584 else if (IS_A(pNode, NodeBitmap)) 00585 { 00586 // Add Bitmap memory size to the count 00587 // This will hit the threshold at about 128kB 00588 KernelBitmapRef *BmpRef = ((NodeBitmap*)pNode)->GetBitmapRef(); 00589 if (BmpRef != NULL) 00590 { 00591 KernelBitmap *KernelBmp = BmpRef->GetBitmap(); 00592 if (KernelBmp != NULL) 00593 { 00594 OILBitmap *OilBmp = KernelBmp->ActualBitmap; 00595 if (OilBmp != NULL) 00596 { 00597 BitmapInfo BmpInfo; 00598 OilBmp->GetInfo(&BmpInfo); 00599 RoughNodeCount += BmpInfo.MemoryUsed / 32; 00600 } 00601 } 00602 } 00603 00604 } 00605 else 00606 RoughNodeCount += 10; // All other nodes count as 10 00607 00608 pNode = pNode->FindNextDepthFirst(pRoot); 00609 } 00610 00611 // Default to saving the clipboard content on exit... 00612 KeepFormatsOnExit = TRUE; 00613 00614 if (RoughNodeCount >= KeepClipboardThreshold) 00615 { 00616 // It looks a bit complicated, so maybe we'd better ask the user if they want the 00617 // clipboard contents to stick around once Camelot has quit. 00618 INT32 ButtonPressed = AskQuestion(_R(IDS_CLIPBOARD_KEEPONQUIT), 00619 _R(IDS_CLIPBOARD_KEEP), _R(IDS_CLIPBOARD_DISCARD)); 00620 00621 // Then remember whether we should render all available formats to the clipboard 00622 KeepFormatsOnExit = (ButtonPressed == 1); 00623 } 00624 }
|
|
Tells the ExternalClipboard that you have finished copying data to it. This interacts with the external clipboard in order to make the new data available to the outside world.
This is called AFTER have updated the internal clipboard. However, if we already own the Windows clipboard, Windows very kindly asks us to destroy our clipboard when we call EmptyClipboard. To avoid disembowling ourselves we thus have to check if we are the owner of the clipboard so that we only wipe the internal clipboard if someone else takes control of the external clipboard - see DestroyClipboard Scope: protected (for friend class InternalClipboard only)
Definition at line 1056 of file clipext.cpp. 01057 { 01058 // TRACEUSER( "JustinF", _T("In ExternalClipboard::CopyCompleted\n")); 01059 InternalClipboardFormat VectorFormat(CLIPTYPE_VECTOR); 01060 01061 ClipboardMapping *Mapping = (ClipboardMapping *) Mappings.GetHead(); 01062 while (Mapping != NULL) 01063 { 01064 // Mark all "vector" mappings available for export 01065 Mapping->Available = Mapping->GetInternalDataType()->IsSameFormat(VectorFormat); 01066 Mapping = (ClipboardMapping *) Mappings.GetNext(Mapping); 01067 } 01068 01069 // Scan the InternalClipboard document tree to determine which internal formats are available 01070 Node *pRoot = InternalClipboard::GetInsertionLayer(); 01071 Node *pNode = pRoot->FindFirstDepthFirst(); 01072 BOOL AllDone = FALSE; // Becomes TRUE when there is no need to continue the scan 01073 01074 while (pNode != NULL && !AllDone) 01075 { 01076 AllDone = TRUE; 01077 Mapping = (ClipboardMapping *) Mappings.GetHead(); 01078 while (Mapping != NULL) 01079 { 01080 if (!Mapping->Available && Mapping->Type != CLIPMAP_IMPORTONLY) 01081 { 01082 // Check if this mapping can be used on this node to provide another 01083 // output data format that was previously unavailable 01084 Mapping->Available = pNode->SupportsClipboardFormat(Mapping->GetInternalDataType()); 01085 if (!Mapping->Available) AllDone = FALSE; 01086 } 01087 01088 Mapping = (ClipboardMapping *) Mappings.GetNext(Mapping); 01089 } 01090 01091 pNode = pNode->FindNextDepthFirst(pRoot); 01092 } 01093 01094 01095 #if (_OLE_VER >= 0x200) 01096 01097 // Put the contents of the internal clipboard on the OLE clipboard, using the 01098 // associated CCamSrvrItem to do the hard stuff. 01099 01100 m_fIgnoreChange = TRUE; 01101 01102 // Only put stuff on the external clipboard if we are allowed to ... 01103 if (m_fUpdateSystemClipboard) 01104 { 01105 // If you have been using something like GIF construction set then this may 01106 // lock the clipboard. At this point, an exception will be thrown. This is an unknown 01107 // exception as far a Camelot is concerned and so is very bad. We should really stop 01108 // the main expection handler getting its claws on it and not knowing what to do with it. 01109 // Our exception handler can just pretend that nothing really happened. 01110 // Just mention to the user about the problem. 01111 TRY 01112 { 01113 // Get the oil form of the document and the associated server item 01114 CCamDoc * pCamDoc = InternalClipboard::Instance()->GetOilDoc(); 01115 CCamSrvrItem* pServer = NULL; 01116 if (pCamDoc != NULL) 01117 pServer = pCamDoc->GetEmbeddedItem(); 01118 // If that went well then ask it to copy the data to the clipboard 01119 if (pServer != NULL) 01120 pServer->CopyToClipboard(); 01121 } 01122 CATCH(COleException, e) // Handle all ole exceptions 01123 { 01124 // "e" contains information about the exception. 01125 TRACEUSER( "Neville", _T("ExternalClipboard::CopyCompleted exception handler\n")); 01126 01127 // Do nothing special, as all this means is that the external clipboard 01128 // has had a problem. Just report a generic error to the user so that they 01129 // know that something is not working correctly. 01130 InformError(_R(IDE_CLIPBOARDCOPYPROBLEM)); // There was a problem copying to the Windows clipboard 01131 } 01132 END_CATCH 01133 } 01134 01135 m_fIgnoreChange = FALSE; 01136 return TRUE; 01137 01138 #else 01139 01140 CWnd *Parent = GetOwnerWindow(); 01141 if (Parent->OpenClipboard() != NULL) 01142 { 01143 ::EmptyClipboard(); // Clear the windows clipboard 01144 01145 // Add all available export formats onto the clipboard 01146 Mapping = (ClipboardMapping *) Mappings.GetHead(); 01147 while (Mapping != NULL) 01148 { 01149 01150 #if FALSE 01151 #if _DEBUG 01152 TRACEUSER( "Jason", _T("Mapping %s available (for ICF %ld)\n"), 01153 Mapping->Available?"is":"NOT", (INT32)(Mapping->GetInternalDataType()->GetFormatID())); 01154 #endif 01155 #endif 01156 01157 if (Mapping->Available && Mapping->Type != CLIPMAP_IMPORTONLY) 01158 ::SetClipboardData(Mapping->ExternalDataType, NULL); 01159 01160 Mapping = (ClipboardMapping *) Mappings.GetNext(Mapping); 01161 } 01162 01163 ::CloseClipboard(); 01164 } 01165 // else another application/window has the clipboard open! 01166 01167 return(TRUE); 01168 01169 #endif 01170 }
|
|
De-Initialises the ExternalClipboard when you're shutting down.
Definition at line 360 of file clipext.cpp.
|
|
To get the textual description of the clipboard format which will be pasted if a paste operation is to be applied now.
Definition at line 728 of file clipext.cpp. 00729 { 00730 ERROR3IF(Result == NULL, "Illegal null param"); 00731 00732 // Ensure a safe return value 00733 *Result = TEXT(""); 00734 00735 if (pInstance == NULL) // There ain't no clipboard hereabouts, mac! 00736 return; 00737 00738 if (pInstance->IsOurs() || !InternalClipboard::IsEmpty(FALSE)) 00739 { 00740 // We own the clipboard, or have a cached result - Use the internal one 00741 ERROR3IF(InternalClipboard::IsEmpty(FALSE), 00742 "We own the clipboard but the internal clipboard is empty!!"); 00743 00744 InternalClipboard::DescribeContentsInternal(Result); 00745 return; 00746 } 00747 00748 if (GetOwnerWindow()->OpenClipboard() == NULL) 00749 return; // Can't open the clipboard 00750 00751 UINT32 ThisFormat = 0; 00752 UINT32 DefaultImportFormat = 0; 00753 INT32 NumExternalFormats = 0; 00754 BOOL IncludesTextFormat = FALSE; 00755 do 00756 { 00757 ThisFormat = EnumClipboardFormats(ThisFormat); 00758 if (ThisFormat != 0 && ExternalClipboard::CanImport(ThisFormat)) 00759 { 00760 // Bodge - text can be on the clipboard in 3 forms, but we only want to treat 00761 // it as a single format for the 'paste special' count 00762 if (ThisFormat == CF_TEXT || ThisFormat == CF_UNICODETEXT || ThisFormat == CF_OEMTEXT) 00763 { 00764 if (!IncludesTextFormat) 00765 NumExternalFormats++; 00766 00767 IncludesTextFormat = TRUE; 00768 } 00769 else 00770 NumExternalFormats++; 00771 00772 // Remember which format we will import by default 00773 if (DefaultImportFormat == 0) 00774 DefaultImportFormat = ThisFormat; 00775 } 00776 } while (ThisFormat != 0); 00777 00778 ::CloseClipboard(); 00779 00780 if (NumExternalFormats > 1) 00781 { 00782 // if there are 2 or more external formats, then we'll paste special ("Paste...") 00783 *Result = _R(IDS_CLIPFORMAT_ELIPSES); // TEXT("..."); 00784 } 00785 else 00786 { 00787 // There is no data, or only one format that we recognise. If there is something we 00788 // can paste, then lob its name on the end ("Paste blobby"), else leave result blank ("Paste") 00789 if (DefaultImportFormat != 0) 00790 GetExternalFormatName(DefaultImportFormat, Result); 00791 } 00792 }
|
|
Destroys the external and internal clipboards.
Notes: Now scans all registered mappings, and calls their RemoveTempFile methods in order to remove any tempfiles left lying about "on" the clipboard. Definition at line 1590 of file clipext.cpp. 01591 { 01592 // Whenever this method is called, we only wipe the clipboard if someone else owns it 01593 // (we're guaranteed to be called with us as the owner in all the situations where 01594 // we don't want to wipe the internal clipboard! Excellent!) 01595 if (!IsOurs()) 01596 { 01597 // And try to remove any temporary files that were hanging around "on" the clipboard 01598 InternalClipboard::Clear(); 01599 ClipboardMapping* Mapping = (ClipboardMapping*) Mappings.GetHead(); 01600 while (Mapping != NULL) 01601 { 01602 Mapping->RemoveTempFile(); 01603 Mapping = (ClipboardMapping*) Mappings.GetNext(Mapping); 01604 } 01605 } 01606 }
|
|
Finds the external clipboard. Only really of any use to the InternalClipboard and the main window which has to pass events to the ExternalClipboard.
Definition at line 1842 of file clipext.cpp. 01843 { 01844 return(pInstance); 01845 }
|
|
To get the textual description of a clipboard format.
Definition at line 816 of file clipext.cpp. 00817 { 00818 ERROR3IF(Result == NULL, "Illegal NULL param"); 00819 00820 if (ExternalFormat >= 0xC000 && ExternalFormat <= 0xFFFF) 00821 { 00822 GetClipboardFormatName(ExternalFormat, (LPTSTR)((TCHAR *)*Result), 63); 00823 if (*Result==String_64(_T("CorelXARA Document"))) 00824 *Result = String(_R(IDS_CLIPFORMAT_NATIVE)); 00825 } 00826 else 00827 { 00828 switch(ExternalFormat) 00829 { 00830 case CF_TEXT: 00831 *Result = String(_R(IDS_CLIPFORMAT_ATEXT)); 00832 break; 00833 00834 case CF_BITMAP: 00835 *Result = String(_R(IDS_CLIPFORMAT_BMP)); 00836 break; 00837 00838 case CF_METAFILEPICT: 00839 *Result = String(_R(IDS_CLIPFORMAT_WMF)); 00840 break; 00841 00842 // case CF_SYLK: 00843 // *Result = TEXT("Symbolic Link"); 00844 // break; 00845 00846 // case CF_DIF: 00847 // *Result = TEXT("Data Interchange Format"); 00848 // break; 00849 00850 case CF_TIFF: 00851 *Result = String(_R(IDS_CLIPFORMAT_TIFF)); 00852 break; 00853 00854 case CF_OEMTEXT: 00855 *Result = String(_R(IDS_CLIPFORMAT_ATEXT)); // Shares 'unformatted text' with CF_TEXT 00856 break; 00857 00858 case CF_DIB: 00859 *Result = String(_R(IDS_CLIPFORMAT_DIB)); 00860 break; 00861 00862 // case CF_PALETTE: 00863 // *Result = TEXT("Palette"); 00864 // break; 00865 00866 // case CF_PENDATA: 00867 // *Result = TEXT("Pen data"); 00868 // break; 00869 00870 // case CF_RIFF: 00871 // *Result = TEXT("RIFF data"); 00872 // break; 00873 00874 // case CF_WAVE: 00875 // *Result = TEXT("WAVE sound"); 00876 // break; 00877 00878 case CF_UNICODETEXT: 00879 *Result = String(_R(IDS_CLIPFORMAT_UTEXT)); 00880 break; 00881 00882 case CF_ENHMETAFILE: 00883 *Result = String(_R(IDS_CLIPFORMAT_EMF)); 00884 break; 00885 00886 default: 00887 *Result = String(_R(IDS_CLIPFORMAT_UNRECOGNISED_FORMAT)); // "Unrecognised format" 00888 TRACE( _T("WARNING: Unrecognised 'standard' windows clipboard format (%ld), %s,%ld\n"), 00889 (INT32)ExternalFormat, __FILE__, __LINE__); 00890 break; 00891 } 00892 } 00893 00894 00895 // If you want to hack a clipboard format, this little baby knows 00896 // how to dump it into the file c:\jason.tmp 00897 #if FALSE 00898 #if _DEBUG 00899 /* 00900 if (!camStrncmp((TCHAR *)(*Result), "QuarkXPress", 10)) // A Quack XPress clipboard format? 00901 { 00902 HANDLE Bob = GetClipboardData(ExternalFormat); 00903 char *buff = (char *) GlobalLock(Bob); 00904 00905 FILE *fp = _tfopen("c:\\jason.tmp", "wb"); 00906 size_t Size = (size_t)GlobalSize(Bob); 00907 fwrite(buff, 1, Size, fp); 00908 fclose(fp); 00909 00910 GlobalUnlock(Bob); 00911 00912 ERROR3("Quack XPress data detected and saved!"); 00913 } 00914 */ 00915 #endif 00916 #endif 00917 }
|
|
Finds the main window of camelot, which is used to handle all communications between us and Windows regardingthe clipboard.
Definition at line 1865 of file clipext.cpp. 01866 { 01867 return GetMainFrame(); 01868 }
|
|
Initialises the ExternalClipboard ready for operation.
Definition at line 271 of file clipext.cpp. 00272 { 00273 if (!OpClipboardExport::Init()) 00274 return(FALSE); 00275 00276 if (!OpClipboardImport::Init()) 00277 return(FALSE); 00278 00279 if (!PasteSpecialDlg::Init()) 00280 return(FALSE); 00281 00282 ExternalClipboard *TheClipboard = new ExternalClipboard(); 00283 if (TheClipboard == NULL) 00284 return(FALSE); 00285 00286 00287 // **** !!!! DEBUG BODGE - add export mapping for text characters - ideally this 00288 // clipboard mapping should be provided by a proper text import/export filter, 00289 // but one does not exist yet. 00290 // Add a UNICODE filter - this only works under NT, as nobody else supports unicode 00291 BodgeUnicodeClipMap::CreateAndRegister(CLIPMAP_IMPORTEXPORT, CF_UNICODETEXT); 00292 00293 // 8-bit text (windows implicitly converts between these for us) 00294 // The first one is the filter, while the second one is an 'alias' for import 00295 // which will make windows convert the OEMTEXT into TEXT and then we put this through 00296 // our normal TEXT mapping... 00297 BodgeTextClipMap::CreateAndRegister(CLIPMAP_IMPORTEXPORT, CF_TEXT); 00298 BodgeTextClipMap::CreateAndRegister(CLIPMAP_IMPORTONLY, CF_OEMTEXT); 00299 00300 // Add bitmap/DIB import/export mappings 00301 // Note that if we export WMF and DIB, there is no need to bother with Bitmap 00302 // (Corel don't, probably because there is no way of getting a quality image via Bitmaps, 00303 // and also because some programs are stupid and corrupt the DIB by using the palette 00304 // which we supply for the Bitmap! Arrgh!) 00305 // BitmapClipMap::CreateAndRegister(CLIPMAP_IMPORTEXPORT); 00306 BitmapClipMap::CreateAndRegister(CLIPMAP_IMPORTONLY); 00307 00308 DIBClipMap::CreateAndRegister(CLIPMAP_IMPORTEXPORT); 00309 00310 // CMX import and export stuff to make commicating with Corel happier 00311 CMX16ClipMap::CreateAndRegister(CLIPMAP_IMPORTEXPORT, ::RegisterClipboardFormat("Corel Presentation Exchange Data")); 00312 CMX32ClipMap::CreateAndRegister(CLIPMAP_IMPORTEXPORT, ::RegisterClipboardFormat("Corel 32-bit Presentation Exchange Data")); 00313 00314 // native clipboard thing -- for OLE stuff 00315 // 00316 // this is export only (although functional code does exist for import) 00317 // as there are several technical problems with getting the native filter 00318 // to import into the clipboard document. See the comment near the 00319 // NativeClipMap::HandleImport() function for more details. 00320 NativeClipMap::CreateAndRegister(CLIPMAP_IMPORTEXPORT /*CLIPMAP_EXPORTONLY*/, ::RegisterClipboardFormat("CorelXARA Document")); 00321 // NativeClipMap::CreateAndRegister(CLIPMAP_IMPORTEXPORT /*CLIPMAP_EXPORTONLY*/, ::RegisterClipboardFormat("XaraX Document")); 00322 00323 // Add a palette export mapping - used in conjunction with Bitmap exporter, it provides 00324 // the palette for the given bitmap. (not needed now we don't export BMPs) 00325 // PaletteClipMap::CreateAndRegister(); 00326 00327 #if FALSE 00328 // And add our Quark EPS import filter 00329 QuarkPictureClipMap::CreateAndRegister(); 00330 #endif 00331 00332 // Read the bug-fix preference for CMX. 00333 if (!GetApplication()->DeclareSection(TEXT("OLE Local Server"), 5) || 00334 !GetApplication()->DeclarePref(TEXT("OLE Local Server"), 00335 TEXT("DontExportCMXInIDataObject"), 00336 &fNoCMXDataExport, FALSE, TRUE)) 00337 { 00338 TRACEUSER( "JustinF", _T("Couldn't read CMX pref in ExternalClipboard::Init\n")); 00339 return FALSE; 00340 } 00341 00342 return(TRUE); 00343 }
|
|
To ready the clipboard for a cut/copy operation (copy data TO the clipboard). This will interact with the external clipboard in order to claim the global clipboard, and readies the clipboard for use.
Scope: protected (for friend class InternalClipboard only)
Definition at line 943 of file clipext.cpp. 00944 { 00945 BOOL IsEmpty = TRUE; 00946 00947 if (pInstance == NULL) 00948 return(TRUE); 00949 00950 CWnd *Parent = GetOwnerWindow(); 00951 if (Parent == NULL) return TRUE; 00952 00953 if (pInstance->IsOurs()) // We own the clipboard! Use the internal one 00954 { 00955 if (InternalClipboard::IsEmpty(FALSE)) 00956 { 00957 ERROR3("We own the clipboard but the internal clipboard is empty!!"); 00958 } 00959 else 00960 { 00961 ERROR3("Why are you asking the External clipboard if it's empty when the internal one isn't?"); 00962 } 00963 return(FALSE); 00964 } 00965 00966 if (Parent->OpenClipboard() == NULL) 00967 return(TRUE); // Can't open the clipboard, so we're empty 00968 00969 ClipboardMapping *Mapping; 00970 UINT32 ThisFormat = 0; // 0 makes EnumClipboardFormats start from the beginning 00971 do 00972 { 00973 ThisFormat = EnumClipboardFormats(ThisFormat); 00974 00975 if (ThisFormat != 0) 00976 { 00977 Mapping = (ClipboardMapping *) pInstance->Mappings.GetHead(); 00978 while (Mapping != NULL && IsEmpty) 00979 { 00980 // If this mapping is an import mapping and can handle this external format, 00981 // then we need look no further - there is importable data on the clipboard 00982 if (Mapping->Type != CLIPMAP_EXPORTONLY && Mapping->ExternalDataType == ThisFormat) 00983 IsEmpty = FALSE; 00984 00985 Mapping = (ClipboardMapping *) pInstance->Mappings.GetNext(Mapping); 00986 } 00987 } 00988 } while (ThisFormat != 0 && IsEmpty); 00989 00990 ::CloseClipboard(); 00991 return(IsEmpty); 00992 }
|
|
Definition at line 427 of file clipext.cpp. 00428 { 00429 #if (_OLE_VER >= 0x200) 00430 // OLE does it with data sources (but paste still does it with window handles). 00431 return CCamDataSource::GetClipboardOwner() != 0 || 00432 CWnd::GetClipboardOwner() == GetOwnerWindow(); 00433 #else 00434 // Windows does it with window handles. 00435 return CWnd::GetClipboardOwner() == GetOwnerWindow(); 00436 #endif 00437 }
|
|
Create a new temporary clipboard document and point the statics at it.
Definition at line 2717 of file clipext.cpp. 02718 { 02719 // TODO: Make new internal and external clipboard objects 02720 // BODGE: Just use the existing clipboards 02721 return(ExternalClipboard::pInstance); 02722 }
|
|
Tells the ExternalClipboard that you have finished copying data from it. This provides interaction with the external clipboard.
Scope: protected (for friend class InternalClipboard only)
Definition at line 1564 of file clipext.cpp. 01565 { 01566 // Do nothing 01567 01568 return(TRUE); 01569 }
|
|
To ready the clipboard for a cut/copy operation (copy data TO the clipboard). This will interact with the external clipboard in order to claim the global clipboard, and readies the clipboard for use.
Scope: protected (for friend class InternalClipboard only)
Definition at line 1018 of file clipext.cpp. 01019 { 01020 // Do nothing 01021 01022 return(TRUE); 01023 }
|
|
To ready the clipboard for a paste operation (copy data FROM the clipboard). This may interact with the external clipboard in order to provide the necessary data.
Scope: protected (for friend class InternalClipboard only)
Definition at line 1386 of file clipext.cpp. 01387 { 01388 // Open the clipboard - if this fails, return immediately 01389 CWnd *Parent = GetOwnerWindow(); 01390 if (Parent->OpenClipboard() == NULL) 01391 return(FALSE); 01392 01393 ClipboardMapping *Mapping; 01394 01395 UINT32 ForceFormat = 0; 01396 UINT32 ThisFormat = 0; 01397 01398 #if DO_PASTE_SPECIAL 01399 // First, count how many external formats are available - if there are less than 2 formats 01400 // which we can import, then there is no point in showing the paste-special dialogue. 01401 INT32 NumExternalFormats = 0; 01402 BOOL IncludesTextFormat = FALSE; 01403 do 01404 { 01405 ThisFormat = EnumClipboardFormats(ThisFormat); 01406 if (ThisFormat != 0 && ExternalClipboard::CanImport(ThisFormat)) 01407 { 01408 // Bodge - text can be on the clipboard in 3 forms, but we only want to treat 01409 // it as a single format for the 'paste special' count 01410 if (ThisFormat == CF_TEXT || ThisFormat == CF_UNICODETEXT || ThisFormat == CF_OEMTEXT) 01411 { 01412 if (!IncludesTextFormat) 01413 NumExternalFormats++; 01414 01415 IncludesTextFormat = TRUE; 01416 } 01417 else 01418 NumExternalFormats++; 01419 } 01420 } while (ThisFormat != 0); 01421 01422 // if there are 2 or more external fornmats, then pop up the paste special dialogue automatically 01423 if (NumExternalFormats > 1) 01424 { 01425 ForceFormat = PasteSpecialDlg::InvokeDialog(); 01426 if (ForceFormat == 0) 01427 { 01428 // User pressed "cancel" 01429 ::CloseClipboard(); 01430 return(FALSE); 01431 } 01432 } 01433 01434 #if _DEBUG 01435 { 01436 TRACEUSER( "Jason", _T("\nClipboard formats available:\n")); 01437 UINT32 ThisFormat = 0; 01438 do 01439 { 01440 ThisFormat = EnumClipboardFormats(ThisFormat); 01441 if (ThisFormat != 0) 01442 { 01443 String_64 name; 01444 GetExternalFormatName(ThisFormat, &name); 01445 TRACEUSER( "Jason", _T(" %ld %s %s\n", (INT32)ThisFormat, (TCHAR *)name, CanImport(ThisFormat)?" (supported)":"")); 01446 } 01447 } while (ThisFormat != 0); 01448 } 01449 #endif 01450 #endif 01451 01452 BOOL IKnowWhatType = FALSE; 01453 ThisFormat = 0; 01454 01455 // If we know we`ve only one format type and it`s a text object, find out if the clipboard 01456 // is holding it as a UNICODE format 01457 if(IncludesTextFormat && NumExternalFormats == 1) 01458 { 01459 // To find out if it`s unicode, we need to search the clipboard enumerations to 01460 // see if it contains the unicode type. 01461 IKnowWhatType = TRUE; 01462 UINT32 Type = EnumClipboardFormats(0); 01463 01464 while(Type > 0) 01465 { 01466 if(Type == 13) 01467 { 01468 ThisFormat = 13; 01469 break; 01470 } 01471 01472 Type = EnumClipboardFormats(Type); 01473 } 01474 01475 // If we didn`t find the unicode type set it to the normal type! 01476 if(ThisFormat == 0) 01477 ThisFormat = 1; 01478 } 01479 01480 do 01481 { 01482 if(!IKnowWhatType) 01483 ThisFormat = EnumClipboardFormats(ThisFormat); 01484 01485 if (ThisFormat != 0) 01486 { 01487 if (ForceFormat == 0 || ForceFormat == ThisFormat) 01488 Mapping = (ClipboardMapping *) Mappings.GetHead(); 01489 else 01490 Mapping = NULL; 01491 01492 while (Mapping != NULL) 01493 { 01494 // Is this mapping an import mapping for the given format? 01495 if (Mapping->Type != CLIPMAP_EXPORTONLY && Mapping->ExternalDataType == ThisFormat) 01496 { 01497 // Little check here - if this is a simple mapping, then we can go ahead. however, 01498 // if it says 'unformatted text' but will actually try to use windows' implicit conversion 01499 // to unicode text, we really need to check if the 'real' data type (unicode) is also 01500 // available on the clipboard. 01501 if (Mapping->ExternalDataType == Mapping->RealExternalType || 01502 ::IsClipboardFormatAvailable(Mapping->RealExternalType)) 01503 { 01504 #if _DEBUG 01505 { 01506 String_64 name; 01507 GetExternalFormatName(ThisFormat, &name); 01508 TRACEUSER( "Jason", _T("I choose to import: %s\n"), (TCHAR *)name); 01509 if (Mapping->ExternalDataType != Mapping->RealExternalType) 01510 { 01511 GetExternalFormatName(Mapping->RealExternalType, &name); 01512 TRACEUSER( "Jason", _T(" (Which actually imports via implicit conversion to %s)\n"), (TCHAR *)name); 01513 } 01514 } 01515 #endif 01516 OpDescriptor *ImportOp = OpDescriptor::FindOpDescriptor(CC_RUNTIME_CLASS(OpClipboardImport)); 01517 ERROR3IF(ImportOp == NULL, "Clipboard Import OpDesc not found!"); 01518 01519 if (ImportOp != NULL) 01520 { 01521 OpParam Bob((INT32)Mapping, 0); 01522 ImportOp->Invoke(&Bob); 01523 } 01524 01525 ::CloseClipboard(); 01526 return(!InternalClipboard::IsEmpty(FALSE)); 01527 } 01528 01529 ERROR3("Windows implicit clipboard conversion unavailable! Trying other formats"); 01530 } 01531 01532 Mapping = (ClipboardMapping *) Mappings.GetNext(Mapping); 01533 } 01534 } 01535 } while (ThisFormat != 0); 01536 01537 ::CloseClipboard(); 01538 return(FALSE); 01539 }
|
|
Definition at line 465 of file clipext.cpp. 00466 { 00467 // Is there a clipboard? 00468 if (InternalClipboard::IsEmpty(FALSE)) return; 00469 00470 ExternalClipboard* pClipboard = GetExternalClipboard(); 00471 if (pClipboard == NULL) return; 00472 00473 pClipboard->CheckKeepClipboardOnExit(); 00474 00475 #if (_OLE_VER >= 0x200) 00476 00477 if (pClipboard->KeepFormatsOnExit) 00478 { 00479 // Render all the clipboard formats now (except CMX cos it may crash if there's a 00480 // bitmap or a fractal about - doh-doh-double-doh?!?!?) 00481 // TRACEUSER( "JustinF", _T("Rendering clipboard formats now ...\n")); 00482 fBodgeNoCMX = TRUE; 00483 CCamDataSource::FlushClipboard(); 00484 fBodgeNoCMX = FALSE; 00485 } 00486 else 00487 { 00488 // Discard the clipboard contents now. 00489 // TRACEUSER( "JustinF", _T("Discarding clipboard formats ...\n")); 00490 COleDataSource* pSource = CCamDataSource::GetClipboardOwner(); 00491 if (pSource) pSource->Empty(); 00492 } 00493 00494 #else 00495 00496 // This member var. will have been set by someone calling CheckKeepClipboardOnExit() 00497 if (!pClipboard->KeepFormatsOnExit) 00498 { 00499 // They don't want to keep the clipboard formats, so wipe the clipboard. 00500 CWnd* pParent = GetOwnerWindow(); 00501 if (pParent->OpenClipboard() != NULL) 00502 { 00503 ::EmptyClipboard(); 00504 ::CloseClipboard(); 00505 } 00506 return; 00507 } 00508 00509 // They do want to keep the clipboard contents, so render all formats to it now 00510 pClipboard->RenderAllFormats(); 00511 00512 #endif 00513 00514 // And make sure that we ignore any further attempt to make us render formats 00515 pClipboard->KeepFormatsOnExit = FALSE; 00516 }
|
|
Called by filters to add import/export mappings to the external clipboard. Each mapping indicates which filter to call in order to convert data between a particular internal and external clipboard format.
Definition at line 678 of file clipext.cpp. 00679 { 00680 ERROR3IF(Mapping == NULL, "Illegal NULL param"); 00681 00682 if (pInstance == NULL) 00683 { 00684 ERROR3("Attempt to register a clipboard mapping when there is no ExternalClipboard"); 00685 delete Mapping; 00686 return; 00687 } 00688 00689 List *TheList = &pInstance->Mappings; 00690 ClipboardMapping *Ptr = (ClipboardMapping *) TheList->GetHead(); 00691 00692 while (Ptr != NULL) 00693 { 00694 if (Ptr->Priority < Mapping->Priority) 00695 { 00696 TheList->InsertBefore(Ptr, Mapping); 00697 return; 00698 } 00699 00700 Ptr = (ClipboardMapping *) TheList->GetNext(Ptr); 00701 } 00702 00703 // Haven't found a lower-priority entry, so this one belongs at the tail 00704 TheList->AddTail(Mapping); 00705 }
|
|
Renders all available formats onto the windows clipboard Called when WM_RENDER_ALL_FORMATS is received (if the application quits when it owns the clipboard).
Despite what some help entries in books online may say, this method should NOT OpenClipboard() before doing SetClipboardData()
Definition at line 1795 of file clipext.cpp. 01796 { 01797 if (InternalClipboard::IsEmpty(FALSE)) // No clipboard! Eek! 01798 return; 01799 01800 // **** !!!! Check if the user wants us to keep the clipboard contents 01801 // This should be called from elsewhere so the question box appears before the main frame 01802 // window has been closed... 01803 // CheckKeepClipboardOnExit(); 01804 // **** 01805 01806 // This member var. will have been set by someone calling CheckKeepClipboardOnExit() 01807 if (!KeepFormatsOnExit) 01808 return; 01809 01810 CWnd *Parent = GetOwnerWindow(); 01811 if (Parent->OpenClipboard() != NULL) 01812 { 01813 ClipboardMapping *Mapping = (ClipboardMapping *) Mappings.GetHead(); 01814 while (Mapping != NULL) 01815 { 01816 if (Mapping->Type != CLIPMAP_IMPORTONLY && Mapping->Available) 01817 RenderFormat(Mapping); // Only render the available formats 01818 01819 Mapping = (ClipboardMapping *) Mappings.GetNext(Mapping); 01820 } 01821 01822 ::CloseClipboard(); 01823 } 01824 }
|
|
"Renders" the given format to the clipboard (i.e. exports the internal clipboard to the windows clipboard using the specified mapping)
Notes: This is the internal form of this method; It is called by the other form once the mapping has been determined. Despite what some help entries in books online may say, this method should NOT OpenClipboard() before doing SetClipboardData() Definition at line 1722 of file clipext.cpp. 01723 { 01724 ERROR3IF(pMapping == NULL, "Illegal NULL param"); 01725 ERROR3IF(!pMapping->Available, "Requested clipboard format is not available!"); 01726 ERROR3IF(pMapping->Type == CLIPMAP_IMPORTONLY, "Attempt to use import-only mapping for export"); 01727 01728 if (pMapping == NULL || !pMapping->Available || pMapping->Type == CLIPMAP_IMPORTONLY) 01729 return; 01730 01731 // JustinF says: bodge alert! We mustn't render CMX formats on shut-down because they 01732 // crash if the clipboard doc contains bitmaps or fractals. 01733 if (pMapping->IS_KIND_OF(CMXClipMap) && (fBodgeNoCMX || fNoCMXDataExport)) 01734 { 01735 TRACEUSER( "JustinF", _T("Skipping CMX mapping at 0x%p\n"), (LPVOID) pMapping); 01736 return; 01737 } 01738 01739 // The "export to clipboard" must be done inside an Op so it can call filters, so find the 01740 // OpDescriptor, and call our Export Op. 01741 OpDescriptor* pExportOp = OpDescriptor::FindOpDescriptor(CC_RUNTIME_CLASS(OpClipboardExport)); 01742 ERROR3IF(pExportOp == NULL, "Clipboard Export OpDesc not found!"); 01743 01744 // The OLE clipboard can pass you an already allocated memory block of a given size. 01745 if (pExportOp) 01746 { 01747 #if (_OLE_VER >= 0x200) 01748 01749 // Pass on the mapping and the parameters from SetRenderMemory. 01750 OpClipboardExportParams prm; 01751 prm.pMapping = pMapping; 01752 prm.hMem = m_hMem; 01753 prm.cbMemSize = m_cbMemSize; 01754 prm.pDoc = m_pDoc; 01755 01756 // Invoke the export op for the given format on the given memory. 01757 OpParam opp((INT32) &prm, 0); 01758 pExportOp->Invoke(&opp); 01759 01760 // Maybe the operation allocated the memory, so update these just in case. 01761 m_hMem = prm.hMem; 01762 m_cbMemSize = prm.cbMemSize; 01763 01764 #else 01765 01766 OpParam opp((INT32) pMapping, 0); 01767 pExportOp->Invoke(&opp); 01768 01769 #endif 01770 } 01771 }
|
|
"Renders" the given format to the clipboard (i.e. exports the internal clipboard to the windows clipboard using the specified mapping)
Notes: This is the external interface. This then calls the other override of RenderFormat to actually do the rendering. Despite what some help entries in books online may say, this method should NOT OpenClipboard() before doing SetClipboardData() Definition at line 1669 of file clipext.cpp. 01670 { 01671 if (InternalClipboard::IsEmpty(FALSE)) // No clipboard! Eek! 01672 return; 01673 01674 // Check for all the boring old static formats. 01675 ClipboardMapping *Mapping = (ClipboardMapping *) Mappings.GetHead(); 01676 while (Mapping != NULL) 01677 { 01678 // If this mapping is for export, and matches the desired output format 01679 if (Mapping->Type != CLIPMAP_IMPORTONLY && Mapping->ExternalDataType == nFmt) 01680 { 01681 if (Mapping->Available) 01682 RenderFormat(Mapping); 01683 else 01684 { 01685 ERROR2RAW("Requested clipboard format is unavailable!"); 01686 InformError(); 01687 } 01688 01689 return; 01690 } 01691 Mapping = (ClipboardMapping *) Mappings.GetNext(Mapping); 01692 } 01693 01694 ERROR2RAW("Requested clipboard format is illegal (unknown)!"); 01695 InformError(); 01696 }
|
|
Delete the temporary clipboard and return any static pointers to normal.
Definition at line 2740 of file clipext.cpp. 02741 { 02742 return TRUE; 02743 }
|
|
Definition at line 302 of file clipext.h. 00303 { m_fUpdateSystemClipboard = fState; }
|
|
Destroys the internal clipboard.
Definition at line 1624 of file clipext.cpp. 01625 { 01626 #if (_OLE_VER >= 0x200) 01627 // The comment below is no longer true, as now OLE takes possession of the clipboard 01628 // for us, which the old code thinks is someone else taking possession, and hence it 01629 // clears out the clipboard. This bodgy flag stops that happening when we ask OLE 01630 // to set the clipboard for us. 01631 // TRACEUSER( "JustinF", _T("In ExternalClipboard::WindowsClipboardHasChanged\n")); 01632 if (m_fIgnoreChange) 01633 { 01634 // TRACEUSER( "JustinF", _T("\t- ignoring this change to the clipboard ...\n")); 01635 return; 01636 } 01637 #endif 01638 01639 // Whenever this method is called, we only wipe the clipboard if someone else owns it 01640 // (we're guaranteed to be called with us as the owner in all the situations where 01641 // we don't want to wipe the internal clipboard! Excellent!) 01642 if (!IsOurs() && m_fUpdateSystemClipboard) InternalClipboard::Clear(); 01643 }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|