4#include "Stroika/Frameworks/StroikaPreComp.h"
8#if qStroika_HasComponent_ATLMFC
13DISABLE_COMPILER_MSC_WARNING_START (5054)
15DISABLE_COMPILER_MSC_WARNING_END (5054)
17#include "Stroika/Foundation/DataExchange/BadFormatException.h"
20#include "MFC_WordProcessor.h"
25using namespace Stroika::Frameworks::Led;
26using namespace Stroika::Frameworks::Led::Platform;
27using namespace Stroika::Frameworks::Led::StyledTextIO;
31#if qSupportOLEControlEmbedding
33inline SIZE HIMETRICtoDP (SIZE s)
37 ((CDC*)NULL)->HIMETRICtoDP (&s);
40inline SIZE DPtoHIMETRIC (SIZE s)
44 ((CDC*)NULL)->DPtoHIMETRIC (&s);
53COleDocument* Led_MFC_ControlItem::DocContextDefiner::sDoc = NULL;
56const Led_ClipFormat Led_MFC_ControlItem::kClipFormat =
static_cast<Led_ClipFormat
> (::RegisterClipboardFormat (_T(
"Object Descriptor")));
57const Led_PrivateEmbeddingTag Led_MFC_ControlItem::kEmbeddingTag =
"OLE2Embed";
59IMPLEMENT_SERIAL (Led_MFC_ControlItem, COleClientItem, 0)
61Led_MFC_ControlItem::Led_MFC_ControlItem (COleDocument* pContainer)
62 : COleClientItem (pContainer)
63 , fSize (Led_Size (0, 0))
67Led_MFC_ControlItem::~Led_MFC_ControlItem ()
71SimpleEmbeddedObjectStyleMarker* Led_MFC_ControlItem::mkLed_MFC_ControlItemStyleMarker (
const char* embeddingTag,
const void* data,
size_t len)
73 Require (memcmp (embeddingTag, kEmbeddingTag,
sizeof (kEmbeddingTag)) == 0 or
74 memcmp (embeddingTag, RTFIO::RTFOLEEmbedding::kEmbeddingTag,
sizeof (RTFIO::RTFOLEEmbedding::kEmbeddingTag)) == 0);
79 Led_MFC_ControlItem* e =
new Led_MFC_ControlItem (DocContextDefiner::GetDoc ());
81 return mkLed_MFC_ControlItemStyleMarker_ (embeddingTag, data, len, e);
84SimpleEmbeddedObjectStyleMarker* Led_MFC_ControlItem::mkLed_MFC_ControlItemStyleMarker (
ReaderFlavorPackage& flavorPackage)
89 Led_MFC_ControlItem* e =
new Led_MFC_ControlItem (DocContextDefiner::GetDoc ());
91 return mkLed_MFC_ControlItemStyleMarker_ (flavorPackage, e);
94struct MyOLEStream_input : OLESTREAM {
95 OLESTREAMVTBL theVTbl;
99 static DWORD __stdcall MyOLE1STREAMGetter (LPOLESTREAM lpoleStr,
void* data, DWORD nb)
101 MyOLEStream_input* myStream = (MyOLEStream_input*)lpoleStr;
102 size_t bytesLeft = myStream->end - myStream->cur;
103 size_t bytesToRead = min<size_t> (bytesLeft, nb);
104 (void)::memcpy (data, myStream->cur, bytesToRead);
105 myStream->cur += bytesToRead;
106 return static_cast<DWORD
> (bytesToRead);
108 MyOLEStream_input (
const void* data,
size_t nBytes)
109 : start ((byte*)data)
110 , end ((byte*)data + nBytes)
114 theVTbl.Get = MyOLE1STREAMGetter;
118SimpleEmbeddedObjectStyleMarker* Led_MFC_ControlItem::mkLed_MFC_ControlItemStyleMarker_ (
const char* embeddingTag,
const void* data,
119 size_t len, Led_MFC_ControlItem* builtItem)
121 Require (memcmp (embeddingTag, kEmbeddingTag,
sizeof (kEmbeddingTag)) == 0 or
122 memcmp (embeddingTag, RTFIO::RTFOLEEmbedding::kEmbeddingTag,
sizeof (RTFIO::RTFOLEEmbedding::kEmbeddingTag)) == 0);
125 if (memcmp (embeddingTag, kEmbeddingTag,
sizeof (kEmbeddingTag)) == 0) {
127 CMemFile memFile ((
unsigned char*)data,
static_cast<UINT
> (len));
128 CArchive archive (&memFile, CArchive::load);
129 builtItem->Serialize (archive);
131 else if (memcmp (embeddingTag, RTFIO::RTFOLEEmbedding::kEmbeddingTag,
sizeof (RTFIO::RTFOLEEmbedding::kEmbeddingTag)) == 0) {
144 builtItem->m_dwItemNumber = builtItem->GetNewItemNumber ();
145 builtItem->GetItemStorage ();
148 MyOLEStream_input myStream (data, len);
151 builtItem->CheckGeneral (::OleConvertOLESTREAMToIStorage (&myStream, builtItem->m_lpStorage, NULL));
153 Assert (Led_MFC_ControlItem::DocContextDefiner::sWindowsWhichHadDisplaySuppressed.empty ());
161 IUnknown* pUnk = NULL;
162 builtItem->CheckGeneral (::OleLoad (builtItem->m_lpStorage, IID_IUnknown, builtItem->GetClientSite (), (LPVOID*)&pUnk));
163 Assert (pUnk != NULL);
173 for (
auto i = Led_MFC_ControlItem::DocContextDefiner::sWindowsWhichHadDisplaySuppressed.begin ();
174 i != Led_MFC_ControlItem::DocContextDefiner::sWindowsWhichHadDisplaySuppressed.end (); ++i) {
175 Verify (::InvalidateRect (*i, NULL,
true) != 0);
177 Led_MFC_ControlItem::DocContextDefiner::sWindowsWhichHadDisplaySuppressed.clear ();
180 if (pUnk->QueryInterface (IID_IOleObject, (LPVOID*)&builtItem->m_lpObject) != S_OK) {
186 if (not builtItem->FinishCreate (S_OK)) {
187 AfxThrowArchiveException (CArchiveException::genericException);
191 builtItem->GetExtent (&size);
192 builtItem->fSize = AsLedSize (HIMETRICtoDP (size));
197SimpleEmbeddedObjectStyleMarker* Led_MFC_ControlItem::mkLed_MFC_ControlItemStyleMarker_ (
ReaderFlavorPackage& flavorPackage, Led_MFC_ControlItem* builtItem)
199 Led_MFC_ControlItem* e = builtItem;
204 ReaderClipboardFlavorPackage* rcfp =
dynamic_cast<ReaderClipboardFlavorPackage*
> (&flavorPackage);
208 HWND oldClipOwner = ::GetOpenClipboardWindow ();
210 (void)::CloseClipboard ();
213 e->CreateFromClipboard ();
216 (void)::OpenClipboard (oldClipOwner);
219 Led_MFCReaderDAndDFlavorPackage* dndfp =
dynamic_cast<Led_MFCReaderDAndDFlavorPackage*
> (&flavorPackage);
221 DISABLE_COMPILER_MSC_WARNING_START (28182)
222 if (e->CreateFromData (dndfp->GetOleDataObject ()) == 0) {
223 Execution::Throw (DataExchange::BadFormatException::kThe);
225 DISABLE_COMPILER_MSC_WARNING_END (28182)
230 if (e->GetCachedExtent (&size)) {
231 e->fSize = AsLedSize (HIMETRICtoDP (size));
238void Led_MFC_ControlItem::OnChange (OLE_NOTIFICATION nCode, DWORD dwParam)
242 COleClientItem::OnChange (nCode, dwParam);
250 GetDocument ().UpdateAllViews (NULL);
254BOOL Led_MFC_ControlItem::OnChangeItemPosition (
const CRect& rectPos)
268 if (!COleClientItem::OnChangeItemPosition (rectPos)) {
272 if (fSize != AsLedSize (rectPos.Size ())) {
273 TextStore& textStore = *GetOwner ()->PeekAtTextStore ();
274 TextStore::SimpleUpdater updater (textStore, GetStart (), GetEnd ());
275 fSize = AsLedSize (rectPos.Size ());
281void Led_MFC_ControlItem::OnGetItemPosition (CRect& rPosition)
293 rPosition = AsCRect (GetActiveView ().GetCharWindowLocation (this->GetStart ()));
296BOOL Led_MFC_ControlItem::DoVerb (LONG nVerb, CView* pView, LPMSG lpMsg)
298 BOOL result = COleClientItem::DoVerb (nVerb, pView, lpMsg);
299 if (nVerb == OLEIVERB_SHOW or nVerb == OLEIVERB_OPEN) {
301 const_cast<Led_MFC_ControlItem*
> (
this)->GetExtent (&size);
302 if (fSize != AsLedSize (HIMETRICtoDP (size))) {
303 TextStore& textStore = *GetOwner ()->PeekAtTextStore ();
304 TextStore::SimpleUpdater updater (textStore, GetStart (), GetEnd ());
305 fSize = AsLedSize (HIMETRICtoDP (size));
308 const_cast<Led_MFC_ControlItem*
> (
this)->SetExtent (size);
314void Led_MFC_ControlItem::OnActivate ()
317 Led_MFC& pView = GetActiveView ();
318 COleClientItem* pItem = GetDocument ().GetInPlaceActiveItem (&pView);
319 if (pItem != NULL && pItem !=
this) {
322 COleClientItem::OnActivate ();
325void Led_MFC_ControlItem::OnDeactivateUI (BOOL bUndoable)
327 COleClientItem::OnDeactivateUI (bUndoable);
331 m_lpObject->GetMiscStatus (GetDrawAspect (), &dwMisc);
332 if (dwMisc & OLEMISC_INSIDEOUT) {
333 DoVerb (OLEIVERB_HIDE, NULL);
337void Led_MFC_ControlItem::DrawSegment (
const StyledTextImager* imager,
const StyleRunElement& , Tablet* tablet,
338 [[maybe_unused]]
size_t from, [[maybe_unused]]
size_t to, [[maybe_unused]]
const TextLayoutBlock& text,
339 const Led_Rect& drawInto,
const Led_Rect& , CoordinateType useBaseLine, DistanceType* pixelsDrawn)
341 Require (to - from == 1);
342 Require (text.PeekAtVirtualText ()[0] == kEmbeddingSentinelChar);
344 Color foreColor = imager->GetEffectiveDefaultTextColor (TextImager::eDefaultTextColor);
346 Color backColor = imager->GetEffectiveDefaultTextColor (TextImager::eDefaultBackgroundColor);
347 GDI_Obj_Selector pen (tablet, ::GetStockObject (WHITE_PEN));
348 tablet->SetTextColor (foreColor.GetOSRep ());
349 tablet->SetBkColor (backColor.GetOSRep ());
351 Led_Rect ourBoundsRect = drawInto;
352 ourBoundsRect.right = ourBoundsRect.left + fSize.h + 2 * kDefaultEmbeddingMargin.h;
353 CoordinateType embedBottom = useBaseLine;
354 CoordinateType embedTop = embedBottom - fSize.v;
355 Assert (embedTop >= drawInto.top);
356 Assert (embedBottom <= drawInto.bottom);
357 Led_Rect innerBoundsRect = Led_Rect (Led_Point (embedTop, drawInto.left + kDefaultEmbeddingMargin.h), fSize);
359 if (pixelsDrawn != NULL) {
360 *pixelsDrawn = ourBoundsRect.GetWidth ();
363 COleClientItem::Draw (Led_MFC_CDCFromTablet (tablet), CRect (AsRECT (innerBoundsRect)));
366void Led_MFC_ControlItem::MeasureSegmentWidth ([[maybe_unused]]
const StyledTextImager* imager, [[maybe_unused]]
const StyleRunElement& runElement,
367 [[maybe_unused]]
size_t from, [[maybe_unused]]
size_t to,
368 [[maybe_unused]]
const Led_tChar* text, DistanceType* distanceResults)
const
370 Assert (from + 1 == to);
371 Assert (text[0] == kEmbeddingSentinelChar);
372 distanceResults[0] = fSize.h + 2 * kDefaultEmbeddingMargin.h;
375DistanceType Led_MFC_ControlItem::MeasureSegmentHeight (
const StyledTextImager* ,
const StyleRunElement& ,
376 [[maybe_unused]]
size_t from, [[maybe_unused]]
size_t to)
const
378 Assert (from + 1 == to);
379 return fSize.v + 2 * kDefaultEmbeddingMargin.v;
382void Led_MFC_ControlItem::Write (SinkStream& sink)
385 CArchive archive (&memFile, CArchive::store);
388 size_t nBytes =
static_cast<size_t> (memFile.GetLength ());
389 BYTE* written = memFile.Detach ();
390 if (written != NULL) {
391 sink.write (written, nBytes);
398 WriterClipboardFlavorPackage* wcfp =
dynamic_cast<WriterClipboardFlavorPackage*
> (&flavorPackage);
402 HWND oldClipOwner = ::GetOpenClipboardWindow ();
404 (void)::CloseClipboard ();
410 (void)::OpenClipboard (oldClipOwner);
413 Led_MFCWriterDAndDFlavorPackage* dndfp =
dynamic_cast<Led_MFCWriterDAndDFlavorPackage*
> (&flavorPackage);
415 DISABLE_COMPILER_MSC_WARNING_START (28182)
416 GetClipboardData (dndfp->GetOleDataSource ());
417 DISABLE_COMPILER_MSC_WARNING_END (28182)
421const
char* Led_MFC_ControlItem::GetTag ()
const
423 return kEmbeddingTag;
426void Led_MFC_ControlItem::Serialize (CArchive& ar)
428 COleClientItem::Serialize (ar);
429 if (not ar.IsStoring ()) {
433 const_cast<Led_MFC_ControlItem*
> (
this)->GetExtent (&size);
434 fSize = AsLedSize (HIMETRICtoDP (size));
438void Led_MFC_ControlItem::DidUpdateText (
const MarkerOwner::UpdateInfo& updateInfo)
noexcept
440 if (GetLength () == 0) {
442 GetOwner ()->PeekAtTextStore ()->RemoveMarker (
this);
446 SimpleEmbeddedObjectStyleMarker::DidUpdateText (updateInfo);
450void Led_MFC_ControlItem::PostCreateSpecifyExtraInfo (TWIPS_Point size)
459 fSize = Led_Size (Led_CvtScreenPixelsFromTWIPSV (size.v), Led_CvtScreenPixelsFromTWIPSH (size.h));
462SDKString Led_MFC_ControlItem::GetObjClassName ()
const
466 LPOLESTR oleStr = NULL;
467 if (::ProgIDFromCLSID (clsid, &oleStr) == S_OK) {
469 ::CoTaskMemFree (oleStr);
475struct MyOLEStream_output : OLESTREAM {
476 OLESTREAMVTBL theVTbl;
478 static DWORD __stdcall MyOLE1STREAMPutter (LPOLESTREAM lpoleStr,
const void* data, DWORD nb)
480 MyOLEStream_output* myStream = (MyOLEStream_output*)lpoleStr;
481 using ci =
const char*;
482 myStream->fData.insert (myStream->fData.end (), ci (data), ci (data) + nb);
485 MyOLEStream_output ()
489 theVTbl.Put = MyOLE1STREAMPutter;
492void Led_MFC_ControlItem::DoWriteToOLE1Stream (
size_t* nBytes,
byte** resultData)
494 IStorage* pStorage = NULL;
495 IPersistStorage* ips = NULL;
498 CheckGeneral (::StgCreateDocfile (NULL, STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &pStorage));
502 CheckGeneral (m_lpObject->QueryInterface (IID_IPersistStorage, (LPVOID*)&ips));
505 GetClassID (&myCLSID);
506 CheckGeneral (::WriteClassStg (pStorage, myCLSID));
507 DISABLE_COMPILER_MSC_WARNING_START (6011)
508 CheckGeneral (ips->Save (pStorage, false));
509 CheckGeneral (ips->SaveCompleted (pStorage));
510 DISABLE_COMPILER_MSC_WARNING_END (6011)
513 MyOLEStream_output myStream;
514 CheckGeneral (::OleConvertIStorageToOLESTREAM (pStorage, &myStream));
515 *nBytes = myStream.fData.size ();
516 *resultData = new
byte[*nBytes];
517 (
void)::memcpy (*resultData, Traversal::Iterator2Pointer (myStream.fData.begin ()), *nBytes);
520 if (pStorage != NULL) {
521 pStorage->Release ();
525 pStorage->Release ();
529Led_Size Led_MFC_ControlItem::GetSize ()
534bool Led_MFC_ControlItem::HandleOpen ()
536 (void)DoVerb (OLEIVERB_PRIMARY, NULL);
540vector<Led_MFC_ControlItem::PrivateCmdNumber> Led_MFC_ControlItem::GetCmdNumbers ()
const
542 vector<PrivateCmdNumber> x;
543 x.push_back (eOpenCmdNum);
547bool Led_MFC_ControlItem::IsCmdEnabled (PrivateCmdNumber cmd)
const
553 return SimpleEmbeddedObjectStyleMarker::IsCmdEnabled (cmd);
557#if qStroika_Foundation_Debug_AssertionsChecked
558COleDocument& Led_MFC_ControlItem::GetDocument ()
const
560 COleDocument* result = (COleDocument*)COleClientItem::GetDocument ();
562 ASSERT_VALID (result);
563 Assert (result->IsKindOf (RUNTIME_CLASS (COleDocument)));
567Led_MFC& Led_MFC_ControlItem::GetActiveView ()
const
570 AssertMember (COleClientItem::GetActiveView (), Led_MFC);
571 return *(Led_MFC*)COleClientItem::GetActiveView ();
581set<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