Beispiel #1
0
// pRCon may be NULL, pszChars may be NULL
const ConEmuHotKey* CConEmuCtrl::ProcessHotKey(DWORD VkState, bool bKeyDown, const wchar_t *pszChars, CRealConsole* pRCon)
{
	UINT vk = ConEmuHotKey::GetHotkey(VkState);
	if (!(vk >= '0' && vk <= '9'))
		ResetDoubleKeyConsoleNum();

	const ConEmuHotKey* pHotKey = gpSetCls->GetHotKeyInfo(VkState, bKeyDown, pRCon);
	gpCurrentHotKey = pHotKey;

	if (pHotKey && (pHotKey != ConEmuSkipHotKey))
	{
		bool bEnabled = true;
		if (pHotKey->Enabled)
		{
			bEnabled = pHotKey->Enabled();
			if (!bEnabled)
			{
				pHotKey = NULL;
			}
		}

		if (pHotKey)
		{
			// Чтобы у консоли не сносило крышу (FAR может выполнить макрос на Alt)
			if (((VkState & cvk_ALLMASK) == cvk_LAlt) || ((VkState & cvk_ALLMASK) == cvk_RAlt))
			{
				if (pRCon && gpSet->isFixAltOnAltTab)
					pRCon->PostKeyPress(VK_CONTROL, LEFT_ALT_PRESSED, 0);
			}

			// Теперь собственно действие
			if (pHotKey->fkey)
			{
				bool bApps = (VkState & cvk_Apps) == cvk_Apps;
				if (bApps)
					gpConEmu->SkipOneAppsRelease(true);

				pHotKey->fkey(VkState, false, pHotKey, pRCon);

				if (bApps && !isPressed(VK_APPS))
					gpConEmu->SkipOneAppsRelease(false);
			}
			else
			{
				_ASSERTE(pHotKey->fkey!=NULL);
			}
		}
	}

	gpCurrentHotKey = NULL;

	return pHotKey;
}
Beispiel #2
0
// pRCon may be NULL, pszChars may be NULL
const ConEmuHotKey* CConEmuCtrl::ProcessHotKey(const ConEmuChord& VkState, bool bKeyDown, const wchar_t *pszChars, CRealConsole* pRCon)
{
	// For testing and checking purposes
	// User may disable "GuiMacro" processing with "ConEmu /NoHotkey"
	if (gpConEmu->DisableAllHotkeys)
	{
		return NULL;
	}

	UINT vk = VkState.Vk;
	if (!(vk >= '0' && vk <= '9'))
		ResetDoubleKeyConsoleNum();

	const ConEmuHotKey* pHotKey = gpSetCls->GetHotKeyInfo(VkState, bKeyDown, pRCon);
	gpCurrentHotKey = pHotKey;

	if (pHotKey == NULL && pRCon && pRCon->isSelectionPresent())
	{
		pHotKey = pRCon->ProcessSelectionHotKey(VkState, bKeyDown, pszChars);
	}

	if (pHotKey && (pHotKey != ConEmuSkipHotKey))
	{
		// For testing and checking purposes
		// User may disable "GuiMacro" processing with "ConEmu /NoMacro"
		if (pHotKey && gpConEmu->DisableAllMacro)
		{
			if ((pHotKey->HkType == chk_Macro) || (pHotKey->GuiMacro && *pHotKey->GuiMacro))
			{
				pHotKey = NULL;
			}
		}

		bool bEnabled = true;
		if (pHotKey && pHotKey->Enabled)
		{
			bEnabled = pHotKey->Enabled();
			if (!bEnabled)
			{
				pHotKey = NULL;
			}
		}

		if (pHotKey)
		{
			// Чтобы у консоли не сносило крышу (FAR может выполнить макрос на Alt)
			if (((VkState.Mod & cvk_ALLMASK) == cvk_LAlt) || ((VkState.Mod & cvk_ALLMASK) == cvk_RAlt))
			{
				if (pRCon && gpSet->isFixAltOnAltTab)
					pRCon->PostKeyPress(VK_CONTROL, LEFT_ALT_PRESSED, 0);
			}

			// Теперь собственно действие
			if (pHotKey->fkey)
			{
				bool bApps = (VkState.Mod & cvk_Apps) == cvk_Apps;
				if (bApps)
					gpConEmu->SkipOneAppsRelease(true);

				pHotKey->fkey(VkState, false, pHotKey, pRCon);

				if (bApps && !isPressed(VK_APPS))
					gpConEmu->SkipOneAppsRelease(false);
			}
			else
			{
				_ASSERTE(pHotKey->fkey!=NULL);
			}
		}
	}

	gpCurrentHotKey = NULL;

	return pHotKey;
}
Beispiel #3
0
// true - запретить передачу в консоль, сами обработали
// pRCon may be NULL, pszChars may be NULL
bool CConEmuCtrl::ProcessHotKeyMsg(UINT messg, WPARAM wParam, LPARAM lParam, const wchar_t *pszChars, CRealConsole* pRCon)
{
	_ASSERTE((messg == WM_KEYDOWN || messg == WM_SYSKEYDOWN) || (messg == WM_KEYUP || messg == WM_SYSKEYUP));

	WARNING("CConEmuCtrl:: Наверное нужно еще какие-то пляски с бубном при отпускании хоткеев");
	WARNING("CConEmuCtrl:: Ибо в CConEmuMain::OnKeyboard была запутанная логика с sm_SkipSingleHostkey, sw_SkipSingleHostkey, sl_SkipSingleHostkey");

	// Обновить и подготовить "r.Event.KeyEvent.dwControlKeyState"
	UpdateControlKeyState();

	DWORD vk = (DWORD)(wParam & 0xFF);
	bool bKeyDown = (messg == WM_KEYDOWN || messg == WM_SYSKEYDOWN);
	bool bKeyUp = (messg == WM_KEYUP || messg == WM_SYSKEYUP);

	if (mn_DoubleKeyConsoleNum && (!(vk >= '0' && vk <= '9')))
	{
		//if (!(vk >= '0' && vk <= '9'))
		//	ResetDoubleKeyConsoleNum();

		int nNewIdx = -1;
		// попытка активации одной кнопкой
		if (mn_DoubleKeyConsoleNum>='1' && mn_DoubleKeyConsoleNum<='9')
			nNewIdx = mn_DoubleKeyConsoleNum - '1';
		else if (mn_DoubleKeyConsoleNum=='0')
			nNewIdx = 9;

		ResetDoubleKeyConsoleNum();

		if (nNewIdx >= 0)
			gpConEmu->ConActivate(nNewIdx);
	}

	if (bKeyUp)
	{
		if ((mb_InWinTabSwitch && (vk == VK_RWIN || vk == VK_LWIN))
			|| (mb_InCtrlTabSwitch && (vk == VK_CONTROL || vk == VK_LCONTROL || vk == VK_RCONTROL)))
		{
			mb_InWinTabSwitch = mb_InCtrlTabSwitch = FALSE;
			gpConEmu->TabCommand(ctc_SwitchCommit);
			WARNING("CConEmuCtrl:: В фар отпускание кнопки таки пропустим?");
		}
	}

	// На сами модификаторы - действий не вешается
	if (vk == VK_LWIN || vk == VK_RWIN /*|| vk == VK_APPS*/
		|| vk == VK_SHIFT || vk == VK_LSHIFT || vk == VK_RSHIFT
		|| vk == VK_CONTROL || vk == VK_LCONTROL || vk == VK_RCONTROL
		|| vk == VK_MENU || vk == VK_LMENU || vk == VK_RMENU)
	{
		if (pRCon)
		{
			// Однако, если это был одиночный обработанный модификатор - его нужно "пофиксить",
			// чтобы на его отпускание не выполнился Far-макрос например
			if (bKeyUp)
			{
				FixSingleModifier(vk, pRCon);
			}
			else
			{
				_ASSERTE(bKeyDown);
				int ModCount = 0;
				if (bLAlt) ModCount++;
				if (bRAlt) ModCount++;
				if (bLCtrl) ModCount++;
				if (bRCtrl) ModCount++;
				if (bLShift || bRShift) ModCount++;

				if ((ModCount == 1) && (vk != VK_APPS) && (vk != VK_LWIN))
				{
					mb_LastSingleModifier = FALSE;
					mn_LastSingleModifier =
						(vk == VK_LMENU || vk == VK_RMENU || vk == VK_MENU) ? VK_MENU :
						(vk == VK_LCONTROL || vk == VK_RCONTROL || vk == VK_CONTROL) ? VK_CONTROL :
						(vk == VK_LSHIFT || vk == VK_RSHIFT || vk == VK_SHIFT) ? VK_SHIFT : 0;

					if (!mn_LastSingleModifier)
					{
						// Win и прочие модификаторы здесь не интересуют
					}
					else
					{
						mn_SingleModifierFixState = dwControlKeyState;
						switch (mn_LastSingleModifier)
						{
						case VK_MENU:
							mn_SingleModifierFixKey = VK_CONTROL;
							mn_SingleModifierFixState |= (LEFT_CTRL_PRESSED);
							break;
						case VK_CONTROL:
							mn_SingleModifierFixKey = VK_MENU;
							mn_SingleModifierFixState |= (RIGHT_ALT_PRESSED);
							break;
						case VK_SHIFT:
							mn_SingleModifierFixKey = VK_MENU;
							mn_SingleModifierFixState |= RIGHT_ALT_PRESSED;
							break;
						}
					}
				}
				else if (ModCount > 1)
				{
					// Больше не нужно
					mb_LastSingleModifier = FALSE;
					mn_LastSingleModifier = mn_SingleModifierFixKey = mn_SingleModifierFixState = 0;
				}
			}
		}
		return false;
	}

	ConEmuChord VkState = ChordFromVk(vk);

	if (bKeyDown)
		m_SkippedMsg = 0;

	const ConEmuHotKey* pHotKey = ProcessHotKey(VkState, bKeyDown, pszChars, pRCon);

	// Для "одиночных"
	if (pHotKey && mn_LastSingleModifier)
	{
		if (pHotKey != ConEmuSkipHotKey)
		{
			mb_LastSingleModifier = TRUE;
		}
	}
	else if (!pHotKey && !(VkState.Mod & (cvk_Ctrl|cvk_Alt|cvk_Shift)))
	{
		if (bKeyDown)
		{
			// Раз мы попали сюда - значит сам Apps у нас не хоткей, но может быть модификатором?
			if ((vk == VK_APPS) && gpSet->isModifierExist(vk))
			{
				m_SkippedMsg = messg; m_SkippedMsgWParam = wParam; m_SkippedMsgLParam = lParam;
				// Откладываем либо до
				// *) нажатия другой кнопки, не перехватываемой нами (например Apps+U)
				// *) отпускания самого Apps
				return ConEmuSkipHotKey;
			}
		}
		else if ((vk == VK_APPS) && m_SkippedMsg && pRCon)
		{
			// Отпускается Apps. Сначала нужно "дослать" в консоль ее нажатие
			pRCon->ProcessKeyboard(m_SkippedMsg, m_SkippedMsgWParam, m_SkippedMsgLParam, NULL);
		}
	}

	if (((VkState.Mod & cvk_ALLMASK) == cvk_Win)
		&& (vk == VK_DOWN || vk == VK_LEFT || vk == VK_RIGHT))
	{
		//120821 - в режиме HideCaption почему-то не выходит из Maximized по Win+Down
		if (gpSet->isCaptionHidden())
		{
			if (vk == VK_DOWN)
			{
				if (::IsZoomed(ghWnd)/*тут нужен реальный Zoomed*/)
				{
					gpConEmu->SetWindowMode(wmNormal);
				}
			}
		}
	}

	return (pHotKey != NULL);
}