00001 // $Id: clipmap.cpp 1282 2006-06-09 09:46:49Z alex $ 00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE 00003 ================================XARAHEADERSTART=========================== 00004 00005 Xara LX, a vector drawing and manipulation program. 00006 Copyright (C) 1993-2006 Xara Group Ltd. 00007 Copyright on certain contributions may be held in joint with their 00008 respective authors. See AUTHORS file for details. 00009 00010 LICENSE TO USE AND MODIFY SOFTWARE 00011 ---------------------------------- 00012 00013 This file is part of Xara LX. 00014 00015 Xara LX is free software; you can redistribute it and/or modify it 00016 under the terms of the GNU General Public License version 2 as published 00017 by the Free Software Foundation. 00018 00019 Xara LX and its component source files are distributed in the hope 00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the 00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00022 See the GNU General Public License for more details. 00023 00024 You should have received a copy of the GNU General Public License along 00025 with Xara LX (see the file GPL in the root directory of the 00026 distribution); if not, write to the Free Software Foundation, Inc., 51 00027 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00028 00029 00030 ADDITIONAL RIGHTS 00031 ----------------- 00032 00033 Conditional upon your continuing compliance with the GNU General Public 00034 License described above, Xara Group Ltd grants to you certain additional 00035 rights. 00036 00037 The additional rights are to use, modify, and distribute the software 00038 together with the wxWidgets library, the wxXtra library, and the "CDraw" 00039 library and any other such library that any version of Xara LX relased 00040 by Xara Group Ltd requires in order to compile and execute, including 00041 the static linking of that library to XaraLX. In the case of the 00042 "CDraw" library, you may satisfy obligation under the GNU General Public 00043 License to provide source code by providing a binary copy of the library 00044 concerned and a copy of the license accompanying it. 00045 00046 Nothing in this section restricts any of the rights you have under 00047 the GNU General Public License. 00048 00049 00050 SCOPE OF LICENSE 00051 ---------------- 00052 00053 This license applies to this program (XaraLX) and its constituent source 00054 files only, and does not necessarily apply to other Xara products which may 00055 in part share the same code base, and are subject to their own licensing 00056 terms. 00057 00058 This license does not apply to files in the wxXtra directory, which 00059 are built into a separate library, and are subject to the wxWindows 00060 license contained within that directory in the file "WXXTRA-LICENSE". 00061 00062 This license does not apply to the binary libraries (if any) within 00063 the "libs" directory, which are subject to a separate license contained 00064 within that directory in the file "LIBS-LICENSE". 00065 00066 00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS 00068 ---------------------------------------------- 00069 00070 Subject to the terms of the GNU Public License (see above), you are 00071 free to do whatever you like with your modifications. However, you may 00072 (at your option) wish contribute them to Xara's source tree. You can 00073 find details of how to do this at: 00074 http://www.xaraxtreme.org/developers/ 00075 00076 Prior to contributing your modifications, you will need to complete our 00077 contributor agreement. This can be found at: 00078 http://www.xaraxtreme.org/developers/contribute/ 00079 00080 Please note that Xara will not accept modifications which modify any of 00081 the text between the start and end of this header (marked 00082 XARAHEADERSTART and XARAHEADEREND). 00083 00084 00085 MARKS 00086 ----- 00087 00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara 00089 designs are registered or unregistered trademarks, design-marks, and/or 00090 service marks of Xara Group Ltd. All rights in these marks are reserved. 00091 00092 00093 Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. 00094 http://www.xara.com/ 00095 00096 =================================XARAHEADEREND============================ 00097 */ 00098 // External clipboard interface - classes for encapsulating clipboard data mappings 00099 // and for managing data transfers between the internal and external clipboards 00100 00101 /* 00102 */ 00103 00104 00105 #include "camtypes.h" 00106 00107 // -- clipboard includes 00108 #include "clipext.h" 00109 #include "clipint.h" 00110 #include "clipmap.h" 00111 00112 // --- text includes **** !!!! BODGE 00113 //#include "fillattr.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00114 #include "layer.h" 00115 #include "nodetext.h" 00116 #include "nodetxtl.h" 00117 #include "nodetxts.h" 00118 #include "unicdman.h" 00119 00120 // --- Bitmap Mapping includes 00121 #include "bitmpinf.h" 00122 //#include "dibutil.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00123 //#include "fixmem.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00124 //#include "jason.h" 00125 #include "nodebmp.h" 00126 #include "wbitmap.h" 00127 #include "scrcamvw.h" 00128 //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00129 00130 // --- 00131 //#include "ccfile.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00132 //#include "filters.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00133 //#include "nev.h" 00134 00135 #include "cmxifltr.h" 00136 00137 // This class is defined in kernel\cliptype.h 00138 CC_IMPLEMENT_MEMDUMP(InternalClipboardFormat, CC_CLASS_MEMDUMP) 00139 00140 CC_IMPLEMENT_DYNCREATE(ClipboardMapping, ListItem) 00141 00142 CC_IMPLEMENT_DYNCREATE(BodgeTextClipMap, ClipboardMapping) 00143 CC_IMPLEMENT_DYNCREATE(BodgeUnicodeClipMap, ClipboardMapping) 00144 00145 CC_IMPLEMENT_DYNAMIC(CMXClipMap, ClipboardMapping) 00146 CC_IMPLEMENT_DYNCREATE(CMX16ClipMap, CMXClipMap) 00147 CC_IMPLEMENT_DYNCREATE(CMX32ClipMap, CMXClipMap) 00148 00149 #ifdef _DEBUG 00150 CC_IMPLEMENT_DYNCREATE(RTFClipMap, ClipboardMapping) 00151 #endif 00152 00153 CC_IMPLEMENT_DYNCREATE(BitmapClipMap, ClipboardMapping) 00154 //CC_IMPLEMENT_DYNCREATE(PaletteClipMap, ClipboardMapping) 00155 CC_IMPLEMENT_DYNCREATE(DIBClipMap, ClipboardMapping) 00156 00157 #if FALSE 00158 CC_IMPLEMENT_DYNCREATE(QuarkPictureClipMap, ClipboardMapping) 00159 #endif 00160 00161 #define new CAM_DEBUG_NEW 00162 00163 00164 00165 00166 /******************************************************************************************** 00167 00168 > ClipboardMapping::ClipboardMapping() 00169 00170 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00171 Created: 16/4/95 00172 00173 Purpose: Constructor 00174 00175 Notes: DON'T call the constructor - call CreateAndRegister 00176 00177 SeeAlso: ClipboardMapping::CreateAndRegister 00178 00179 ********************************************************************************************/ 00180 00181 ClipboardMapping::ClipboardMapping() 00182 { 00183 ERROR3("You can't directly construct an ClipboardMapping - Call CreateAndRegister"); 00184 } 00185 00186 00187 00188 /******************************************************************************************** 00189 00190 > ClipboardMapping::~ClipboardMapping() 00191 00192 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00193 Created: 16/4/95 00194 00195 Purpose: Destructor 00196 00197 ********************************************************************************************/ 00198 00199 ClipboardMapping::~ClipboardMapping() 00200 { 00201 RemoveTempFile(); 00202 } 00203 00204 00205 00206 /******************************************************************************************** 00207 00208 > ClipboardMapping::ClipboardMapping(ClipboardMappingType TheType, Filter *TheFilter, 00209 InternalClipboardFormat &TheInternalDataType, 00210 UINT32 TheExternalDataType, 00211 UINT32 ThePriority) 00212 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00213 Created: 16/4/95 00214 00215 Inputs: TheType - indicates import / export / import & export 00216 00217 TheFilter - The filter which can apply this conversion 00218 00219 TheInternalDatatType - A class defining the internal data type 00220 (see cliptype.h) 00221 00222 TheExternalDataType - A Windows CF_ constant defining the external 00223 clipboard data type which will be imported/exported. 00224 00225 ThePriority - An integer indicating the priority of this mapping. 00226 The highest available priority mapping will be used in order to 00227 retain as much information in the data as possible. See 00228 docs\howtouse\ExtClip.doc for details of the existing mappings. 00229 00230 Purpose: Constructs a clipboard mapping with the ExternalClipboard 00231 manager. This mapping info describes a filter which is able to import 00232 data from or export data to a windows clipboard in some way. 00233 00234 Notes: DON'T call the constructor - call CreateAndRegister 00235 00236 SeeAlso: ClipboardMapping::CreateAndRegister; InternalClipboardFormat 00237 00238 ********************************************************************************************/ 00239 00240 ClipboardMapping::ClipboardMapping(ClipboardMappingType TheType, Filter *TheFilter, 00241 InternalClipboardFormat &TheInternalDataType, 00242 UINT32 TheExternalDataType, 00243 UINT32 ThePriority) 00244 { 00245 Type = TheType; 00246 pFilter = TheFilter; 00247 00248 InternalDataType.SetFormatID(TheInternalDataType.GetFormatID()); 00249 ExternalDataType = RealExternalType = TheExternalDataType; 00250 00251 Priority = ThePriority; 00252 00253 Available = FALSE; 00254 00255 tempfilename = NULL; 00256 } 00257 00258 00259 00261 // 00262 // The OLE clipboard 00263 // 00264 00265 #if (_OLE_VER >= 0x200) 00266 00267 /******************************************************************************************** 00268 > void ClipboardMapping::SetRenderMemory(HGLOBAL hMem, DWORD cbMemSize) 00269 00270 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00271 Created: 16/9/96 00272 Inputs: hMem --- the global memory to delay-render into, or null if 00273 the rendering functions themselves should allocate 00274 it. 00275 cbMemSize --- the size of the given memory block. 00276 Purpose: Sets the memory that the delay-render functions will render into. 00277 SeeAlso: ExternalClipboard::SetRenderMemory; OpClipboardExport::DoWithParam 00278 ********************************************************************************************/ 00279 00280 void ClipboardMapping::SetRenderMemory(HGLOBAL hMem, DWORD cbMemSize) 00281 { 00282 // Record the handle and its size. 00283 m_hMem = hMem; 00284 m_cbMemSize = cbMemSize; 00285 } 00286 00287 #endif 00288 00290 00291 00292 00293 /******************************************************************************************** 00294 00295 > static void ClipboardMapping::CreateAndRegister(ClipboardMappingType TheType, Filter *TheFilter, 00296 InternalClipboardFormat &TheInternalDataType, 00297 UINT32 TheExternalDataType, 00298 UINT32 ThePriority) 00299 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00300 Created: 16/4/95 00301 00302 Inputs: TheType - indicates import / export / import & export 00303 00304 TheFilter - The filter which can apply this conversion 00305 00306 TheInternalDatatType - An object defining the internal data type 00307 (see cliptype.h) 00308 00309 TheExternalDataType - A Windows CF_ constant defining the external 00310 clipboard data type which will be imported/exported. 00311 00312 ThePriority - An integer indicating the priority of this mapping. 00313 The highest available priority mapping will be used in order to 00314 retain as much information in the data as possible. See 00315 docs\howtouse\ExtClip.doc for details of the existing mappings. 00316 00317 Purpose: Constructs and registers a clipboard mapping with the ExternalClipboard 00318 manager. This mapping info describes a filter which is able to import 00319 data from or export data to a windows clipboard in some way. 00320 00321 SeeAlso: InternalClipboardFormat 00322 00323 ********************************************************************************************/ 00324 00325 void ClipboardMapping::CreateAndRegister(ClipboardMappingType TheType, Filter *TheFilter, 00326 InternalClipboardFormat &TheInternalDataType, 00327 UINT32 TheExternalDataType, 00328 UINT32 ThePriority) 00329 { 00330 ClipboardMapping *Mapping = new ClipboardMapping(TheType, TheFilter, 00331 TheInternalDataType, TheExternalDataType, 00332 ThePriority); 00333 if (Mapping == NULL) 00334 InformError(); 00335 else 00336 ExternalClipboard::RegisterDataType(Mapping); 00337 } 00338 00339 00340 00341 /******************************************************************************************** 00342 00343 > BOOL ClipboardMapping::ImportFromTempFile(TCHAR *filename, SelOperation *Caller, 00344 InternalClipboard *Dest) 00345 00346 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00347 Created: 20/4/95 00348 00349 Inputs: filename - the file name of the temporary scratch file to be loaded 00350 Dest - the internal clipboard document to import into 00351 00352 00353 Purpose: Internal helper function. Invokes pFilter::DoImport into the Dest doc, 00354 using the given file as a source. 00355 00356 Notes: You must remove() the tem file yourself afterwards. 00357 00358 ********************************************************************************************/ 00359 00360 BOOL ClipboardMapping::ImportFromTempFile(TCHAR *filename, SelOperation *Caller, 00361 InternalClipboard *Dest) 00362 { 00363 PathName FileToLoad(filename); 00364 00365 CCLexFile* pFile = new CCDiskFile(1024, FALSE, TRUE); 00366 00367 // See if we have a valid file 00368 if (pFile == NULL) 00369 return FALSE; 00370 00371 // we have to try and open the file 00372 TRY 00373 { 00374 if (!((CCDiskFile*)pFile)->open(FileToLoad, ios::in | ios::binary)) 00375 { 00376 // Failed to open the file... 00377 delete pFile; 00378 pFile = NULL; 00379 ERROR2RAW("Failed to open temp file for import into clipboard"); 00380 return(FALSE); 00381 } 00382 00383 // Found the Filter, so ask it to import the file please 00384 00385 // Provide a current view for the filter to chomp on; We stack the current 00386 // view so that we do not corrupt it. 00387 View *OldCurrentView = View::GetCurrent(); 00388 ClipboardView ImportView; 00389 if (!ImportView.Init()) 00390 { 00391 delete pFile; 00392 pFile = NULL; 00393 return(FALSE); 00394 } 00395 00396 ImportView.SetCurrent(); 00397 00398 if (!pFilter->DoImport(Caller, pFile, InternalClipboard::Instance())) 00399 { 00400 // Something went a bit wrong - tell the user what it was. 00401 // Only tell them if not special user cancelled error message 00402 if (Error::GetErrorNumber() != _R(IDN_USER_CANCELLED)) 00403 InformError(); 00404 00405 // If the file is open, then close it 00406 if (pFile->isOpen()) 00407 pFile->close(); 00408 00409 // and die a bit 00410 delete pFile; 00411 pFile = NULL; 00412 00413 if (OldCurrentView != NULL) 00414 OldCurrentView->SetCurrent(); 00415 return FALSE; 00416 } 00417 00418 if (OldCurrentView != NULL) 00419 OldCurrentView->SetCurrent(); 00420 00421 // If the file is open, then close it 00422 if (pFile->isOpen()) 00423 pFile->close(); 00424 } 00425 00426 // See if there was a file I/O error 00427 CATCH(CFileException, e) 00428 { 00429 // Report the error if no one else did 00430 if (Error::GetErrorNumber() != _R(IDN_USER_CANCELLED)) 00431 InformError(); 00432 00433 // Make sure that the file is closed 00434 TRY 00435 { 00436 // Close the file 00437 if (pFile->isOpen()) 00438 pFile->close(); 00439 } 00440 CATCH(CFileException, e) 00441 { 00442 // Not a lot we can do really... 00443 } 00444 END_CATCH 00445 00446 // and fail 00447 delete pFile; 00448 pFile = NULL; 00449 return FALSE; 00450 } 00451 END_CATCH 00452 00453 // Make sure that we have got rid of the file 00454 delete pFile; 00455 00456 return(TRUE); 00457 } 00458 00459 00460 00461 /******************************************************************************************** 00462 00463 > virtual BOOL ClipboardMapping::HandleImport(SelOperation *Caller, 00464 HANDLE ClipboardData, 00465 InternalClipboard *Dest) 00466 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00467 Created: 20/4/95 00468 00469 Inputs: Caller - The operation within which this method is being called 00470 ClipboardData - The result of calling GetClipboardData for your datatype 00471 Dest - The InternalClipboard (document) to import the data into. 00472 00473 Returns: TRUE for success 00474 00475 Purpose: Calls the parent filter as appropriate to import the given data from 00476 the external clipboard. 00477 00478 Notes: This base-class default treats the clipboard data as a file, and makes 00479 the associated filter import it directly. (Note: It is currently 00480 implemented by slaving a temp file to disc, in order to avoid CCMemFiles 00481 which are not currently good enough for us to use) 00482 00483 ********************************************************************************************/ 00484 00485 BOOL ClipboardMapping::HandleImport(SelOperation *Caller, 00486 HANDLE ClipboardData, InternalClipboard *Dest) 00487 { 00488 BOOL ok = TRUE; 00489 00490 // --- 00491 // Get a scratch file - if TMP isn't set, this will try for c:\temp. 00492 // The filename will have XS as a prefix 00493 char *tempname = GetTempFileName(); //_ttempnam("C:\temp", "XS~"); 00494 if (tempname == NULL) 00495 { 00496 ERROR3("Couldn't get a temp filename"); 00497 return(FALSE); 00498 } 00499 00500 PathName FullPath(tempname); 00501 00502 // --- 00503 // Save the clipboard data into our tempfile 00504 OFSTRUCT OpenBuf; 00505 OpenBuf.cBytes = sizeof(OpenBuf); 00506 HFILE OutFile = OpenFile(tempname, &OpenBuf, OF_CREATE); 00507 00508 // Did it work ok? 00509 if (OutFile == HFILE_ERROR) 00510 { 00511 ERROR2RAW("Import tempfile couldn't be opened"); 00512 InformError(); 00513 free(tempname); 00514 return(FALSE); 00515 } 00516 00517 // And write it to the tempfile 00518 LPCSTR lpbuffer = (LPCSTR) GlobalLock(ClipboardData); 00519 if (lpbuffer != NULL) 00520 { 00521 DWORD DataSize = GlobalSize(ClipboardData); 00522 00523 if (DataSize != 0) 00524 { 00525 UINT32 BytesWritten = _lwrite(OutFile, lpbuffer, DataSize); 00526 00527 if (BytesWritten != DataSize) 00528 { 00529 ERROR2RAW("Import tempfile save seems to have failed"); 00530 InformError(); 00531 ok = FALSE; 00532 } 00533 } 00534 else 00535 { 00536 ERROR3("No data in clipboard!"); 00537 ok = FALSE; 00538 } 00539 00540 GlobalUnlock(ClipboardData); 00541 } 00542 else 00543 { 00544 ERROR3("Clipboard memory chunk couldn't be locked!"); 00545 ok = FALSE; 00546 } 00547 00548 _lclose(OutFile); 00549 00550 00551 // --- 00552 // Now, import the temp file using our 'parent' filter 00553 if (ok) 00554 ok = ImportFromTempFile(tempname, Caller, InternalClipboard::Instance()); 00555 00556 00557 // Delete the temp file, and deallocate the tempname memory 00558 _tremove(tempname); 00559 free(tempname); 00560 return(ok); 00561 } 00562 00563 00564 00565 /******************************************************************************************** 00566 00567 > BOOL ClipboardMapping::ExportToTempFile(TCHAR *filename, 00568 Operation *Caller, InternalClipboard *Source) 00569 00570 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00571 Created: 20/4/95 00572 00573 Inputs: filename - the file name of the temporary scratch file to be loaded 00574 Caller - the operation we're being called from 00575 Source - the internal clipboard document to export from 00576 00577 Returns: TRUE if it succeeds. 00578 00579 Purpose: Internal helper function. Invokes pFilter::DoExport from the Source doc, 00580 using the given file as a destination. 00581 00582 Notes: You must delete the temp file afterwards - use 'remove()' 00583 00584 ********************************************************************************************/ 00585 00586 BOOL ClipboardMapping::ExportToTempFile(TCHAR *filename, 00587 Operation *Caller, InternalClipboard *Source) 00588 { 00589 // Provide a current view for the filter to chomp on; We stack the current 00590 // view so that we do not corrupt it. 00591 View *OldCurrentView = View::GetCurrent(); 00592 ClipboardView ExportView; 00593 if (!ExportView.Init()) 00594 return(FALSE); 00595 00596 ExportView.SetCurrent(); 00597 00598 PathName FullPath(filename); 00599 00600 // Try and open the temporary file 00601 CCDiskFile DiskFile(1024, FALSE, TRUE); 00602 BOOL AllOK = TRUE; 00603 00604 TRY 00605 { 00606 if (!DiskFile.open(FullPath, ios::out | ios::binary)) 00607 { 00608 if (OldCurrentView != NULL) 00609 OldCurrentView->SetCurrent(); 00610 return(FALSE); // Failed to open the export file 00611 } 00612 00613 // Tell the filter we would like a Preview Bitmap please 00614 if (pFilter->CanIncludePreviewBmp()) 00615 pFilter->IncludePreviewBmp(TRUE); 00616 00617 // Try and export the internal clipboard document 00618 if (!pFilter->DoExport(Caller, &DiskFile, &FullPath, InternalClipboard::Instance())) 00619 { 00620 // Something went a bit wrong - tell the user what it was. 00621 // Suppress the error if it was the 'user has cancelled one' 00622 if (Error::GetErrorNumber() != _R(IDN_USER_CANCELLED)) 00623 { 00624 InformError(); 00625 // Caller should clean up the temp file 00626 } 00627 else 00628 Error::ClearError(); // otherwise remove the error so it won't get reported 00629 00630 // Set the error 00631 AllOK = FALSE; 00632 } 00633 00634 // Close the file 00635 if (DiskFile.isOpen()) 00636 DiskFile.close(); 00637 } 00638 00639 // See if there was a file io error 00640 CATCH(CFileException, e) 00641 { 00642 // Report the error if no one else did 00643 if (Error::GetErrorNumber() != _R(IDN_USER_CANCELLED)) 00644 { 00645 InformError(); 00646 } 00647 else 00648 Error::ClearError(); // otherwise remove the error so it won't get reported 00649 00650 // Make sure that the file is closed 00651 TRY 00652 { 00653 // Close that file 00654 if (DiskFile.isOpen()) 00655 DiskFile.close(); 00656 } 00657 CATCH(CFileException, e) 00658 { 00659 // Not a lot we can do really... 00660 } 00661 END_CATCH 00662 00663 // And restore the previous current view 00664 if (OldCurrentView != NULL) 00665 OldCurrentView->SetCurrent(); 00666 00667 return(FALSE); 00668 } 00669 END_CATCH 00670 00671 // Tell the filter we would NOT like a Preview Bitmap ready for next time 00672 if (pFilter->CanIncludePreviewBmp()) 00673 pFilter->IncludePreviewBmp(FALSE); 00674 00675 // And restore the previous current view 00676 if (OldCurrentView != NULL) 00677 OldCurrentView->SetCurrent(); 00678 00679 return(TRUE); 00680 } 00681 00682 00683 /******************************************************************************************** 00684 00685 > virtual BOOL ClipboardMapping::HandleExport(Operation *Caller, 00686 InternalClipboard *Source) 00687 00688 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00689 Created: 20/4/95 00690 00691 Inputs: Caller - the operation within which this method is being called 00692 Source - the internal clipboard (document) to be exported 00693 00694 Returns: NULL (if it failed), or a windows handle of the data to be placed on 00695 the clipboard. 00696 00697 Purpose: Invokes this mapping for exporting 00698 This takes the document tree of Source, and exports it to the external 00699 (windows) clipboard. Usually this just involves calling Filter::DoExport 00700 for the parent filter, and then returning the handle to the global memory 00701 block to be placed onto the external clipboard. 00702 00703 Notes: The returned handle should be the thing you'd pass to SetClipboardData 00704 if you were dealing with it directly. You must adhere to all the Windows 00705 rules for this - i.e. a global data block, unlocked, etc etc. 00706 00707 ********************************************************************************************/ 00708 00709 HANDLE ClipboardMapping::HandleExport(Operation *Caller, InternalClipboard *Source) 00710 { 00711 ERROR3("Base class ClipboardMapping::HandleExport called"); 00712 00713 /* 00714 PathName FullPath; 00715 00716 char *tempname = _ttempnam("C:\temp", "XS"); 00717 if (tempname == NULL) 00718 { 00719 ERROR3("Couldn't get a temp filename"); 00720 return(NULL); 00721 } 00722 00723 if (!ExportToTempFile(tempname, Caller, Source)) 00724 { 00725 remove(tempname); 00726 free(tempname); 00727 return(NULL); 00728 } 00729 00730 00731 // In the switch statement below, set this handle to the global mem handle 00732 // of the data you want to place on the clipboard. If you don't want to 00733 // put anything on, leave this handle NULL. 00734 HANDLE hGlobalMem = NULL; 00735 00736 00737 // **** !!!! Export the file 00738 00739 // Delete the temp file, and return the result 00740 remove(tempname); 00741 free(tempname); 00742 return(hGlobalMem); 00743 */ 00744 return(NULL); 00745 } 00746 00747 00748 00749 /******************************************************************************************** 00750 00751 > char *ClipboardMapping::GetTempFileName(void) 00752 00753 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00754 Created: 29/4/95 00755 00756 Returns: NULL, or a a filename to be used as a temporary file 00757 00758 Purpose: Finds a temporary file 00759 Remove it with ClipboardMapping::RemoveTempFile 00760 00761 SeeAlso: ClipboardMapping::RemoveTempFile 00762 00763 ********************************************************************************************/ 00764 00765 char *ClipboardMapping::GetTempFileName(void) 00766 { 00767 RemoveTempFile(); // Try to ensure any previous tempfile is gone 00768 00769 tempfilename = _ttempnam("C:\temp", "XS~"); 00770 00771 return(tempfilename); 00772 } 00773 00774 00775 00776 /******************************************************************************************** 00777 00778 > void ClipboardMapping::RemoveTempFile(void) 00779 00780 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00781 Created: 29/4/95 00782 00783 Purpose: Removes the last temporary file 'allocated' with GetTempFilename 00784 00785 This function is automatically called when the clipboard is wiped, 00786 as usually we had to leave the tempfile around while it was "on" the 00787 clipboard. 00788 00789 SeeAlso: ClipboardMapping::GetTempFilename 00790 00791 ********************************************************************************************/ 00792 00793 void ClipboardMapping::RemoveTempFile(void) 00794 { 00795 if (tempfilename != NULL) 00796 { 00797 _tremove(tempfilename); 00798 free(tempfilename); 00799 tempfilename = NULL; 00800 } 00801 } 00802 00803 00804 00805 00806 00807 00808 00809 00810 00811 00812 00813 00814 00815 00816 00817 00818 BodgeTextClipMap::BodgeTextClipMap() 00819 { 00820 ERROR3("Please don't press that button again"); 00821 } 00822 00823 00824 /******************************************************************************************** 00825 00826 > BodgeTextClipMap::BodgeTextClipMap(ClipboardMappingType TheType, UINT32 ClaimType = 0) 00827 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00828 Created: 16/4/95 00829 00830 Inputs: TheType - indicates import / export / import & export 00831 00832 ClaimType - specifies the text type that this mapping will claim from the 00833 windows clipboard - that is, create 3 of these mappings, specifying 00834 CF_TEXT, CF_UNICODETEXT, and CF_OEMTEXT, and they will all ask the 00835 clipboard for UNICODE text when they actually go to import. This allows 00836 us to detect the 3 implicitly-converted clipboard formats, and map them 00837 all to UNICODE, i.e. use the UNICODE mapping for all 3 available formats. 00838 If ClaimType == 0, UNICODE is assumed 00839 00840 Purpose: Constructs a clipboard mapping with the ExternalClipboard 00841 manager. This mapping info describes a filter which is able to import 00842 data from or export data to a windows clipboard in some way. 00843 00844 Notes: DON'T call the constructor - call CreateAndRegister 00845 00846 SeeAlso: BodgeTextClipMap::CreateAndRegister 00847 00848 ********************************************************************************************/ 00849 00850 BodgeTextClipMap::BodgeTextClipMap(ClipboardMappingType TheType, UINT32 ClaimType) 00851 : ClipboardMapping(TheType, NULL, InternalClipboardFormat(CLIPTYPE_TEXT), 00852 CF_TEXT, 50) 00853 { 00854 if (ClaimType != 0) 00855 ExternalDataType = ClaimType; 00856 } 00857 00858 00859 00860 /******************************************************************************************** 00861 00862 > static void BodgeTextClipMap::CreateAndRegister(ClipboardMappingType TheType, UINT32 ClaimType = 0) 00863 00864 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00865 Created: 16/4/95 00866 00867 Inputs: TheType - indicates import / export / import & export 00868 00869 ClaimType - specifies the text type that this mapping will claim from the 00870 windows clipboard - that is, create 3 of these mappings, specifying 00871 CF_TEXT, CF_UNICODETEXT, and CF_OEMTEXT, and they will all ask the 00872 clipboard for UNICODE text when they actually go to import. This allows 00873 us to detect the 3 implicitly-converted clipboard formats, and map them 00874 all to UNICODE, i.e. use the UNICODE mapping for all 3 available formats. 00875 If ClaimType == 0, UNICODE is assumed 00876 00877 Purpose: Constructs and registers a clipboard mapping with the ExternalClipboard 00878 manager. This mapping info describes a filter which is able to import 00879 data from or export data to a windows clipboard in some way. 00880 00881 ********************************************************************************************/ 00882 00883 void BodgeTextClipMap::CreateAndRegister(ClipboardMappingType TheType, UINT32 ClaimType) 00884 { 00885 BodgeTextClipMap *Mapping = new BodgeTextClipMap(TheType, ClaimType); 00886 if (Mapping == NULL) 00887 InformError(); 00888 else 00889 ExternalClipboard::RegisterDataType(Mapping); 00890 } 00891 00892 00893 00894 /******************************************************************************************** 00895 > virtual BOOL BodgeTextClipMap::HandleImport(SelOperation *Caller, HANDLE ClipboardData, 00896 InternalClipboard *Dest) 00897 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00898 Created: 20/4/95 00899 Inputs: Caller - The operation within which this method is being called 00900 ClipboardData - The result of calling GetClipboardData for your datatype 00901 Dest - The InternalClipboard (document) to import the data into. 00902 Returns: TRUE for success 00903 Purpose: Calls the parent filter as appropriate to import the given data from 00904 the external clipboard. 00905 This bodge mapping for text scans the docuemnt tree for text chars and 00906 strips them out by hand. Styles and suchlike are lost. It's a bodge. 00907 ********************************************************************************************/ 00908 00909 BOOL BodgeTextClipMap::HandleImport(SelOperation *Caller, HANDLE ClipboardData, InternalClipboard *Dest) 00910 { 00911 char *buff=(char*)GlobalLock(ClipboardData); 00912 if (buff != NULL && buff[0] != 0) 00913 { 00914 // position arbitarily on clipboard - when pasted the clip contents are centered anyway 00915 TextStory* TheStory=TextStory::CreateFromChars(DocCoord(100,100), buff, NULL, 00916 InternalClipboard::Instance(), NULL, TRUE); 00917 00918 // Unlock the clipboard data, as we won't need it again 00919 GlobalUnlock(ClipboardData); 00920 00921 if (TheStory!=NULL) 00922 { 00923 // OK, attach the new story to the clipboard document 00924 TheStory->AttachNode(InternalClipboard::GetInsertionLayer(), LASTCHILD); 00925 TheStory->NormaliseAttributes(); 00926 00927 // And make it reformat itself properly 00928 TheStory->FormatAndChildren(NULL,FALSE,FALSE); 00929 return(TRUE); 00930 } 00931 00932 // We failed (no text story), so report and ensure the clipboard is 'clean' 00933 InformError(); 00934 InternalClipboard::Clear(); 00935 } 00936 00937 // We failed 00938 return(FALSE); 00939 } 00940 00941 //BOOL BodgeTextClipMap::HandleImport(SelOperation *Caller, 00942 // HANDLE ClipboardData, InternalClipboard *Dest) 00943 //{ 00944 // char *buff = (char *) GlobalLock(ClipboardData); 00945 // if (buff != NULL && buff[0] != 0) 00946 // { 00947 // DWORD Index = 0; 00948 // 00949 // TextStory *pStory = new TextStory(Dest->GetInsertionLayer(), LASTCHILD); 00950 // if (pStory == NULL) 00951 // goto Abort; 00952 // 00953 // // Lob in some default attributes (black fill, no line colour, line width = 250 00954 // Node *pNode; 00955 // FlatFillAttribute *pAttrFill = new FlatFillAttribute(DocColour(COLOUR_BLACK)); 00956 // if (pAttrFill == NULL) 00957 // goto Abort; 00958 // pNode = pAttrFill->MakeNode(); 00959 // if (pNode == NULL) 00960 // goto Abort; 00961 // pNode->AttachNode(pStory, LASTCHILD, FALSE); 00962 // 00963 // StrokeColourAttribute *pAttrLine = new StrokeColourAttribute(DocColour(COLOUR_TRANS)); 00964 // if (pAttrLine == NULL) 00965 // goto Abort; 00966 // pNode = pAttrLine->MakeNode(); 00967 // if (pNode == NULL) 00968 // goto Abort; 00969 // pNode->AttachNode(pStory, LASTCHILD, FALSE); 00970 // 00971 // LineWidthAttribute *pAttrLineWidth = new LineWidthAttribute(250); 00972 // if (pAttrLineWidth == NULL) 00973 // goto Abort; 00974 // pNode = pAttrLineWidth->MakeNode(); 00975 // if (pNode == NULL) 00976 // goto Abort; 00977 // pNode->AttachNode(pStory, LASTCHILD, FALSE); 00978 // 00979 // // Set the top left position for the text area - this doesn't matter because 00980 // // the absolute position on the clipboard is ignored when we paste 00981 // Matrix StoryMatrix(1000, 1000); 00982 // pStory->SetStoryMatrix(StoryMatrix); 00983 // 00984 // TextLine *pLine = new TextLine(pStory, LASTCHILD); 00985 // if (pLine == NULL) 00986 // goto Abort; 00987 // 00988 // Node *pChar = NULL; 00989 // 00990 // while(buff[Index] != 0) 00991 // { 00992 // if (buff[Index] == 0x0D) 00993 // { 00994 // if (buff[Index+1] == 0x0A) // Skip LF if it's a CRLF pair 00995 // Index++; 00996 // 00997 // pChar = new EOLNode(pLine, LASTCHILD); 00998 // if (pChar == NULL) 00999 // goto Abort; 01000 // 01001 // // Make sure if this is the last char exported, we don't leave 01002 // // this next TextLine without an EOLNode in it! 01003 // pChar = NULL; 01004 // 01005 // pLine = new TextLine(pStory, LASTCHILD); 01006 // if (pLine == NULL) 01007 // goto Abort; 01008 // } 01009 // else 01010 // { 01011 // // Ignore control chars like tabs and suchlike for now 01012 // if (buff[Index] > 31) 01013 // { 01014 // pChar = new TextChar(pLine, LASTCHILD, (WCHAR) buff[Index]); 01015 // if (pChar == NULL) 01016 // goto Abort; 01017 // } 01018 // } 01019 // 01020 // Index++; 01021 // } 01022 // 01023 // if (pChar == NULL || !pChar->IsKindOf(CC_RUNTIME_CLASS(EOLNode))) 01024 // { 01025 // // no terminating newline, so add one 01026 // pChar = new EOLNode(pLine, LASTCHILD); 01027 // if (pChar == NULL) 01028 // goto Abort; 01029 // } 01030 // 01031 // // And lob a caret in, 'cos it seems to get upset if this isn't in there! 01032 // pChar = new CaretNode(pChar, PREV); 01033 // if (pChar == NULL) 01034 // goto Abort; 01035 // 01036 // // And finally, format the text, else the chars all stack on top of each other! 01037 // pStory->FormatAndChildren(); 01038 // 01039 // GlobalUnlock(ClipboardData); 01040 // return(TRUE); 01041 // } 01042 // 01043 // return(FALSE); 01044 // 01045 //Abort: 01046 // ERROR2RAW("Text import failed, probably due to lack of memory"); 01047 // InformError(); 01048 // 01049 // GlobalUnlock(ClipboardData); 01050 // Dest->ClearClipboard(); // We failed, so ensure the doc is wiped 01051 // return(FALSE); 01052 //} 01053 01054 01055 /******************************************************************************************** 01056 01057 > virtual BOOL BodgeTextClipMap::HandleExport(Operation *Caller, 01058 InternalClipboard *Source) 01059 01060 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01061 Created: 20/4/95 01062 01063 Inputs: Caller - the operation within which this method is being called 01064 Source - the internal clipboard (document) to be exported 01065 01066 Returns: NULL (if it failed), or a windows handle of the data to be placed on 01067 the clipboard. 01068 01069 Purpose: Invokes this mapping for exporting 01070 This takes the document tree of Source, and exports it to the external 01071 (windows) clipboard. 01072 01073 This bodge mapping for text scans the docuemnt tree for text chars and 01074 strips them out by hand. Styles and suchlike are lost. It's a bodge. 01075 01076 Notes: The returned handle should be the thing you'd pass to SetClipboardData 01077 if you were dealing with it directly. You must adhere to all the Windows 01078 rules for this - i.e. a global data block, unlocked, etc etc. 01079 01080 ********************************************************************************************/ 01081 01082 HANDLE BodgeTextClipMap::HandleExport(Operation *Caller, InternalClipboard *Source) 01083 { 01084 const DWORD Increment = 1024 * sizeof(char); 01085 DWORD CurrentSize = 0; 01086 DWORD MaxSize = Increment; 01087 01088 #if (_OLE_VER >= 0x200) 01089 01090 // If necessary allocate the memory. 01091 BOOL fDidAlloc = FALSE; 01092 HANDLE hGlobalMem = m_hMem; 01093 if (hGlobalMem) 01094 { 01095 // We have some already. Set the size. 01096 MaxSize = m_cbMemSize; 01097 } 01098 else 01099 { 01100 // We don't have any, so try to allocate and remember that we did so. 01101 hGlobalMem = m_hMem = GlobalAlloc(GHND, MaxSize); 01102 if (!hGlobalMem) return 0; 01103 fDidAlloc = TRUE; 01104 } 01105 01106 #else 01107 01108 // Allocate a block of global memory to store the text 01109 HANDLE hGlobalMem = GlobalAlloc(GHND, MaxSize); 01110 01111 if (hGlobalMem == NULL) 01112 return(NULL); 01113 01114 #endif 01115 01116 // Get a UNICODE text buffer 01117 char* buff = (char*) GlobalLock(hGlobalMem); 01118 if (buff == NULL) 01119 { 01120 return(NULL); 01121 } 01122 01123 // Scan the entire document tree, and lob every TextChar we find into the export buffer 01124 // NOTE that the Global{Re}Alloc zeros memory, so we don't need to worry about 0-termination. 01125 Node *pSubtree = InternalClipboard::GetInsertionLayer(); 01126 Node *pNode = pSubtree->FindFirstDepthFirst(); 01127 while (pNode != NULL) 01128 { 01129 if (pNode->IsKindOf(CC_RUNTIME_CLASS(TextChar)) || pNode->IsKindOf(CC_RUNTIME_CLASS(EOLNode))) 01130 { 01131 if (pNode->IsKindOf(CC_RUNTIME_CLASS(TextChar))) 01132 { 01133 UINT32 ComposedChar = UnicodeManager::UnicodeToMultiByte(((TextChar *) pNode)->GetUnicodeValue()); 01134 BYTE LeadByte = 0; 01135 BYTE TrailByte = 0; 01136 UnicodeManager::DecomposeMultiBytes(ComposedChar, &LeadByte, &TrailByte); 01137 01138 if (LeadByte != 0) 01139 buff[CurrentSize++] = LeadByte; 01140 01141 buff[CurrentSize++] = TrailByte; 01142 } 01143 else 01144 { 01145 if (!((EOLNode*)pNode)->IsVirtual()) 01146 { 01147 buff[CurrentSize++] = (char) 0x0D; // CRLF - newline 01148 buff[CurrentSize++] = (char) 0x0A; 01149 } 01150 } 01151 01152 // Check if we've overrun the buffer - if so, we need to make the buffer bigger 01153 // (Allow 3 entries at the end (1 to guarantee we have a zero terminator, and 2 more 01154 // to allow room to fit the 2-char newline sequence in!) 01155 if ( (CurrentSize * sizeof(char)) >= MaxSize - 3) 01156 { 01157 #if (_OLE_VER >= 0x200) 01158 // If we didn't allocate the block then we can't resize it. 01159 if (!fDidAlloc) return 0; 01160 m_hMem = 0; 01161 #endif 01162 01163 GlobalUnlock(hGlobalMem); 01164 01165 MaxSize += Increment; 01166 HANDLE hNewMem = GlobalReAlloc(hGlobalMem, MaxSize, GHND); 01167 if (hNewMem == NULL) 01168 { 01169 GlobalFree(hGlobalMem); 01170 return(NULL); 01171 } 01172 01173 hGlobalMem = hNewMem; 01174 buff = (char *)GlobalLock(hGlobalMem); 01175 01176 if (buff == NULL) 01177 { 01178 GlobalFree(hGlobalMem); 01179 return(NULL); 01180 } 01181 01182 #if (_OLE_VER >= 0x200) 01183 // Remember this block. 01184 m_hMem = hNewMem; 01185 #endif 01186 } 01187 } 01188 pNode = pNode->FindNextDepthFirst(pSubtree); 01189 } 01190 01191 // We must unlock the block before giving it to the clipboard 01192 GlobalUnlock(hGlobalMem); 01193 01194 return(hGlobalMem); 01195 } 01196 01197 01198 01199 01200 01201 01202 01203 01204 01205 01206 BodgeUnicodeClipMap::BodgeUnicodeClipMap() 01207 { 01208 ERROR3("Please don't press that button again"); 01209 } 01210 01211 01212 /******************************************************************************************** 01213 01214 > BodgeUnicodeClipMap::BodgeUnicodeClipMap(ClipboardMappingType TheType, UINT32 ClaimType = 0) 01215 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01216 Created: 16/4/95 01217 01218 Inputs: TheType - indicates import / export / import & export 01219 01220 ClaimType - specifies the text type that this mapping will claim from the 01221 windows clipboard - that is, create 3 of these mappings, specifying 01222 CF_TEXT, CF_UNICODETEXT, and CF_OEMTEXT, and they will all ask the 01223 clipboard for UNICODE text when they actually go to import. This allows 01224 us to detect the 3 implicitly-converted clipboard formats, and map them 01225 all to UNICODE, i.e. use the UNICODE mapping for all 3 available formats. 01226 If ClaimType == 0, UNICODE is assumed 01227 01228 Purpose: Constructs a clipboard mapping with the ExternalClipboard 01229 manager. This mapping info describes a filter which is able to import 01230 data from or export data to a windows clipboard in some way. 01231 01232 Notes: DON'T call the constructor - call CreateAndRegister 01233 01234 SeeAlso: BodgeUnicodeClipMap::CreateAndRegister 01235 01236 ********************************************************************************************/ 01237 01238 BodgeUnicodeClipMap::BodgeUnicodeClipMap(ClipboardMappingType TheType, UINT32 ClaimType) 01239 : ClipboardMapping(TheType, NULL, InternalClipboardFormat(CLIPTYPE_TEXT), 01240 CF_UNICODETEXT, 55) 01241 { 01242 if (ClaimType != 0) 01243 ExternalDataType = ClaimType; 01244 } 01245 01246 01247 01248 /******************************************************************************************** 01249 01250 > static void BodgeUnicodeClipMap::CreateAndRegister(ClipboardMappingType TheType, UINT32 ClaimType = 0) 01251 01252 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01253 Created: 16/4/95 01254 01255 Inputs: TheType - indicates import / export / import & export 01256 01257 ClaimType - specifies the text type that this mapping will claim from the 01258 windows clipboard - that is, create 3 of these mappings, specifying 01259 CF_TEXT, CF_UNICODETEXT, and CF_OEMTEXT, and they will all ask the 01260 clipboard for UNICODE text when they actually go to import. This allows 01261 us to detect the 3 implicitly-converted clipboard formats, and map them 01262 all to UNICODE, i.e. use the UNICODE mapping for all 3 available formats. 01263 If ClaimType == 0, UNICODE is assumed 01264 01265 Purpose: Constructs and registers a clipboard mapping with the ExternalClipboard 01266 manager. This mapping info describes a filter which is able to import 01267 data from or export data to a windows clipboard in some way. 01268 01269 ********************************************************************************************/ 01270 01271 void BodgeUnicodeClipMap::CreateAndRegister(ClipboardMappingType TheType, UINT32 ClaimType) 01272 { 01273 BodgeUnicodeClipMap *Mapping = new BodgeUnicodeClipMap(TheType, ClaimType); 01274 if (Mapping == NULL) 01275 InformError(); 01276 else 01277 ExternalClipboard::RegisterDataType(Mapping); 01278 } 01279 01280 01281 01282 /******************************************************************************************** 01283 > virtual BOOL BodgeUnicodeClipMap::HandleImport(SelOperation *Caller, HANDLE ClipboardData, 01284 InternalClipboard *Dest) 01285 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01286 Created: 20/4/95 01287 Inputs: Caller - The operation within which this method is being called 01288 ClipboardData - The result of calling GetClipboardData for your datatype 01289 Dest - The InternalClipboard (document) to import the data into. 01290 Returns: TRUE for success 01291 Purpose: Calls the parent filter as appropriate to import the given data from 01292 the external clipboard. 01293 This bodge mapping for text scans the docuemnt tree for text chars and 01294 strips them out by hand. Styles and suchlike are lost. It's a bodge. 01295 ********************************************************************************************/ 01296 01297 BOOL BodgeUnicodeClipMap::HandleImport(SelOperation *Caller, HANDLE ClipboardData, InternalClipboard *Dest) 01298 { 01299 WCHAR *buff=(WCHAR*)GlobalLock(ClipboardData); 01300 if (buff != NULL && buff[0] != 0) 01301 { 01302 // position arbitarily on clipboard - when pasted the clip contents are centered anyway 01303 TextStory* TheStory=TextStory::CreateFromChars(DocCoord(100,100), NULL, buff, 01304 InternalClipboard::Instance(), NULL, TRUE); 01305 01306 // Unlock the clipboard data, as we won't need it again 01307 GlobalUnlock(ClipboardData); 01308 01309 if (TheStory!=NULL) 01310 { 01311 // OK, attach the new story to the clipboard document 01312 TheStory->AttachNode(InternalClipboard::GetInsertionLayer(), LASTCHILD); 01313 TheStory->NormaliseAttributes(); 01314 01315 // And make it reformat itself properly 01316 TheStory->FormatAndChildren(NULL,FALSE,FALSE); 01317 return(TRUE); 01318 } 01319 01320 // We failed (no text story), so report and ensure the clipboard is 'clean' 01321 InformError(); 01322 InternalClipboard::Clear(); 01323 } 01324 01325 // We failed 01326 return(FALSE); 01327 } 01328 01329 01330 //BOOL BodgeUnicodeClipMap::HandleImport(SelOperation *Caller, HANDLE ClipboardData, InternalClipboard *Dest) 01331 //{ 01332 // WCHAR *buff = (WCHAR *) GlobalLock(ClipboardData); 01333 // if (buff != NULL && buff[0] != 0) 01334 // { 01335 // DWORD Index = 0; 01336 // 01337 // TextStory *pStory = new TextStory(Dest->GetInsertionLayer(), LASTCHILD); 01338 // if (pStory == NULL) 01339 // goto Abort; 01340 // 01341 // // Lob in some default attributes (black fill, no line colour, line width = 250 01342 // Node *pNode; 01343 // FlatFillAttribute *pAttrFill = new FlatFillAttribute(DocColour(COLOUR_BLACK)); 01344 // if (pAttrFill == NULL) 01345 // goto Abort; 01346 // pNode = pAttrFill->MakeNode(); 01347 // if (pNode == NULL) 01348 // goto Abort; 01349 // pNode->AttachNode(pStory, LASTCHILD, FALSE); 01350 // 01351 // StrokeColourAttribute *pAttrLine = new StrokeColourAttribute(DocColour(COLOUR_TRANS)); 01352 // if (pAttrLine == NULL) 01353 // goto Abort; 01354 // pNode = pAttrLine->MakeNode(); 01355 // if (pNode == NULL) 01356 // goto Abort; 01357 // pNode->AttachNode(pStory, LASTCHILD, FALSE); 01358 // 01359 // LineWidthAttribute *pAttrLineWidth = new LineWidthAttribute(250); 01360 // if (pAttrLineWidth == NULL) 01361 // goto Abort; 01362 // pNode = pAttrLineWidth->MakeNode(); 01363 // if (pNode == NULL) 01364 // goto Abort; 01365 // pNode->AttachNode(pStory, LASTCHILD, FALSE); 01366 // 01367 // // Set the top left position for the text area - this doesn't matter because 01368 // // the absolute position on the clipboard is ignored when we paste 01369 // Matrix StoryMatrix(1000, 1000); 01370 // pStory->SetStoryMatrix(StoryMatrix); 01371 // 01372 // TextLine *pLine = new TextLine(pStory, LASTCHILD); 01373 // if (pLine == NULL) 01374 // goto Abort; 01375 // 01376 // Node *pChar = NULL; 01377 // 01378 // while(buff[Index] != 0) 01379 // { 01380 // if (buff[Index] == 0x000D) 01381 // { 01382 // if (buff[Index+1] == 0x000A) // Skip LF if it's a CRLF pair 01383 // Index++; 01384 // 01385 // pChar = new EOLNode(pLine, LASTCHILD); 01386 // if (pChar == NULL) 01387 // goto Abort; 01388 // 01389 // // Make sure if this is the last char exported, we don't leave 01390 // // this next TextLine without an EOLNode in it! 01391 // pChar = NULL; 01392 // 01393 // pLine = new TextLine(pStory, LASTCHILD); 01394 // if (pLine == NULL) 01395 // goto Abort; 01396 // } 01397 // else 01398 // { 01399 // // Ignore control chars like tabs and suchlike for now 01400 // if (buff[Index] > 31) 01401 // { 01402 // pChar = new TextChar(pLine, LASTCHILD, buff[Index]); 01403 // if (pChar == NULL) 01404 // goto Abort; 01405 // } 01406 // } 01407 // 01408 // Index++; 01409 // } 01410 // 01411 // if (pChar == NULL || !pChar->IsKindOf(CC_RUNTIME_CLASS(EOLNode))) 01412 // { 01413 // // no terminating newline, so add one 01414 // pChar = new EOLNode(pLine, LASTCHILD); 01415 // if (pChar == NULL) 01416 // goto Abort; 01417 // } 01418 // 01419 // // And lob a caret in, 'cos it seems to get upset if this isn't in there! 01420 // pChar = new CaretNode(pChar, PREV); 01421 // if (pChar == NULL) 01422 // goto Abort; 01423 // 01424 // // And finally, format the text, else the chars all stack on top of each other! 01425 // pStory->FormatAndChildren(); 01426 // 01427 // GlobalUnlock(ClipboardData); 01428 // return(TRUE); 01429 // } 01430 // 01431 // return(FALSE); 01432 // 01433 //Abort: 01434 // ERROR2RAW("Text import failed, probably due to lack of memory"); 01435 // InformError(); 01436 // 01437 // GlobalUnlock(ClipboardData); 01438 // Dest->ClearClipboard(); // We failed, so ensure the doc is wiped 01439 // return(FALSE); 01440 //} 01441 01442 01443 /******************************************************************************************** 01444 01445 > virtual BOOL BodgeUnicodeClipMap::HandleExport(Operation *Caller, 01446 InternalClipboard *Source) 01447 01448 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01449 Created: 20/4/95 01450 01451 Inputs: Caller - the operation within which this method is being called 01452 Source - the internal clipboard (document) to be exported 01453 01454 Returns: NULL (if it failed), or a windows handle of the data to be placed on 01455 the clipboard. 01456 01457 Purpose: Invokes this mapping for exporting 01458 This takes the document tree of Source, and exports it to the external 01459 (windows) clipboard. 01460 01461 This bodge mapping for text scans the docuemnt tree for text chars and 01462 strips them out by hand. Styles and suchlike are lost. It's a bodge. 01463 01464 Notes: The returned handle should be the thing you'd pass to SetClipboardData 01465 if you were dealing with it directly. You must adhere to all the Windows 01466 rules for this - i.e. a global data block, unlocked, etc etc. 01467 01468 ********************************************************************************************/ 01469 01470 HANDLE BodgeUnicodeClipMap::HandleExport(Operation *Caller, InternalClipboard *Source) 01471 { 01472 const DWORD Increment = 1024 * sizeof(WCHAR); 01473 DWORD CurrentSize = 0; 01474 DWORD MaxSize = Increment; 01475 01476 #if (_OLE_VER >= 0x200) 01477 01478 // If necessary allocate the memory. 01479 BOOL fDidAlloc = FALSE; 01480 HANDLE hGlobalMem = m_hMem; 01481 if (hGlobalMem) 01482 { 01483 // We have some already. Set the size. 01484 MaxSize = m_cbMemSize; 01485 } 01486 else 01487 { 01488 // We don't have any, so try to allocate and remember that we did so. 01489 hGlobalMem = m_hMem = GlobalAlloc(GHND, MaxSize); 01490 if (!hGlobalMem) return 0; 01491 fDidAlloc = TRUE; 01492 } 01493 01494 #else 01495 01496 // Allocate a block of global memory to store the text 01497 HANDLE hGlobalMem = GlobalAlloc(GHND, MaxSize); 01498 01499 if (hGlobalMem == NULL) 01500 return(NULL); 01501 01502 #endif 01503 01504 // Get a UNICODE text buffer 01505 WCHAR *buff = (WCHAR *)GlobalLock(hGlobalMem); 01506 if (buff == NULL) 01507 { 01508 return(NULL); 01509 } 01510 01511 // Scan the entire document tree, and lob every TextChar we find into the export buffer 01512 // NOTE that the Global{Re}Alloc zeros memory, so we don't need to worry about 0-termination. 01513 Node *pSubtree = InternalClipboard::GetInsertionLayer(); 01514 Node *pNode = pSubtree->FindFirstDepthFirst(); 01515 while (pNode != NULL) 01516 { 01517 if (pNode->IsKindOf(CC_RUNTIME_CLASS(TextChar)) || pNode->IsKindOf(CC_RUNTIME_CLASS(EOLNode))) 01518 { 01519 if (pNode->IsKindOf(CC_RUNTIME_CLASS(TextChar))) 01520 { 01521 buff[CurrentSize] = ((TextChar *) pNode)->GetUnicodeValue(); 01522 CurrentSize++; 01523 } 01524 else 01525 { 01526 buff[CurrentSize++] = 0x000D; // CRLF - newline 01527 buff[CurrentSize++] = 0x000A; 01528 } 01529 01530 // Check if we've overrun the buffer - if so, we need to make the buffer bigger 01531 // (Allow 3 entries at the end (1 to guarantee we have a zero terminator, and 2 more 01532 // to allow room to fit the 2-char newline sequence in!) 01533 if ( (CurrentSize * sizeof(WCHAR)) >= MaxSize - 3) 01534 { 01535 #if (_OLE_VER >= 0x200) 01536 // If we didn't allocate the block then we can't resize it. 01537 if (!fDidAlloc) return 0; 01538 m_hMem = 0; 01539 #endif 01540 01541 GlobalUnlock(hGlobalMem); 01542 01543 MaxSize += Increment; 01544 HANDLE hNewMem = GlobalReAlloc(hGlobalMem, MaxSize, GHND); 01545 if (hNewMem == NULL) 01546 { 01547 GlobalFree(hGlobalMem); 01548 return(NULL); 01549 } 01550 01551 hGlobalMem = hNewMem; 01552 buff = (WCHAR *)GlobalLock(hGlobalMem); 01553 01554 if (buff == NULL) 01555 { 01556 GlobalFree(hGlobalMem); 01557 return(NULL); 01558 } 01559 01560 #if (_OLE_VER >= 0x200) 01561 // Remember this block. 01562 m_hMem = hNewMem; 01563 #endif 01564 } 01565 } 01566 pNode = pNode->FindNextDepthFirst(pSubtree); 01567 } 01568 01569 // We must unlock the block before giving it to the clipboard 01570 GlobalUnlock(hGlobalMem); 01571 01572 return(hGlobalMem); 01573 } 01574 01575 BitmapClipMap::BitmapClipMap() 01576 { 01577 ERROR3("Please don't press that button again"); 01578 } 01579 01580 01581 /******************************************************************************************** 01582 01583 > BitmapClipMap::BitmapClipMap(ClipboardMappingType TheType, UINT32 ClaimType = 0) 01584 01585 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01586 Created: 16/4/95 01587 01588 Inputs: TheType - indicates import / export / import & export 01589 01590 ClaimType - CF_DIB for straight import, CF_BITMAP for an alias 01591 01592 Purpose: Constructs a clipboard mapping with the ExternalClipboard 01593 manager. This mapping info describes a filter which is able to import 01594 data from or export data to a windows clipboard in some way. 01595 01596 Notes: DON'T call the constructor - call CreateAndRegister 01597 01598 SeeAlso: BitmapClipMap::CreateAndRegister 01599 01600 ********************************************************************************************/ 01601 01602 BitmapClipMap::BitmapClipMap(ClipboardMappingType TheType, UINT32 ClaimType) 01603 : ClipboardMapping(TheType, NULL, InternalClipboardFormat(CLIPTYPE_BITMAP), 01604 CF_BITMAP, 75) 01605 { 01606 if (ClaimType != 0) 01607 ExternalDataType = ClaimType; 01608 } 01609 01610 01611 01612 /******************************************************************************************** 01613 01614 > static void BitmapClipMap::CreateAndRegister(ClipboardMappingType TheType, UINT32 ClaimType = 0) 01615 01616 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01617 Created: 16/4/95 01618 01619 Inputs: TheType - indicates import / export / import & export 01620 01621 ClaimType - CF_DIB for straight import, CF_BITMAP for an alias 01622 01623 Purpose: Constructs and registers a clipboard mapping with the ExternalClipboard 01624 manager. This mapping info describes a filter which is able to import 01625 data from or export data to a windows clipboard in some way. 01626 01627 ********************************************************************************************/ 01628 01629 void BitmapClipMap::CreateAndRegister(ClipboardMappingType TheType, UINT32 ClaimType) 01630 { 01631 BitmapClipMap *Mapping = new BitmapClipMap(TheType, ClaimType); 01632 if (Mapping == NULL) 01633 InformError(); 01634 else 01635 ExternalClipboard::RegisterDataType(Mapping); 01636 } 01637 01638 01639 01640 /******************************************************************************************** 01641 01642 > static BOOL ConvertBMPToDIB(HBITMAP hSourceBmp, HPALETTE hSourcePal, 01643 BITMAPINFOHEADER **ResultHeader, LPBYTE *ResultBits) 01644 01645 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01646 Created: 2/5/95 01647 01648 Inputs: hSourceBmp - The handle of the source bitmap GDI object 01649 hSourcePal - NULL, or a handle of the palette to use 01650 01651 Outputs: ResultHeader - Will be NULL or point at the resulting DIB header 01652 ResultBits - Will be NULL or point at the resulting DIB body 01653 01654 Returns: TRUE for success 01655 01656 Purpose: Converts a Windows HBITMAP GDI DDB into a DIB 01657 01658 Notes: Both returned pointers will be NULL unless the return value is TRUE. 01659 These pointers are CCMalloc'd blocks as used by other DIBUtil calls 01660 and WBitmaps. 01661 01662 If hSourcePal is not supplied, a default palette will be used 01663 01664 SeeAlso: DibUtil::AloocDIB; DIBUtil::FreeDIB 01665 01666 ********************************************************************************************/ 01667 01668 static BOOL ConvertBMPToDIB(HBITMAP hSourceBmp, HPALETTE hSourcePal, 01669 LPBITMAPINFO *ResultHeader, LPBYTE *ResultBits) 01670 { 01671 ERROR3IF(hSourceBmp == NULL || ResultHeader == NULL || 01672 ResultBits == NULL, "Illegal NULL params"); 01673 01674 // Safe results if we fail 01675 *ResultHeader = NULL; 01676 *ResultBits = NULL; 01677 01678 BITMAPINFOHEADER *Header; 01679 LPBYTE Bits; 01680 01681 // See if we can get a palette from the clipboard - if not, grab a default one 01682 if (hSourcePal == NULL) 01683 hSourcePal = (HPALETTE) GetStockObject(DEFAULT_PALETTE); 01684 01685 // Fill in the BITMAP info from the source bitmap 01686 BITMAP bm; 01687 GetObject(hSourceBmp, sizeof(bm), (LPSTR) &bm); 01688 01689 UINT32 Depth = bm.bmPlanes * bm.bmBitsPixel; 01690 if (Depth > 8) // DDBs can be 16bpp, but DIBs cannot -> convert it to 24bpp 01691 Depth = 24; 01692 01693 INT32 PaletteSize = DIBUtil::CalcPaletteSize(Depth, FALSE); 01694 01695 Header = (BITMAPINFOHEADER *) CCMalloc(sizeof(BITMAPINFOHEADER) + PaletteSize); 01696 if (Header == NULL) 01697 return(FALSE); 01698 01699 INT32 BitmapSize = DIBUtil::ScanlineSize(bm.bmWidth, Depth) * bm.bmHeight; 01700 if (BitmapSize == 0) // Make sure we correctly handle zero width/height 01701 BitmapSize = 4; 01702 01703 Header->biSize = sizeof(BITMAPINFOHEADER); 01704 Header->biWidth = bm.bmWidth; 01705 Header->biHeight = bm.bmHeight; 01706 Header->biPlanes = 1; 01707 Header->biBitCount = Depth; 01708 Header->biCompression = BI_RGB; 01709 Header->biSizeImage = BitmapSize; 01710 Header->biXPelsPerMeter = 0; 01711 Header->biYPelsPerMeter = 0; 01712 Header->biClrUsed = 0; 01713 Header->biClrImportant = 0; 01714 01715 // Add padding for Gavin rampancy etc 01716 BitmapSize += EXTRA_GAVIN_BYTES + DIBUtil::ScanlineSize(bm.bmWidth, Depth); 01717 01718 Bits = (LPBYTE) CCMalloc(BitmapSize); 01719 if (Bits == NULL) 01720 { 01721 CCFree(Header); 01722 return(FALSE); 01723 } 01724 01725 // Get a screen DC, and select in the palette 01726 HDC hDC = GetDC(NULL); 01727 if (Depth <= 8) 01728 { 01729 hSourcePal = SelectPalette(hDC, hSourcePal, FALSE); 01730 RealizePalette(hDC); 01731 } 01732 01733 // Call GetDIBits to blit the bitmap data across 01734 INT32 result = GetDIBits(hDC, hSourceBmp, 0, (WORD)Header->biHeight, 01735 Bits, (LPBITMAPINFO) Header, DIB_RGB_COLORS); 01736 01737 // Restore the screen DC 01738 if (Depth <= 8) 01739 SelectPalette(hDC, hSourcePal, FALSE); 01740 ReleaseDC(NULL, hDC); 01741 01742 // Result will be zero for failure, else the number of scanlines copied 01743 if (result == 0) 01744 { 01745 CCFree(Bits); 01746 CCFree(Header); 01747 return(FALSE); 01748 } 01749 01750 if (Depth <= 8) 01751 { 01752 // If either of these fields are 0, they mean "The maximum number of colours" 01753 // and this doesn't export quite right, so we "fix" the value (eg 8bpp=>256 cols) 01754 if (Header->biClrUsed == 0) 01755 Header->biClrUsed = 1<<Depth; 01756 01757 if (Header->biClrImportant == 0) 01758 Header->biClrImportant = 1<<Depth; 01759 } 01760 01761 // And return successfully 01762 *ResultHeader = (LPBITMAPINFO) Header; 01763 *ResultBits = Bits; 01764 return(TRUE); 01765 } 01766 01767 01768 01769 /******************************************************************************************** 01770 01771 > virtual BOOL BitmapClipMap::HandleImport(SelOperation *Caller, 01772 HANDLE ClipboardData, 01773 InternalClipboard *Dest) 01774 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01775 Created: 20/4/95 01776 01777 Inputs: Caller - The operation within which this method is being called 01778 ClipboardData - The result of calling GetClipboardData for your datatype 01779 Dest - The InternalClipboard (document) to import the data into. 01780 01781 Returns: TRUE for success 01782 01783 Purpose: Calls the parent filter as appropriate to import the given data from 01784 the external clipboard. 01785 01786 This bodge mapping for text scans the docuemnt tree for text chars and 01787 strips them out by hand. Styles and suchlike are lost. It's a bodge. 01788 01789 SeeAlso: DIBClipMap::HandleImport 01790 01791 ********************************************************************************************/ 01792 01793 BOOL BitmapClipMap::HandleImport(SelOperation *Caller, 01794 HANDLE ClipboardData, InternalClipboard *Dest) 01795 { 01796 LPBYTE Bits = NULL; 01797 LPBITMAPINFO BmpInfo = NULL; 01798 WinBitmap *WinBmp = NULL; 01799 KernelBitmap *KernelBmp = NULL; 01800 // NodeBitmap *pNode = NULL; 01801 01802 // Try to retrieve the palette from the clipboard - if there is not one there, 01803 // we'll get a NULL, which ConvertBMPToDIB is quite happy with. 01804 HPALETTE hPalette = (HPALETTE) GetClipboardData(CF_PALETTE); 01805 if (!ConvertBMPToDIB((HBITMAP)ClipboardData, hPalette, /* TO */ &BmpInfo, &Bits)) 01806 goto Abort; 01807 01808 WinBmp = new WinBitmap(BmpInfo, Bits); 01809 if (WinBmp == NULL) 01810 goto Abort; 01811 01812 KernelBmp = new KernelBitmap(WinBmp); 01813 if (KernelBmp == NULL) 01814 goto Abort; 01815 01816 #if FALSE 01817 /* 01818 // And now, lob a bitmap node for it into the clipboard 01819 pNode = new NodeBitmap(); 01820 if (pNode == NULL || pNode->GetBitmapRef() == NULL || !(pNode->SetUpPath(12,12))) 01821 goto Abort; 01822 01823 // Attach this bitmap reference to the new bitmap, and put in the clipboard document 01824 pNode->GetBitmapRef()->Attach(KernelBmp, Dest); 01825 01826 // And set up the node's bounds appropriately 01827 BitmapInfo Info; 01828 pNode->GetBitmap()->ActualBitmap->GetInfo(&Info); 01829 01830 { 01831 DocRect BoundsRect; 01832 BoundsRect.lo.x = 0; 01833 BoundsRect.lo.y = 0; 01834 BoundsRect.hi.x = Info.RecommendedWidth/2; 01835 BoundsRect.hi.y = Info.RecommendedHeight/2; 01836 01837 pNode->CreateShape(BoundsRect); 01838 } 01839 01840 pNode->AttachNode(Dest->GetInsertionLayer(), LASTCHILD, FALSE); 01841 */ 01842 #else 01843 { 01844 // Compile information on where to put the imported NodeBitmap 01845 PageDropInfo DropInfo; 01846 01847 DropInfo.pDoc = InternalClipboard::Instance(); 01848 DropInfo.pDocView = DocView::GetCurrent(); 01849 DropInfo.pSpread = InternalClipboard::Instance()->FindFirstSpread(); //GetInsertionLayer()->FindParent(); 01850 DropInfo.DropPos = DocCoord(100,100); // Position is unimportant as it is centered when pasted 01851 DropInfo.TargetHit = NO_TARGET; 01852 DropInfo.pObjectHit = NULL; 01853 01854 // Invoke an Op to create a NodeBitmap for us 01855 OpDescriptor* OpCreateNodeBmp = OpDescriptor::FindOpDescriptor(CC_RUNTIME_CLASS(OpCreateNodeBitmap)); 01856 OpCreateNodeBmp->Invoke(&OpParam((INT32)KernelBmp,(INT32)&DropInfo)); 01857 } 01858 #endif 01859 01860 return(TRUE); 01861 01862 Abort: 01863 // ERROR2RAW("Bitmap import failed, probably due to lack of memory"); 01864 InformError(); 01865 01866 if (KernelBmp != NULL) 01867 delete KernelBmp; 01868 01869 if (WinBmp != NULL) 01870 delete WinBmp; 01871 else if (BmpInfo != NULL || Bits != NULL) 01872 FreeDIB(BmpInfo, Bits); 01873 01874 InternalClipboard::Clear(); // We failed, so ensure the doc is wiped 01875 01876 return(FALSE); 01877 } 01878 01879 01880 01881 /******************************************************************************************** 01882 01883 > static HPALETTE CreateBMPPalette(LPBITMAPINFOHEADER lpbi) 01884 01885 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01886 Created: 3/5/95 01887 01888 Inputs: lpbi - A pointer to your DIB's header 01889 01890 Returns: NULL (failed, or no palette), or a windows handle of the GDI palette data 01891 01892 Purpose: Given a DIB, creates a GDI HPALETTE based on the DIB's palette. 01893 If the DIB is 24 or 32 bit or whatever, this will return NULL, so it is a 01894 quite normal return value. 01895 01896 ********************************************************************************************/ 01897 01898 static HPALETTE CreateBMPPalette(LPBITMAPINFOHEADER lpbi) 01899 { 01900 ERROR3IF(lpbi == NULL, "Illegal NULL param"); 01901 01902 // Is it a windows DIB? If not, we can't get a palette out of it 01903 if (lpbi->biSize != sizeof(BITMAPINFOHEADER)) 01904 return NULL; 01905 01906 // Get a pointer to the colour table and the number of colours in it 01907 RGBQUAD *pRGB = (RGBQUAD *)((LPSTR)lpbi + (WORD)lpbi->biSize); 01908 INT32 NumColours = DIBUtil::CalcPaletteSize(lpbi->biBitCount, lpbi->biCompression == BI_BITFIELDS) / sizeof(RGBQUAD); 01909 01910 HPALETTE hpal = NULL; 01911 01912 if (NumColours > 0) 01913 { 01914 // Allocate temporary memory 01915 LOGPALETTE *pPal = (LOGPALETTE *) LocalAlloc(LPTR, sizeof(LOGPALETTE) + NumColours * sizeof(PALETTEENTRY)); 01916 if (pPal == NULL) 01917 return NULL; 01918 01919 // Set up the LOGPALETTE structure, copying the pal entries across 01920 pPal->palNumEntries = NumColours; 01921 pPal->palVersion = 0x300; // Palette structure Windows version number 01922 01923 for (INT32 i = 0; i < NumColours; i++) 01924 { 01925 pPal->palPalEntry[i].peRed = pRGB[i].rgbRed; 01926 pPal->palPalEntry[i].peGreen = pRGB[i].rgbGreen; 01927 pPal->palPalEntry[i].peBlue = pRGB[i].rgbBlue; 01928 pPal->palPalEntry[i].peFlags = (BYTE)0; 01929 } 01930 hpal = CreatePalette(pPal); 01931 LocalFree((HANDLE)pPal); 01932 } 01933 01934 return hpal; 01935 } 01936 01937 01938 01939 /******************************************************************************************** 01940 01941 > static KernelBitmap *FindBitmapToExport(InternalClipboard *Source) 01942 01943 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01944 Created: 3/5/95 01945 01946 Inputs: Source - the internal clipboard (document) to be exported 01947 01948 Returns: NULL (if it failed), or a KernelBitmap to be exported 01949 01950 Purpose: Scans the clipboard for bitmap objects that can be exported, and 01951 returns the first one found. 01952 01953 Used by the Bitmap, DIB, and Palette exporters to find the export data 01954 01955 ********************************************************************************************/ 01956 01957 static KernelBitmap *FindBitmapToExport(InternalClipboard *Source) 01958 { 01959 KernelBitmap *KernelBmp = NULL; 01960 01961 // Scan the entire document tree, looking for a bitmap to export 01962 Node *pSubtree = InternalClipboard::GetInsertionLayer(); 01963 Node *pNode = pSubtree->FindFirstDepthFirst(); 01964 01965 while (pNode != NULL && KernelBmp == NULL) 01966 { 01967 // Is this node a NodeBitmap? 01968 if (pNode->IsAnObject() && pNode->GetRuntimeClass() == CC_RUNTIME_CLASS(NodeBitmap)) 01969 { 01970 NodeBitmap* pNodeBmp = (NodeBitmap*)pNode; 01971 KernelBitmapRef *BmpRef = pNodeBmp->GetBitmapRef(); 01972 if (BmpRef != NULL) 01973 KernelBmp = BmpRef->GetBitmap(); 01974 } 01975 /* 01976 // How about a bitmap fill? 01977 else if (pNode->IsAnAttribute()) 01978 { 01979 if (((NodeAttribute*)pNode)->IsABitmapFill()) 01980 { 01981 // We've found either a Bitmap or Fractal fill 01982 AttrFillGeometry* pBmpFill = (AttrFillGeometry*)pNode; 01983 KernelBitmapRef *BmpRef = pBmpFill->GetBitmapRef(); 01984 if (BmpRef != NULL) 01985 KernelBmp = BmpRef->GetBitmap(); 01986 } 01987 } 01988 */ 01989 pNode = pNode->FindNextDepthFirst(pSubtree); 01990 } 01991 01992 return(KernelBmp); 01993 } 01994 01995 01996 01997 /******************************************************************************************** 01998 01999 > virtual BOOL BitmapClipMap::HandleExport(Operation *Caller, 02000 InternalClipboard *Source) 02001 02002 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 02003 Created: 20/4/95 02004 02005 Inputs: Caller - the operation within which this method is being called 02006 Source - the internal clipboard (document) to be exported 02007 02008 Returns: NULL (if it failed), or a windows handle of the data to be placed on 02009 the clipboard. 02010 02011 Purpose: Invokes this mapping for exporting 02012 This takes the document tree of Source, and exports it to the external 02013 (windows) clipboard. 02014 02015 This bodge mapping for text scans the docuemnt tree for text chars and 02016 strips them out by hand. Styles and suchlike are lost. It's a bodge. 02017 02018 Notes: The returned handle should be the thing you'd pass to SetClipboardData 02019 if you were dealing with it directly. You must adhere to all the Windows 02020 rules for this - i.e. a global data block, unlocked, etc etc. 02021 02022 Note that when a bitmap is available on the clipabord, a palette will 02023 also be available - see the SeeAlso 02024 02025 SeeAlso: PaletteClipMap::HandleExport; DIBClipMap::HandleExport 02026 02027 ********************************************************************************************/ 02028 02029 HANDLE BitmapClipMap::HandleExport(Operation *Caller, InternalClipboard *Source) 02030 { 02031 ERROR3("Bitmap export is unsupported on the grounds that it won't work thanks to Windows"); 02032 return(NULL); 02033 02034 /* 02035 // Scan the entire document tree, looking for a bitmap to export 02036 KernelBitmap *KernelBmp = FindBitmapToExport(Source); 02037 if (KernelBmp == NULL) // Didn't find a bitmap 02038 return(NULL); 02039 02040 OILBitmap *pOilBitmap = KernelBmp->ActualBitmap; 02041 ERROR3IF(pOilBitmap == NULL, "Unattached kernel bitmap found!"); 02042 WinBitmap* pWBitmap = (WinBitmap*)pOilBitmap; 02043 LPBITMAPINFO Info = pWBitmap->BMInfo; 02044 LPBYTE Bytes = pWBitmap->BMBytes; 02045 02046 // Convert the DIB into GDI BITMAP format 02047 HDC hDCScreen = GetDC(NULL); 02048 HBITMAP hBitmap = NULL; 02049 if (hDCScreen != NULL) 02050 { 02051 // HGDIOBJ OldPal = ::SelectObject(hDCScreen, CMainFrame::MainPalette.GetSafeHandle()); 02052 // RealizePalette(hDCScreen); 02053 02054 HPALETTE hPal = CreateBMPPalette(&Info->bmiHeader); 02055 HPALETTE hOldPal = NULL; 02056 02057 #if _DEBUG 02058 if (IsUserName("Jason")) 02059 ERROR3IF(hPal == NULL, "Couldn't create a palette for that image"); 02060 #endif 02061 02062 if (hPal != NULL) 02063 { 02064 hOldPal = SelectPalette(hDCScreen, hPal, FALSE); 02065 RealizePalette(hDCScreen); 02066 } 02067 02068 hBitmap = CreateDIBitmap(hDCScreen, &Info->bmiHeader, CBM_INIT, Bytes, Info, DIB_RGB_COLORS); 02069 SetClipboardData(CF_PALETTE, hPal); 02070 02071 // if (OldPal != NULL) 02072 // ::SelectObject(hDCScreen, OldPal); 02073 02074 02075 if (hPal != NULL) 02076 { 02077 SelectPalette(hDCScreen, hOldPal, FALSE); 02078 RealizePalette(hDCScreen); 02079 } 02080 02081 ReleaseDC(NULL, hDCScreen); 02082 } 02083 02084 // And return the bitmap handle, which is put on the clipboard for the CF_BITMAP data 02085 return((HANDLE) hBitmap); 02086 */ 02087 /* 02088 // Scan the entire document tree, looking for a bitmap to export 02089 KernelBitmap *KernelBmp = FindBitmapToExport(Source); 02090 if (KernelBmp == NULL) // Didn't find a bitmap 02091 return(NULL); 02092 02093 OILBitmap *pOilBitmap = KernelBmp->ActualBitmap; 02094 ERROR3IF(pOilBitmap == NULL, "Unattached kernel bitmap found!"); 02095 WinBitmap* pWBitmap = (WinBitmap*)pOilBitmap; 02096 LPBITMAPINFO Info = pWBitmap->BMInfo; 02097 LPBYTE Bytes = pWBitmap->BMBytes; 02098 02099 // Convert the DIB into GDI BITMAP format 02100 // HDC hDCScreen = GetDC(NULL); 02101 HBITMAP hBitmap = NULL; 02102 // if (hDCScreen != NULL) 02103 { 02104 // hBitmap = CreateDIBitmap(hDCScreen, &Info->bmiHeader, CBM_INIT, Bytes, Info, DIB_RGB_COLORS); 02105 hBitmap = CreateBitmap(Info->bmiHeader.biWidth, Info->bmiHeader.biHeight, 02106 1, Info->bmiHeader.biBitCount, NULL);//Bytes); 02107 02108 // Copy the DIB bits into the bitmap 02109 SetDIBits(NULL, hBitmap, 0, Info->bmiHeader.biHeight, Bytes, Info, NULL);//DIB_RGB_COLORS); 02110 02111 HPALETTE hPal = CreateBMPPalette(&Info->bmiHeader); 02112 SetClipboardData(CF_PALETTE, hPal); 02113 02114 // ReleaseDC(NULL, hDCScreen); 02115 } 02116 02117 // And return the bitmap handle, which is put on the clipboard for the CF_BITMAP data 02118 return((HANDLE) hBitmap); 02119 */ 02120 } 02121 02122 02123 02124 02125 02126 02127 02128 02129 02130 #if FALSE 02131 02132 // Palettes are only needed when exporting DDB Bitmaps, and we don't do this because they 02133 // almost never work. Also, fabbily, some programs out there stupidly use the palette we 02134 // supply with any DIB that we put on the clipboard (dang!) so it's generally a bad thing to 02135 // even try exporting a bitmap with palette. 02136 02137 /******************************************************************************************** 02138 02139 //> PaletteClipMap::PaletteClipMap() 02140 02141 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 02142 Created: 16/4/95 02143 02144 Purpose: Constructs a clipboard mapping with the ExternalClipboard 02145 manager. This mapping info describes a filter which is able to export 02146 palette data from bitmaps to a windows clipboard in CF_PALETTE format. 02147 02148 Notes: DON'T call the constructor - call CreateAndRegister 02149 02150 SeeAlso: PaletteClipMap::CreateAndRegister 02151 02152 ********************************************************************************************/ 02153 PaletteClipMap::PaletteClipMap() 02154 : ClipboardMapping(CLIPMAP_EXPORTONLY, NULL, 02155 InternalClipboardFormat(CLIPTYPE_BITMAP), 02156 CF_PALETTE, 70) 02157 { 02158 } 02159 02160 02161 02162 /******************************************************************************************** 02163 02164 //> static void PaletteClipMap::CreateAndRegister(void) 02165 02166 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 02167 Created: 3/5/95 02168 02169 Purpose: Constructs and registers a clipboard mapping with the ExternalClipboard 02170 manager. This mapping info describes a filter which is able to export 02171 data to a windows clipboard in CF_PALETTE format 02172 02173 ********************************************************************************************/ 02174 02175 void PaletteClipMap::CreateAndRegister(void) 02176 { 02177 PaletteClipMap *Mapping = new PaletteClipMap(); 02178 if (Mapping == NULL) 02179 InformError(); 02180 else 02181 ExternalClipboard::RegisterDataType(Mapping); 02182 } 02183 02184 02185 02186 /******************************************************************************************** 02187 02188 //> virtual BOOL PaletteClipMap::HandleExport(Operation *Caller, 02189 InternalClipboard *Source) 02190 02191 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 02192 Created: 20/4/95 02193 02194 Inputs: Caller - the operation within which this method is being called 02195 Source - the internal clipboard (document) to be exported 02196 02197 Returns: NULL (if it failed), or a windows handle of the data to be placed on 02198 the clipboard. 02199 02200 Purpose: Invokes this mapping for exporting 02201 This takes the document tree of Source, and exports it to the external 02202 (windows) clipboard. 02203 02204 This bodge mapping for text scans the docuemnt tree for text chars and 02205 strips them out by hand. Styles and suchlike are lost. It's a bodge. 02206 02207 Notes: The returned handle should be the thing you'd pass to SetClipboardData 02208 if you were dealing with it directly. You must adhere to all the Windows 02209 rules for this - i.e. a global data block, unlocked, etc etc. 02210 02211 ********************************************************************************************/ 02212 02213 HANDLE PaletteClipMap::HandleExport(Operation *Caller, InternalClipboard *Source) 02214 { 02215 ERROR3("Palette not exported\n"); 02216 return(NULL); 02217 02218 /* 02219 KernelBitmap *KernelBmp = FindBitmapToExport(Source); 02220 if (KernelBmp == NULL) // Didn't find a bitmap 02221 return(NULL); 02222 02223 OILBitmap *pOilBitmap = KernelBmp->ActualBitmap; 02224 ERROR3IF(pOilBitmap == NULL, "Unattached kernel bitmap found!"); 02225 WinBitmap* pWBitmap = (WinBitmap*)pOilBitmap; 02226 02227 // Generate a palette for the bitmap 02228 ERROR3IF(pWBitmap->BMInfo == NULL, "Incomplete winoil bitmap"); 02229 HPALETTE hPal = CreateBMPPalette(&(pWBitmap->BMInfo->bmiHeader)); 02230 if (hPal != NULL) 02231 return(hPal); 02232 02233 // It failed (probably a 24 or 32 bpp BMP) so give them the mainframe's palette 02234 return(CMainFrame::MainPalette.GetSafeHandle()); 02235 */ 02236 } 02237 #endif 02238 02239 02240 02241 02242 02243 02244 02245 02246 02247 02248 02249 DIBClipMap::DIBClipMap() 02250 { 02251 ERROR3("Please don't press that button again"); 02252 } 02253 02254 02255 /******************************************************************************************** 02256 02257 > DIBClipMap::DIBClipMap(ClipboardMappingType TheType, UINT32 ClaimType = 0) 02258 02259 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 02260 Created: 16/4/95 02261 02262 Inputs: TheType - indicates import / export / import & export 02263 02264 ClaimType - CF_DIB for straight import, CF_BITMAP for an alias 02265 02266 Purpose: Constructs a clipboard mapping with the ExternalClipboard 02267 manager. This mapping info describes a filter which is able to import 02268 data from or export data to a windows clipboard in some way. 02269 02270 Notes: DON'T call the constructor - call CreateAndRegister 02271 02272 SeeAlso: DIBClipMap::CreateAndRegister 02273 02274 ********************************************************************************************/ 02275 02276 DIBClipMap::DIBClipMap(ClipboardMappingType TheType, UINT32 ClaimType) 02277 : ClipboardMapping(TheType, NULL, InternalClipboardFormat(CLIPTYPE_BITMAP), 02278 CF_DIB, 80) 02279 { 02280 if (ClaimType != 0) 02281 ExternalDataType = ClaimType; 02282 } 02283 02284 02285 02286 /******************************************************************************************** 02287 02288 > static void DIBClipMap::CreateAndRegister(ClipboardMappingType TheType, UINT32 ClaimType = 0) 02289 02290 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 02291 Created: 16/4/95 02292 02293 Inputs: TheType - indicates import / export / import & export 02294 02295 ClaimType - CF_DIB for straight import, CF_BITMAP for an alias 02296 02297 Purpose: Constructs and registers a clipboard mapping with the ExternalClipboard 02298 manager. This mapping info describes a filter which is able to import 02299 data from or export data to a windows clipboard in some way. 02300 02301 ********************************************************************************************/ 02302 02303 void DIBClipMap::CreateAndRegister(ClipboardMappingType TheType, UINT32 ClaimType) 02304 { 02305 DIBClipMap *Mapping = new DIBClipMap(TheType, ClaimType); 02306 if (Mapping == NULL) 02307 InformError(); 02308 else 02309 ExternalClipboard::RegisterDataType(Mapping); 02310 } 02311 02312 02313 02314 /******************************************************************************************** 02315 02316 > virtual BOOL DIBClipMap::HandleImport(SelOperation *Caller, 02317 HANDLE ClipboardData, 02318 InternalClipboard *Dest) 02319 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 02320 Created: 20/4/95 02321 02322 Inputs: Caller - The operation within which this method is being called 02323 ClipboardData - The result of calling GetClipboardData for your datatype 02324 Dest - The InternalClipboard (document) to import the data into. 02325 02326 Returns: TRUE for success 02327 02328 Purpose: Calls the parent filter as appropriate to import the given data from 02329 the external clipboard. 02330 02331 This bodge mapping for text scans the docuemnt tree for text chars and 02332 strips them out by hand. Styles and suchlike are lost. It's a bodge. 02333 02334 ********************************************************************************************/ 02335 02336 BOOL DIBClipMap::HandleImport(SelOperation *Caller, 02337 HANDLE ClipboardData, InternalClipboard *Dest) 02338 { 02339 LPBYTE Bits = NULL; 02340 LPBITMAPINFO BmpInfo = NULL; 02341 WinBitmap *WinBmp = NULL; 02342 KernelBitmap *KernelBmp = NULL; 02343 CCMemFile MemFile; 02344 02345 BITMAPINFO *buff = (BITMAPINFO *) GlobalLock(ClipboardData); 02346 if (buff != NULL) 02347 { 02348 String_64 ProgressMsg(_R(IDS_CLIPBOARD_IMPORTDIB)); 02349 MemFile.open(buff, GlobalSize(ClipboardData), CCMemRead); 02350 if (!DIBUtil::ReadFromFile(&MemFile, &BmpInfo, &Bits, FALSE, &ProgressMsg)) 02351 goto Abort; 02352 02353 MemFile.close(); 02354 GlobalUnlock(ClipboardData); 02355 02356 WinBmp = new WinBitmap(BmpInfo, Bits); 02357 if (WinBmp == NULL) 02358 goto Abort; 02359 02360 KernelBmp = new KernelBitmap(WinBmp); 02361 if (KernelBmp == NULL) 02362 goto Abort; 02363 02364 // And now, lob a bitmap node for it into the clipboard 02365 NodeBitmap *pNode = new NodeBitmap(); 02366 if (pNode == NULL || pNode->GetBitmapRef() == NULL || !(pNode->SetUpPath(12,12))) 02367 goto Abort; 02368 02369 // Attach this bitmap reference to the new bitmap, and put in the clipboard document 02370 pNode->GetBitmapRef()->Attach(KernelBmp, InternalClipboard::Instance()); 02371 if (pNode->GetBitmap() != KernelBmp) 02372 { 02373 // It didn't use the bitmap we gave it, so we can delete it 02374 delete KernelBmp; 02375 } 02376 02377 // And set up the node's bounds appropriately 02378 BitmapInfo Info; 02379 pNode->GetBitmap()->ActualBitmap->GetInfo(&Info); 02380 02381 DocRect BoundsRect; 02382 BoundsRect.lo.x = 0; 02383 BoundsRect.lo.y = 0; 02384 BoundsRect.hi.x = Info.RecommendedWidth/2; 02385 BoundsRect.hi.y = Info.RecommendedHeight/2; 02386 02387 pNode->CreateShape(BoundsRect); 02388 02389 // Apply the default bitmap attributes 02390 pNode->ApplyDefaultBitmapAttrs(NULL); 02391 02392 pNode->AttachNode(InternalClipboard::GetInsertionLayer(), LASTCHILD, FALSE); 02393 return(TRUE); 02394 } 02395 02396 return(FALSE); 02397 02398 Abort: 02399 // ERROR2RAW("Bitmap import failed, probably due to lack of memory"); 02400 // InformError(); 02401 02402 GlobalUnlock(ClipboardData); 02403 02404 if (MemFile.isOpen()) 02405 MemFile.close(); 02406 02407 if (KernelBmp != NULL) 02408 delete KernelBmp; 02409 02410 if (WinBmp != NULL) 02411 delete WinBmp; 02412 /* else if (BmpInfo != NULL || Bits != NULL) 02413 FreeDIB(BmpInfo, Bits); 02414 */ 02415 InternalClipboard::Clear(); // We failed, so ensure the doc is wiped 02416 InformError(); 02417 return(FALSE); 02418 } 02419 02420 02421 02422 /******************************************************************************************** 02423 02424 > virtual BOOL DIBClipMap::HandleExport(Operation *Caller, 02425 InternalClipboard *Source) 02426 02427 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 02428 Created: 20/4/95 02429 02430 Inputs: Caller - the operation within which this method is being called 02431 Source - the internal clipboard (document) to be exported 02432 02433 Returns: NULL (if it failed), or a windows handle of the data to be placed on 02434 the clipboard. 02435 02436 Purpose: Invokes this mapping for exporting 02437 This takes the document tree of Source, and exports it to the external 02438 (windows) clipboard. 02439 02440 This bodge mapping for text scans the docuemnt tree for text chars and 02441 strips them out by hand. Styles and suchlike are lost. It's a bodge. 02442 02443 Notes: The returned handle should be the thing you'd pass to SetClipboardData 02444 if you were dealing with it directly. You must adhere to all the Windows 02445 rules for this - i.e. a global data block, unlocked, etc etc. 02446 02447 ********************************************************************************************/ 02448 02449 HANDLE DIBClipMap::HandleExport(Operation *Caller, InternalClipboard *Source) 02450 { 02451 // Scan the entire document tree, looking for a bitmap to export 02452 KernelBitmap *KernelBmp = FindBitmapToExport(InternalClipboard::Instance()); 02453 if (KernelBmp == NULL) // Didn't find a bitmap 02454 return(NULL); 02455 02456 OILBitmap *pOilBitmap = KernelBmp->ActualBitmap; 02457 ERROR3IF(pOilBitmap == NULL, "Unattached kernel bitmap found!"); 02458 WinBitmap* pWBitmap = (WinBitmap*)pOilBitmap; 02459 LPBITMAPINFO Info = pWBitmap->BMInfo; 02460 LPBYTE Bytes = pWBitmap->BMBytes; 02461 02462 ERROR3IF(Info->bmiHeader.biSizeImage == 0, "Bitmap data size is zero - I'm about to screw up the export"); 02463 02464 // Neville 14/10/97 02465 // Don't just use the number of colours in the colour depth. If we have set biClrUsed to 02466 // something between 0 and max number of colours for that colour depth then that is 02467 // the size of the palette that is expected. We set biClrUsed when exporting an 02468 // optimised palette with a user specified number of colours. 02469 // If we don't make sure that this matches the the destination program will skew the 02470 // bitmap. 02471 UINT32 PalSize = DIBUtil::CalcPaletteSize(pWBitmap->GetBPP(), Info->bmiHeader.biCompression == BI_BITFIELDS, 02472 Info->bmiHeader.biClrUsed); 02473 DWORD HeaderSize = Info->bmiHeader.biSize + PalSize; 02474 DWORD BitmapSize = Info->bmiHeader.biSizeImage; 02475 02476 #if (_OLE_VER >= 0x200) 02477 02478 // Get the memory block's handle. 02479 BOOL fDidAlloc = FALSE; 02480 HANDLE hGlobalMem = m_hMem; 02481 if (!hGlobalMem) 02482 { 02483 // We don't have any memory, so try to allocate some and remember that we did so. 02484 fDidAlloc = TRUE; 02485 hGlobalMem = m_hMem = GlobalAlloc(GHND, HeaderSize + BitmapSize); 02486 if (hGlobalMem == NULL) 02487 { 02488 ERROR3("Couldn't get enough memory to export bitmap"); 02489 return(NULL); 02490 } 02491 } 02492 02493 #else 02494 02495 // Allocate a block of global memory to store the DIB 02496 HANDLE hGlobalMem = GlobalAlloc(GHND, HeaderSize + BitmapSize); 02497 02498 if (hGlobalMem == NULL) 02499 { 02500 ERROR3("Couldn't get enough memory to export bitmap"); 02501 return(NULL); 02502 } 02503 02504 #endif 02505 02506 char* buff = (char*) GlobalLock(hGlobalMem); 02507 if (buff == NULL) 02508 { 02509 ERROR3("Couldn't get clipboard memory"); 02510 #if (_OLE_VER >= 0x200) 02511 if (fDidAlloc) GlobalFree(hGlobalMem); 02512 #else 02513 GlobalFree(hGlobalMem); 02514 #endif 02515 return(NULL); 02516 } 02517 02518 // Copy the DIB onto the clipboard (copy the header and body separately as they 02519 // may not lie in contiguous memory) 02520 memcpy(buff, Info, HeaderSize); 02521 memcpy(buff + HeaderSize, Bytes, BitmapSize); 02522 02523 // We must unlock the block before giving it to the clipboard 02524 GlobalUnlock(hGlobalMem); 02525 return(hGlobalMem); 02526 } 02527 02528 02529 02530 02531 02532 02533 02534 02535 #if FALSE 02536 02537 // Experimental code to attempt to load EPSF files copied from Quark XPress 02538 // It doesn't work very well, and it's highly specific, so not worth using. 02539 02540 /******************************************************************************************** 02541 02542 > QuarkPictureClipMap::QuarkPictureClipMap() 02543 02544 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 02545 Created: 16/4/95 02546 02547 Inputs: TheType - indicates import / export / import & export 02548 02549 ClaimType - CF_DIB for straight import, CF_BITMAP for an alias 02550 02551 Purpose: Constructs a clipboard mapping with the ExternalClipboard 02552 manager. This mapping info describes a filter which is able to import 02553 data from or export data to a windows clipboard in some way. 02554 02555 Notes: DON'T call the constructor - call CreateAndRegister 02556 02557 SeeAlso: QuarkPictureClipMap::CreateAndRegister 02558 02559 ********************************************************************************************/ 02560 02561 QuarkPictureClipMap::QuarkPictureClipMap() 02562 { 02563 ERROR3("Nope. Wrong constructor dude"); 02564 } 02565 02566 QuarkPictureClipMap::QuarkPictureClipMap(UINT32 MyFormat) 02567 : ClipboardMapping(CLIPMAP_IMPORTONLY, NULL, 02568 InternalClipboardFormat(CLIPTYPE_VECTOR), 02569 MyFormat, 110) 02570 { 02571 } 02572 02573 02574 02575 /******************************************************************************************** 02576 02577 > static void QuarkPictureClipMap::CreateAndRegister(void) 02578 02579 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 02580 Created: 16/4/95 02581 02582 Purpose: Constructs and registers a clipboard mapping with the ExternalClipboard 02583 manager. This mapping info describes a filter which is able to import 02584 data from or export data to a windows clipboard in some way. 02585 02586 Notes: This also registers a custom clipboard format with Windows 02587 02588 ********************************************************************************************/ 02589 02590 void QuarkPictureClipMap::CreateAndRegister(void) 02591 { 02592 #if _DEBUG 02593 // Register or determine the Format ID for the Quack XPress custom clipboard format 02594 UINT32 MyFormat = RegisterClipboardFormat("QuarkXPress Picture Data"); 02595 02596 if (MyFormat == 0) 02597 { 02598 ERROR3("Couldn't register QuarkXPress clipboard handler"); 02599 return; 02600 } 02601 02602 QuarkPictureClipMap *Mapping = new QuarkPictureClipMap(MyFormat); 02603 if (Mapping == NULL) 02604 InformError(); 02605 else 02606 ExternalClipboard::RegisterDataType(Mapping); 02607 #endif 02608 } 02609 02610 02611 02612 typedef struct 02613 { 02614 BYTE dunno1[2]; // Yep, I've really sussed their format now! ;-) 02615 char ID[4]; 02616 BYTE dunno2[40]; 02617 char Type[4]; 02618 BYTE dunno3[28]; 02619 char Pathname[260]; // Zero terminated, with a bit of crap on the end 02620 } QUACKDATA; 02621 02622 02623 /******************************************************************************************** 02624 02625 > virtual BOOL QuarkPictureClipMap::HandleImport(SelOperation *Caller, 02626 HANDLE ClipboardData, 02627 InternalClipboard *Dest) 02628 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 02629 Created: 20/4/95 02630 02631 Inputs: Caller - The operation within which this method is being called 02632 ClipboardData - The result of calling GetClipboardData for your datatype 02633 Dest - The InternalClipboard (document) to import the data into. 02634 02635 Returns: TRUE for success 02636 02637 Purpose: Calls the parent filter as appropriate to import the given data from 02638 the external clipboard. 02639 02640 This bodge mapping for text scans the docuemnt tree for text chars and 02641 strips them out by hand. Styles and suchlike are lost. It's a bodge. 02642 02643 ********************************************************************************************/ 02644 02645 BOOL QuarkPictureClipMap::HandleImport(SelOperation *Caller, 02646 HANDLE ClipboardData, InternalClipboard *Dest) 02647 { 02648 #if _DEBUG 02649 QUACKDATA *buff = (QUACKDATA *) GlobalLock(ClipboardData); 02650 02651 if (buff != NULL) 02652 { 02653 if (IsUserName("Jason")) 02654 { 02655 FILE *fp = _tfopen("c:\\jason.tmp", "wb"); 02656 size_t Size = (size_t)GlobalSize(ClipboardData); 02657 fwrite(buff, 1, Size, fp); 02658 fclose(fp); 02659 } 02660 02661 if (camStrncmp(buff->ID, "XPR3", 4)) 02662 { 02663 ERROR3("Not a Quark XPress 3 clipboard thingo"); 02664 goto Abort; 02665 } 02666 02667 if (camStrncmp(buff->Type, "EPSF", 4)) 02668 { 02669 ERROR3("Doesn't appear to be EPSF"); 02670 goto Abort; 02671 } 02672 02673 // Attempt to load the EPS data from the given pathname - BODGE! ******* !!!!!!!!!!! 02674 CDocument* pDoc = AfxGetApp()->OpenDocumentFile(buff->Pathname); 02675 02676 GlobalUnlock(ClipboardData); 02677 return(TRUE); 02678 } 02679 #endif 02680 02681 return(FALSE); 02682 02683 Abort: 02684 GlobalUnlock(ClipboardData); 02685 return(FALSE); 02686 } 02687 02688 #endif 02689 02690 02691 #ifdef _DEBUG 02692 /******************************************************************************************** 02693 > RTFClipMap::RTFClipMap(ClipboardMappingType TheType, Filter *TheFilter, 02694 InternalClipboardFormat *TheInternalDataType, 02695 UINT32 TheExternalDataType, 02696 UINT32 ThePriority) 02697 Author: Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> 02698 Created: 13/12/95 02699 Inputs: TheType - 1 (import), 2 (export), or 3 (import and export) 02700 TheFilter - The filter which can apply this conversion 02701 TheInternalDatatType - An object defining the internal data type 02702 (see cliptype.h) 02703 TheExternalDataType - A Windows CF_ constant defining the external 02704 clipboard data type which will be imported/exported. 02705 ThePriority - An integer indicating the priority of this mapping. 02706 The highest available priority mapping will be used in order to 02707 retain as much information in the data as possible. See 02708 docs\howtouse\ExtClip.doc for details of the existing mappings. 02709 Purpose: Constructs a clipboard mapping with the ExternalClipboard 02710 manager. This mapping info describes a filter which is able to import 02711 data from or export data to a windows clipboard in some way. 02712 Notes: DON'T call the constructor - call CreateAndRegister 02713 SeeAlso: RTFClipMap::CreateAndRegister 02714 ********************************************************************************************/ 02715 02716 RTFClipMap::RTFClipMap(ClipboardMappingType TheType, Filter *TheFilter, 02717 InternalClipboardFormat &TheInternalDataType, 02718 UINT32 TheExternalDataType, 02719 UINT32 ThePriority) 02720 : ClipboardMapping(TheType, TheFilter, TheInternalDataType, 02721 TheExternalDataType, ThePriority) 02722 { 02723 } 02724 02725 02726 02727 /******************************************************************************************** 02728 > static void RTFClipMap::CreateAndRegister(ClipboardMappingType TheType, Filter *TheFilter, 02729 InternalClipboardFormat &TheInternalDataType, 02730 UINT32 TheExternalDataType, 02731 UINT32 ThePriority) 02732 Author: Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> 02733 Created: 13/12/95 02734 Inputs: ImportOrExport - TRUE == Import, FALSE == Export 02735 02736 TheFilter - The filter which can apply this conversion 02737 02738 TheInternalDatatType - An object defining the internal data type 02739 (see cliptype.h) 02740 02741 TheExternalDataType - A Windows CF_ constant defining the external 02742 clipboard data type which will be imported/exported. 02743 02744 ThePriority - An integer indicating the priority of this mapping. 02745 The highest available priority mapping will be used in order to 02746 retain as much information in the data as possible. See 02747 docs\howtouse\ExtClip.doc for details of the existing mappings. 02748 02749 Purpose: Constructs and registers a clipboard mapping with the ExternalClipboard 02750 manager. This mapping info describes a filter which is able to import 02751 data from or export data to a windows clipboard in some way. 02752 ********************************************************************************************/ 02753 void RTFClipMap::CreateAndRegister(ClipboardMappingType TheType, Filter *TheFilter, 02754 InternalClipboardFormat &TheInternalDataType, 02755 UINT32 TheExternalDataType, 02756 UINT32 ThePriority) 02757 { 02758 RTFClipMap *Mapping = new RTFClipMap(TheType, TheFilter, 02759 TheInternalDataType, 02760 TheExternalDataType, 02761 ThePriority); 02762 if (Mapping == NULL) 02763 InformError(); 02764 else 02765 ExternalClipboard::RegisterDataType(Mapping); 02766 } 02767 02768 02769 02770 /******************************************************************************************** 02771 > virtual BOOL RTFClipMap::HandleImport(SelOperation *Caller, HANDLE ClipboardData, InternalClipboard *Dest) 02772 Author: Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> 02773 Created: 13/12/95 02774 Inputs: Caller - The operation within which this method is being called 02775 ClipboardData - The result of calling GetClipboardData for your datatype 02776 Dest - The InternalClipboard (document) to import the data into. 02777 Returns: TRUE for success 02778 Purpose: Calls the parent filter as appropriate to import the given data from 02779 the external clipboard. 02780 ********************************************************************************************/ 02781 BOOL RTFClipMap::HandleImport(SelOperation *Caller, HANDLE ClipboardData, InternalClipboard *Dest) 02782 { 02783 CCMemFile MemFile; 02784 BOOL ok = TRUE; 02785 02786 // Get a lock on the clipboard data 02787 BYTE* buff = (BYTE*) GlobalLock(ClipboardData); 02788 ERROR1IF(buff == NULL, FALSE, "_R(IDE_NOMORE_MEMORY)"); 02789 02790 // Provide a current view for the filter to chomp on; We stack the current 02791 // view so that we do not corrupt it. 02792 View *OldCurrentView = NULL; 02793 ClipboardView ImportView; 02794 if (ok) 02795 OldCurrentView = View::GetCurrent(); 02796 if (ok) 02797 ok = ImportView.Init(); 02798 if (ok) 02799 ImportView.SetCurrent(); 02800 02801 // Open a memfile onto that data 02802 if (ok) 02803 ok = MemFile.open(buff, GlobalSize(ClipboardData)-1, CCMemRead); 02804 02805 // Attempt to import the file 02806 if (ok) 02807 ok = pFilter->DoImport(Caller, &MemFile, InternalClipboard::Instance()); 02808 02809 // Clean up behind messy importers 02810 if (MemFile.isOpen()) 02811 MemFile.close(); 02812 02813 if (OldCurrentView != NULL) 02814 OldCurrentView->SetCurrent(); 02815 02816 GlobalUnlock(ClipboardData); 02817 02818 return ok; 02819 } 02820 02821 02822 02823 /******************************************************************************************** 02824 > virtual BOOL RTFClipMap::HandleExport(Operation *Caller, 02825 InternalClipboard *Source) 02826 Author: Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> 02827 Created: 13/12/95 02828 Inputs: Caller - the operation within which this method is being called 02829 Source - the internal clipboard (document) to be exported 02830 Returns: NULL (if it failed), or a windows handle of the data to be placed on 02831 the clipboard. 02832 Purpose: Invokes this mapping for exporting 02833 This takes the document tree of Source, and exports it to the external 02834 (windows) clipboard. Usually this just involves calling Filter::DoExport 02835 for the parent filter, and then returning the handle to the global memory 02836 block to be placed onto the external clipboard. 02837 Notes: The returned handle should be the thing you'd pass to SetClipboardData 02838 if you were dealing with it directly. You must adhere to all the Windows 02839 rules for this - i.e. a global data block, unlocked, etc etc. 02840 ********************************************************************************************/ 02841 HANDLE RTFClipMap::HandleExport(Operation *Caller, InternalClipboard *Source) 02842 { 02843 return NULL; 02844 } 02845 #endif 02846 02847 02848 02849 /******************************************************************************************** 02850 02851 > CMXClipMap::CMXClipMap(ClipboardMappingType TheType, UINT32 ClaimType = 0) 02852 Author: Ben_Summers (Xara Group Ltd) <camelotdev@xara.com> 02853 Created: 04/09/96 02854 02855 Inputs: TheType - indicates import / export / import & export 02856 02857 ClaimType - specifies the text type that this mapping will claim from the 02858 windows clipboard - that is, create 3 of these mappings, specifying 02859 CF_TEXT, CF_UNICODETEXT, and CF_OEMTEXT, and they will all ask the 02860 clipboard for UNICODE text when they actually go to import. This allows 02861 us to detect the 3 implicitly-converted clipboard formats, and map them 02862 all to UNICODE, i.e. use the UNICODE mapping for all 3 available formats. 02863 If ClaimType == 0, UNICODE is assumed 02864 02865 Purpose: Constructs a clipboard mapping with the ExternalClipboard 02866 manager. This mapping info describes a filter which is able to import 02867 data from or export data to a windows clipboard in some way. 02868 02869 Notes: DON'T call the constructor - call CreateAndRegister 02870 02871 SeeAlso: BodgeTextClipMap::CreateAndRegister 02872 02873 ********************************************************************************************/ 02874 02875 CMXClipMap::CMXClipMap(ClipboardMappingType TheType, UINT32 ClaimType, UINT32 nPriority) 02876 : ClipboardMapping(TheType, NULL, InternalClipboardFormat(CLIPTYPE_VECTOR), 02877 ClaimType, nPriority) 02878 { 02879 if (ClaimType != 0) 02880 ExternalDataType = ClaimType; 02881 } 02882 02883 CMX16ClipMap::CMX16ClipMap() 02884 { 02885 ERROR3("Please don't press that button again"); 02886 } 02887 02888 CMX32ClipMap::CMX32ClipMap() 02889 { 02890 ERROR3("Please don't press that button again"); 02891 } 02892 02893 /******************************************************************************************** 02894 02895 > static void CMXClipMap::CreateAndRegister(ClipboardMappingType TheType, UINT32 ClaimType = 0) 02896 02897 Author: Ben_Summers (Xara Group Ltd) <camelotdev@xara.com> 02898 Created: 04/09/96 02899 02900 Inputs: TheType - indicates import / export / import & export 02901 02902 ClaimType - specifies the text type that this mapping will claim from the 02903 02904 Purpose: Constructs and registers a clipboard mapping with the ExternalClipboard 02905 manager. This mapping info describes a filter which is able to import 02906 data from or export data to a windows clipboard in some way. 02907 02908 ********************************************************************************************/ 02909 02910 void CMX16ClipMap::CreateAndRegister(ClipboardMappingType TheType, UINT32 ClaimType) 02911 { 02912 CMXClipMap *Mapping = new CMX16ClipMap(TheType, ClaimType, 120); 02913 if (Mapping == NULL) 02914 InformError(); 02915 else 02916 ExternalClipboard::RegisterDataType(Mapping); 02917 } 02918 02919 void CMX32ClipMap::CreateAndRegister(ClipboardMappingType TheType, UINT32 ClaimType) 02920 { 02921 // CMX32 should have a higher priority than CMX16! 02922 CMXClipMap *Mapping = new CMX32ClipMap(TheType, ClaimType, 121); 02923 if (Mapping == NULL) 02924 InformError(); 02925 else 02926 ExternalClipboard::RegisterDataType(Mapping); 02927 } 02928 02929 02930 /******************************************************************************************** 02931 02932 > virtual BOOL CMXClipMap::HandleImport(SelOperation *Caller, HANDLE ClipboardData, 02933 InternalClipboard *Dest) 02934 Author: Ben_Summers (Xara Group Ltd) <camelotdev@xara.com> 02935 Created: 04/09/96 02936 Inputs: Caller - The operation within which this method is being called 02937 ClipboardData - The result of calling GetClipboardData for your datatype 02938 Dest - The InternalClipboard (document) to import the data into. 02939 Returns: TRUE for success 02940 Purpose: Calls the parent filter as appropriate to import the given data from 02941 the external clipboard. 02942 This bodge mapping for text scans the docuemnt tree for text chars and 02943 strips them out by hand. Styles and suchlike are lost. It's a bodge. 02944 ********************************************************************************************/ 02945 02946 BOOL CMXClipMap::HandleImport(SelOperation *Caller, HANDLE ClipboardData, InternalClipboard *Dest) 02947 { 02948 BOOL ok = FALSE; 02949 02950 // Get a scratch file - if TMP isn't set, this will try for c:\temp. 02951 // The filename will have XS as a prefix 02952 char *tempname = GetTempFileName(); 02953 if (tempname == NULL) 02954 { 02955 ERROR3("Couldn't get a temp filename"); 02956 return(FALSE); 02957 } 02958 02959 void *pMem = GlobalLock(ClipboardData); 02960 ok = (pMem != NULL); 02961 02962 BOOL Layers = Filter::ImportWithLayers; 02963 Filter::ImportWithLayers = FALSE; 02964 pFilter = new CMXImportFilter; 02965 ok = (pFilter != NULL); 02966 02967 CCDiskFile File; 02968 if(ok) 02969 { 02970 // get a file and write to it 02971 PathName pathname(tempname); 02972 if(!File.open(pathname, (ios::out | ios::binary))) 02973 ok = FALSE; // error! 02974 } 02975 02976 if(ok) 02977 { 02978 File.write(pMem, GlobalSize(ClipboardData)); 02979 02980 File.close(); 02981 } 02982 02983 GlobalUnlock(ClipboardData); 02984 02985 if(ok) 02986 { 02987 ok = ImportFromTempFile(tempname, Caller, InternalClipboard::Instance()); 02988 } 02989 02990 RemoveTempFile(); 02991 02992 if(pFilter != NULL) 02993 { 02994 delete pFilter; 02995 pFilter = NULL; 02996 } 02997 02998 Filter::ImportWithLayers = Layers; 02999 03000 return(ok); 03001 03002 03003 /* char *buff=(char*)GlobalLock(ClipboardData); 03004 if (buff != NULL && buff[0] != 0) 03005 { 03006 // get a filter to play with 03007 CMXImportFilter *pFilter = new CMXImportFilter; 03008 BOOL ok = (pFilter != NULL); 03009 03010 // Provide a current view for the filter to chomp on; We stack the current 03011 // view so that we do not corrupt it. 03012 View *OldCurrentView = View::GetCurrent(); 03013 ClipboardView ImportView; 03014 if(!ImportView.Init()) 03015 { 03016 ok = FALSE; 03017 } 03018 else 03019 { 03020 ImportView.SetCurrent(); 03021 } 03022 03023 // position arbitarily on clipboard - when pasted the clip contents are centered anyway 03024 if(ok) 03025 { 03026 // make a memfile based on this thingy 03027 CCMemFile File(buff, GlobalSize(ClipboardData), CCMemRead, TRUE, TRUE); 03028 03029 // run it through the filter 03030 ok = pFilter->DoImport(Caller, &File, Dest); 03031 03032 if(File.isOpen()) 03033 File.close(); 03034 03035 if (OldCurrentView != NULL) 03036 OldCurrentView->SetCurrent(); 03037 } 03038 03039 // Unlock the clipboard data, as we won't need it again 03040 GlobalUnlock(ClipboardData); 03041 03042 if(ok) 03043 return TRUE; 03044 03045 // We failed (no text story), so report and ensure the clipboard is 'clean' 03046 InformError(); 03047 Dest->ClearClipboard(); 03048 } 03049 03050 // We failed 03051 return FALSE;*/ 03052 } 03053 03054 03055 03056 03057 /******************************************************************************************** 03058 03059 > virtual BOOL CMXClipMap::HandleExport(Operation *Caller, 03060 InternalClipboard *Source) 03061 03062 Author: Ben_Summers (Xara Group Ltd) <camelotdev@xara.com> 03063 Created: 04/09/96 03064 03065 Inputs: Caller - the operation within which this method is being called 03066 Source - the internal clipboard (document) to be exported 03067 03068 Returns: NULL (if it failed), or a windows handle of the data to be placed on 03069 the clipboard. 03070 03071 Purpose: Invokes this mapping for exporting 03072 This takes the document tree of Source, and exports it to the external 03073 (windows) clipboard. Usually this just involves calling Filter::DoExport 03074 for the parent filter, and then returning the handle to the global memory 03075 block to be placed onto the external clipboard. 03076 03077 Notes: The returned handle should be the thing you'd pass to SetClipboardData 03078 if you were dealing with it directly. You must adhere to all the Windows 03079 rules for this - i.e. a global data block, unlocked, etc etc. 03080 03081 ********************************************************************************************/ 03082 03083 HANDLE CMXClipMap::HandleExport(Operation *Caller, InternalClipboard *Source) 03084 { 03085 char *tempname = GetTempFileName(); //_ttempnam("C:\temp", "XS"); 03086 if (tempname == NULL) 03087 { 03088 ERROR3("Couldn't get a temp filename"); 03089 return(FALSE); 03090 } 03091 03092 03093 // make a new disk file of this name 03094 CCDiskFile File; 03095 PathName pathname(tempname); 03096 if(!File.open(pathname, (ios::in | ios::out | ios::binary))) 03097 return 0; // error! 03098 03099 // get a filter to export the thingy to 03100 CMXFilter* pFilter = CreateExportFilter(); 03101 BOOL ok = (pFilter != NULL); 03102 03103 if(ok) 03104 { 03105 // tell the filter not to do non clipboardy thing 03106 pFilter->SetIsDoingClipboardExport(TRUE); 03107 03109 // 03110 // JustinF says: this is a ultra-late bodge so that we can render OLE presentation 03111 // data in CMX format. The only app that requires this is CorelDRAW. We are 03112 // tricking the CMX exporter to work with any kernel Document rather than only 03113 // the internal clipboard document. 03114 // 03115 03116 // WEBSTER - markn 12/2/97 03117 #if (_OLE_VER >= 0x200) 03118 ok = pFilter->DoExport(Caller, &File, &pathname, m_pDoc, TRUE); 03119 #else 03120 // export to the file 03121 ok = pFilter->DoExport(Caller, &File, &pathname, InternalClipboard::Instance()); 03122 #endif 03123 03124 // reset clipboardy flag 03125 pFilter->SetIsDoingClipboardExport(FALSE); 03126 } 03127 03128 delete pFilter; 03129 03130 void* pMem; 03131 INT32 FileSize; 03132 HANDLE hGlobalMem; 03133 03134 if (ok) 03135 { 03136 // find out how big the file is 03137 FileSize = File.Size(); 03138 03139 #if (_OLE_VER >= 0x200) 03140 03141 // Is memory already allocated? 03142 if ((hGlobalMem = m_hMem) != 0) 03143 { 03144 // Is the file too big? 03145 if (UINT32(FileSize) > m_cbMemSize) return 0; 03146 } 03147 else 03148 { 03149 // No. Allocate some. 03150 hGlobalMem = m_hMem = GlobalAlloc(GHND, FileSize); 03151 } 03152 03153 #else 03154 03155 // copy the file into the global block 03156 pMem = GlobalLock(hGlobalMem); 03157 03158 #endif 03159 03160 // Lock the block. 03161 pMem = GlobalLock(hGlobalMem); 03162 ok = (pMem != 0); 03163 } 03164 03165 03166 if (ok) 03167 { 03168 // seek to beginning of file 03169 File.seekIn(0); 03170 03171 // load data.. 03172 File.read(pMem, FileSize); 03173 } 03174 03175 // close the file 03176 if(File.isOpen()) 03177 File.close(); 03178 03179 // get rid of the temp file 03180 RemoveTempFile(); 03181 03182 // We must unlock the block before giving it to the clipboard 03183 GlobalUnlock(hGlobalMem); 03184 03185 return hGlobalMem; 03186 }