Stroika Library 3.0d25
 
Loading...
Searching...
No Matches
MFC.h
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2026. All rights reserved
3 */
4#ifndef _Stroika_Frameworks_Led_Platform_MFC_h_
5#define _Stroika_Frameworks_Led_Platform_MFC_h_ 1
6
7#include "Stroika/Frameworks/StroikaPreComp.h"
8
9/*
10@MODULE: Led_MFC
11@DESCRIPTION:
12 <p>Led MFC specific wrappers.</p>
13 <p>Note that since MFC provides no abstract base classes for implementing editor-like
14 behavior, Led cannot subclass from CEdit or CEditView.</p>
15 <p>Also - for some purposes, it would be better to inherit from CWnd. And for others, better to inherit
16 from CView. Versions of Led prior to Led 2.3 inherited from CView.</p>
17 <p>Now - through the magic of templates - Led supports (almost) any MFC base class (at least
18 CView and CWnd) for a Led-based editor, so long as it supports at least the functionality of CWnd/CView.</p>
19 <p>The current Led sample applications (LedIt! and LedLineIt! all use Led inheriting from
20 a CView, and that is necessary to get the OLE/embedding funcitonality built in. But Led has also been
21 tested as a replacemnt edit control inheriting from CWnd (@LEC).</p>
22 */
23
24static_assert (qStroika_HasComponent_ATLMFC,
25 "Error: Stroika::Framework::Led::Platform MFC code requires the ATLMFC feature to be set true");
26
27#include <afxole.h>
28
29#include <afxwin.h>
30#include <oleidl.h>
31
32#include "Stroika/Frameworks/Led/IdleManager.h"
33#include "Stroika/Frameworks/Led/Platform/Windows.h"
34#include "Stroika/Frameworks/Led/TextInteractor.h"
35
36namespace Stroika::Frameworks::Led::Platform {
37
38/*
39 **************** Windows Specific configuration variables **************
40 */
41
42/*
43 @CONFIGVAR: qStroika_Frameworks_Led_AssertsDefaultToMFCAsserts
44 @DESCRIPTION: <p>By default when using MFC, make the Led asserts fall-thru into the default
45 MFC assertion code. Some customers have indicated they prefer this (spr#0424).</p>
46 <p>Originally I made this default to TRUE, as the SPR requested. But I personally
47 find the MFC Assert stuff a major pain in the donkey. Whenever you get an assert
48 due to a display bug, it brings up a dialog, and dimissing that alert triggers
49 (due to extra redisplay) extra re-enters into the same code which had the assert
50 doing displays.</p>
51 <p>Since it was requested, I'll continue to make it easy for others to turn this on.
52 But I leave it off by default.</p>
53 */
54#ifndef qStroika_Frameworks_Led_AssertsDefaultToMFCAsserts
55#define qStroika_Frameworks_Led_AssertsDefaultToMFCAsserts 0
56#endif
57
58/*
59 @CONFIGVAR: qSupportDrawTextGetTextExtent
60 @DESCRIPTION:
61 <p>Turn OFF by default (because requires including SimpleTextStore and SimpleTextImager and WordWrappedTextImager
62 in your projects - which you may not want to do).
63 See @'Led_DrawText' and @'Led_GetTextExtent'.</p>
64 */
65#ifndef qSupportDrawTextGetTextExtent
66#define qSupportDrawTextGetTextExtent 0
67#endif
68
69/*
70 **************** MFC bug workaround defines **************
71 */
72
73// Still broken In MSVC 6.0 (LGP 990304) - CFrameWnd::CreateView() still does cast of void* to CWnd* which breaks unless CWnd* is leftmost
74// Still broken In MSVC 5.0 (LGP 970318) - now the bug is in CFrameWnd::CreateView() though...
75// Still broken In MSVC 4.0 (LGP 951125)
76// (only not broken for old LedTestMFC app - breaks in new LedIt! app however. Maybe
77// should re-investigate???)
78// LGP 941129 (updated 950506)
79// The bug is with MFC 3.0/3.1, in CFrameWnd::OnCreateClient()
80// It did a cast of the result of CreateObject() to CWnd*, without
81// knowing the real type it started with, so that code looses if
82// CWnd is not the left-most base class.
83#ifndef qStroika_Frameworks_Led_MFCRequiresCWndLeftmostBaseClass
84#define qStroika_Frameworks_Led_MFCRequiresCWndLeftmostBaseClass 1
85#endif
86
87 CPoint AsCPoint (Led_Point p);
88 Led_Point AsLedPoint (CPoint p);
89
90 CRect AsCRect (Led_Rect r);
91 Led_Rect AsLedRect (CRect r);
92
93 CSize AsCSize (Led_Size s);
94
95 /*
96 @CLASS: Led_MFC_TmpCDCFromTablet
97 @DESCRIPTION: <p>Helper class to convert a @'Tablet*' to an MFC CDC. Just creates a temporary wrapper.</p>
98 <p><strong>Caution</strong>:
99 You must create a NAMED temporary.
100 A named temporary has lifetime til the end of the enclosing scope.
101 An unnamed temporary has lifetime only til the next sequence point (less or equal to the rest of the current statement - I believe).</p>
102 */
103 class Led_MFC_CDCFromTablet {
104 public:
105 Led_MFC_CDCFromTablet (Tablet* t);
106 ~Led_MFC_CDCFromTablet ();
107 operator CDC*();
108
109 private:
110 CDC fCDC;
111 };
112
113 /*
114 @CLASS: Led_MFC_TabletFromCDC
115 @DESCRIPTION: <p>Helper class to convert an MFC CDC to a @'Tablet*'. Just creates a temporary wrapper.</p>
116 <p><strong>Caution</strong>:
117 You must create a NAMED temporary.
118 A named temporary has lifetime til the end of the enclosing scope.
119 An unnamed temporary has lifetime only til the next sequence point (less or equal to the rest of the current statement - I believe).</p>
120 */
121 class Led_MFC_TabletFromCDC {
122 public:
123 Led_MFC_TabletFromCDC (CDC* pDC);
124 ~Led_MFC_TabletFromCDC ();
125
126 public:
127 operator Tablet*();
128 Tablet* operator->();
129
130 private:
131 Tablet fTablet;
132 };
133
134 /*
135 @CLASS: Led_MFC_Helper<MFC_BASE_CLASS,BASE_INTERACTOR>
136 @BASES: MFC_BASE_CLASS=@'CWnd', @'Led_Win32_Helper<BASE_INTERACTOR>', BASE_INTERACTOR=@'TextInteractor'
137 @DESCRIPTION: <p>There are two obvious ways to hook into MFC. One is to create a subclass of CWnd. The other is
138 to create a subclass of CView. Because CView inherits from CWnd, but not virtually, you are strongly encouraged
139 to pick one or the other. Alas - neither is really a good choice for ALL applications. For a big, main view, associated
140 with a document, you want to subclass from CView. For a little control (as in a dialog), you want to subclass from CWnd.</p>
141 <p>This template makes it easier (soon easy, but for now, just easier) to subclass from either one. The default one, and
142 the one Led mainly uses is CView. But soon I'll support (better) subclassing from CWnd.</p>
143 */
144 template <typename MFC_BASE_CLASS = CWnd, typename BASE_INTERACTOR = TextInteractor>
145 class Led_MFC_Helper :
146#if qStroika_Frameworks_Led_MFCRequiresCWndLeftmostBaseClass
147 public MFC_BASE_CLASS,
148 public Led_Win32_Helper<BASE_INTERACTOR>
149#else
150 public Led_Win32_Helper<BASE_INTERACTOR>,
151 public MFC_BASE_CLASS
152#endif
153 {
154 private:
155 using inherited = void*; // avoid using this keyword since this is mixin of two classes
156 private:
157 using LED_WIN32_HELPER = Led_Win32_Helper<BASE_INTERACTOR>;
158
159 public:
160 using UpdateInfo = MarkerOwner::UpdateInfo;
161
162 protected:
163 Led_MFC_Helper ();
164
165 public:
166 virtual ~Led_MFC_Helper ();
167
168 public:
169 nonvirtual BOOL ReplaceWindow (HWND hWnd);
170
171 // Led_Win32_Helper Hooks
172 public:
173 virtual HWND GetHWND () const override;
174
175 // Window message hooks NEEDED to get basic editor functionality
176 protected:
177 afx_msg int OnCreate (LPCREATESTRUCT lpCreateStruct);
178 afx_msg void OnPaint ();
179 afx_msg BOOL OnSetCursor (CWnd* pWnd, UINT nHitTest, UINT message);
180 afx_msg UINT OnGetDlgCode ();
181 afx_msg void OnChar (UINT nChar, UINT nRepCnt, UINT /*nFlags*/);
182 afx_msg LRESULT OnUniChar (WPARAM wParam, LPARAM lParam);
183 afx_msg LRESULT OnIMEChar (WPARAM wParam, LPARAM lParam);
184 afx_msg LRESULT OnIME_COMPOSITION (WPARAM wParam, LPARAM lParam);
185 afx_msg LRESULT OnIME_ENDCOMPOSITION (WPARAM wParam, LPARAM lParam);
186 afx_msg void OnKeyDown (UINT nChar, UINT nRepCnt, UINT /*nFlags*/);
187 afx_msg void OnMouseMove (UINT /*nFlags*/, CPoint oPoint);
188 afx_msg void OnLButtonDown (UINT nFlags, CPoint oPoint);
189 afx_msg void OnLButtonUp (UINT /*nFlags*/, CPoint oPoint);
190 afx_msg void OnLButtonDblClk (UINT /*nFlags*/, CPoint oPoint);
191 afx_msg void OnSetFocus (CWnd* pOldWnd);
192 afx_msg void OnKillFocus (CWnd* pNewWnd);
193 afx_msg void OnSize (UINT nType, int cx, int cy);
194 afx_msg BOOL OnEraseBkgnd (CDC* pDC);
195 afx_msg void OnVScroll (UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
196 afx_msg void OnHScroll (UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
197 afx_msg BOOL OnMouseWheel (UINT fFlags, short zDelta, CPoint point);
198 afx_msg void OnEnable (BOOL bEnable);
199 afx_msg void OnTimer (UINT_PTR nEventID);
200
201 // Disambiguate mixins
202 public:
203 virtual Led_Rect GetWindowRect () const;
204 nonvirtual void GetWindowRect (LPRECT lpRect) const;
205
206 public:
207 nonvirtual DWORD GetStyle () const;
208
209 // Command handing - map MFC commands to Led/TextInteractor commands
210 public:
211 afx_msg void OnUpdateCommand_MSG (CCmdUI* pCmdUI);
212 afx_msg void OnPerformCommand_MSG (UINT commandNumber);
213
214 protected:
215 DECLARE_MESSAGE_MAP ()
216 };
217
218 /*
219 @CLASS: Led_MFC_MimicMFCAPIHelper<BASECLASS>
220 @BASES: BASECLASS = @'Led_MFC_Helper<MFC_BASE_CLASS,BASE_INTERACTOR>'
221 @DESCRIPTION: <p>Mimicry of the MFC CEdit methods - to facilitate using this class in place of any
222 existing CEdit usage. These methods simply do send-message calls just as their
223 CEdit counterparts. Then messages are then trapped in the OnMsgXXX handlers.</p>
224 <p>NB: Use of this class almost ALWAYS requires also mixing in the template
225 @'Led_MFC_OptionalWin32SDKMessageMimicHelper<BASECLASS>'. since that is what (by default) implements
226 the OnMsgXXX helpers.</p>
227 */
228 template <typename BASECLASS = Led_MFC_Helper<>>
229 class Led_MFC_MimicMFCAPIHelper : public BASECLASS {
230 protected:
231 Led_MFC_MimicMFCAPIHelper () = default;
232
233 public:
234 nonvirtual BOOL Create (DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID);
235 nonvirtual BOOL CanUndo () const;
236 nonvirtual int GetLineCount_CEdit () const; // HAD to rename cuz of conflict...
237 nonvirtual BOOL GetModify () const;
238 nonvirtual void SetModify (BOOL bModified = TRUE);
239 nonvirtual void GetRect (LPRECT lpRect) const;
240 nonvirtual DWORD GetSel () const;
241 nonvirtual void GetSel (int& nStartChar, int& nEndChar) const;
242 nonvirtual int GetLine (int nIndex, LPTSTR lpszBuffer) const;
243 nonvirtual int GetLine (int nIndex, LPTSTR lpszBuffer, int nMaxLength) const;
244 nonvirtual void EmptyUndoBuffer ();
245 nonvirtual BOOL FmtLines (BOOL bAddEOL);
246 nonvirtual void LimitText (int nChars = 0);
247 nonvirtual int LineFromChar (int nIndex = -1) const;
248 nonvirtual int LineIndex (int nLine = -1) const;
249 nonvirtual int LineLength (int nLine = -1) const;
250 nonvirtual void LineScroll (int nLines, int nChars = 0);
251 nonvirtual void ReplaceSel (LPCTSTR lpszNewText);
252 nonvirtual void SetPasswordChar (TCHAR ch);
253 nonvirtual void SetRect (LPCRECT lpRect);
254 nonvirtual void SetRectNP (LPCRECT lpRect);
255 nonvirtual void SetSel (DWORD dwSelection, BOOL bNoScroll = FALSE);
256 nonvirtual void SetSel (int nStartChar, int nEndChar, BOOL bNoScroll = FALSE);
257 nonvirtual BOOL SetTabStops (int nTabStops, LPINT rgTabStops);
258 nonvirtual void SetTabStops ();
259 nonvirtual BOOL SetTabStops (const int& cxEachStop); // takes an 'int'
260 nonvirtual BOOL Undo ();
261 nonvirtual void Clear ();
262 nonvirtual void Copy ();
263 nonvirtual void Cut ();
264 nonvirtual void Paste ();
265 nonvirtual BOOL SetReadOnly (BOOL bReadOnly = TRUE);
266 nonvirtual int GetFirstVisibleLine () const;
267 nonvirtual TCHAR GetPasswordChar () const;
268 };
269
270 /*
271 @CLASS: Led_MFC_OptionalWin32SDKMessageMimicHelper<BASECLASS>
272 @BASES: BASECLASS = @'Led_MFC_Helper<MFC_BASE_CLASS,BASE_INTERACTOR>'
273 @DESCRIPTION: <p>Mimicry of the starndard Win32 messages sent to an edit control. We cannot
274 mimic ALL the messages. Some just don't make sense (like GETHANDLE). But for those that do, we
275 do our best.</p>
276 */
277 template <typename BASECLASS = Led_MFC_Helper<>>
278 class Led_MFC_OptionalWin32SDKMessageMimicHelper : public Led_Win32_Win32SDKMessageMimicHelper<BASECLASS> {
279 private:
280 using inherited = Led_Win32_Win32SDKMessageMimicHelper<BASECLASS>;
281
282 protected:
283 Led_MFC_OptionalWin32SDKMessageMimicHelper () = default;
284
285 public:
286 template <int MESSAGE_NUMBER>
287 afx_msg LRESULT OnMFCSDKMessageDispatcher (WPARAM wParam, LPARAM lParam)
288 {
289 LRESULT result = 0;
290 Verify (this->HandleMessage (MESSAGE_NUMBER, wParam, lParam, &result));
291 return result;
292 }
293
294 protected:
295 DECLARE_MESSAGE_MAP ()
296 };
297
298 /*
299 @CLASS: Led_MFC_DragAndDropWindow<BASECLASS>
300 @BASES: BASECLASS
301 @DESCRIPTION: <p>NB: BASECLASS <em>must</em> derive (possibly indirectly) from CWnd.</p>
302 <p>Probably eventually migrate more stuff from @'Led_MFC_CViewHelper<BASECLASS>' here to this class. But for now,
303 I'm risk averse. I don't want to break the class library. And this is all that is needed to move out to meet the immediate
304 complaints.</p>
305 */
306 template <typename BASECLASS = Led_MFC_Helper<>>
307 class Led_MFC_DragAndDropWindow : public BASECLASS {
308 private:
309 using inherited = BASECLASS;
310
311 protected:
312 Led_MFC_DragAndDropWindow ();
313
314 public:
315 ~Led_MFC_DragAndDropWindow ();
316
317 public:
318 /*
319 @CLASS: Led_MFC_DragAndDropWindow<BASECLASS>::CommandNames
320 @DESCRIPTION: <p>Command names for each of the user-visible commands produced by the @'TextInteractor' module.
321 This name is used used in the constructed Undo command name, as
322 in, "Undo Drag and Drop". You can replace this name with whatever you like.
323 You change this value with @'TextInteractor::SetCommandNames'.</p>
324 <p> The point of this is to allow for different UI-language localizations,
325 without having to change Led itself.</p>
326 <p>See also @'Led_MFC_DragAndDropWindow<BASECLASS>::GetCommandNames'.</p>
327 <p>See also @'TextInteractor::CommandNames'.</p>
328 <p>Note - also - this class must be declared lexically inside the
329 outer template -and not outside - do to compiler bugs with MSVC60(SP4).
330 Didn't take the time to trace them down carefully - LGP 2000-08-19.</p>
331 */
332 struct CommandNames {
333 CommandNames ()
334 : fDragCommandName (Led_SDK_TCHAROF ("Drag"))
335 , fDropCommandName (Led_SDK_TCHAROF ("Drop"))
336 , fDragNDropCommandName (Led_SDK_TCHAROF ("Drag and Drop"))
337 {
338 }
339
340 SDKString fDragCommandName;
341 SDKString fDropCommandName;
342 SDKString fDragNDropCommandName;
343 };
344
345 // This class builds commands with command names. The UI may wish to change these
346 // names (eg. to customize for particular languages, etc)
347 // Just patch these strings here, and commands will be created with these names.
348 // (These names appear in text of undo menu item)
349 public:
350 static const CommandNames& GetCommandNames ();
351 static void SetCommandNames (const CommandNames& cmdNames);
352
353 private:
354 static CommandNames sCommandNames;
355
356 protected:
357 COleDropTarget fDropTarget;
358
359 protected:
360 afx_msg int OnCreate (LPCREATESTRUCT lpCreateStruct);
361
362 // mouse down tracking... and drag and drop...
363 protected:
364 virtual bool IsADragSelect (Led_Point clickedWhere) const;
365 nonvirtual void HandleDragSelect (UINT nFlags, CPoint oPoint);
366 nonvirtual void HandleSharedDragOverUpdateSelCode ();
367 nonvirtual DROPEFFECT HelperDragEnter (COleDataObject* pDataObject, DWORD dwKeyState, CPoint point);
368 nonvirtual DROPEFFECT HelperDragOver (COleDataObject* pDataObject, DWORD dwKeyState, CPoint point);
369 nonvirtual BOOL HelperDrop (COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point);
370 nonvirtual void HelperDragLeave ();
371
372 protected:
373 CPoint fDragPoint; // current position
374 CSize fDragSize; // size of dragged object
375 CSize fDragOffset; // offset to focus rect
376 DROPEFFECT fPrevDropEffect;
377
378 protected:
379 nonvirtual bool GetObjectInfo (COleDataObject* pDataObject, CSize* pSize, CSize* pOffset);
380
381 protected:
382 afx_msg void OnTimer (UINT_PTR nEventID);
383
384 private:
385 nonvirtual void StartDragAutoscrollTimer ();
386 nonvirtual void StopDragAutoscrollTimer ();
387 enum {
388 eAutoscrolling4DragTimerEventID = 435
389 }; // Magic#
390 UINT_PTR fDragAutoScrollTimerID; // zero means no timer
391
392 private:
393 struct LedStartDragAndDropContext {
394 public:
395 LedStartDragAndDropContext (Led_MFC_DragAndDropWindow<BASECLASS>* ledMFCView)
396 : fOurDrag (false)
397 , fOurDragStart (0)
398 , fOurDragEnd (0)
399 , fWeRecievedDrop (false)
400 , fLedMFCView (ledMFCView)
401 , fOrigSelection (ledMFCView->GetTextStore (), ledMFCView->GetSelectionStart (), ledMFCView->GetSelectionEnd ())
402 {
403 }
404
405 public:
406 bool fOurDrag;
407 size_t fOurDragStart;
408 size_t fOurDragEnd;
409 bool fWeRecievedDrop;
410 Led_MFC_DragAndDropWindow<BASECLASS>* fLedMFCView;
411 TempMarker fOrigSelection;
412 };
413
414 static LedStartDragAndDropContext* sCurrentDragInfo;
415
416 protected:
417 DECLARE_MESSAGE_MAP ()
418 };
419
420 /*
421 @CLASS: Led_MFC_CViewHelper<BASECLASS>
422 @BASES: BASECLASS
423 @DESCRIPTION: <p>NB: BASECLASS <em>must</em> derive (possibly indirectly) from CView.</p>
424 */
425 template <typename BASECLASS = Led_MFC_DragAndDropWindow<>>
426 class Led_MFC_CViewHelper : public BASECLASS {
427 private:
428 using inherited = BASECLASS;
429
430 protected:
431 Led_MFC_CViewHelper ();
432
433 public:
434 virtual ~Led_MFC_CViewHelper ();
435
436 // CEditView storage methods.
437 public:
438 virtual void DeleteContents ();
439 virtual void Serialize (CArchive& ar);
440 nonvirtual void SerializeRaw (CArchive& ar);
441 nonvirtual void ReadFromArchive (CArchive& ar, UINT nLen);
442 nonvirtual void WriteToArchive (CArchive& ar);
443
444 protected:
445 afx_msg void OnPaint ();
446 virtual void OnDraw (CDC* pDC) override;
447 afx_msg void OnLButtonDown (UINT nFlags, CPoint oPoint);
448 afx_msg int OnCreate (LPCREATESTRUCT lpCreateStruct);
449 afx_msg void OnVScroll (UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
450 afx_msg void OnHScroll (UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
451
452 public:
453 nonvirtual TWIPS_Rect GetPrintMargins () const;
454 nonvirtual void SetPrintMargins (const TWIPS_Rect& printMargins);
455
456 private:
457 TWIPS_Rect fPrintMargins;
458
459 protected:
460 virtual BOOL OnPreparePrinting (CPrintInfo* pInfo) override;
461 virtual void OnBeginPrinting (CDC* pDC, CPrintInfo* pInfo) override;
462 virtual void OnPrint (CDC* pDC, CPrintInfo* pInfo) override;
463 virtual void OnEndPrinting (CDC* pDC, CPrintInfo* pInfo) override;
464
465 public:
466 virtual void OnPrepareDC (CDC* pDC, CPrintInfo* pInfo) override;
467
468 protected:
469 virtual Led_Rect CalculatePrintingRect (CDC* pDC) const;
470
471 protected:
472 struct PrintInfo {
473 PrintInfo (BASECLASS& editor, CDC* useTablet, Led_Rect oldWindowRect, size_t savedScrollPos, bool savedForceAlLRowsFlag)
474 : fTmpTablet{useTablet}
475 , fOldUpdateTablet{editor, fTmpTablet, BASECLASS::TemporarilyUseTablet::eDontDoTextMetricsChangedCall}
476 , fOldWindowRect{oldWindowRect}
477 , fSavedScrollPos{savedScrollPos}
478 , fSavedForceAllRowsFlag{savedForceAlLRowsFlag}
479 {
480 }
481 Led_MFC_TabletFromCDC fTmpTablet;
482 typename BASECLASS::TemporarilyUseTablet fOldUpdateTablet;
483 Led_Rect fOldWindowRect;
484 size_t fSavedScrollPos;
485 bool fSavedForceAllRowsFlag;
486 vector<size_t> fWindowStarts;
487 };
488 PrintInfo* fPrintInfo; // Non-NULL only during printing...
489
490 // mouse down tracking... and drag and drop...
491 protected:
492 virtual DROPEFFECT OnDragEnter (COleDataObject* pDataObject, DWORD dwKeyState, CPoint point) override;
493 virtual DROPEFFECT OnDragOver (COleDataObject* pDataObject, DWORD dwKeyState, CPoint point) override;
494 virtual BOOL OnDrop (COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point) override;
495 virtual void OnDragLeave () override;
496
497 public:
498 virtual void InvalidateScrollBarParameters () override;
499
500 protected:
501 virtual void UpdateScrollBars () override;
502
503 protected:
504 DECLARE_MESSAGE_MAP ()
505 };
506
507 /*
508 @CLASS: Led_MFC
509 @BASES: @'Led_MFC_CViewHelper<BASECLASS>', where BASECLASS=@'Led_MFC_OptionalWin32SDKMessageMimicHelper<BASECLASS>, where BASECLASS=@'Led_MFC_MimicMFCAPIHelper<BASECLASS>', where BASECLASS == @'Led_MFC_Helper<BASECLASS>', where BASECLASS=CView
510 @DESCRIPTION: <p>This template is provided partly as a convenience, for such a common case. But MOSTLY as backwards compatability
511 for Led 2.2. In Led 2.2, Led_MFC was the SOLE class provided to integrated Led with MFC. Now there is a whole suite of
512 individually selectable templates to provide that interfacing.</p>
513 */
514 using Led_MFC =
515 Led_MFC_CViewHelper<Led_MFC_DragAndDropWindow<Led_MFC_OptionalWin32SDKMessageMimicHelper<Led_MFC_MimicMFCAPIHelper<Led_MFC_Helper<CView, TextInteractor>>>>>;
516
517 /*
518 @CLASS: Led_MFC_COleControlHelper<BASECLASS>
519 @BASES: BASECLASS
520 @DESCRIPTION: <p>NB: BASECLASS <em>must</em> derive (possibly indirectly) from CView.</p>
521 */
522 template <typename BASECLASS = Led_MFC_DragAndDropWindow<>>
523 class Led_MFC_COleControlHelper : public BASECLASS {
524 private:
525 using inherited = BASECLASS;
526
527 public:
528 using UpdateMode = TextInteractor::UpdateMode;
529
530 protected:
531 Led_MFC_COleControlHelper ()
532 {
533 }
534
535 public:
536 virtual ~Led_MFC_COleControlHelper ()
537 {
538 }
539
540 public:
541 nonvirtual void Refresh (UpdateMode updateMode = TextInteractor::eDefaultUpdate) const
542 {
543 const TextInteractor* ti = this;
544 ti->Refresh (updateMode);
545 }
546 nonvirtual void Refresh (const Led_Rect& area, UpdateMode updateMode = TextInteractor::eDefaultUpdate) const
547 {
548 const TextInteractor* ti = this;
549 ti->Refresh (area, updateMode);
550 }
551 nonvirtual void Refresh (size_t from, size_t to, UpdateMode updateMode = TextInteractor::eDefaultUpdate) const
552 {
553 const TextInteractor* ti = this;
554 ti->Refresh (from, to, updateMode);
555 }
556 nonvirtual void Refresh (const Marker* range, UpdateMode updateMode = TextInteractor::eDefaultUpdate) const
557 {
558 const TextInteractor* ti = this;
559 ti->Refresh (range, updateMode);
560 }
561 };
562
563 /*
564 @CLASS: Led_MFC_ExceptionHandlerHelper<BASECLASS>
565 @BASES: BASECLASS = @'Led_MFC_Helper<MFC_BASE_CLASS,BASE_INTERACTOR>'
566 @DESCRIPTION: <p>This helper is designed to manage exception handling, when the Led class is being used in a context (say OCX)
567 where it cannot throw exceptions in error situations.</p>
568 <p>This class wraps many messages the control is likely to get, and when there is an exception, it calls a virtual
569 exception-handling method (which by default - beeps), and then returns normally.</p>
570 */
571 template <typename BASECLASS = Led_MFC>
572 class Led_MFC_ExceptionHandlerHelper : public BASECLASS {
573 private:
574 using inherited = BASECLASS;
575
576 protected:
577 virtual void HandleException () const;
578
579 public:
580 afx_msg void OnChar (UINT nChar, UINT nRepCnt, UINT nFlags);
581 afx_msg LRESULT OnIMEChar (WPARAM wParam, LPARAM lParam);
582 afx_msg void OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags);
583 afx_msg LRESULT OnMsgPaste (WPARAM wParam, LPARAM lParam);
584 afx_msg void OnLButtonDown (UINT nFlags, CPoint oPoint);
585 afx_msg void OnLButtonUp (UINT /*nFlags*/, CPoint oPoint);
586 afx_msg void OnLButtonDblClk (UINT /*nFlags*/, CPoint oPoint);
587 afx_msg BOOL OnCmdMsg (UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo);
588
589 protected:
590 DECLARE_MESSAGE_MAP ()
591 };
592
593 DISABLE_COMPILER_MSC_WARNING_START (4250) // inherits via dominance warning
594 /*
595 @CLASS: Led_MFC_X
596 @BASES: ChosenInteractor, @'Led_MFC'
597 @DESCRIPTION: <p>Utility template to mix together Led_MFC an a <code>ChosenInteractor</code> which already has support
598 for a particular TextImager mixed in.</p>
599 */
600 template <typename ChosenInteractor, typename LEDMFC = Led_MFC>
601 class Led_MFC_X :
602#if qStroika_Frameworks_Led_MFCRequiresCWndLeftmostBaseClass
603 public LEDMFC,
604 public ChosenInteractor
605#else
606 public ChosenInteractor,
607 public LEDMFC
608#endif
609 {
610 public:
611 Led_MFC_X ();
612
613 public:
614 virtual void AboutToUpdateText (const MarkerOwner::UpdateInfo& updateInfo) override;
615 virtual void DidUpdateText (const MarkerOwner::UpdateInfo& updateInfo) noexcept override;
616 };
617 DISABLE_COMPILER_MSC_WARNING_END (4250) // inherits via dominance warning
618
619 /*
620 @CLASS: Led_MFCReaderDAndDFlavorPackage
621 @BASES: @'ReaderFlavorPackage'
622 @DESCRIPTION: <p>ReaderFlavorPackage which reads from a COleDataObject as
623 its underlying storage. Useful for Drop (Drag and Drop) processing.</p>
624 */
625 class Led_MFCReaderDAndDFlavorPackage : public ReaderFlavorPackage {
626 public:
627 Led_MFCReaderDAndDFlavorPackage (COleDataObject* dataObject);
628
629 virtual bool GetFlavorAvailable (Led_ClipFormat clipFormat) const override;
630 virtual size_t GetFlavorSize (Led_ClipFormat clipFormat) const override;
631 virtual size_t ReadFlavorData (Led_ClipFormat clipFormat, size_t bufSize, void* buf) const override;
632
633 nonvirtual COleDataObject* GetOleDataObject () const;
634
635 private:
636 COleDataObject* fDataObject;
637 };
638
639 /*
640 @CLASS: Led_MFCWriterDAndDFlavorPackage
641 @BASES: @'WriterFlavorPackage'
642 @DESCRIPTION: <p>A WriterFlavorPackage which writes to a COleDataObject as
643 its underlying storage. Useful for Drag (Drag and Drop) processing.</p>
644 */
645 class Led_MFCWriterDAndDFlavorPackage : public WriterFlavorPackage {
646 public:
647 Led_MFCWriterDAndDFlavorPackage (COleDataSource* dataObject);
648
649 virtual void AddFlavorData (Led_ClipFormat clipFormat, size_t bufSize, const void* buf) override;
650
651 nonvirtual COleDataSource* GetOleDataSource () const;
652
653 private:
654 COleDataSource* fDataObject;
655 };
656
657 template <typename TRIVIALWORDWRAPPEDTEXTIMAGER, typename SIMPLETEXTIMAGER, typename TEXTSTORE>
658 CSize Led_GetTextExtent (CDC* cdc, const Led_tString& text, CRect r, bool wordWrap);
659
660 template <typename TRIVIALWORDWRAPPEDTEXTIMAGER, typename SIMPLETEXTIMAGER, typename TEXTSTORE>
661 void Led_DrawText (CDC* cdc, const Led_tString& text, CRect r, bool wordWrap);
662
663#if qSupportDrawTextGetTextExtent
664 CSize Led_GetTextExtent (CDC* cdc, const Led_tString& text, CRect r, bool wordWrap);
665 void Led_DrawText (CDC* cdc, const Led_tString& text, CRect r, bool wordWrap);
666#endif
667
668 /*
669 @CLASS: MFC_CommandNumberMapping
670 @DESCRIPTION: <p></p>
671 */
672 class MFC_CommandNumberMapping : public CommandNumberMapping<UINT> {
673 protected:
674 MFC_CommandNumberMapping ();
675 };
676
677 /*
678 @CLASS: Led_MFC_TmpCmdUpdater
679 @BASES: @'TextInteractor::CommandUpdater'
680 @DESCRIPTION: <p>Helper used in @'Led_Win32_Helper<BASE_INTERACTOR>'</p>
681 */
682 class Led_MFC_TmpCmdUpdater : public TextInteractor::CommandUpdater {
683 public:
684 explicit Led_MFC_TmpCmdUpdater (CCmdUI* pCmdUI);
685
686 public:
687 virtual CommandNumber GetCmdID () const override;
688 virtual bool GetEnabled () const override;
689 virtual void SetEnabled (bool enabled) override;
690 virtual void SetChecked (bool checked) override;
691 virtual void SetText (const SDKChar* text) override;
692
693 public:
694 operator CCmdUI*();
695 operator Led_MFC_TmpCmdUpdater*();
696
697 private:
698 CommandNumber fCmdNum;
699 CCmdUI* fCmdUI;
700 bool fEnabled;
701 };
702
703/*
704 @CLASS: LED_MFC_HANDLE_COMMAND
705 @DESCRIPTION: <p>Trivial helper for building MFC message maps.</p>
706 */
707#define LED_MFC_HANDLE_COMMAND(A) \
708 ON_COMMAND_RANGE (A, A, &ThisClass::OnPerformCommand_MSG) \
709 ON_UPDATE_COMMAND_UI (A, &ThisClass::OnUpdateCommand_MSG)
710
711/*
712 @CLASS: LED_MFC_HANDLE_COMMAND_RANGE
713 @DESCRIPTION: <p>Trivial helper for building MFC message maps.</p>
714 */
715#define LED_MFC_HANDLE_COMMAND_RANGE(A, B) \
716 ON_COMMAND_RANGE (A, B, &ThisClass::OnPerformCommand_MSG) \
717 ON_UPDATE_COMMAND_UI_RANGE (A, B, &ThisClass::OnUpdateCommand_MSG)
718
719/*
720 @CLASS: LED_MFC_HANDLE_COMMAND_M
721 @DESCRIPTION: <p></p>
722 */
723#define LED_MFC_HANDLE_COMMAND_M(A) LED_MFC_HANDLE_COMMAND (MFC_CommandNumberMapping::Get ().ReverseLookup (A))
724
725/*
726 @CLASS: LED_MFC_HANDLE_COMMAND_RANGE_M
727 @DESCRIPTION: <p></p>
728 */
729#define LED_MFC_HANDLE_COMMAND_RANGE_M(A, B) \
730 LED_MFC_HANDLE_COMMAND_RANGE (MFC_CommandNumberMapping::Get ().ReverseLookup (A), MFC_CommandNumberMapping::Get ().ReverseLookup (B))
731}
732
733/*
734 ********************************************************************************
735 ***************************** Implementation Details ***************************
736 ********************************************************************************
737 */
738#include "MFC.inl"
739
740#endif /*_Stroika_Frameworks_Led_Platform_MFC_h_*/
#define Verify(c)
Definition Assertions.h:422
void Copy(T *dest, size_t nEltsInDest, const T *src)
Safe variant of strncpy() - which always NUL-terminates the string.
basic_string< SDKChar > SDKString
Definition SDKString.h:38