Stroika Library 3.0d25
 
Loading...
Searching...
No Matches
MFC_WordProcessor.cpp
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2026. All rights reserved
3 */
4#include "Stroika/Frameworks/StroikaPreComp.h"
5
6#include <climits>
7
8#if qStroika_HasComponent_ATLMFC
9
10#include <afxext.h>
11#include <atlstr.h>
12
13#include <afxole.h>
14
15#include "Stroika/Foundation/DataExchange/BadFormatException.h"
17
18#include "MFC_WordProcessor.h"
19
20using std::byte;
21
22using namespace Stroika::Foundation;
23using namespace Stroika::Frameworks::Led;
24using namespace Stroika::Frameworks::Led::Platform;
25using namespace Stroika::Frameworks::Led::StyledTextIO;
26
27using std::byte;
28
29#if qSupportOLEControlEmbedding
30
31inline SIZE HIMETRICtoDP (SIZE s)
32{
33 // Crazy convention of passing NULL as this, used in MFC alot and the routine
34 // checks for NULL this??? - WOW!
35 ((CDC*)NULL)->HIMETRICtoDP (&s);
36 return s;
37}
38inline SIZE DPtoHIMETRIC (SIZE s)
39{
40 // Crazy convention of passing NULL as this, used in MFC alot and the routine
41 // checks for NULL this??? - WOW!
42 ((CDC*)NULL)->DPtoHIMETRIC (&s);
43 return s;
44}
45
46/*
47 ********************************************************************************
48 ***************************** Led_MFC_ControlItem ******************************
49 ********************************************************************************
50 */
51COleDocument* Led_MFC_ControlItem::DocContextDefiner::sDoc = NULL;
52
53// Note sure this is the right type????
54const Led_ClipFormat Led_MFC_ControlItem::kClipFormat = static_cast<Led_ClipFormat> (::RegisterClipboardFormat (_T("Object Descriptor")));
55const Led_PrivateEmbeddingTag Led_MFC_ControlItem::kEmbeddingTag = "OLE2Embed";
56
57IMPLEMENT_SERIAL (Led_MFC_ControlItem, COleClientItem, 0)
58
59Led_MFC_ControlItem::Led_MFC_ControlItem (COleDocument* pContainer)
60 : COleClientItem (pContainer)
61 , fSize (Led_Size (0, 0))
62{
63}
64
65Led_MFC_ControlItem::~Led_MFC_ControlItem ()
66{
67}
68
69SimpleEmbeddedObjectStyleMarker* Led_MFC_ControlItem::mkLed_MFC_ControlItemStyleMarker (const char* embeddingTag, const void* data, size_t len)
70{
71 Require (memcmp (embeddingTag, kEmbeddingTag, sizeof (kEmbeddingTag)) == 0 or
72 memcmp (embeddingTag, RTFIO::RTFOLEEmbedding::kEmbeddingTag, sizeof (RTFIO::RTFOLEEmbedding::kEmbeddingTag)) == 0);
73
74 RequireNotNull (DocContextDefiner::GetDoc ()); // See doc in header for class DocContextDefiner.
75 // must declare one of these on call stack before calling this
76 // method...
77 Led_MFC_ControlItem* e = new Led_MFC_ControlItem (DocContextDefiner::GetDoc ());
78
79 return mkLed_MFC_ControlItemStyleMarker_ (embeddingTag, data, len, e);
80}
81
82SimpleEmbeddedObjectStyleMarker* Led_MFC_ControlItem::mkLed_MFC_ControlItemStyleMarker (ReaderFlavorPackage& flavorPackage)
83{
84 RequireNotNull (DocContextDefiner::GetDoc ()); // See doc in header for class DocContextDefiner.
85 // must declare one of these on call stack before calling this
86 // method...
87 Led_MFC_ControlItem* e = new Led_MFC_ControlItem (DocContextDefiner::GetDoc ());
88
89 return mkLed_MFC_ControlItemStyleMarker_ (flavorPackage, e);
90}
91
92struct MyOLEStream_input : OLESTREAM {
93 OLESTREAMVTBL theVTbl;
94 const byte* start;
95 const byte* end;
96 const byte* cur;
97 static DWORD __stdcall MyOLE1STREAMGetter (LPOLESTREAM lpoleStr, void* data, DWORD nb)
98 {
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);
105 }
106 MyOLEStream_input (const void* data, size_t nBytes)
107 : start ((byte*)data)
108 , end ((byte*)data + nBytes)
109 , cur ((byte*)data)
110 {
111 lpstbl = &theVTbl;
112 theVTbl.Get = MyOLE1STREAMGetter;
113 theVTbl.Put = NULL;
114 }
115};
116SimpleEmbeddedObjectStyleMarker* Led_MFC_ControlItem::mkLed_MFC_ControlItemStyleMarker_ (const char* embeddingTag, const void* data,
117 size_t len, Led_MFC_ControlItem* builtItem)
118{
119 Require (memcmp (embeddingTag, kEmbeddingTag, sizeof (kEmbeddingTag)) == 0 or
120 memcmp (embeddingTag, RTFIO::RTFOLEEmbedding::kEmbeddingTag, sizeof (RTFIO::RTFOLEEmbedding::kEmbeddingTag)) == 0);
121 // Need todo try/catch eror handling...??? Or does caller delete embedding? On error? Decide!!!
122 //&&&&&&&
123 if (memcmp (embeddingTag, kEmbeddingTag, sizeof (kEmbeddingTag)) == 0) {
124 Memory::StackBuffer<char> buf{Memory::eUninitialized, len};
125 CMemFile memFile ((unsigned char*)data, static_cast<UINT> (len));
126 CArchive archive (&memFile, CArchive::load);
127 builtItem->Serialize (archive);
128 }
129 else if (memcmp (embeddingTag, RTFIO::RTFOLEEmbedding::kEmbeddingTag, sizeof (RTFIO::RTFOLEEmbedding::kEmbeddingTag)) == 0) {
130 /*
131 * NB: The RTF 1.4 spec says the contents are in a format where all you need todo is to call
132 * ::OleLoadFromStream. But this is apparantly not so. The data is apparantly in OLE1 format, and
133 * so must be converted via OleConvertOLESTREAMToIStorage (). This - in turn - is extrememly badly
134 * documented. But I've managed to cobble something together which appears to work.
135 *
136 * Then - there is the matter of patching all the right MFC COleClientItem member variables so they
137 * are all happy. MFC (4.2? version with MSVC50) doesn't make this very clear. But what I did was trace
138 * through the code which was executed during a "Serialize" call. And I do most of that stuff.
139 */
140
141 // Magic from COleClientItem::Serialize()
142 builtItem->m_dwItemNumber = builtItem->GetNewItemNumber ();
143 builtItem->GetItemStorage ();
144
145 // Build my own OLE1 OLESTREAM
146 MyOLEStream_input myStream (data, len);
147
148 // Docs don't seem to say passing NULL for DVTARGETDEVICE, but - seems to work - and I don't know which one to use?
149 builtItem->CheckGeneral (::OleConvertOLESTREAMToIStorage (&myStream, builtItem->m_lpStorage, NULL));
150
151 Assert (Led_MFC_ControlItem::DocContextDefiner::sWindowsWhichHadDisplaySuppressed.empty ()); // if someplace ELSE is adding these windows,
152 // we must be careful - else could be using bogus windows!
153 /*
154 * See COleClientItem::ReadFlat code - next query OleXXX interface, and assign that to some
155 * data member, and then call finish create???
156 *
157 * NB: unlike ReadFlat, we cannot call OleLoadFromStream - since this appears to assume an OLE2 format stream.
158 */
159 IUnknown* pUnk = NULL;
160 builtItem->CheckGeneral (::OleLoad (builtItem->m_lpStorage, IID_IUnknown, builtItem->GetClientSite (), (LPVOID*)&pUnk));
161 Assert (pUnk != NULL);
162
163 {
164 /*
165 * Building OLE controls CAN cause the MFC COleMessageFilter to pass WM_PAINT messages to us. That is a big
166 * performance no-no (reading in large files, because it disables the IsWholeWindowInvalid () optimization).
167 * So - inside of WordProcessorCommonCommandHelper_MFC<BASECLASS,CMD_INFO>::OnPaint () we check
168 * and see that we are not creating OLE objects, and if we are, then skip the paint event and save the window
169 * so we can RE-INVALIDATE it (here).
170 */
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);
174 }
175 Led_MFC_ControlItem::DocContextDefiner::sWindowsWhichHadDisplaySuppressed.clear ();
176 }
177
178 if (pUnk->QueryInterface (IID_IOleObject, (LPVOID*)&builtItem->m_lpObject) != S_OK) {
179 pUnk->Release ();
180 throw bad_alloc ();
181 }
182 pUnk->Release ();
183
184 if (not builtItem->FinishCreate (S_OK)) {
185 AfxThrowArchiveException (CArchiveException::genericException);
186 }
187
188 SIZE size;
189 builtItem->GetExtent (&size);
190 builtItem->fSize = AsLedSize (HIMETRICtoDP (size));
191 }
192 return builtItem;
193}
194
195SimpleEmbeddedObjectStyleMarker* Led_MFC_ControlItem::mkLed_MFC_ControlItemStyleMarker_ (ReaderFlavorPackage& flavorPackage, Led_MFC_ControlItem* builtItem)
196{
197 Led_MFC_ControlItem* e = builtItem;
198
199 // MUST BE MORE EXCPETION FRIENDLY HERE!!! - DELETE e if FIALURE AND ALSO BE CAREFUL OF CLIP OWNER!!!
200 // LGP 960412
201
202 ReaderClipboardFlavorPackage* rcfp = dynamic_cast<ReaderClipboardFlavorPackage*> (&flavorPackage);
203 if (rcfp != NULL) {
204 // fairly complex what MFC does here... Rather than reproduce it all, close the clipboard, and let MFC take care of it all.
205 // Reopen it so we our later close code doesn't fail...
206 HWND oldClipOwner = ::GetOpenClipboardWindow ();
207 AssertNotNull (oldClipOwner);
208 (void)::CloseClipboard ();
209
210 // Let MFC do the OLE clipboard copy...
211 e->CreateFromClipboard ();
212
213 // now restore things so we don't fail later on our attempt to close...
214 (void)::OpenClipboard (oldClipOwner);
215 }
216 else {
217 Led_MFCReaderDAndDFlavorPackage* dndfp = dynamic_cast<Led_MFCReaderDAndDFlavorPackage*> (&flavorPackage);
218 AssertNotNull (dndfp); // if not from clip, must be from Drag and Drop!
219 DISABLE_COMPILER_MSC_WARNING_START (28182)
220 if (e->CreateFromData (dndfp->GetOleDataObject ()) == 0) {
221 Execution::Throw (DataExchange::BadFormatException::kThe);
222 }
223 DISABLE_COMPILER_MSC_WARNING_END (28182)
224 }
225
226 {
227 CSize size;
228 if (e->GetCachedExtent (&size)) {
229 e->fSize = AsLedSize (HIMETRICtoDP (size));
230 }
231 }
232
233 return e;
234}
235
236void Led_MFC_ControlItem::OnChange (OLE_NOTIFICATION nCode, DWORD dwParam)
237{
238 ASSERT_VALID (this);
239
240 COleClientItem::OnChange (nCode, dwParam);
241 // When an item is being edited (either in-place or fully open)
242 // it sends OnChange notifications for changes in the state of the
243 // item or visual appearance of its content.
244
245 // TODO: invalidate the item by calling UpdateAllViews
246 // (with hints appropriate to your application)
247
248 GetDocument ().UpdateAllViews (NULL);
249 // for now just update ALL views/no hints
250}
251
252BOOL Led_MFC_ControlItem::OnChangeItemPosition (const CRect& rectPos)
253{
254 ASSERT_VALID (this);
255
256 // During in-place activation Led_MFC_ControlItem::OnChangeItemPosition
257 // is called by the server to change the position of the in-place
258 // window. Usually, this is a result of the data in the server
259 // document changing such that the extent has changed or as a result
260 // of in-place resizing.
261 //
262 // The default here is to call the base class, which will call
263 // COleClientItem::SetItemRects to move the item
264 // to the new position.
265
266 if (!COleClientItem::OnChangeItemPosition (rectPos)) {
267 return FALSE;
268 }
269
270 if (fSize != AsLedSize (rectPos.Size ())) {
271 TextStore& textStore = *GetOwner ()->PeekAtTextStore ();
272 TextStore::SimpleUpdater updater (textStore, GetStart (), GetEnd ());
273 fSize = AsLedSize (rectPos.Size ());
274 }
275
276 return TRUE;
277}
278
279void Led_MFC_ControlItem::OnGetItemPosition (CRect& rPosition)
280{
281 ASSERT_VALID (this);
282
283 // During in-place activation, Led_MFC_ControlItem::OnGetItemPosition
284 // will be called to determine the location of this item. The default
285 // implementation created from AppWizard simply returns a hard-coded
286 // rectangle. Usually, this rectangle would reflect the current
287 // position of the item relative to the view used for activation.
288 // You can obtain the view by calling Led_MFC_ControlItem::GetActiveView.
289
290 // return correct rectangle (in pixels) in rPosition
291 rPosition = AsCRect (GetActiveView ().GetCharWindowLocation (this->GetStart ()));
292}
293
294BOOL Led_MFC_ControlItem::DoVerb (LONG nVerb, CView* pView, LPMSG lpMsg)
295{
296 BOOL result = COleClientItem::DoVerb (nVerb, pView, lpMsg);
297 if (nVerb == OLEIVERB_SHOW or nVerb == OLEIVERB_OPEN) {
298 SIZE size;
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));
304
305 // SPR#1450 - quirky hack so embedded widgets show up immediately at the right size.
306 const_cast<Led_MFC_ControlItem*> (this)->SetExtent (size);
307 }
308 }
309 return result;
310}
311
312void Led_MFC_ControlItem::OnActivate ()
313{
314 // Allow only one inplace activate item per frame
315 Led_MFC& pView = GetActiveView ();
316 COleClientItem* pItem = GetDocument ().GetInPlaceActiveItem (&pView);
317 if (pItem != NULL && pItem != this) {
318 pItem->Close ();
319 }
320 COleClientItem::OnActivate ();
321}
322
323void Led_MFC_ControlItem::OnDeactivateUI (BOOL bUndoable)
324{
325 COleClientItem::OnDeactivateUI (bUndoable);
326
327 // Hide the object if it is not an outside-in object
328 DWORD dwMisc = 0;
329 m_lpObject->GetMiscStatus (GetDrawAspect (), &dwMisc);
330 if (dwMisc & OLEMISC_INSIDEOUT) {
331 DoVerb (OLEIVERB_HIDE, NULL);
332 }
333}
334
335void Led_MFC_ControlItem::DrawSegment (const StyledTextImager* imager, const StyleRunElement& /*runElement*/, 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& /*invalidRect*/, CoordinateType useBaseLine, DistanceType* pixelsDrawn)
338{
339 Require (to - from == 1);
340 Require (text.PeekAtVirtualText ()[0] == kEmbeddingSentinelChar);
341
342 Color foreColor = imager->GetEffectiveDefaultTextColor (TextImager::eDefaultTextColor);
343 ;
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 ());
348
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);
356
357 if (pixelsDrawn != NULL) {
358 *pixelsDrawn = ourBoundsRect.GetWidth ();
359 }
360
361 COleClientItem::Draw (Led_MFC_CDCFromTablet (tablet), CRect (AsRECT (innerBoundsRect)));
362}
363
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
367{
368 Assert (from + 1 == to);
369 Assert (text[0] == kEmbeddingSentinelChar);
370 distanceResults[0] = fSize.h + 2 * kDefaultEmbeddingMargin.h;
371}
372
373DistanceType Led_MFC_ControlItem::MeasureSegmentHeight (const StyledTextImager* /*imager*/, const StyleRunElement& /*runElement*/,
374 [[maybe_unused]] size_t from, [[maybe_unused]] size_t to) const
375{
376 Assert (from + 1 == to);
377 return fSize.v + 2 * kDefaultEmbeddingMargin.v;
378}
379
380void Led_MFC_ControlItem::Write (SinkStream& sink)
381{
382 CMemFile memFile;
383 CArchive archive (&memFile, CArchive::store);
384 Serialize (archive);
385 archive.Close ();
386 size_t nBytes = static_cast<size_t> (memFile.GetLength ());
387 BYTE* written = memFile.Detach ();
388 if (written != NULL) {
389 sink.write (written, nBytes);
390 ::free (written);
391 }
392}
393
394void Led_MFC_ControlItem::ExternalizeFlavors (WriterFlavorPackage& flavorPackage)
395{
396 WriterClipboardFlavorPackage* wcfp = dynamic_cast<WriterClipboardFlavorPackage*> (&flavorPackage);
397 if (wcfp != NULL) {
398 // fairly complex what MFC does here... Rather than reproduce it all, close the clipboard, and let MFC take care of it all.
399 // Reopen it so we our later close code doesn't fail...
400 HWND oldClipOwner = ::GetOpenClipboardWindow ();
401 AssertNotNull (oldClipOwner);
402 (void)::CloseClipboard ();
403
404 // Let MFC do the OLE clipboard copy...
405 CopyToClipboard ();
406
407 // now restore things so we don't fail later on our attempt to close...
408 (void)::OpenClipboard (oldClipOwner);
409 }
410 else {
411 Led_MFCWriterDAndDFlavorPackage* dndfp = dynamic_cast<Led_MFCWriterDAndDFlavorPackage*> (&flavorPackage);
412 AssertNotNull (dndfp);
413 DISABLE_COMPILER_MSC_WARNING_START (28182)
414 GetClipboardData (dndfp->GetOleDataSource ());
415 DISABLE_COMPILER_MSC_WARNING_END (28182)
416 }
417}
418
419const char* Led_MFC_ControlItem::GetTag () const
420{
421 return kEmbeddingTag;
422}
423
424void Led_MFC_ControlItem::Serialize (CArchive& ar)
425{
426 COleClientItem::Serialize (ar);
427 if (not ar.IsStoring ()) {
428 // then grab our size from the GetExtent() method to see the fSize field...
429 // Don't need to notify owning textstore etc cuz not yet even owned (probably?).
430 SIZE size;
431 const_cast<Led_MFC_ControlItem*> (this)->GetExtent (&size);
432 fSize = AsLedSize (HIMETRICtoDP (size));
433 }
434}
435
436void Led_MFC_ControlItem::DidUpdateText (const MarkerOwner::UpdateInfo& updateInfo) noexcept
437{
438 if (GetLength () == 0) {
439 AssertNotNull (GetOwner ()->PeekAtTextStore ());
440 GetOwner ()->PeekAtTextStore ()->RemoveMarker (this);
441 Delete (); // calls 'delete this', after doing much other needed cleanup
442 }
443 else {
444 SimpleEmbeddedObjectStyleMarker::DidUpdateText (updateInfo);
445 }
446}
447
448void Led_MFC_ControlItem::PostCreateSpecifyExtraInfo (TWIPS_Point size)
449{
450 // SetExtent (DPtoHIMETRIC (AsSIZE (size)));
451 // Cannot call SetExtent() here. Only after we've called Run () - otherwise exception.
452 // Really I think all my current logic for deadling with sizes of embeddings is questionable. I just don't
453 // understand it very well.
454 //
455 // Probably, all needs to be redone. Anyhow, for now, setting fSize field seems to work pretty well.
456 // LGP 971017
457 fSize = Led_Size (Led_CvtScreenPixelsFromTWIPSV (size.v), Led_CvtScreenPixelsFromTWIPSH (size.h));
458}
459
460SDKString Led_MFC_ControlItem::GetObjClassName () const
461{
462 CLSID clsid;
463 GetClassID (&clsid);
464 LPOLESTR oleStr = NULL;
465 if (::ProgIDFromCLSID (clsid, &oleStr) == S_OK) {
466 SDKString result = SDKString{::CString (oleStr)};
467 ::CoTaskMemFree (oleStr);
468 return result;
469 }
470 return SDKString{};
471}
472
473struct MyOLEStream_output : OLESTREAM {
474 OLESTREAMVTBL theVTbl;
475 vector<char> fData;
476 static DWORD __stdcall MyOLE1STREAMPutter (LPOLESTREAM lpoleStr, const void* data, DWORD nb)
477 {
478 MyOLEStream_output* myStream = (MyOLEStream_output*)lpoleStr;
479 using ci = const char*;
480 myStream->fData.insert (myStream->fData.end (), ci (data), ci (data) + nb);
481 return nb;
482 }
483 MyOLEStream_output ()
484 {
485 lpstbl = &theVTbl;
486 theVTbl.Get = NULL;
487 theVTbl.Put = MyOLE1STREAMPutter;
488 }
489};
490void Led_MFC_ControlItem::DoWriteToOLE1Stream (size_t* nBytes, byte** resultData)
491{
492 IStorage* pStorage = NULL;
493 IPersistStorage* ips = NULL;
494 try {
495 // Create a tmp storage
496 CheckGeneral (::StgCreateDocfile (NULL, STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &pStorage));
497 AssertNotNull (pStorage);
498
499 // Get IPersistStorage interface, and save data to my storage
500 CheckGeneral (m_lpObject->QueryInterface (IID_IPersistStorage, (LPVOID*)&ips));
501 AssertNotNull (ips);
502 CLSID myCLSID;
503 GetClassID (&myCLSID);
504 CheckGeneral (::WriteClassStg (pStorage, myCLSID));
505 DISABLE_COMPILER_MSC_WARNING_START (6011) // safe because ips != null = due to assert on QueryInterface above
506 CheckGeneral (ips->Save (pStorage, false));
507 CheckGeneral (ips->SaveCompleted (pStorage));
508 DISABLE_COMPILER_MSC_WARNING_END (6011) // safe because ips != null = due to assert on QueryInterface above
509
510 // Convert storage into array of bytes
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);
516 }
517 catch (...) {
518 if (pStorage != NULL) {
519 pStorage->Release ();
520 }
521 throw;
522 }
523 pStorage->Release ();
524 ips->Release ();
525}
526
527Led_Size Led_MFC_ControlItem::GetSize ()
528{
529 return fSize;
530}
531
532bool Led_MFC_ControlItem::HandleOpen ()
533{
534 (void)DoVerb (OLEIVERB_PRIMARY, NULL); // invoke in-place editing, or whatever the primary verb for the object is...
535 return false; // eat the open command
536}
537
538vector<Led_MFC_ControlItem::PrivateCmdNumber> Led_MFC_ControlItem::GetCmdNumbers () const
539{
540 vector<PrivateCmdNumber> x;
541 x.push_back (eOpenCmdNum);
542 return x;
543}
544
545bool Led_MFC_ControlItem::IsCmdEnabled (PrivateCmdNumber cmd) const
546{
547 switch (cmd) {
548 case eOpenCmdNum:
549 return true;
550 default:
551 return SimpleEmbeddedObjectStyleMarker::IsCmdEnabled (cmd);
552 }
553}
554
555#if qStroika_Foundation_Debug_AssertionsChecked
556COleDocument& Led_MFC_ControlItem::GetDocument () const
557{
558 COleDocument* result = (COleDocument*)COleClientItem::GetDocument ();
559 EnsureNotNull (result);
560 ASSERT_VALID (result);
561 Assert (result->IsKindOf (RUNTIME_CLASS (COleDocument)));
562 return *result;
563}
564
565Led_MFC& Led_MFC_ControlItem::GetActiveView () const
566{
567 EnsureNotNull (COleClientItem::GetActiveView ());
568 AssertMember (COleClientItem::GetActiveView (), Led_MFC);
569 return *(Led_MFC*)COleClientItem::GetActiveView ();
570}
571#endif
572
573/*
574 ********************************************************************************
575 ******************** Led_MFC_ControlItem::DocContextDefiner ********************
576 ********************************************************************************
577 */
578
579set<HWND> Led_MFC_ControlItem::DocContextDefiner::sWindowsWhichHadDisplaySuppressed;
580
581#endif
582#endif
#define AssertNotNull(p)
Definition Assertions.h:336
#define EnsureNotNull(p)
Definition Assertions.h:343
#define RequireNotNull(p)
Definition Assertions.h:350
#define AssertMember(p, c)
Definition Assertions.h:315
#define Verify(c)
Definition Assertions.h:422
Logically halfway between std::array and std::vector; Smart 'direct memory array' - which when needed...
basic_string< SDKChar > SDKString
Definition SDKString.h:38