Stroika Library 3.0d18
 
Loading...
Searching...
No Matches
UserConfigCommands.cpp
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#include "Stroika/Foundation/StroikaPreComp.h"
5
6DISABLE_COMPILER_MSC_WARNING_START (5054)
7#include <afxctl.h>
8DISABLE_COMPILER_MSC_WARNING_END (5054)
9
10#include <atlbase.h>
11
14
15#include "FontMenu.h"
16
17#include "UserConfigCommands.h"
18
19using Characters::String;
20
21namespace {
22 template <class EnumType, class CollType>
23 HRESULT CreateSTLEnumerator (IUnknown** ppUnk, IUnknown* pUnkForRelease, CollType& collection)
24 {
25 if (ppUnk == NULL)
26 return E_POINTER;
27 *ppUnk = NULL;
28
29 CComObject<EnumType>* pEnum = NULL;
30 HRESULT hr = CComObject<EnumType>::CreateInstance (&pEnum);
31
32 if (FAILED (hr))
33 return hr;
34
35 hr = pEnum->Init (pUnkForRelease, collection);
36
37 if (SUCCEEDED (hr))
38 hr = pEnum->QueryInterface (ppUnk);
39
40 if (FAILED (hr))
41 delete pEnum;
42
43 return hr;
44 }
45}
46
47namespace {
48 template <typename INT_NAME_GRABBER>
49 void DoRemove (vector<CComPtr<IDispatch>>* list, VARIANT eltIntNameOrIndex)
50 {
51 CComVariant e2r (eltIntNameOrIndex);
52 if (SUCCEEDED (e2r.ChangeType (VT_UI4))) {
53 size_t idx = e2r.ulVal;
54 if (idx >= list->size ()) {
55 ThrowIfErrorHRESULT (DISP_E_MEMBERNOTFOUND);
56 }
57 list->erase (list->begin () + idx, list->begin () + idx + 1);
58 }
59 else if (SUCCEEDED (e2r.ChangeType (VT_BSTR))) {
60 for (vector<CComPtr<IDispatch>>::iterator i = list->begin (); i != list->end (); ++i) {
61 if (wstring (INT_NAME_GRABBER (*i)) == wstring (e2r.bstrVal)) {
62 list->erase (i, i + 1);
63 break;
64 }
65 }
66 }
67 else if (SUCCEEDED (e2r.ChangeType (VT_DISPATCH))) {
68 for (vector<CComPtr<IDispatch>>::iterator i = list->begin (); i != list->end (); ++i) {
69 if ((*i).p == e2r.pdispVal) {
70 list->erase (i, i + 1);
71 break;
72 }
73 }
74 }
75 }
76 template <typename INT_NAME_GRABBER>
77 size_t DoFindIndex (vector<CComPtr<IDispatch>>* list, VARIANT eltIntNameOrObj)
78 {
79 for (vector<CComPtr<IDispatch>>::iterator i = list->begin (); i != list->end (); ++i) {
80 CComVariant nameV (eltIntNameOrObj);
81 if (SUCCEEDED (nameV.ChangeType (VT_BSTR))) {
82 if (wstring (INT_NAME_GRABBER (*i)) == wstring (nameV.bstrVal)) {
83 return i - list->begin ();
84 }
85 }
86 else if (SUCCEEDED (nameV.ChangeType (VT_DISPATCH))) {
87 if ((*i).p == nameV.pdispVal) {
88 return i - list->begin ();
89 }
90 }
91 }
92 return kBadIndex;
93 }
94}
95
96namespace {
97 struct CMD_NAME_GRABBER {
98 CMD_NAME_GRABBER (IDispatch* p)
99 : fDisp (p)
100 {
101 }
102 operator wstring ()
103 {
104#if qCompilerAndStdLib_altComPtrCvt2ComQIPtrRequiresExtraCast_Buggy
105 CComQIPtr<IALCommand> c = (IDispatch*)fDisp;
106#else
107 CComQIPtr<IALCommand> c = fDisp;
108#endif
109 CComBSTR name;
110 ThrowIfErrorHRESULT (c->get_InternalName (&name));
111 return wstring (name);
112 }
113 CComPtr<IDispatch> fDisp;
114 };
115
116 struct ACCEL_NAME_GRABBER {
117 ACCEL_NAME_GRABBER (IDispatch* p)
118 : fDisp (p)
119 {
120 }
121 operator wstring ()
122 {
123#if qCompilerAndStdLib_altComPtrCvt2ComQIPtrRequiresExtraCast_Buggy
124 CComQIPtr<IALAcceleratorElement> c = (IDispatch*)fDisp;
125#else
126 CComQIPtr<IALAcceleratorElement> c = fDisp;
127#endif
128 CComBSTR name;
129 ThrowIfErrorHRESULT (c->get_CommandInternalName (&name));
130 return wstring (name);
131 }
132 CComPtr<IDispatch> fDisp;
133 };
134}
135
136namespace {
137 // Used as an implemenation detail for CComEnumOnSTL<> invocation
138 struct STL_ATL_COPY_VARIANT_IDISPATCH {
139 static HRESULT copy (VARIANT* p1, const ATL::CComPtr<IDispatch>* p2)
140 {
141 if (p2 != NULL and *p2 != NULL) {
142 p1->vt = VT_DISPATCH;
143 p1->pdispVal = *p2;
144 IDispatch* pp2 = *p2;
145 pp2->AddRef ();
146 return S_OK;
147 }
148 else {
149 p1->vt = VT_EMPTY;
150 return E_FAIL;
151 }
152 }
153 static void init (VARIANT* p)
154 {
155 p->vt = VT_EMPTY;
156 }
157 static void destroy (VARIANT* p)
158 {
159 ::VariantClear (p);
160 }
161 };
162}
163
164namespace {
165 wstring NormalizeCmdNameToInternal (const wstring& cmdName)
166 {
167 wstring result = cmdName;
168 ReStart:
169 for (wstring::iterator i = result.begin (); i != result.end (); ++i) {
170 // erase spaces, and punctuation (except dash/underbar)
171 if (iswspace (*i) or (iswpunct (*i) and *i != '-' and *i != '_')) {
172 result.erase (i, i + 1);
173 goto ReStart;
174 }
175 }
176 return result;
177 }
178}
179
180namespace {
181 const string kFontNameCMDPrefix = "FontName";
182}
183
184/*
185 ********************************************************************************
186 ****************************** AL_CommandListHelper ****************************
187 ********************************************************************************
188 */
189UserCommandNameNumberRegistry* UserCommandNameNumberRegistry::sThis;
190
191UserCommandNameNumberRegistry& UserCommandNameNumberRegistry::Get ()
192{
193 if (sThis == NULL) {
194 sThis = new UserCommandNameNumberRegistry ();
195 }
196 return *sThis;
197}
198
199UserCommandNameNumberRegistry::UserCommandNameNumberRegistry ()
200 : fName2Num ()
201 , fNum2Name ()
202 , fNextUserCmdNum (kFirstOLEUserCmdCmdID)
203{
204}
205
206UINT UserCommandNameNumberRegistry::Enter (const wstring& internalName)
207{
208 UINT cmdNum = 0;
209 if (not Lookup (internalName, &cmdNum)) {
210 fName2Num.insert (map<wstring, UINT>::value_type (internalName, fNextUserCmdNum));
211 fNum2Name.insert (map<UINT, wstring>::value_type (fNextUserCmdNum, internalName));
212 cmdNum = fNextUserCmdNum;
213 ++fNextUserCmdNum;
214 if (fNextUserCmdNum > kLastOLEUserCmdCmdID) {
215 Assert (false); // not a good thing - should deal with this more gracefully... probably wont ever happen - LGP 2004-01-21
216 fNextUserCmdNum = kFirstOLEUserCmdCmdID;
217 }
218 }
219 return cmdNum;
220}
221
222bool UserCommandNameNumberRegistry::Lookup (UINT cmdNum, wstring* internalName)
223{
224 map<UINT, wstring>::const_iterator i = fNum2Name.find (cmdNum);
225 if (i == fNum2Name.end ()) {
226 return false;
227 }
228 else {
229 *internalName = (*i).second;
230 return true;
231 }
232}
233
234bool UserCommandNameNumberRegistry::Lookup (const wstring& internalName, UINT* cmdNum)
235{
236 map<wstring, UINT>::const_iterator i = fName2Num.find (internalName);
237 if (i == fName2Num.end ()) {
238 return false;
239 }
240 else {
241 *cmdNum = (*i).second;
242 return true;
243 }
244}
245
246wstring UserCommandNameNumberRegistry::Lookup (UINT cmdNum)
247{
248 wstring name;
249 [[maybe_unused]] bool r = Lookup (cmdNum, &name);
250 Assert (r);
251 return name;
252}
253
254/*
255 ********************************************************************************
256 ************************* ActiveLedIt_CurrentEventArguments ********************
257 ********************************************************************************
258 */
259ActiveLedIt_CurrentEventArguments::ActiveLedIt_CurrentEventArguments ()
260 : fInternalName ()
261 , fEnabled (false)
262 , fChecked (false)
263 , fName ()
264{
265}
266
267ActiveLedIt_CurrentEventArguments::~ActiveLedIt_CurrentEventArguments ()
268{
269}
270
271STDMETHODIMP ActiveLedIt_CurrentEventArguments::get_InternalCommandName (BSTR* pVal)
272{
273 if (pVal == NULL) {
274 return E_INVALIDARG;
275 }
276 try {
277 *pVal = CComBSTR (fInternalName.c_str ()).Detach ();
278 }
279 CATCH_AND_HANDLE_EXCEPTIONS_IN_HRESULT_FUNCTION ()
280 return S_OK;
281}
282
283STDMETHODIMP ActiveLedIt_CurrentEventArguments::put_InternalCommandName (BSTR val)
284{
285 if (val == NULL) {
286 return E_INVALIDARG;
287 }
288 try {
289 fInternalName = val;
290 }
291 CATCH_AND_HANDLE_EXCEPTIONS_IN_HRESULT_FUNCTION ()
292 return S_OK;
293}
294
295STDMETHODIMP ActiveLedIt_CurrentEventArguments::get_Enabled (VARIANT_BOOL* pVal)
296{
297 if (pVal == NULL) {
298 return E_INVALIDARG;
299 }
300 try {
301 *pVal = fEnabled;
302 }
303 CATCH_AND_HANDLE_EXCEPTIONS_IN_HRESULT_FUNCTION ()
304 return S_OK;
305}
306
307STDMETHODIMP ActiveLedIt_CurrentEventArguments::put_Enabled (VARIANT_BOOL val)
308{
309 fEnabled = !!val;
310 return S_OK;
311}
312
313STDMETHODIMP ActiveLedIt_CurrentEventArguments::get_Checked (VARIANT_BOOL* pVal)
314{
315 if (pVal == NULL) {
316 return E_INVALIDARG;
317 }
318 try {
319 *pVal = fChecked;
320 }
321 CATCH_AND_HANDLE_EXCEPTIONS_IN_HRESULT_FUNCTION ()
322 return S_OK;
323}
324
325STDMETHODIMP ActiveLedIt_CurrentEventArguments::put_Checked (VARIANT_BOOL val)
326{
327 fChecked = !!val;
328 return S_OK;
329}
330
331STDMETHODIMP ActiveLedIt_CurrentEventArguments::get_Name (BSTR* pVal)
332{
333 if (pVal == NULL) {
334 return E_INVALIDARG;
335 }
336 try {
337 *pVal = CComBSTR (fName.c_str ()).Detach ();
338 }
339 CATCH_AND_HANDLE_EXCEPTIONS_IN_HRESULT_FUNCTION ()
340 return S_OK;
341}
342
343STDMETHODIMP ActiveLedIt_CurrentEventArguments::put_Name (BSTR val)
344{
345 if (val == NULL) {
346 return E_INVALIDARG;
347 }
348 try {
349 fName = val;
350 }
351 CATCH_AND_HANDLE_EXCEPTIONS_IN_HRESULT_FUNCTION ()
352 return S_OK;
353}
354
355HRESULT ActiveLedIt_CurrentEventArguments::FinalConstruct ()
356{
357 return S_OK;
358}
359
360void ActiveLedIt_CurrentEventArguments::FinalRelease ()
361{
362}
363
364/*
365 ********************************************************************************
366 ****************************** AL_CommandListHelper ****************************
367 ********************************************************************************
368 */
369AL_CommandListHelper::AL_CommandListHelper ()
370 : fOwnedItems ()
371{
372}
373
374AL_CommandListHelper::~AL_CommandListHelper ()
375{
376}
377
378STDMETHODIMP AL_CommandListHelper::GeneratePopupMenu (IDispatch* acceleratorTable, HMENU* val)
379{
380 try {
381 if (val == NULL) {
382 return E_INVALIDARG;
383 }
384 HMENU hMenu = ::CreatePopupMenu ();
385 for (vector<CComPtr<IDispatch>>::iterator i = fOwnedItems.begin (); i != fOwnedItems.end (); ++i) {
386#if qCompilerAndStdLib_altComPtrCvt2ComQIPtrRequiresExtraCast_Buggy
387 CComQIPtr<IALCommand> alc = (IDispatch*)*i;
388#else
389 CComQIPtr<IALCommand> alc = *i;
390#endif
391 CComBSTR cmdName;
392 ThrowIfErrorHRESULT (alc->get_Name (&cmdName));
393 ThrowIfErrorHRESULT (alc->AppendSelfToMenu (hMenu, acceleratorTable));
394 }
395 *val = hMenu;
396 return S_OK;
397 }
398 CATCH_AND_HANDLE_EXCEPTIONS_IN_HRESULT_FUNCTION ()
399}
400
401STDMETHODIMP AL_CommandListHelper::LookupCommand (BSTR internalName, IDispatch** val)
402{
403 if (val == NULL) {
404 return E_INVALIDARG;
405 }
406 try {
407 *val = NULL;
408 for (vector<CComPtr<IDispatch>>::iterator i = fOwnedItems.begin (); i != fOwnedItems.end (); ++i) {
409#if qCompilerAndStdLib_altComPtrCvt2ComQIPtrRequiresExtraCast_Buggy
410 CComQIPtr<IALCommand> alc = (IDispatch*)*i;
411#else
412 CComQIPtr<IALCommand> alc = *i;
413#endif
414 CComBSTR iName;
415 ThrowIfErrorHRESULT (alc->get_InternalName (&iName));
416 if (iName == internalName) {
417 *val = *i;
418 AssertNotNull (*val);
419 (*val)->AddRef ();
420 return S_OK;
421 }
422#if qCompilerAndStdLib_altComPtrCvt2ComQIPtrRequiresExtraCast_Buggy
423 CComQIPtr<IALCommandList> alcl = (IDispatch*)*i;
424#else
425 CComQIPtr<IALCommandList> alcl = *i;
426#endif
427 if (alcl.p != NULL) {
428 // If its a popup menu - recurse
429 ThrowIfErrorHRESULT (alcl->LookupCommand (internalName, val));
430 if (*val != NULL) {
431 // then were done - found in a submenu - so return at this point
432 return S_OK;
433 }
434 }
435 }
436 return S_OK;
437 }
438 CATCH_AND_HANDLE_EXCEPTIONS_IN_HRESULT_FUNCTION ()
439}
440
441STDMETHODIMP AL_CommandListHelper::IndexOf (VARIANT internalNameOrObject, UINT* val)
442{
443 if (val == NULL) {
444 return E_INVALIDARG;
445 }
446 try {
447 *val = static_cast<UINT> (DoFindIndex<CMD_NAME_GRABBER> (&fOwnedItems, internalNameOrObject));
448 return S_OK;
449 }
450 CATCH_AND_HANDLE_EXCEPTIONS_IN_HRESULT_FUNCTION ()
451}
452
453STDMETHODIMP AL_CommandListHelper::get__NewEnum (IUnknown** ppUnk)
454{
455 using VarVarEnum = CComEnumOnSTL<IEnumVARIANT, &IID_IEnumVARIANT, VARIANT, STL_ATL_COPY_VARIANT_IDISPATCH, std::vector<CComPtr<IDispatch>>>;
456 if (ppUnk == NULL) {
457 return E_INVALIDARG;
458 }
459 try {
460 return CreateSTLEnumerator<VarVarEnum> (ppUnk, this, fOwnedItems);
461 }
462 CATCH_AND_HANDLE_EXCEPTIONS_IN_HRESULT_FUNCTION ()
463}
464
465STDMETHODIMP AL_CommandListHelper::get_Item (long Index, IDispatch** pVal)
466{
467 if (pVal == NULL) {
468 return E_INVALIDARG;
469 }
470 if (Index < 0 or static_cast<size_t> (Index) >= fOwnedItems.size ()) {
471 return E_INVALIDARG;
472 }
473 try {
474 *pVal = fOwnedItems[Index];
475 (*pVal)->AddRef ();
476 }
477 CATCH_AND_HANDLE_EXCEPTIONS_IN_HRESULT_FUNCTION ()
478 return S_OK;
479}
480
481STDMETHODIMP AL_CommandListHelper::get_Count (long* pVal)
482{
483 if (pVal == NULL) {
484 return E_INVALIDARG;
485 }
486 try {
487 *pVal = static_cast<long> (fOwnedItems.size ());
488 }
489 CATCH_AND_HANDLE_EXCEPTIONS_IN_HRESULT_FUNCTION ()
490 return S_OK;
491}
492
493void AL_CommandListHelper::AppendBuiltinCmd (const BuiltinCmdSpec& cmdSpec)
494{
495 fOwnedItems.push_back (ActiveLedIt_BuiltinCommand::mk (cmdSpec));
496}
497
498void AL_CommandListHelper::AppendBuiltinCmds (const BuiltinCmdSpec* cmdSpecsStart, const BuiltinCmdSpec* cmdSpecsEnd)
499{
500 for (const BuiltinCmdSpec* i = cmdSpecsStart; i != cmdSpecsEnd; ++i) {
501 AppendBuiltinCmd (*i);
502 }
503}
504
505/*
506 ********************************************************************************
507 *************************** AL_UserCommandListHelper ***************************
508 ********************************************************************************
509 */
510AL_UserCommandListHelper::AL_UserCommandListHelper ()
511{
512}
513
514AL_UserCommandListHelper::~AL_UserCommandListHelper ()
515{
516}
517
518STDMETHODIMP AL_UserCommandListHelper::Insert (IDispatch* newElt, UINT afterElt)
519{
520 try {
521 if (newElt == NULL) {
522 return E_INVALIDARG;
523 }
524 size_t idx = min (static_cast<size_t> (afterElt), fOwnedItems.size ());
525 fOwnedItems.insert (fOwnedItems.begin () + idx, newElt);
526 }
527 CATCH_AND_HANDLE_EXCEPTIONS_IN_HRESULT_FUNCTION ()
528 return S_OK;
529}
530
531STDMETHODIMP AL_UserCommandListHelper::Remove (VARIANT eltIntNameOrIndex)
532{
533 try {
534 DoRemove<CMD_NAME_GRABBER> (&fOwnedItems, eltIntNameOrIndex);
535 return S_OK;
536 }
537 CATCH_AND_HANDLE_EXCEPTIONS_IN_HRESULT_FUNCTION ()
538}
539
540STDMETHODIMP AL_UserCommandListHelper::Clear ()
541{
542 try {
543 fOwnedItems.clear ();
544 return S_OK;
545 }
546 CATCH_AND_HANDLE_EXCEPTIONS_IN_HRESULT_FUNCTION ()
547}
548
549/*
550 ********************************************************************************
551 ***************************** ActiveLedIt_UserCommand **************************
552 ********************************************************************************
553 */
554ActiveLedIt_UserCommand::ActiveLedIt_UserCommand ()
555{
556 fCommandNumber = UserCommandNameNumberRegistry::Get ().Enter (fInternalName);
557}
558
559ActiveLedIt_UserCommand::~ActiveLedIt_UserCommand ()
560{
561}
562
563HRESULT ActiveLedIt_UserCommand::FinalConstruct ()
564{
565 return S_OK;
566}
567
568void ActiveLedIt_UserCommand::FinalRelease ()
569{
570}
571
572STDMETHODIMP ActiveLedIt_UserCommand::put_Name (BSTR val)
573{
574 if (val == NULL) {
575 return E_INVALIDARG;
576 }
577 try {
578 fName = val;
579 }
580 CATCH_AND_HANDLE_EXCEPTIONS_IN_HRESULT_FUNCTION ()
581 return S_OK;
582}
583
584STDMETHODIMP ActiveLedIt_UserCommand::put_InternalName (BSTR val)
585{
586 if (val == NULL) {
587 return E_INVALIDARG;
588 }
589 try {
590 fInternalName = val;
591 fCommandNumber = UserCommandNameNumberRegistry::Get ().Enter (fInternalName);
592 }
593 CATCH_AND_HANDLE_EXCEPTIONS_IN_HRESULT_FUNCTION ()
594 return S_OK;
595}
596
597/*
598 ********************************************************************************
599 ************************ ActiveLedIt_AcceleratorElement ************************
600 ********************************************************************************
601 */
602ActiveLedIt_AcceleratorElement::ActiveLedIt_AcceleratorElement ()
603 : fCommandInternalName ()
604 , fAcceleratorModifierFlag (static_cast<AcceleratorModifierFlag> (0))
605 , fKey (0)
606{
607}
608
609HRESULT ActiveLedIt_AcceleratorElement::FinalConstruct ()
610{
611 return S_OK;
612}
613
614void ActiveLedIt_AcceleratorElement::FinalRelease ()
615{
616}
617
618STDMETHODIMP ActiveLedIt_AcceleratorElement::get_CommandInternalName (BSTR* pVal)
619{
620 if (pVal == NULL) {
621 return E_INVALIDARG;
622 }
623 try {
624 *pVal = CComBSTR (fCommandInternalName.c_str ()).Detach ();
625 return S_OK;
626 }
627 CATCH_AND_HANDLE_EXCEPTIONS_IN_HRESULT_FUNCTION ()
628}
629
630STDMETHODIMP ActiveLedIt_AcceleratorElement::put_CommandInternalName (BSTR val)
631{
632 if (val == NULL) {
633 return E_INVALIDARG;
634 }
635 try {
636 fCommandInternalName = val;
637 }
638 CATCH_AND_HANDLE_EXCEPTIONS_IN_HRESULT_FUNCTION ()
639 return S_OK;
640}
641
642STDMETHODIMP ActiveLedIt_AcceleratorElement::get_ModifierFlag (AcceleratorModifierFlag* pVal)
643{
644 if (pVal == NULL) {
645 return E_INVALIDARG;
646 }
647 try {
648 *pVal = fAcceleratorModifierFlag;
649 return S_OK;
650 }
651 CATCH_AND_HANDLE_EXCEPTIONS_IN_HRESULT_FUNCTION ()
652}
653
654STDMETHODIMP ActiveLedIt_AcceleratorElement::put_ModifierFlag (AcceleratorModifierFlag val)
655{
656 if (val == NULL) {
657 return E_INVALIDARG;
658 }
659 try {
660 fAcceleratorModifierFlag = val;
661 }
662 CATCH_AND_HANDLE_EXCEPTIONS_IN_HRESULT_FUNCTION ()
663 return S_OK;
664}
665
666STDMETHODIMP ActiveLedIt_AcceleratorElement::get_Key (WORD* pVal)
667{
668 if (pVal == NULL) {
669 return E_INVALIDARG;
670 }
671 try {
672 *pVal = fKey;
673 return S_OK;
674 }
675 CATCH_AND_HANDLE_EXCEPTIONS_IN_HRESULT_FUNCTION ()
676}
677
678STDMETHODIMP ActiveLedIt_AcceleratorElement::put_Key (WORD val)
679{
680 if (val == NULL) {
681 return E_INVALIDARG;
682 }
683 try {
684 fKey = val;
685 }
686 CATCH_AND_HANDLE_EXCEPTIONS_IN_HRESULT_FUNCTION ()
687 return S_OK;
688}
689
690/*
691 ********************************************************************************
692 ************************ ActiveLedIt_AcceleratorTable **************************
693 ********************************************************************************
694 */
695ActiveLedIt_AcceleratorTable::ActiveLedIt_AcceleratorTable ()
696 : fAccelerators ()
697{
698}
699
700ActiveLedIt_AcceleratorTable::~ActiveLedIt_AcceleratorTable ()
701{
702}
703
704HRESULT ActiveLedIt_AcceleratorTable::FinalConstruct ()
705{
706 return S_OK;
707}
708
709void ActiveLedIt_AcceleratorTable::FinalRelease ()
710{
711}
712
713void ActiveLedIt_AcceleratorTable::AppendACCEL (const char* internalCmdName, AcceleratorModifierFlag modifierFlag, WORD key)
714{
715 CComObject<ActiveLedIt_AcceleratorElement>* ae = NULL;
716 ThrowIfErrorHRESULT (CComObject<ActiveLedIt_AcceleratorElement>::CreateInstance (&ae));
717 CComQIPtr<IDispatch> result = ae->GetUnknown ();
718 ae->put_CommandInternalName (CComBSTR (internalCmdName));
719 ae->put_ModifierFlag (modifierFlag);
720 ae->put_Key (key);
721 Add (ae);
722}
723
724STDMETHODIMP ActiveLedIt_AcceleratorTable::get__NewEnum (IUnknown** ppUnk)
725{
726 using VarVarEnum = CComEnumOnSTL<IEnumVARIANT, &IID_IEnumVARIANT, VARIANT, STL_ATL_COPY_VARIANT_IDISPATCH, std::vector<CComPtr<IDispatch>>>;
727 if (ppUnk == NULL) {
728 return E_INVALIDARG;
729 }
730 try {
731 return CreateSTLEnumerator<VarVarEnum> (ppUnk, this, fAccelerators);
732 }
733 CATCH_AND_HANDLE_EXCEPTIONS_IN_HRESULT_FUNCTION ()
734}
735
736STDMETHODIMP ActiveLedIt_AcceleratorTable::get_Item (long Index, IDispatch** pVal)
737{
738 if (pVal == NULL) {
739 return E_INVALIDARG;
740 }
741 if (Index < 0 or static_cast<size_t> (Index) >= fAccelerators.size ()) {
742 return E_INVALIDARG;
743 }
744 try {
745 *pVal = fAccelerators[Index];
746 (*pVal)->AddRef ();
747 }
748 CATCH_AND_HANDLE_EXCEPTIONS_IN_HRESULT_FUNCTION ()
749 return S_OK;
750}
751
752STDMETHODIMP ActiveLedIt_AcceleratorTable::get_Count (long* pVal)
753{
754 if (pVal == NULL) {
755 return E_INVALIDARG;
756 }
757 try {
758 *pVal = static_cast<long> (fAccelerators.size ());
759 }
760 CATCH_AND_HANDLE_EXCEPTIONS_IN_HRESULT_FUNCTION ()
761 return S_OK;
762}
763
764STDMETHODIMP ActiveLedIt_AcceleratorTable::Lookup (BSTR cmdInternalName, IDispatch** pVal)
765{
766 if (pVal == NULL) {
767 return E_INVALIDARG;
768 }
769 if (cmdInternalName == NULL) {
770 return E_INVALIDARG;
771 }
772 try {
773 *pVal = NULL;
774 for (vector<CComPtr<IDispatch>>::const_iterator i = fAccelerators.begin (); i != fAccelerators.end (); ++i) {
775#if qCompilerAndStdLib_altComPtrCvt2ComQIPtrRequiresExtraCast_Buggy
776 CComQIPtr<IALAcceleratorElement> ae = (IDispatch*)*i;
777#else
778 CComQIPtr<IALAcceleratorElement> ae = *i;
779#endif
780 CComBSTR itsInternalCmdName;
781 ThrowIfErrorHRESULT (ae->get_CommandInternalName (&itsInternalCmdName));
782 if (CComBSTR (cmdInternalName) == itsInternalCmdName) {
783 *pVal = *i;
784 (*pVal)->AddRef ();
785 return S_OK;
786 }
787 }
788 return S_OK;
789 }
790 CATCH_AND_HANDLE_EXCEPTIONS_IN_HRESULT_FUNCTION ()
791}
792
793STDMETHODIMP ActiveLedIt_AcceleratorTable::Add (IDispatch* newElt, UINT atIndex)
794{
795 if (newElt == NULL) {
796 return E_INVALIDARG;
797 }
798 try {
799 size_t idx = min (static_cast<size_t> (atIndex), fAccelerators.size ());
800 fAccelerators.insert (fAccelerators.begin () + idx, newElt);
801 }
802 CATCH_AND_HANDLE_EXCEPTIONS_IN_HRESULT_FUNCTION ()
803 return S_OK;
804}
805
806STDMETHODIMP ActiveLedIt_AcceleratorTable::Remove (VARIANT eltIntNameOrIndex)
807{
808 try {
809 DoRemove<ACCEL_NAME_GRABBER> (&fAccelerators, eltIntNameOrIndex);
810 return S_OK;
811 }
812 CATCH_AND_HANDLE_EXCEPTIONS_IN_HRESULT_FUNCTION ()
813}
814
815STDMETHODIMP ActiveLedIt_AcceleratorTable::Clear ()
816{
817 try {
818 fAccelerators.clear ();
819 }
820 CATCH_AND_HANDLE_EXCEPTIONS_IN_HRESULT_FUNCTION ()
821 return S_OK;
822}
823
824STDMETHODIMP ActiveLedIt_AcceleratorTable::GenerateWin32AcceleratorTable (HACCEL* pVal)
825{
826 if (pVal == NULL) {
827 return E_INVALIDARG;
828 }
829 try {
830#if qCompilerAndStdLib_altComPtrCvt2ComQIPtrRequiresExtraCast_Buggy
831 CComQIPtr<IALCommandList> builtins = (IDispatch*)GenerateBuiltinCommandsObject ();
832#else
833 CComQIPtr<IALCommandList> builtins = GenerateBuiltinCommandsObject ();
834#endif
835
836 Memory::StackBuffer<ACCEL> accels{fAccelerators.size ()};
837 size_t goodKeysFound = 0;
838 for (vector<CComPtr<IDispatch>>::const_iterator i = fAccelerators.begin (); i != fAccelerators.end (); ++i) {
839#if qCompilerAndStdLib_altComPtrCvt2ComQIPtrRequiresExtraCast_Buggy
840 CComQIPtr<IALAcceleratorElement> ae = (IDispatch*)*i;
841#else
842 CComQIPtr<IALAcceleratorElement> ae = *i;
843#endif
844 CComBSTR internalCmdName;
845 ThrowIfErrorHRESULT (ae->get_CommandInternalName (&internalCmdName));
846 UINT cmdNum = 0;
847 if (cmdNum == 0) {
848 // See if its in the builtin command list
849 long bicc = 0;
850 builtins->get_Count (&bicc);
851 for (long ii = 0; ii < bicc; ++ii) {
852 CComPtr<IDispatch> e;
853 ThrowIfErrorHRESULT (builtins->get_Item (ii, &e));
854#if qCompilerAndStdLib_altComPtrCvt2ComQIPtrRequiresExtraCast_Buggy
855 CComQIPtr<IALCommand> alc = (IDispatch*)e;
856#else
857 CComQIPtr<IALCommand> alc = e;
858#endif
859 CComBSTR bicCmdName;
860 ThrowIfErrorHRESULT (alc->get_InternalName (&bicCmdName));
861 if (bicCmdName == internalCmdName) {
862 // trick to extract CMD# from the element
863 HMENU hMenu = ::CreatePopupMenu ();
864 ThrowIfErrorHRESULT (alc->AppendSelfToMenu (hMenu, NULL));
865 cmdNum = ::GetMenuItemID (hMenu, 0);
866 ::DestroyMenu (hMenu);
867 }
868 }
869 }
870 if (cmdNum == 0) {
871 // See if its a user-command...
872 (void)UserCommandNameNumberRegistry::Get ().Lookup (wstring (internalCmdName), &cmdNum);
873 }
874
875 // If we have a cmd# - then add it....
876 if (cmdNum != 0) {
877 AcceleratorModifierFlag modfierFlag;
878 ThrowIfErrorHRESULT (ae->get_ModifierFlag (&modfierFlag));
879 WORD key;
880 ThrowIfErrorHRESULT (ae->get_Key (&key));
881 accels[goodKeysFound].fVirt = static_cast<BYTE> (modfierFlag);
882 accels[goodKeysFound].key = key;
883 Assert (cmdNum <= numeric_limits<WORD>::max ());
884 accels[goodKeysFound].cmd = static_cast<WORD> (cmdNum);
885 ++goodKeysFound;
886 }
887 *pVal = ::CreateAcceleratorTable (accels.data (), static_cast<int> (goodKeysFound));
888 }
889 }
890 CATCH_AND_HANDLE_EXCEPTIONS_IN_HRESULT_FUNCTION ()
891 return S_OK;
892}
893
894/*
895 ********************************************************************************
896 ************************* ActiveLedIt_StaticCommandList ************************
897 ********************************************************************************
898 */
899ActiveLedIt_StaticCommandList::ActiveLedIt_StaticCommandList ()
900{
901}
902
903ActiveLedIt_StaticCommandList::~ActiveLedIt_StaticCommandList ()
904{
905}
906
907void ActiveLedIt_StaticCommandList::Append (IDispatch* p)
908{
909 fOwnedItems.push_back (p);
910}
911
912HRESULT ActiveLedIt_StaticCommandList::FinalConstruct ()
913{
914 return S_OK;
915}
916
917void ActiveLedIt_StaticCommandList::FinalRelease ()
918{
919}
920
921/*
922 ********************************************************************************
923 *************************** ActiveLedIt_UserCommandList ************************
924 ********************************************************************************
925 */
926ActiveLedIt_UserCommandList::ActiveLedIt_UserCommandList ()
927{
928}
929
930ActiveLedIt_UserCommandList::~ActiveLedIt_UserCommandList ()
931{
932}
933
934HRESULT ActiveLedIt_UserCommandList::FinalConstruct ()
935{
936 return S_OK;
937}
938
939void ActiveLedIt_UserCommandList::FinalRelease ()
940{
941}
942
943/*
944 ********************************************************************************
945 *************************** ActiveLedIt_MenuItemPopup **************************
946 ********************************************************************************
947 */
948ActiveLedIt_MenuItemPopup::ActiveLedIt_MenuItemPopup ()
949{
950}
951
952ActiveLedIt_MenuItemPopup::~ActiveLedIt_MenuItemPopup ()
953{
954}
955
956HRESULT ActiveLedIt_MenuItemPopup::FinalConstruct ()
957{
958 return S_OK;
959}
960
961void ActiveLedIt_MenuItemPopup::FinalRelease ()
962{
963}
964
965STDMETHODIMP ActiveLedIt_MenuItemPopup::Insert (IDispatch* newElt, UINT afterElt)
966{
967 if (newElt == NULL) {
968 return E_INVALIDARG;
969 }
970 try {
971 size_t idx = min (static_cast<size_t> (afterElt), fOwnedItems.size ());
972 fOwnedItems.insert (fOwnedItems.begin () + idx, newElt);
973 }
974 CATCH_AND_HANDLE_EXCEPTIONS_IN_HRESULT_FUNCTION ()
975 return S_OK;
976}
977
978STDMETHODIMP ActiveLedIt_MenuItemPopup::Remove (VARIANT eltIntNameOrIndex)
979{
980 try {
981 DoRemove<CMD_NAME_GRABBER> (&fOwnedItems, eltIntNameOrIndex);
982 return S_OK;
983 }
984 CATCH_AND_HANDLE_EXCEPTIONS_IN_HRESULT_FUNCTION ()
985}
986
987STDMETHODIMP ActiveLedIt_MenuItemPopup::Clear ()
988{
989 try {
990 fOwnedItems.clear ();
991 }
992 CATCH_AND_HANDLE_EXCEPTIONS_IN_HRESULT_FUNCTION ()
993 return S_OK;
994}
995
996STDMETHODIMP ActiveLedIt_MenuItemPopup::AppendSelfToMenu (HMENU menu, IDispatch* acceleratorTable)
997{
998 try {
999 HMENU subMenu = NULL;
1000 ThrowIfErrorHRESULT (GeneratePopupMenu (acceleratorTable, &subMenu));
1001 ::AppendMenu (menu, MF_POPUP, reinterpret_cast<UINT_PTR> (subMenu), String{L"&" + fName}.AsSDKString ().c_str ());
1002 return S_OK;
1003 }
1004 CATCH_AND_HANDLE_EXCEPTIONS_IN_HRESULT_FUNCTION ()
1005}
1006
1007/*
1008 ********************************************************************************
1009 ********************************* AL_CommandHelper *****************************
1010 ********************************************************************************
1011 */
1012AL_CommandHelper::AL_CommandHelper ()
1013 : fName ()
1014 , fInternalName ()
1015 , fCommandNumber (0)
1016{
1017}
1018
1019AL_CommandHelper::~AL_CommandHelper ()
1020{
1021}
1022
1023STDMETHODIMP AL_CommandHelper::get_Name (BSTR* pVal)
1024{
1025 if (pVal == NULL) {
1026 return E_INVALIDARG;
1027 }
1028 try {
1029 *pVal = CComBSTR (fName.c_str ()).Detach ();
1030 }
1031 CATCH_AND_HANDLE_EXCEPTIONS_IN_HRESULT_FUNCTION ()
1032 return S_OK;
1033}
1034
1035STDMETHODIMP AL_CommandHelper::get_InternalName (BSTR* pVal)
1036{
1037 if (pVal == NULL) {
1038 return E_INVALIDARG;
1039 }
1040 try {
1041 *pVal = CComBSTR (fInternalName.c_str ()).Detach ();
1042 return S_OK;
1043 }
1044 CATCH_AND_HANDLE_EXCEPTIONS_IN_HRESULT_FUNCTION ()
1045}
1046
1047STDMETHODIMP AL_CommandHelper::AppendSelfToMenu (HMENU menu, IDispatch* acceleratorTable)
1048{
1049 // MUST CALL SOME NEW - AS YET UNDEFEIND - MEMBER OF ACCELTABLE TO GET STRING FROM PRIVATE CMD NAME
1050 try {
1051 wstring suffix;
1052 if (acceleratorTable) {
1053 CComQIPtr<IALAcceleratorTable> at = acceleratorTable;
1054 if (at.p != NULL) {
1055 CComPtr<IDispatch> accelElt;
1056 ThrowIfErrorHRESULT (at->Lookup (CComBSTR (fInternalName.c_str ()), &accelElt));
1057 if (accelElt.p != NULL) {
1058#if qCompilerAndStdLib_altComPtrCvt2ComQIPtrRequiresExtraCast_Buggy
1059 CComQIPtr<IALAcceleratorElement> accelerator = (IDispatch*)accelElt;
1060#else
1061 CComQIPtr<IALAcceleratorElement> accelerator = accelElt;
1062#endif
1063
1064 AcceleratorModifierFlag modFlag = static_cast<AcceleratorModifierFlag> (0);
1065 ThrowIfErrorHRESULT (accelerator->get_ModifierFlag (&modFlag));
1066 WORD key = 0;
1067 ThrowIfErrorHRESULT (accelerator->get_Key (&key));
1068
1069 if (modFlag & eVIRTKEY) {
1070 suffix += L"\t";
1071 }
1072 if (modFlag & eCONTROL) {
1073 suffix += L"Ctrl+";
1074 }
1075 if (modFlag & eALT) {
1076 suffix += L"Alt+";
1077 }
1078 if (modFlag & eSHIFT) {
1079 suffix += L"Shift+";
1080 }
1081 if (modFlag & eVIRTKEY) {
1082 if (VK_F1 <= key and key <= VK_F12) {
1083 suffix += String::FromSDKString (Characters::CString::Format (Led_SDK_TCHAROF ("F%d"), key + 1 - VK_F1)).As<wstring> ();
1084 }
1085 else if (key == VK_SUBTRACT) {
1086 suffix += L"Num-";
1087 }
1088 else if (key == VK_ADD) {
1089 suffix += L"Num+";
1090 }
1091 else if (key == VK_RETURN) {
1092 suffix += L"Enter";
1093 }
1094 else if (key == VK_BACK) {
1095 suffix += L"Backspace";
1096 }
1097 else if (key == VK_TAB) {
1098 suffix += L"Tab";
1099 }
1100 else if (key == VK_DELETE) {
1101 suffix += L"Delete";
1102 }
1103 else if (key == VK_INSERT) {
1104 suffix += L"Insert";
1105 }
1106 else if ('A' <= key and key <= 'Z') {
1107 suffix.push_back (key);
1108 }
1109 else {
1110 suffix += L"(Unknown key)";
1111 }
1112 }
1113 }
1114 }
1115 }
1116 ::AppendMenu (menu, fCommandNumber == 0 ? MF_SEPARATOR : MF_STRING, fCommandNumber,
1117 String::FromSDKString ((fCommandNumber == 0 ? L"" : L"&") + fName + suffix).AsSDKString ().c_str ());
1118 return S_OK;
1119 }
1120 CATCH_AND_HANDLE_EXCEPTIONS_IN_HRESULT_FUNCTION ()
1121}
1122
1123/*
1124 ********************************************************************************
1125 ******************************* AL_UserCommandHelper ***************************
1126 ********************************************************************************
1127 */
1128AL_UserCommandHelper::AL_UserCommandHelper ()
1129{
1130}
1131
1132AL_UserCommandHelper::~AL_UserCommandHelper ()
1133{
1134}
1135
1136STDMETHODIMP AL_UserCommandHelper::put_Name (BSTR val)
1137{
1138 if (val == NULL) {
1139 return E_INVALIDARG;
1140 }
1141 try {
1142 fName = val;
1143 return S_OK;
1144 }
1145 CATCH_AND_HANDLE_EXCEPTIONS_IN_HRESULT_FUNCTION ()
1146}
1147
1148STDMETHODIMP AL_UserCommandHelper::put_InternalName (BSTR val)
1149{
1150 if (val == NULL) {
1151 return E_INVALIDARG;
1152 }
1153 try {
1154 fInternalName = val;
1155 return S_OK;
1156 }
1157 CATCH_AND_HANDLE_EXCEPTIONS_IN_HRESULT_FUNCTION ()
1158}
1159
1160/*
1161 ********************************************************************************
1162 **************************** ActiveLedIt_BuiltinCommand ************************
1163 ********************************************************************************
1164 */
1165ActiveLedIt_BuiltinCommand::ActiveLedIt_BuiltinCommand ()
1166{
1167}
1168
1169ActiveLedIt_BuiltinCommand::~ActiveLedIt_BuiltinCommand ()
1170{
1171}
1172
1173ActiveLedIt_BuiltinCommand* ActiveLedIt_BuiltinCommand::mk (const BuiltinCmdSpec& cmdSpec)
1174{
1175 // Careful to return object with ZERO ref count (like CreateInstance) - so person calling this guy - will
1176 // be in balance when he first grabs a ref! So - be careful about catching excpetions while filling in detail
1177 // on object.
1178 CComObject<ActiveLedIt_BuiltinCommand>* o = NULL;
1179 ThrowIfErrorHRESULT (CComObject<ActiveLedIt_BuiltinCommand>::CreateInstance (&o));
1180 try {
1181 o->fName = String::FromNarrowSDKString (cmdSpec.fCmdName).As<wstring> ();
1182 o->fInternalName = NormalizeCmdNameToInternal (String::FromNarrowSDKString (cmdSpec.fInternalCmdName).As<wstring> ());
1183 o->fCommandNumber = cmdSpec.fCmdNum;
1184 return o;
1185 }
1186 catch (...) {
1187 delete o;
1188 throw;
1189 }
1190}
1191
1192HRESULT ActiveLedIt_BuiltinCommand::FinalConstruct ()
1193{
1194 return S_OK;
1195}
1196
1197void ActiveLedIt_BuiltinCommand::FinalRelease ()
1198{
1199}
1200
1201/*
1202 ********************************************************************************
1203 ********************************** mkFontNameCMDName ***************************
1204 ********************************************************************************
1205 */
1206string mkFontNameCMDName (const SDKString& fontName)
1207{
1208 return kFontNameCMDPrefix + String::FromSDKString (fontName).AsNarrowSDKString ();
1209}
1210
1211/*
1212 ********************************************************************************
1213 **************************** GenerateBuiltinCommandsObject *********************
1214 ********************************************************************************
1215 */
1216CComPtr<IDispatch> GenerateBuiltinCommandsObject ()
1217{
1218 CComPtr<IDispatch> builtinCmds;
1219 CComObject<ActiveLedIt_StaticCommandList>* o = NULL;
1220 ThrowIfErrorHRESULT (CComObject<ActiveLedIt_StaticCommandList>::CreateInstance (&o));
1221 builtinCmds = o;
1222
1223 o->AppendBuiltinCmds (kAllCmds, kAllCmds + Memory::NEltsOf (kAllCmds));
1224 {
1225 const vector<SDKString>& fontNames = GetUsableFontNames ();
1226 Assert (fontNames.size () <= kLastFontNameCmd - kBaseFontNameCmd + 1);
1227 for (UINT i = 0; i < fontNames.size (); ++i) {
1228 UINT cmdNum = kBaseFontNameCmd + i;
1229 if (cmdNum > kLastFontNameCmd) {
1230 break; // asserted out before above - now just ignore extra font names...
1231 }
1232 ActiveLedIt_BuiltinCommand* c = ActiveLedIt_BuiltinCommand::mk (BuiltinCmdSpec (cmdNum, mkFontNameCMDName (fontNames[i]).c_str ()));
1233 c->SetName (String::FromSDKString (fontNames[i]).As<wstring> ());
1234 o->Append (c);
1235 }
1236 }
1237 return builtinCmds;
1238}
1239
1240/*
1241 ********************************************************************************
1242 *********************************** CmdObjOrName2Num ***************************
1243 ********************************************************************************
1244 */
1245UINT CmdObjOrName2Num (const VARIANT& cmdObjOrName)
1246{
1247 CComVariant c (cmdObjOrName);
1248 if (SUCCEEDED (c.ChangeType (VT_BSTR))) {
1249 wstring lookForCmdName = c.bstrVal == NULL ? wstring () : wstring (c.bstrVal);
1250 for (const BuiltinCmdSpec* i = kAllCmds; i != kAllCmds + Memory::NEltsOf (kAllCmds); ++i) {
1251 if (NormalizeCmdNameToInternal (String::FromNarrowSDKString ((*i).fInternalCmdName).As<wstring> ()) == lookForCmdName) {
1252 return (*i).fCmdNum;
1253 }
1254 }
1255
1256 if (lookForCmdName.length () > kFontNameCMDPrefix.length () and
1257 lookForCmdName.substr (0, kFontNameCMDPrefix.length ()) == String::FromNarrowSDKString (kFontNameCMDPrefix)) {
1258 const vector<SDKString>& fontNames = GetUsableFontNames ();
1259 Assert (fontNames.size () <= kLastFontNameCmd - kBaseFontNameCmd + 1);
1260 for (UINT i = 0; i < fontNames.size (); ++i) {
1261 UINT cmdNum = kBaseFontNameCmd + i;
1262 if (cmdNum > kLastFontNameCmd) {
1263 break; // asserted out before above - now just ignore extra font names...
1264 }
1265 if (lookForCmdName == NormalizeCmdNameToInternal (String::FromNarrowSDKString (mkFontNameCMDName (fontNames[i])).As<wstring> ())) {
1266 return cmdNum;
1267 }
1268 }
1269 }
1270
1271 // If not found in builtin cmd list - maybe a user command?
1272 UINT uCmdNum = 0;
1273 if (UserCommandNameNumberRegistry::Get ().Lookup (c.bstrVal, &uCmdNum)) {
1274 return uCmdNum;
1275 }
1276 }
1277 else if (SUCCEEDED (c.ChangeType (VT_DISPATCH))) {
1278 CComQIPtr<IALCommand> bicc = c.pdispVal;
1279 if (bicc.p == 0) {
1280 return 0;
1281 }
1282 else {
1283 HMENU hMenu = ::CreatePopupMenu ();
1284 try {
1285 ThrowIfErrorHRESULT (bicc->AppendSelfToMenu (hMenu, NULL));
1286 UINT cmdNum = ::GetMenuItemID (hMenu, 0);
1287 ::DestroyMenu (hMenu);
1288 return static_cast<WORD> (cmdNum);
1289 }
1290 catch (...) {
1291 ::DestroyMenu (hMenu);
1292 throw;
1293 }
1294 }
1295 }
1296 return 0;
1297}
1298
1299/*
1300 ********************************************************************************
1301 *********************************** CmdNum2Name ********************************
1302 ********************************************************************************
1303 */
1304wstring CmdNum2Name (UINT cmdNum)
1305{
1306 // regular builtin CMD
1307 for (const BuiltinCmdSpec* i = kAllCmds; i != kAllCmds + Memory::NEltsOf (kAllCmds); ++i) {
1308 if ((*i).fCmdNum == cmdNum) {
1309 return NormalizeCmdNameToInternal (String::FromNarrowSDKString ((*i).fInternalCmdName).As<wstring> ());
1310 }
1311 }
1312
1313 // Dynamic font name command
1314 if (kBaseFontNameCmd <= cmdNum and cmdNum <= kLastFontNameCmd) {
1315 const vector<SDKString>& fontNames = GetUsableFontNames ();
1316 size_t i = cmdNum - kBaseFontNameCmd;
1317 i = max (fontNames.size () - 1, i);
1318 i = max (fontNames.size (), i);
1319 return NormalizeCmdNameToInternal (String::FromNarrowSDKString (mkFontNameCMDName (fontNames[i])).As<wstring> ());
1320 }
1321
1322 // USER command
1323 wstring userCmdIntName;
1324 if (UserCommandNameNumberRegistry::Get ().Lookup (cmdNum, &userCmdIntName)) {
1325 return userCmdIntName;
1326 }
1327
1328 return wstring (); // no such CMD found...
1329}
#define AssertNotNull(p)
Definition Assertions.h:333
String is like std::u32string, except it is much easier to use, often much more space efficient,...
Definition String.h:201
nonvirtual SDKString AsSDKString() const
Definition String.inl:806