4#include "Stroika/Frameworks/StroikaPreComp.h"
8#if qStroika_HasComponent_ATLMFC
15#include "Stroika/Foundation/DataExchange/BadFormatException.h"
18#include "MFC_WordProcessor.h"
23using namespace Stroika::Frameworks::Led;
24using namespace Stroika::Frameworks::Led::Platform;
25using namespace Stroika::Frameworks::Led::StyledTextIO;
29#if qSupportOLEControlEmbedding
31inline SIZE HIMETRICtoDP (SIZE s)
35 ((CDC*)NULL)->HIMETRICtoDP (&s);
38inline SIZE DPtoHIMETRIC (SIZE s)
42 ((CDC*)NULL)->DPtoHIMETRIC (&s);
51COleDocument* Led_MFC_ControlItem::DocContextDefiner::sDoc = NULL;
54const Led_ClipFormat Led_MFC_ControlItem::kClipFormat =
static_cast<Led_ClipFormat
> (::RegisterClipboardFormat (_T(
"Object Descriptor")));
55const Led_PrivateEmbeddingTag Led_MFC_ControlItem::kEmbeddingTag =
"OLE2Embed";
57IMPLEMENT_SERIAL (Led_MFC_ControlItem, COleClientItem, 0)
59Led_MFC_ControlItem::Led_MFC_ControlItem (COleDocument* pContainer)
60 : COleClientItem (pContainer)
61 , fSize (Led_Size (0, 0))
65Led_MFC_ControlItem::~Led_MFC_ControlItem ()
69SimpleEmbeddedObjectStyleMarker* Led_MFC_ControlItem::mkLed_MFC_ControlItemStyleMarker (
const char* embeddingTag,
const void* data,
size_t len)
71 Require (memcmp (embeddingTag, kEmbeddingTag,
sizeof (kEmbeddingTag)) == 0 or
72 memcmp (embeddingTag, RTFIO::RTFOLEEmbedding::kEmbeddingTag,
sizeof (RTFIO::RTFOLEEmbedding::kEmbeddingTag)) == 0);
77 Led_MFC_ControlItem* e =
new Led_MFC_ControlItem (DocContextDefiner::GetDoc ());
79 return mkLed_MFC_ControlItemStyleMarker_ (embeddingTag, data, len, e);
82SimpleEmbeddedObjectStyleMarker* Led_MFC_ControlItem::mkLed_MFC_ControlItemStyleMarker (
ReaderFlavorPackage& flavorPackage)
87 Led_MFC_ControlItem* e =
new Led_MFC_ControlItem (DocContextDefiner::GetDoc ());
89 return mkLed_MFC_ControlItemStyleMarker_ (flavorPackage, e);
92struct MyOLEStream_input : OLESTREAM {
93 OLESTREAMVTBL theVTbl;
97 static DWORD __stdcall MyOLE1STREAMGetter (LPOLESTREAM lpoleStr,
void* data, DWORD nb)
99 MyOLEStream_input* myStream = (MyOLEStream_input*)lpoleStr;
100 size_t bytesLeft = myStream->end - myStream->cur;
101 size_t bytesToRead = min<size_t> (bytesLeft, nb);
102 (void)::memcpy (data, myStream->cur, bytesToRead);
103 myStream->cur += bytesToRead;
104 return static_cast<DWORD
> (bytesToRead);
106 MyOLEStream_input (
const void* data,
size_t nBytes)
107 : start ((byte*)data)
108 , end ((byte*)data + nBytes)
112 theVTbl.Get = MyOLE1STREAMGetter;
116SimpleEmbeddedObjectStyleMarker* Led_MFC_ControlItem::mkLed_MFC_ControlItemStyleMarker_ (
const char* embeddingTag,
const void* data,
117 size_t len, Led_MFC_ControlItem* builtItem)
119 Require (memcmp (embeddingTag, kEmbeddingTag,
sizeof (kEmbeddingTag)) == 0 or
120 memcmp (embeddingTag, RTFIO::RTFOLEEmbedding::kEmbeddingTag,
sizeof (RTFIO::RTFOLEEmbedding::kEmbeddingTag)) == 0);
123 if (memcmp (embeddingTag, kEmbeddingTag,
sizeof (kEmbeddingTag)) == 0) {
125 CMemFile memFile ((
unsigned char*)data,
static_cast<UINT
> (len));
126 CArchive archive (&memFile, CArchive::load);
127 builtItem->Serialize (archive);
129 else if (memcmp (embeddingTag, RTFIO::RTFOLEEmbedding::kEmbeddingTag,
sizeof (RTFIO::RTFOLEEmbedding::kEmbeddingTag)) == 0) {
142 builtItem->m_dwItemNumber = builtItem->GetNewItemNumber ();
143 builtItem->GetItemStorage ();
146 MyOLEStream_input myStream (data, len);
149 builtItem->CheckGeneral (::OleConvertOLESTREAMToIStorage (&myStream, builtItem->m_lpStorage, NULL));
151 Assert (Led_MFC_ControlItem::DocContextDefiner::sWindowsWhichHadDisplaySuppressed.empty ());
159 IUnknown* pUnk = NULL;
160 builtItem->CheckGeneral (::OleLoad (builtItem->m_lpStorage, IID_IUnknown, builtItem->GetClientSite (), (LPVOID*)&pUnk));
161 Assert (pUnk != NULL);
171 for (
auto i = Led_MFC_ControlItem::DocContextDefiner::sWindowsWhichHadDisplaySuppressed.begin ();
172 i != Led_MFC_ControlItem::DocContextDefiner::sWindowsWhichHadDisplaySuppressed.end (); ++i) {
173 Verify (::InvalidateRect (*i, NULL,
true) != 0);
175 Led_MFC_ControlItem::DocContextDefiner::sWindowsWhichHadDisplaySuppressed.clear ();
178 if (pUnk->QueryInterface (IID_IOleObject, (LPVOID*)&builtItem->m_lpObject) != S_OK) {
184 if (not builtItem->FinishCreate (S_OK)) {
185 AfxThrowArchiveException (CArchiveException::genericException);
189 builtItem->GetExtent (&size);
190 builtItem->fSize = AsLedSize (HIMETRICtoDP (size));
195SimpleEmbeddedObjectStyleMarker* Led_MFC_ControlItem::mkLed_MFC_ControlItemStyleMarker_ (
ReaderFlavorPackage& flavorPackage, Led_MFC_ControlItem* builtItem)
197 Led_MFC_ControlItem* e = builtItem;
202 ReaderClipboardFlavorPackage* rcfp =
dynamic_cast<ReaderClipboardFlavorPackage*
> (&flavorPackage);
206 HWND oldClipOwner = ::GetOpenClipboardWindow ();
208 (void)::CloseClipboard ();
211 e->CreateFromClipboard ();
214 (void)::OpenClipboard (oldClipOwner);
217 Led_MFCReaderDAndDFlavorPackage* dndfp =
dynamic_cast<Led_MFCReaderDAndDFlavorPackage*
> (&flavorPackage);
219 DISABLE_COMPILER_MSC_WARNING_START (28182)
220 if (e->CreateFromData (dndfp->GetOleDataObject ()) == 0) {
221 Execution::Throw (DataExchange::BadFormatException::kThe);
223 DISABLE_COMPILER_MSC_WARNING_END (28182)
228 if (e->GetCachedExtent (&size)) {
229 e->fSize = AsLedSize (HIMETRICtoDP (size));
236void Led_MFC_ControlItem::OnChange (OLE_NOTIFICATION nCode, DWORD dwParam)
240 COleClientItem::OnChange (nCode, dwParam);
248 GetDocument ().UpdateAllViews (NULL);
252BOOL Led_MFC_ControlItem::OnChangeItemPosition (
const CRect& rectPos)
266 if (!COleClientItem::OnChangeItemPosition (rectPos)) {
270 if (fSize != AsLedSize (rectPos.Size ())) {
271 TextStore& textStore = *GetOwner ()->PeekAtTextStore ();
272 TextStore::SimpleUpdater updater (textStore, GetStart (), GetEnd ());
273 fSize = AsLedSize (rectPos.Size ());
279void Led_MFC_ControlItem::OnGetItemPosition (CRect& rPosition)
291 rPosition = AsCRect (GetActiveView ().GetCharWindowLocation (this->GetStart ()));
294BOOL Led_MFC_ControlItem::DoVerb (LONG nVerb, CView* pView, LPMSG lpMsg)
296 BOOL result = COleClientItem::DoVerb (nVerb, pView, lpMsg);
297 if (nVerb == OLEIVERB_SHOW or nVerb == OLEIVERB_OPEN) {
299 const_cast<Led_MFC_ControlItem*
> (
this)->GetExtent (&size);
300 if (fSize != AsLedSize (HIMETRICtoDP (size))) {
301 TextStore& textStore = *GetOwner ()->PeekAtTextStore ();
302 TextStore::SimpleUpdater updater (textStore, GetStart (), GetEnd ());
303 fSize = AsLedSize (HIMETRICtoDP (size));
306 const_cast<Led_MFC_ControlItem*
> (
this)->SetExtent (size);
312void Led_MFC_ControlItem::OnActivate ()
315 Led_MFC& pView = GetActiveView ();
316 COleClientItem* pItem = GetDocument ().GetInPlaceActiveItem (&pView);
317 if (pItem != NULL && pItem !=
this) {
320 COleClientItem::OnActivate ();
323void Led_MFC_ControlItem::OnDeactivateUI (BOOL bUndoable)
325 COleClientItem::OnDeactivateUI (bUndoable);
329 m_lpObject->GetMiscStatus (GetDrawAspect (), &dwMisc);
330 if (dwMisc & OLEMISC_INSIDEOUT) {
331 DoVerb (OLEIVERB_HIDE, NULL);
335void Led_MFC_ControlItem::DrawSegment (
const StyledTextImager* imager,
const StyleRunElement& , Tablet* tablet,
336 [[maybe_unused]]
size_t from, [[maybe_unused]]
size_t to, [[maybe_unused]]
const TextLayoutBlock& text,
337 const Led_Rect& drawInto,
const Led_Rect& , CoordinateType useBaseLine, DistanceType* pixelsDrawn)
339 Require (to - from == 1);
340 Require (text.PeekAtVirtualText ()[0] == kEmbeddingSentinelChar);
342 Color foreColor = imager->GetEffectiveDefaultTextColor (TextImager::eDefaultTextColor);
344 Color backColor = imager->GetEffectiveDefaultTextColor (TextImager::eDefaultBackgroundColor);
345 GDI_Obj_Selector pen (tablet, ::GetStockObject (WHITE_PEN));
346 tablet->SetTextColor (foreColor.GetOSRep ());
347 tablet->SetBkColor (backColor.GetOSRep ());
349 Led_Rect ourBoundsRect = drawInto;
350 ourBoundsRect.right = ourBoundsRect.left + fSize.h + 2 * kDefaultEmbeddingMargin.h;
351 CoordinateType embedBottom = useBaseLine;
352 CoordinateType embedTop = embedBottom - fSize.v;
353 Assert (embedTop >= drawInto.top);
354 Assert (embedBottom <= drawInto.bottom);
355 Led_Rect innerBoundsRect = Led_Rect (Led_Point (embedTop, drawInto.left + kDefaultEmbeddingMargin.h), fSize);
357 if (pixelsDrawn != NULL) {
358 *pixelsDrawn = ourBoundsRect.GetWidth ();
361 COleClientItem::Draw (Led_MFC_CDCFromTablet (tablet), CRect (AsRECT (innerBoundsRect)));
364void Led_MFC_ControlItem::MeasureSegmentWidth ([[maybe_unused]]
const StyledTextImager* imager, [[maybe_unused]]
const StyleRunElement& runElement,
365 [[maybe_unused]]
size_t from, [[maybe_unused]]
size_t to,
366 [[maybe_unused]]
const Led_tChar* text, DistanceType* distanceResults)
const
368 Assert (from + 1 == to);
369 Assert (text[0] == kEmbeddingSentinelChar);
370 distanceResults[0] = fSize.h + 2 * kDefaultEmbeddingMargin.h;
373DistanceType Led_MFC_ControlItem::MeasureSegmentHeight (
const StyledTextImager* ,
const StyleRunElement& ,
374 [[maybe_unused]]
size_t from, [[maybe_unused]]
size_t to)
const
376 Assert (from + 1 == to);
377 return fSize.v + 2 * kDefaultEmbeddingMargin.v;
380void Led_MFC_ControlItem::Write (SinkStream& sink)
383 CArchive archive (&memFile, CArchive::store);
386 size_t nBytes =
static_cast<size_t> (memFile.GetLength ());
387 BYTE* written = memFile.Detach ();
388 if (written != NULL) {
389 sink.write (written, nBytes);
396 WriterClipboardFlavorPackage* wcfp =
dynamic_cast<WriterClipboardFlavorPackage*
> (&flavorPackage);
400 HWND oldClipOwner = ::GetOpenClipboardWindow ();
402 (void)::CloseClipboard ();
408 (void)::OpenClipboard (oldClipOwner);
411 Led_MFCWriterDAndDFlavorPackage* dndfp =
dynamic_cast<Led_MFCWriterDAndDFlavorPackage*
> (&flavorPackage);
413 DISABLE_COMPILER_MSC_WARNING_START (28182)
414 GetClipboardData (dndfp->GetOleDataSource ());
415 DISABLE_COMPILER_MSC_WARNING_END (28182)
419const
char* Led_MFC_ControlItem::GetTag ()
const
421 return kEmbeddingTag;
424void Led_MFC_ControlItem::Serialize (CArchive& ar)
426 COleClientItem::Serialize (ar);
427 if (not ar.IsStoring ()) {
431 const_cast<Led_MFC_ControlItem*
> (
this)->GetExtent (&size);
432 fSize = AsLedSize (HIMETRICtoDP (size));
436void Led_MFC_ControlItem::DidUpdateText (
const MarkerOwner::UpdateInfo& updateInfo)
noexcept
438 if (GetLength () == 0) {
440 GetOwner ()->PeekAtTextStore ()->RemoveMarker (
this);
444 SimpleEmbeddedObjectStyleMarker::DidUpdateText (updateInfo);
448void Led_MFC_ControlItem::PostCreateSpecifyExtraInfo (TWIPS_Point size)
457 fSize = Led_Size (Led_CvtScreenPixelsFromTWIPSV (size.v), Led_CvtScreenPixelsFromTWIPSH (size.h));
460SDKString Led_MFC_ControlItem::GetObjClassName ()
const
464 LPOLESTR oleStr = NULL;
465 if (::ProgIDFromCLSID (clsid, &oleStr) == S_OK) {
467 ::CoTaskMemFree (oleStr);
473struct MyOLEStream_output : OLESTREAM {
474 OLESTREAMVTBL theVTbl;
476 static DWORD __stdcall MyOLE1STREAMPutter (LPOLESTREAM lpoleStr,
const void* data, DWORD nb)
478 MyOLEStream_output* myStream = (MyOLEStream_output*)lpoleStr;
479 using ci =
const char*;
480 myStream->fData.insert (myStream->fData.end (), ci (data), ci (data) + nb);
483 MyOLEStream_output ()
487 theVTbl.Put = MyOLE1STREAMPutter;
490void Led_MFC_ControlItem::DoWriteToOLE1Stream (
size_t* nBytes,
byte** resultData)
492 IStorage* pStorage = NULL;
493 IPersistStorage* ips = NULL;
496 CheckGeneral (::StgCreateDocfile (NULL, STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &pStorage));
500 CheckGeneral (m_lpObject->QueryInterface (IID_IPersistStorage, (LPVOID*)&ips));
503 GetClassID (&myCLSID);
504 CheckGeneral (::WriteClassStg (pStorage, myCLSID));
505 DISABLE_COMPILER_MSC_WARNING_START (6011)
506 CheckGeneral (ips->Save (pStorage, false));
507 CheckGeneral (ips->SaveCompleted (pStorage));
508 DISABLE_COMPILER_MSC_WARNING_END (6011)
511 MyOLEStream_output myStream;
512 CheckGeneral (::OleConvertIStorageToOLESTREAM (pStorage, &myStream));
513 *nBytes = myStream.fData.size ();
514 *resultData = new
byte[*nBytes];
515 (
void)::memcpy (*resultData, Traversal::Iterator2Pointer (myStream.fData.begin ()), *nBytes);
518 if (pStorage != NULL) {
519 pStorage->Release ();
523 pStorage->Release ();
527Led_Size Led_MFC_ControlItem::GetSize ()
532bool Led_MFC_ControlItem::HandleOpen ()
534 (void)DoVerb (OLEIVERB_PRIMARY, NULL);
538vector<Led_MFC_ControlItem::PrivateCmdNumber> Led_MFC_ControlItem::GetCmdNumbers ()
const
540 vector<PrivateCmdNumber> x;
541 x.push_back (eOpenCmdNum);
545bool Led_MFC_ControlItem::IsCmdEnabled (PrivateCmdNumber cmd)
const
551 return SimpleEmbeddedObjectStyleMarker::IsCmdEnabled (cmd);
555#if qStroika_Foundation_Debug_AssertionsChecked
556COleDocument& Led_MFC_ControlItem::GetDocument ()
const
558 COleDocument* result = (COleDocument*)COleClientItem::GetDocument ();
560 ASSERT_VALID (result);
561 Assert (result->IsKindOf (RUNTIME_CLASS (COleDocument)));
565Led_MFC& Led_MFC_ControlItem::GetActiveView ()
const
568 AssertMember (COleClientItem::GetActiveView (), Led_MFC);
569 return *(Led_MFC*)COleClientItem::GetActiveView ();
579set<HWND> Led_MFC_ControlItem::DocContextDefiner::sWindowsWhichHadDisplaySuppressed;
#define RequireNotNull(p)
#define AssertMember(p, c)
Logically halfway between std::array and std::vector; Smart 'direct memory array' - which when needed...
basic_string< SDKChar > SDKString