コード例 #1
0
ファイル: Inside.cpp プロジェクト: Alexander-Shukaev/ConEmu
bool CConEmuInside::TurnExplorerTipPane(wchar_t (&szAddMsg)[128])
{
	bool bRepeat = false;
	int nBtn = IDCANCEL;
	DWORD_PTR nRc;
	LRESULT lSendRc;

	if (gnOsVer < 0x600)
	{
		// WinXP, Win2k3
		nBtn = IDYES; // MessageBox(L"Tip pane is not found in Explorer window!\nThis pane is required for 'ConEmu Inside' mode.\nDo you want to show this pane?", MB_ICONQUESTION|MB_YESNO);
		if (nBtn == IDYES)
		{

		#if 0

			HWND hWorker = GetDlgItem(mh_InsideParentRoot, 0xA005);

			#ifdef _DEBUG
			if (hWorker)
			{
				HWND hReBar = FindWindowEx(hWorker, NULL, L"ReBarWindow32", NULL);
				if (hReBar)
				{
					POINT pt = {4,4};
					HWND hTool = ChildWindowFromPoint(hReBar, pt);
					if (hTool)
					{
						//TBBUTTON tb = {};
						//lSendRc = SendMessageTimeout(mh_InsideParentRoot, TB_GETBUTTON, 2, (LPARAM)&tb, SMTO_NOTIMEOUTIFNOTHUNG, 500, &nRc);
						//if (tb.idCommand)
						//{
						//	NMTOOLBAR nm = {{hTool, 0, TBN_DROPDOWN}, 32896/*tb.idCommand*/};
						//	lSendRc = SendMessageTimeout(mh_InsideParentRoot, WM_NOTIFY, 0, (LPARAM)&nm, SMTO_NOTIMEOUTIFNOTHUNG, 500, &nRc);
						//}
						lSendRc = SendMessageTimeout(mh_InsideParentRoot, WM_COMMAND, 32896, 0, SMTO_NOTIMEOUTIFNOTHUNG, 500, &nRc);
					}
				}
			}
			// There is no way to force "Tip pane" in WinXP
			// if popup menu "View -> Explorer bar" was not _shown_ at least once
			// In that case, Explorer ignores WM_COMMAND(41536) and does not reveal tip pane.
			HMENU hMenu1 = GetMenu(mh_InsideParentRoot), hMenu2 = NULL, hMenu3 = NULL;
			if (hMenu1)
			{
				hMenu2 = GetSubMenu(hMenu1, 2);
				//if (!hMenu2)
				//{
				//	lSendRc = SendMessageTimeout(mh_InsideParentRoot, WM_MENUSELECT, MAKELONG(2,MF_POPUP), (LPARAM)hMenu1, SMTO_NOTIMEOUTIFNOTHUNG, 1500, &nRc);
				//	hMenu2 = GetSubMenu(hMenu1, 2);
				//}

				if (hMenu2)
				{
					hMenu3 = GetSubMenu(hMenu2, 2);
				}
			}
			#endif
		#endif

			//INPUT keys[4] = {INPUT_KEYBOARD,INPUT_KEYBOARD,INPUT_KEYBOARD,INPUT_KEYBOARD};
			//keys[0].ki.wVk = VK_F10; keys[0].ki.dwFlags = 0; //keys[0].ki.wScan = MapVirtualKey(VK_F10,MAPVK_VK_TO_VSC);
			//keys[1].ki.wVk = VK_F10; keys[1].ki.dwFlags = KEYEVENTF_KEYUP; //keys[0].ki.wScan = MapVirtualKey(VK_F10,MAPVK_VK_TO_VSC);
			//keys[1].ki.wVk = 'V';
			//keys[2].ki.wVk = 'E';
			//keys[3].ki.wVk = 'T';

			//LRESULT lSentRc = 0;
			//SetForegroundWindow(mh_InsideParentRoot);
			//LRESULT lSentRc = SendInput(2/*countof(keys)*/, keys, sizeof(keys[0]));
			//lSentRc = SendMessageTimeout(mh_InsideParentRoot, WM_SYSKEYUP, 'V', 0, SMTO_NOTIMEOUTIFNOTHUNG, 5000, &nRc);

			lSendRc = SendMessageTimeout(mh_InsideParentRoot, WM_COMMAND, EMID_TIPOFDAY/*41536*/, 0, SMTO_NOTIMEOUTIFNOTHUNG, 5000, &nRc);
			UNREFERENCED_PARAMETER(lSendRc);

			mb_InsidePaneWasForced = true;
			// Подготовим сообщение если не удастся
			wcscpy_c(szAddMsg, L"Forcing Explorer to show Tip pane failed.\nShow pane yourself and recall ConEmu.\n\n");
		}
	}

	if (nBtn == IDYES)
	{
		// Первая проверка
		mh_InsideParentWND = mh_InsideParentRel = NULL;
		m_InsideIntegration = ii_Auto;
		InsideFindShellView(mh_InsideParentRoot);
		if (mh_InsideParentWND && mh_InsideParentRel)
		{
			bRepeat = true;
			goto wrap;
		}
		// Если не нашли - задержка и повторная проверка
		Sleep(500);
		mh_InsideParentWND = mh_InsideParentRel = NULL;
		m_InsideIntegration = ii_Auto;
		InsideFindShellView(mh_InsideParentRoot);
		if (mh_InsideParentWND && mh_InsideParentRel)
		{
			bRepeat = true;
			goto wrap;
		}

		// Last chance - try to post key sequence "F10 Left Left Down Down Down Left"
		// This will opens popup menu containing "Tip of the day" menuitem
		// "Esc Esc Esc" it and post {WM_COMMAND,EMID_TIPOFDAY} again
		WORD vkPostKeys[] = {VK_ESCAPE, VK_ESCAPE, VK_ESCAPE, VK_RIGHT, VK_RIGHT, VK_RIGHT, VK_DOWN, VK_DOWN, VK_DOWN, VK_RIGHT, VK_ESCAPE, VK_ESCAPE, VK_ESCAPE, 0};

		// Go
		if (SendVkKeySequence(mh_InsideParentRoot, vkPostKeys))
		{
			// Try again (Tip of the day)
			lSendRc = SendMessageTimeout(mh_InsideParentRoot, WM_COMMAND, EMID_TIPOFDAY/*41536*/, 0, SMTO_NOTIMEOUTIFNOTHUNG, 5000, &nRc);
			// Wait and check again
			Sleep(500);
			mh_InsideParentWND = mh_InsideParentRel = NULL;
			m_InsideIntegration = ii_Auto;
			InsideFindShellView(mh_InsideParentRoot);
			if (mh_InsideParentWND && mh_InsideParentRel)
			{
				bRepeat = true;
				goto wrap;
			}
		}
	}

wrap:
	if (bRepeat)
	{
		mb_TipPaneWasShown = true;
	}
	return bRepeat;
}
コード例 #2
0
ファイル: Inside.cpp プロジェクト: Alexander-Shukaev/ConEmu
bool CConEmuInside::InsideFindShellView(HWND hFrom)
{
	wchar_t szClass[128];
	wchar_t szParent[128];
	wchar_t szRoot[128];
	HWND hChild = NULL;
	// Для WinXP
	HWND hXpView = NULL, hXpPlace = NULL;

	while ((hChild = FindWindowEx(hFrom, hChild, NULL, NULL)) != NULL)
	{
		// Нас интересуют только видимые окна!
		if (!IsWindowVisible(hChild))
			continue;

		// Windows 7, Windows 8.
		GetClassName(hChild, szClass, countof(szClass));
		if (lstrcmp(szClass, L"SHELLDLL_DefView") == 0)
		{
			GetClassName(hFrom, szParent, countof(szParent));
			if (lstrcmp(szParent, L"CtrlNotifySink") == 0)
			{
				HWND hParent = GetParent(hFrom);
				if (hParent)
				{
					GetClassName(hParent, szRoot, countof(szRoot));
					_ASSERTE(lstrcmp(szRoot, L"DirectUIHWND") == 0);

					mh_InsideParentWND = hParent;
					mh_InsideParentRel = hFrom;
					m_InsideIntegration = ii_Explorer;

					return true;
				}
			}
			else if ((gnOsVer < 0x600) && (lstrcmp(szParent, L"ExploreWClass") == 0))
			{
				_ASSERTE(mh_InsideParentRoot == hFrom);
				hXpView = hChild;
			}
		}
		else if ((gnOsVer < 0x600) && (lstrcmp(szClass, L"BaseBar") == 0))
		{
			RECT rcBar = {}; GetWindowRect(hChild, &rcBar);
			MapWindowPoints(NULL, hFrom, (LPPOINT)&rcBar, 2);
			RECT rcParent = {}; GetClientRect(hFrom, &rcParent);
			if ((-10 <= (rcBar.right - rcParent.right))
				&& ((rcBar.right - rcParent.right) <= 10))
			{
				// Нас интересует область, прилепленная к правому-нижнему углу
				hXpPlace = hChild;
			}
		}
		// Путь в этом (hChild) хранится в формате "Address: D:\users\max"
		else if ((gnOsVer >= 0x600) && lstrcmp(szClass, L"ToolbarWindow32") == 0)
		{
			GetClassName(hFrom, szParent, countof(szParent));
			if (lstrcmp(szParent, L"Breadcrumb Parent") == 0)
			{
				HWND hParent = GetParent(hFrom);
				if (hParent)
				{
					GetClassName(hParent, szRoot, countof(szRoot));
					_ASSERTE(lstrcmp(szRoot, L"msctls_progress32") == 0);

					mh_InsideParentPath = hChild;

					// Остается ComboBox/Edit, в который можно запихнуть путь, чтобы заставить эксплорер по нему перейти
					// Но есть проблема. Этот контрол не создается при открытии окна!

					return true;
				}
			}
		}

		if ((hChild != hXpView) && (hChild != hXpPlace))
		{
			if (InsideFindShellView(hChild))
			{
				if (mh_InsideParentRel && mh_InsideParentPath)
					return true;
				else
					break;
			}
		}

		if (hXpView && hXpPlace)
		{
			mh_InsideParentRel = FindWindowEx(hXpPlace, NULL, L"ReBarWindow32", NULL);
			if (!mh_InsideParentRel)
			{
				_ASSERTE(mh_InsideParentRel && L"ReBar must be found on XP & 2k3");
				return true; // закончить поиск
			}
			mh_InsideParentWND = hXpPlace;
			mh_InsideParentPath = mh_InsideParentRoot;
			m_InsideIntegration = ii_Explorer;
			return true;
		}
	}

	return false;
}
コード例 #3
0
ファイル: Inside.cpp プロジェクト: Alexander-Shukaev/ConEmu
// Вызывается для инициализации из Settings::LoadSettings()
HWND CConEmuInside::InsideFindParent()
{
	bool bFirstStep = true;
	DWORD nParentPID = 0;

	if (!m_InsideIntegration)
	{
		return NULL;
	}

	if (mh_InsideParentWND)
	{
		if (IsWindow(mh_InsideParentWND))
		{
			if (m_InsideIntegration == ii_Simple)
			{
				if (mh_InsideParentRoot == NULL)
				{
					// Если еще не искали "корневое" окно
					HWND hParent = mh_InsideParentWND;
					while (hParent)
					{
						mh_InsideParentRoot = hParent;
						hParent = GetParent(hParent);
					}
				}
				// В этом режиме занимаем всю клиентскую область
				_ASSERTE(mh_InsideParentRel==NULL);
				mh_InsideParentRel = NULL;
			}

			_ASSERTE(mh_InsideParentWND!=NULL);
			goto wrap;
		}
		else
		{
			if (m_InsideIntegration == ii_Simple)
			{
				DisplayLastError(L"Specified window not found");
				mh_InsideParentWND = NULL;
				goto wrap;
			}
			_ASSERTE(IsWindow(mh_InsideParentWND));
			mh_InsideParentRoot = mh_InsideParentWND = mh_InsideParentRel = NULL;
		}
	}

	_ASSERTE(m_InsideIntegration!=ii_Simple);

	if (mn_InsideParentPID)
	{
		PROCESSENTRY32 pi = {sizeof(pi)};
		if ((mn_InsideParentPID == GetCurrentProcessId())
			|| !GetProcessInfo(mn_InsideParentPID, &pi))
		{
			DisplayLastError(L"Invalid parent process specified");
			m_InsideIntegration = ii_None;
			mh_InsideParentWND = NULL;
			goto wrap;
		}
		nParentPID = mn_InsideParentPID;
	}
	else
	{
		PROCESSENTRY32 pi = {sizeof(pi)};
		if (!GetProcessInfo(GetCurrentProcessId(), &pi) || !pi.th32ParentProcessID)
		{
			DisplayLastError(L"GetProcessInfo(GetCurrentProcessId()) failed");
			m_InsideIntegration = ii_None;
			mh_InsideParentWND = NULL;
			goto wrap;
		}
		nParentPID = pi.th32ParentProcessID;
	}

	EnumWindows(EnumInsideFindParent, nParentPID);
	if (!mh_InsideParentRoot)
	{
		int nBtn = MsgBox(L"Can't find appropriate parent window!\n\nContinue in normal mode?", MB_ICONSTOP|MB_YESNO|MB_DEFBUTTON2);
		if (nBtn != IDYES)
		{
			mh_InsideParentWND = INSIDE_PARENT_NOT_FOUND;
			return mh_InsideParentWND; // Закрыться!
		}
		// Продолжить в обычном режиме
		m_InsideIntegration = ii_None;
		mh_InsideParentWND = NULL;
		goto wrap;
	}


	HWND hExistConEmu;
	if ((hExistConEmu = InsideFindConEmu(mh_InsideParentRoot)) != NULL)
	{
		_ASSERTE(FALSE && "Continue to create tab in existing instance");
		// Если в проводнике уже есть ConEmu - открыть в нем новую вкладку
		gpSetCls->SingleInstanceShowHide = sih_None;
		LPCWSTR pszCmdLine = GetCommandLine();
		LPCWSTR pszCmd = StrStrI(pszCmdLine, L" /cmd ");
		gpConEmu->RunSingleInstance(hExistConEmu, pszCmd ? (pszCmd + 6) : NULL);

		mh_InsideParentWND = INSIDE_PARENT_NOT_FOUND;
		return mh_InsideParentWND; // Закрыться!
	}

	// Теперь нужно найти дочерние окна
	// 1. в которое будем внедряться
	// 2. по которому будем позиционироваться
	// 3. для синхронизации текущего пути
	InsideFindShellView(mh_InsideParentRoot);

RepeatCheck:
	if (!mh_InsideParentWND || (!mh_InsideParentRel && (m_InsideIntegration == ii_Explorer)))
	{
		wchar_t szAddMsg[128] = L"", szMsg[1024];
		if (bFirstStep)
		{
			bFirstStep = false;

			if (TurnExplorerTipPane(szAddMsg))
			{
				goto RepeatCheck;
			}
		}

		//MessageBox(L"Can't find appropriate shell window!", MB_ICONSTOP);
		_wsprintf(szMsg, SKIPLEN(countof(szMsg)) L"%sCan't find appropriate shell window!\nUnrecognized layout of the Explorer.\n\nContinue in normal mode?", szAddMsg);
		int nBtn = MsgBox(szMsg, MB_ICONSTOP|MB_YESNO|MB_DEFBUTTON2);

		if (nBtn != IDYES)
		{
			mh_InsideParentWND = INSIDE_PARENT_NOT_FOUND;
			return mh_InsideParentWND; // Закрыться!
		}
		m_InsideIntegration = ii_None;
		mh_InsideParentRoot = NULL;
		mh_InsideParentWND = NULL;
		goto wrap;
	}

wrap:
	if (!mh_InsideParentWND)
	{
		m_InsideIntegration = ii_None;
		mh_InsideParentRoot = NULL;
	}
	else
	{
		GetWindowThreadProcessId(mh_InsideParentWND, &mn_InsideParentPID);
		// Для мониторинга папки
		GetCurrentDirectory(countof(ms_InsideParentPath), ms_InsideParentPath);
		int nLen = lstrlen(ms_InsideParentPath);
		if ((nLen > 3) && (ms_InsideParentPath[nLen-1] == L'\\'))
		{
			ms_InsideParentPath[nLen-1] = 0;
		}
	}

	return mh_InsideParentWND;
}
コード例 #4
0
ファイル: Inside.cpp プロジェクト: 2asoft/ConEmu
// Вызывается для инициализации из Settings::LoadSettings()
HWND CConEmuInside::InsideFindParent()
{
	bool bFirstStep = true;
	DWORD nParentPID = 0;
	PROCESSENTRY32 pi = {sizeof(pi)};
	EnumFindParentArg find = {};

	if (!m_InsideIntegration)
	{
		return NULL;
	}

	if (mh_InsideParentWND)
	{
		if (IsWindow(mh_InsideParentWND))
		{
			if (m_InsideIntegration == ii_Simple)
			{
				// We cover all client area of mh_InsideParentWND in this mode
				_ASSERTE(mh_InsideParentRel==NULL);
				mh_InsideParentRel = NULL;
			}

			_ASSERTE(mh_InsideParentWND!=NULL);
			goto wrap;
		}
		else
		{
			if (m_InsideIntegration == ii_Simple)
			{
				DisplayLastError(L"Specified window not found");
				SetInsideParentWND(NULL);
				goto wrap;
			}
			_ASSERTE(IsWindow(mh_InsideParentWND));
			SetInsideParentWND(mh_InsideParentRel = NULL);
		}
	}

	_ASSERTE(m_InsideIntegration!=ii_Simple);

	if (mn_InsideParentPID)
	{
		if ((mn_InsideParentPID == GetCurrentProcessId())
			|| !GetProcessInfo(mn_InsideParentPID, &pi))
		{
			DisplayLastError(L"Invalid parent process specified");
			m_InsideIntegration = ii_None;
			SetInsideParentWND(NULL);
			goto wrap;
		}

		nParentPID = mn_InsideParentPID;
	}
	else
	{
		PROCESSENTRY32 pi = {sizeof(pi)};
		if (!GetProcessInfo(GetCurrentProcessId(), &pi) || !pi.th32ParentProcessID)
		{
			DisplayLastError(L"GetProcessInfo(GetCurrentProcessId()) failed");
			m_InsideIntegration = ii_None;
			SetInsideParentWND(NULL);
			goto wrap;
		}

		nParentPID = pi.th32ParentProcessID;
	}

	// Do window enumeration
	find.nPID = nParentPID;
	::EnumWindows(EnumInsideFindParent, (LPARAM)&find);


	if (!find.hParentRoot)
	{
		int nBtn = MsgBox(L"Can't find appropriate parent window!\n\nContinue in normal mode?", MB_ICONSTOP|MB_YESNO|MB_DEFBUTTON2);
		if (nBtn != IDYES)
		{
			SetInsideParentWND(INSIDE_PARENT_NOT_FOUND);
			return mh_InsideParentWND; // Закрыться!
		}
		// Продолжить в обычном режиме
		m_InsideIntegration = ii_None;
		SetInsideParentWND(NULL);
		goto wrap;
	}

	mh_InitialRoot = find.hParentRoot;
	mn_InsideParentPID = nParentPID;

	HWND hExistConEmu;
	if ((hExistConEmu = InsideFindConEmu(find.hParentRoot)) != NULL)
	{
		_ASSERTE(FALSE && "Continue to create tab in existing instance");
		// Если в проводнике уже есть ConEmu - открыть в нем новую вкладку
		gpSetCls->SingleInstanceShowHide = sih_None;
		LPCWSTR pszCmdLine = GetCommandLine();
		CEStr lsArg;
		LPCWSTR pszCmd = pszCmdLine;
		while (0 == NextArg(&pszCmd, lsArg))
		{
			if (lsArg.OneOfSwitches(L"-runlist",L"-cmdlist"))
			{
				pszCmd = NULL; break;
			}
			else if (lsArg.OneOfSwitches(L"-run",L"-cmd"))
			{
				break;
			}
		}
		gpConEmu->RunSingleInstance(hExistConEmu, (pszCmd && *pszCmd) ? (pszCmd) : NULL);

		SetInsideParentWND(INSIDE_PARENT_NOT_FOUND);
		return mh_InsideParentWND; // Закрыться!
	}

	// Теперь нужно найти дочерние окна
	// 1. в которое будем внедряться
	// 2. по которому будем позиционироваться
	// 3. для синхронизации текущего пути
	InsideFindShellView(find.hParentRoot);

RepeatCheck:
	if (!isInsideWndSet() || (!mh_InsideParentRel && (m_InsideIntegration == ii_Explorer)))
	{
		wchar_t szAddMsg[128] = L"", szMsg[1024];
		if (bFirstStep)
		{
			bFirstStep = false;

			if (TurnExplorerTipPane(szAddMsg))
			{
				goto RepeatCheck;
			}
		}

		_wsprintf(szMsg, SKIPLEN(countof(szMsg)) L"%sCan't find appropriate shell window!\nUnrecognized layout of the Explorer.\n\nContinue in normal mode?", szAddMsg);
		int nBtn = MsgBox(szMsg, MB_ICONSTOP|MB_YESNO|MB_DEFBUTTON2);

		if (nBtn != IDYES)
		{
			SetInsideParentWND(INSIDE_PARENT_NOT_FOUND);
			return mh_InsideParentWND; // Закрыться!
		}
		m_InsideIntegration = ii_None;
		SetInsideParentWND(NULL);
		goto wrap;
	}

wrap:
	if (!isInsideWndSet())
	{
		m_InsideIntegration = ii_None;
	}
	else
	{
		GetWindowThreadProcessId(mh_InsideParentWND, &mn_InsideParentPID);
		// Для мониторинга папки
		GetCurrentDirectory(countof(ms_InsideParentPath), ms_InsideParentPath);
		int nLen = lstrlen(ms_InsideParentPath);
		if ((nLen > 3) && (ms_InsideParentPath[nLen-1] == L'\\'))
		{
			ms_InsideParentPath[nLen-1] = 0;
		}
	}

	return mh_InsideParentWND;
}