透明控制台应用程序






4.18/5 (9投票s)
实现一个透明的控制台应用程序。
引言
你有没有见过那些漂亮的 Unix\Linux 透明终端,并想过 - 为什么我不能在 Windows 上拥有一个呢?
好吧,搜索结束了 - 实际上,还没有,还有一段路要走,但这将是一个很好的开始。
致谢
但首先,这篇文章(以及项目)是基于 The Code Project 网站上的文章和代码,我主要集成了这些代码。我将介绍我遇到的一些问题,但废话不多说,它们来了
实现说明
在编写这个小应用程序时,我遇到了一些问题,对于某些人来说,了解这些问题可能很有趣,这样他们\你就可以在将来避免它们(或更快地解决它们)。
将命令从组合框发送到 I\O 重定向器
你可能会期望一个ComboBox
有一个OnEnter
事件,不是吗?不,它没有。那么当您输入命令并想将其发送到控制台时该怎么办?这就是我做的方式
首先,我为事件处理程序提供了一个接口。处理程序在组合框上注册自己,并且可以处理诸如按键之类的事件。组合框的工作是在事件发生时调用处理程序的函数。在这种情况下,我处理了 ENTER 事件和 F1(当操作花费太长时间时重新启动控制台 - 有人说了“tracert”吗?)。
class Eventer
{
public:
Eventer(void);
virtual ~Eventer(void);
virtual void PerformAction(const CString& strCmd) = 0;
virtual void PerformSpecialAction(UINT nAction) = 0;
};
接下来要做的是继承接口并在组合框上注册
class CTConsoleView : public CFormView, Eventer
m_combo.Register(this);
现在我们需要捕捉像 ENTER 这样的事件并执行我们想要的操作 - 在这种情况下,将输入传递给控制台。另一个被捕获的事件是 F1 - 在组合框中处理 CTRL+C 比较困难,但你可能想模仿该命令的功能,因此捕获了 F1 - F12 键并可以处理。例如,我处理了 F1 来重新启动控制台。
BOOL CHMXComboBox::PreTranslateMessage(MSG* pMsg)
{
InitToolTip();
m_tt.RelayEvent(pMsg);
// catching the key down events
if (pMsg->message == WM_KEYDOWN)
{
// making sure we are going to auto complete
// what is written
m_bAutoComplete = TRUE;
int nVirtKey = (int) pMsg->wParam;
if (nVirtKey == VK_DELETE || nVirtKey == VK_BACK)
m_bAutoComplete = FALSE;
// On enter we call our eventer to perform
// it's job
if (nVirtKey == VK_RETURN)
{
CString sText;
GetWindowText(sText);
if(FindString(0,sText) == CB_ERR)
AddString(sText);
for(int i(0);i < m_arrEventers.GetSize(); i++)
{
Eventer* pEvent = (Eventer*)m_arrEventers[i];
// eventer performs action here
Event->PerformAction(sText);
}
}
// Use F1 - F12 keys on the console instead of CTRL+C etc'
if (nVirtKey >= VK_F1 && nVirtKey <= VK_F12)
{
for(int i(0);i < m_arrEventers.GetSize(); i++)
{
Eventer* pEvent = (Eventer*)m_arrEventers[i];
pEvent->PerformSpecialAction(nVirtKey);
}
}
}
最后,处理事件(例如,我们不希望将“edit”命令发送到控制台,因为cmd.exe进程会打开 DOS 编辑实用程序)。因此,为了覆盖它,我们必须对命令执行某种字符串解析。
void CTConsoleView::PerformAction(const CString& strCmd)
{
// if the user typed edit we do not want to open the
// edit utility on the cmd process.
if(!strCmd.Left(4).CompareNoCase("edit"))
{
CString cmd = "notepad.exe ";
cmd += strCmd.Right(strCmd.GetLength()-4);
WinExec(cmd, SW_SHOW);
return;
}
// otherwise we send it to the console
m_redir.Printf("%s\r\n", strCmd);
m_combo.SetWindowText("");
}
最终注释
嗯,我想现在就到此为止。如果您有任何问题,欢迎在评论部分提交或给我发电子邮件。
祝编码愉快。
阿萨。