Ejemplo n.º 1
0
BOOL CTRiASToolBar::OnCommand(WPARAM wParam, LPARAM lParam) 
{
#if !defined(_USE_SEC_CLASSES)
	{	// spezielle Behandlung des VK_RETURN in EditControl einer ComboBox
	HWND hFocusWnd = ::GetFocus();

		if (IsClass (hFocusWnd, "Edit")) {						// if it's an edit control:
			if (IDOK == wParam && 0 == lParam) {
			// VK_RETURN in EditTeil einer ComboBox
			UINT uiID = ::GetDlgCtrlID(hFocusWnd);
			HWND hWndCBox = ::GetParent(hFocusWnd);

				if (IsClass (hWndCBox, "ComboBox")) {
					uiID = ::GetDlgCtrlID (hWndCBox);

				// der ComboBox den Event schicken
					if (OnCmdMsg(uiID, CBN_HITRETURN, NULL, NULL))
						return true;
				}
			}
		}
	}
#endif // _USE_SEC_CLASSES

	return SECCustomToolBar::OnCommand(wParam, lParam);
}
Ejemplo n.º 2
0
String TPropertyHandler::GetAllNamesValues(TComponent* comp)
{
	String list;
	TStringList *tempList = new TStringList;
	try
	{
		tempList->Sorted = true;

		PTypeInfo TypeInfo = (PTypeInfo)comp->ClassInfo();
		PPropInfo* PropList = new TPropList;
		GetPropInfos(TypeInfo, (PPropList)PropList);

		String data;
		for (int i=0; i < PropertyCount(comp); i++)
		{
			String prName = String(PropList[i]->Name);
			if (PropIsType(comp, prName, tkMethod)) continue; // Skip events.
			if (IsClass(comp, prName))
			{	data = GetClassNamesValues(comp, prName); }
			else data = BuildNameValue(comp, prName);
			if (!data.IsEmpty()) tempList->Append( data );
		}

		delete[] PropList;
		list = tempList->Text;
	}
	__finally
	{
		delete tempList;
	}
	return list;
}
Ejemplo n.º 3
0
Variant TPropertyHandler::GetValue(TComponent* comp, String prName)
{
	if (!PropertyExists(comp, prName)) return NULL;
	if (IsClass(comp, prName)) return NULL;
	return GetPropValue(comp, prName, true);
	// Parameter true: Strings are preferred returntype (see TypeInfo.pas).
}
JBoolean
CBSymbolList::IsUniqueClassName
	(
	const JCharacter*	name,
	CBLanguage*			lang
	)
	const
{
	const JSize symCount  = itsSymbolList->GetElementCount();
	const SymbolInfo* sym = itsSymbolList->GetCArray();

	JBoolean found = kJFalse;
	for (JIndex i=0; i<symCount; i++)
		{
		if (IsClass(sym[i].type) &&
			JStringCompare(*(sym[i].name), name, CBIsCaseSensitive(sym[i].lang)) == 0)
			{
			if (!found)
				{
				found = kJTrue;
				*lang = sym[i].lang;
				}
			else
				{
				return kJFalse;
				}
			}
		}

	return found;
}
Ejemplo n.º 5
0
Archivo: Err.cpp Proyecto: 3dik/MPong
//Set
bool Err::Set (wstring sErr)
{
    if (sErr.empty ())
    {
        sErr = L"Error text not specified";
    }

    if (m_pMainErr == NULL) //This object is the main error object
    {
        OPut (L"Error: " + sErr);
        m_bError = true;
        return false;
    }
    if (!IsClass ())
    {
        m_pMainErr->Set (sErr); //The class error object process further
        return false;
    }

    m_pMainErr->GetMain ()->Set (m_sClassName +
                                 L"->" +
                                 m_lsFunctions.back () +
                                 L" : " +
                                 sErr);
    return false;
}//Set
Ejemplo n.º 6
0
Archivo: Err.cpp Proyecto: 3dik/MPong
//~Err
Err::~Err ()
{
    if (!IsClass () && m_pMainErr != NULL)
    {
        m_pMainErr->KickFunction ();
    }
}//~Err
Ejemplo n.º 7
0
  void UlamTypeInfo::PrintPretty(ByteSink & bs) const
  {
    bs.Printf("%s",GetPrettyPrefixFromCategory(m_category));

    if (IsPrimitive()) m_utip.PrintPretty(bs);
    else if (IsClass()) m_utic.PrintPretty(bs);
    else FAIL(ILLEGAL_STATE);
  }
Ejemplo n.º 8
0
BOOL Binder::IsElementType(MethodTable *pMT, CorElementType type)
{
    BinderClassID id = (BinderClassID) (type + CLASS__MSCORLIB_COUNT + kLastException);

    _ASSERTE(GetClassName(id) != NULL);

    return IsClass(pMT, id);
}
Ejemplo n.º 9
0
BOOL CShortcutManager::IsClass(HWND hWnd, LPCTSTR szClass)
{
	if (hWnd)
	{
		return IsClass(szClass, GetClass(hWnd));
	}

	return FALSE;
}
Ejemplo n.º 10
0
BOOL CShortcutManager::IsEditControl(HWND hWnd)
{
	CString sClass = GetClass(hWnd);

	if (IsRichEditControl(sClass))
	{
		return TRUE;
	}

	return IsClass(sClass, WC_EDIT);
}
Ejemplo n.º 11
0
Archivo: Err.cpp Proyecto: 3dik/MPong
//AddFunction
void Err::AddFunction (wstring sName)
{
    if (!IsClass ())
    {
        return;
    }
    if (sName.empty ())
    {
        sName = L"Unspecified";
    }

    m_lsFunctions.push_back (sName);
}//AddFunction
Ejemplo n.º 12
0
// Checks if this object matches with the specified object_node.
// Also keeps wildcards in consideration. Used for triggers.
bool
Object::MatchNode(object_node* node) const
{
	if (IsName(node->name)
		&& IsClass(node->classs)
		&& IsRace(node->race)
		&& IsAlignment(node->alignment)
		&& IsGender(node->gender)
		&& IsGeneral(node->general)
		&& IsSpecific(node->specific)
		&& IsEnemyAlly(node->ea))
		return true;

	return false;
}
Ejemplo n.º 13
0
string FieldBinding::GetFullType() const
{
  string type = GetType();

  if (IsClass())
  {
    type = string("class:") + type;
  }

  if (IsRepeated())
  {
    type = string("vector<") + type + ">";
  }

  return type;
}
Ejemplo n.º 14
0
/**
	setSlot( CLASS:Class, POSITION:Small, METHOD:Method )
	
	1. 	The method is inserted into the correct position in the class's
		slot array. To start with, only one method per slot will be
		permitted.
		
	2.	A call to setMethod is then made with an unsafe access function
		as the method's function. The values are passed on the stack. 
		No stack checks are needed as the size of the argument lists of
		the two functions are the same.
*/
Ref * sysSetSlot( Ref * pc, MachineClass * vm ) {
	if ( vm->count != 3 ) throw Ginger::Mishap( "Wrong number of arguments" );

	Ref method = vm->fastPop();
	Ref position = vm->fastPop();
	Ref gclass = vm->fastPop();

	if ( !IsMethod( method ) ) throw Ginger::Mishap( "Method needed" ).culprit( "Method", refToString( method ) );
	if ( !IsSmall( position ) ) throw Ginger::Mishap( "Small needed" ).culprit( "Position", refToString( position ) );
	if ( !IsClass( gclass ) ) throw Ginger::Mishap( "Class needed" ).culprit( "Class", refToString( gclass ) );
	
	long pos = SmallToLong( position );
	long nfields = SmallToLong( RefToPtr4( gclass )[ CLASS_OFFSET_NFIELDS ] );
	if ( not( 1 <= pos && pos <= nfields ) ) {
		throw 
			Ginger::Mishap( "Position out of range" ).
			culprit( "Position", pos ).
			culprit( "Number of fields", nfields )
		;
	}
	
	//	Update the class-slot.
	INDEX( INDEX( gclass, CLASS_OFFSET_SLOTS ), pos ) = method;

	//	Push onto the stack to get protection from garbage collection.
	vm->fastPush( gclass );
	vm->fastPush( method );

	//	ENDFUNCTION does not in fact cause a garbage collection, as it
	//	forces the heap to grow. However this is a more accurate way
	//	to write the code. 
	//
	//	The following block should not be in-lined but extracted as a 
	//	service function.
	{
		CodeGen codegen = vm->codegen();
		//	TODO: Supply a useful name.
		codegen->vmiFUNCTION( 1, 1 );
		codegen->vmiFIELD( pos );
		codegen->vmiSYS_RETURN();
		vm->fastPush( codegen->vmiENDFUNCTION() );
	}

	//	We do not need to modify vm->count, it's already 3.
	//	Simply chain into sysSetMethod. 
	return sysSetMethod( pc, vm );
}
Ejemplo n.º 15
0
void TPropertyHandler::SetNameValue(TComponent* comp, String prName_Value)
{
	if (prName_Value.LastDelimiter("\r\n"))
	{  // Multi-line string, so call SetNamesValues():
		SetNamesValues(comp, prName_Value);
		return;
	}

	String name2, name1, value; // Reads like this: "name2.name1=value".
	int sep = prName_Value.Pos("=");

	String names = prName_Value.SubString(1, sep - 1);
	value = prName_Value.SubString(sep + 1, prName_Value.Length() - sep + 1);

	sep = names.Pos(".");
	if (sep)
	{	// Format is "propname.subprop=val":
		name1 = names.SubString(sep + 1, names.Length() - sep + 1);
		name2 = names.SubString(1, sep - 1);
		// name2 is the subcomp of comp.
		if (!IsPublishedProp(comp, name2)) // No warning.
		{  /*	name2 is not a component of comp,
				but it might be a component of its own,
				like CheckBox1 is a sub-component of Form1. */
			if ((comp = GetSubComponent(comp, name2)) == NULL) return;
			else
			{
				SetPropValue(comp, name1, value);
				return;
			}
		}
		if (!IsClass(comp, name2)) return;
		// Get pointer to subObj:
		TObject *subObj = (TObject *)GetOrdProp(comp, name2);
		if (subObj == NULL) return;

		SetPropValue(subObj, name1, value);
	}
	else
	{	// Format is "propname=val":
		SetPropValue(comp, names, value);
	}
}
Ejemplo n.º 16
0
tinyxml2::XMLElement* FieldBinding::GenerateWsdl(tinyxml2::XMLDocument* doc) const
{
  tinyxml2::XMLElement* el = doc->NewElement("xs:element");
  el->SetAttribute("name", m_name.c_str());

  if (IsEnum())
  {
    tinyxml2::XMLElement* restriction = doc->NewElement("xs:restriction");
    restriction->SetAttribute("base", "xs:string");

    for (size_t x = 0; x < m_enumValues.size(); ++x)
    {
      tinyxml2::XMLElement* enumeration = doc->NewElement("xs:enumeration");
      enumeration->SetAttribute("value", m_enumValues[x].c_str());
      restriction->LinkEndChild(enumeration);
    }
    el->LinkEndChild(restriction);
  }
  else
  {
    if (IsOptional())
    {
      el->SetAttribute("minOccurs", "0");
    }

    if (IsRepeated())
    {
      el->SetAttribute("maxOccurs", "unbounded");
    }

    if (IsClass())
    {
      el->SetAttribute("type", (string("bntypes:") + m_type).c_str());
    }
    else
    {
      el->SetAttribute("type", (string("xs:") + m_type).c_str());
    }
  }

	return el;
}
Ejemplo n.º 17
0
String TPropertyHandler::GetNamesValues(TComponent* comp, String prNames)
{
	String list, prop, name1, name2;
	int prop_start = 1, prop_end, sep;
	while (prop_start < prNames.Length())
	{
		// Extract (next) prop from props:
		prop_end = prNames.Pos(";"); // Find end of prop.
		if (!prop_end)
			prop_end = prNames.Length() + 1; // Last prop.
		else
			prNames[prop_end] = ' '; // Remove ';'.
		prop = prNames.SubString(prop_start, prop_end - prop_start);
		prop_start = prop_end + 1;

		// Get the value:
		if (!PropertyExists(comp, prop)) continue;
		if (IsClass(comp, prop))
			list = list + GetClassNamesValues(comp, prop) + "\n";
		else
			list = list + BuildNameValue(comp, prop) + "\n";
	}
	return list;
}
Ejemplo n.º 18
0
void
Bindable::ValidateWithEventsVarsInHandlesListsAndSynthesizePropertiesIfRequired()
{
    BCSYM_Container *ContainerOfHandlingMethods = CurrentContainer();

    if (!IsClass(ContainerOfHandlingMethods) &&
        !IsStructure(ContainerOfHandlingMethods) &&
        !IsStdModule(ContainerOfHandlingMethods))
    {
        return;
    }

    Symbols
        SymbolFactory(
            CurrentCompilerInstance(),
            CurrentAllocator(),
            NULL,
            CurrentGenericBindingCache());

    BCITER_CHILD Members(ContainerOfHandlingMethods);
    while(BCSYM_NamedRoot *Member = Members.GetNext())
    {
        // only method implementations can have handles clauses
        if (!Member->IsMethodImpl())
        {
            continue;
        }

        BCSYM_Proc *Proc = Member->PProc();
        BCITER_Handles iterHandles(Member->PMethodImpl());
        BCSYM_HandlesList *Handles = iterHandles.GetNext();

        if (!Handles)
        {
            continue;
        }

        ErrorTable *ErrorLog = CurrentErrorLog(Proc);

        for(;
            Handles;
            Handles = iterHandles.GetNext())
        {
            if (Handles->IsMyBase() ||
                Handles->IsEventFromMeOrMyClass())
            {
                continue;
            }

            bool FoundInBase;
            BCSYM_Variable *WithEventsVar =
                GetWithEventsVarReferredToInHandlesClause(
                    Handles,
                    FoundInBase);

            if (!WithEventsVar)
            {
                // "Handles clause requires a WithEvents variable."
                ReportErrorAtLocation(
                    ERRID_NoWithEventsVarOnHandlesList,
                    ErrorLog,
                    Handles->GetLocationOfWithEventsVar());

                Handles->SetIsBad();
            }
            else if (WithEventsVar->IsBad() ||
                     WithEventsVar->IsBadVariableType() ||   // the type of the variable is good, but is not a class or interface
                     WithEventsVar->GetType()->IsBad())      // the type of the variable is bad
            {
                // Any metadata errors on a symbol should be reported at the location
                // the symbol is used in source code
                //
                if (DefinedInMetaData(WithEventsVar->GetContainer()))
                {
                    VSASSERT( !DefinedInMetaData(CurrentContainer()),
                                    "How can Current Context for handles clauses not be in VB Source Code ?!");

                    WithEventsVar->ReportError(
                        CurrentCompilerInstance(),
                        ErrorLog,
                        Handles->GetLocationOfWithEventsVar());
                }

                Handles->SetIsBad();
            }
            else
            {
                // get the withevents property if possible
                BCSYM_Property *WithEventsProperty =
                    GetWithEventsPropertyForWithEventsVariable(WithEventsVar->PVariable());

                // Create it if it doesn't exist (for handling events defined on
                // WithEvent vars that exist on a base class).
                //
                if (!WithEventsProperty)
                {
                    VSASSERT(FoundInBase,
                                "Why do we have to synthesize a property for a withevents variable in the current class ? It should already have been synthesized in declared!!");

                    WithEventsProperty =
                        SynthesizeWithEventsProperty(WithEventsVar->PVariable(), SymbolFactory);

                    WithEventsProperty->SetCreatedByHandlesClause(Handles);
                }

                Handles->SetWithEventsProperty(WithEventsProperty);
            }
        }
    }
}
Ejemplo n.º 19
0
wxString TagEntry::FormatComment()
{
    if(m_isCommentForamtted) return m_formattedComment;
    m_isCommentForamtted = true;
    m_formattedComment.Clear();
    
    // Send the plugins an event requesting tooltip for this tag
    if(IsMethod()) {

        if(IsConstructor())
            m_formattedComment << wxT("<b>[Constructor]</b>\n");

        else if(IsDestructor())
            m_formattedComment << wxT("<b>[Destructor]</b>\n");

        TagEntryPtr p(new TagEntry(*this));
        m_formattedComment << wxT("<code>")
               << TagsManagerST::Get()->FormatFunction(p, FunctionFormat_WithVirtual | FunctionFormat_Arg_Per_Line)
               << wxT("</code>\n");
        m_formattedComment.Replace(GetName(), wxT("<b>") + GetName() + wxT("</b>"));
    } else if(IsClass()) {

        m_formattedComment << wxT("<b>Kind:</b> ");
        m_formattedComment << GetKind() << "\n";

        if(GetInheritsAsString().IsEmpty() == false) {
            m_formattedComment << wxT("<b>Inherits:</b> ");
            m_formattedComment << GetInheritsAsString() << wxT("\n");
        }

    } else if(IsMacro() || IsTypedef() || IsContainer() || GetKind() == wxT("member") ||
              GetKind() == wxT("variable")) {

        m_formattedComment << wxT("<b>Kind:</b> ");
        m_formattedComment << GetKind() << "\n";

        m_formattedComment << wxT("<b>Match Pattern:</b> ");

        // Prettify the match pattern
        wxString matchPattern(GetPattern());
        matchPattern.Trim().Trim(false);

        if(matchPattern.StartsWith(wxT("/^"))) {
            matchPattern.Replace(wxT("/^"), wxT(""));
        }

        if(matchPattern.EndsWith(wxT("$/"))) {
            matchPattern.Replace(wxT("$/"), wxT(""));
        }

        matchPattern.Replace(wxT("\t"), wxT(" "));
        while(matchPattern.Replace(wxT("  "), wxT(" "))) {
        }

        matchPattern.Trim().Trim(false);

        // BUG#3082954: limit the size of the 'match pattern' to a reasonable size (200 chars)
        matchPattern = TagsManagerST::Get()->WrapLines(matchPattern);
        matchPattern.Replace(GetName(), wxT("<b>") + GetName() + wxT("</b>"));
        m_formattedComment << wxT("<code>") << matchPattern << wxT("</code>\n");

    }

    // Add comment section
    wxString tagComment;
    if(!GetFile().IsEmpty()) {
        
        CommentParseResult comments;
        ::ParseComments(GetFile().mb_str(wxConvUTF8).data(), comments);
    
        // search for comment in the current line, the line above it and 2 above it
        // use the first match we got
        for(size_t i = 0; i < 3; i++) {
            wxString comment = comments.getCommentForLine(GetLine()-i);
            if(!comment.IsEmpty()) {
                SetComment(comment);
                break;
            }
        }
    }
    
    if(!GetComment().IsEmpty()) {
        wxString theComment;
        theComment = GetComment();

        theComment = TagsManagerST::Get()->WrapLines(theComment);
        theComment.Trim(false);
        wxString tagComment = wxString::Format(wxT("%s\n"), theComment.c_str());
        if(m_formattedComment.IsEmpty() == false) {
            m_formattedComment.Trim().Trim(false);
            m_formattedComment << wxT("\n<hr>");
        }
        m_formattedComment << tagComment;
    }

    // Update all "doxy" comments and surround them with <green> tags
    static wxRegEx reDoxyParam("([@\\\\]{1}param)[ \t]+([_a-z][a-z0-9_]*)?", wxRE_DEFAULT | wxRE_ICASE);
    static wxRegEx reDoxyBrief("([@\\\\]{1}(brief|details))[ \t]*", wxRE_DEFAULT | wxRE_ICASE);
    static wxRegEx reDoxyThrow("([@\\\\]{1}(throw|throws))[ \t]*", wxRE_DEFAULT | wxRE_ICASE);
    static wxRegEx reDoxyReturn("([@\\\\]{1}(return|retval|returns))[ \t]*", wxRE_DEFAULT | wxRE_ICASE);
    static wxRegEx reDoxyToDo("([@\\\\]{1}todo)[ \t]*", wxRE_DEFAULT | wxRE_ICASE);
    static wxRegEx reDoxyRemark("([@\\\\]{1}(remarks|remark))[ \t]*", wxRE_DEFAULT | wxRE_ICASE);
    static wxRegEx reDate("([@\\\\]{1}date)[ \t]*", wxRE_DEFAULT | wxRE_ICASE);
    static wxRegEx reFN("([@\\\\]{1}fn)[ \t]*", wxRE_DEFAULT | wxRE_ICASE);

    if(reDoxyParam.IsValid() && reDoxyParam.Matches(m_formattedComment)) {
        reDoxyParam.ReplaceAll(&m_formattedComment, "\n<b>Parameter</b>\n<i>\\2</i>");
    }

    if(reDoxyBrief.IsValid() && reDoxyBrief.Matches(m_formattedComment)) {
        reDoxyBrief.ReplaceAll(&m_formattedComment, "");
    }

    if(reDoxyThrow.IsValid() && reDoxyThrow.Matches(m_formattedComment)) {
        reDoxyThrow.ReplaceAll(&m_formattedComment, "\n<b>Throws</b>\n");
    }

    if(reDoxyReturn.IsValid() && reDoxyReturn.Matches(m_formattedComment)) {
        reDoxyReturn.ReplaceAll(&m_formattedComment, "\n<b>Returns</b>\n");
    }

    if(reDoxyToDo.IsValid() && reDoxyToDo.Matches(m_formattedComment)) {
        reDoxyToDo.ReplaceAll(&m_formattedComment, "\n<b>TODO</b>\n");
    }

    if(reDoxyRemark.IsValid() && reDoxyRemark.Matches(m_formattedComment)) {
        reDoxyRemark.ReplaceAll(&m_formattedComment, "\n  ");
    }

    if(reDate.IsValid() && reDate.Matches(m_formattedComment)) {
        reDate.ReplaceAll(&m_formattedComment, "<b>Date</b> ");
    }

    if(reFN.IsValid() && reFN.Matches(m_formattedComment)) {
        size_t fnStart, fnLen, fnEnd;
        if(reFN.GetMatch(&fnStart, &fnLen)) {
            fnEnd = m_formattedComment.find('\n', fnStart);
            if(fnEnd != wxString::npos) {
                // remove the string from fnStart -> fnEnd (including ther terminating \n)
                m_formattedComment.Remove(fnStart, (fnEnd - fnStart) + 1);
            }
        }
    }

    // if nothing to display skip this
    m_formattedComment.Trim().Trim(false);
    return m_formattedComment;
}
Ejemplo n.º 20
0
bool TPropertyHandler::IsClass(String prName)
{
	if (!DefaultComponentExists()) return false;
	return IsClass(FDefaultComponent, prName);
}
Ejemplo n.º 21
0
String TPropertyHandler::GetNameValue(TComponent* comp, String prName)
{
	if (!PropertyExists(comp, prName)) return "";
	if (IsClass(comp, prName)) return GetClassNamesValues(comp, prName);
	return BuildNameValue(comp, prName);
}
Ejemplo n.º 22
0
BOOL Binder::IsException(MethodTable *pMT, RuntimeExceptionKind kind)
{
    return IsClass(pMT, (BinderClassID) (kind + CLASS__MSCORLIB_COUNT));
}
Ejemplo n.º 23
0
BOOL CShortcutManager::IsRichEditControl(LPCTSTR szClass)
{
	return (IsClass(szClass, WC_RICHEDIT) || IsClass(szClass, WC_RICHEDIT20));
}
Ejemplo n.º 24
0
UINT CShortcutManager::ProcessMessage(const MSG* pMsg, DWORD* pShortcut) const
{
	// 只处理可用的快捷键
	if (!IsWindowEnabled() || !IsWindowVisible())
	{
		return FALSE;
	}

	// 只处理键盘消息
	if (pMsg->message != WM_KEYDOWN && pMsg->message != WM_SYSKEYDOWN)
	{
		return FALSE;
	}

	CWnd* pWnd = CWnd::FromHandle(pMsg->hwnd);

	CWnd* pMainWnd = GetCWnd();
	CWnd* pTopParent = pWnd->GetParentOwner();

	if (pTopParent != pMainWnd)
	{
		return FALSE;
	}

	switch (pMsg->wParam)
	{
	case VK_CONTROL:
	case VK_SHIFT:
	case VK_MENU:
	case VK_NUMLOCK:
	case VK_SCROLL:
	case VK_CAPITAL:
		return FALSE;

		// 不去处理 return/cancel 键
	case VK_RETURN:
	case VK_CANCEL:
		return FALSE;

	case VK_MBUTTON:
		break;

		// 快捷键
	default: 
		{
			//不去处理发往hotkey控件的消息
			if (IsClass(pMsg->hwnd, WC_HOTKEY))
			{
				return FALSE;
			}

			// get 获取快捷方式DWORD值
			BOOL bExtKey = (pMsg->lParam & 0x01000000);
			DWORD dwShortcut = GetShortcut((WORD)pMsg->wParam, bExtKey);

			// 查找相应的命令ID
			UINT nCmdID = 0;

			if (!m_mapShortcut2ID.Lookup(dwShortcut, nCmdID) || !nCmdID)
			{
				return FALSE;
			}

			if (m_wInvalidComb & HKCOMB_EDITCTRLS)
			{
				if (IsEditControl(pMsg->hwnd))
				{
					if (IsEditShortcut(dwShortcut))
					{
						return FALSE;
					}

					WORD wModifiers = HIWORD(dwShortcut);

					if (pMsg->wParam >= VK_F1 && pMsg->wParam <= VK_F24)
					{
						// ok
					}
					// 3. else must have <ctrl> or <alt>
					else
					{
						if (!(wModifiers & (HOTKEYF_ALT | HOTKEYF_CONTROL)))
						{
							return FALSE;
						}
					}
				}
			}

			// 返回 command ID
			if (m_bAutoSendCmds)
			{
				SendMessage(NULL, WM_COMMAND, nCmdID, 0);
			}

			if (pShortcut)
			{
				*pShortcut = dwShortcut;
			}

			return nCmdID;
		}
	}

	return FALSE;
}