国产化的SSH工具VxTerm:C++中多线程中的子线程中的窗口form的实现

这是一个非常有趣的功能:在Widows中,是可以把子窗口在子线程中实例化并打开进行操作的,实现了子窗口的所有的操作,包括提示,都不会与主窗口和其它的子窗口产生影响,就像是一个独立的进程一样。

右边的主窗口中打开有多个会话实例窗口,同时每个窗口都在实时的接收不同的数据;左边有两个子窗口,一个在实时的下载文件,另一个窗口在操作时,完全不会影响到其它的窗口的运行。

其实,这是一个很让人奇怪的实现,在此之前,曾试过用.net来尝试,结果好像是不行,但当我在实现VxTerm的过程中,竟然发现C++ 中的MFC框架上,竟然是支持这样的窗口方式,这会造成一个奇怪的现象:

左边的那几个窗口实际上是在子线程中运行的,但鼠标和键盘在它们上的操作时,实际上是通过主线程去给它们发送消息的。

事实是,当我试着这么实现后,发现它的运行竟然是稳定的,不会崩溃!

而如果我们不这么去实现的话,除非是用多进程实例的方式去实现,否则窗口的modal提示之间是会互相影响,导致窗口之间的zorder、循环消息等就会互相影响。

比如,当我一开始我没有这么去实现这个子线程中的窗口时,当子窗口中有一个modal提示时,其它窗口就没法正常的响应鼠标、键盘的操作了。

而当我尝试着实现了这么一个子线程里的窗口后,一切都变得美好了,所有窗口之间的操作、提示都互不影响,非常完美!

实现方式:采用CWinThread实现

先写一个xCThreadForSftpFrm,我们需要用它来实例化一个子线程,同时把窗口的参数传递到这

个子线程中,在子线程开始运行后,由这个子线程来实例化一个窗口。

#pragma once



// xCThreadForSftpFrm

class xCThreadForSftpFrm : public CWinThread
{
	DECLARE_DYNCREATE(xCThreadForSftpFrm)

protected:
	xCThreadForSftpFrm();          

	virtual ~xCThreadForSftpFrm();
	int xWidth, xHeight;
	CWnd* xParent = 0;
	CString xIP;
	UINT xPort;
	string xUsername;
	string xPassword;
	CString xTitle;

public:
	virtual BOOL InitInstance();
	virtual int ExitInstance();

protected:
	DECLARE_MESSAGE_MAP()
		afx_msg void xExit(WPARAM wParam, LPARAM lParam);
public:
	xCThreadForSftpFrm(CWnd* xParent
		, const CString& xIP, const UINT& xPort, const string& xUsername, const string& xPassword, const CString& xTitle
		, const int& xWidth, const int& xHeight
	);
};

 在xCThreadForSftpFrm的InitInstance里,实例化一个已定义好的dialog,同时,必须要

return TRUE; //返回真,否则线程将会被中止退出。

BOOL xCThreadForSftpFrm::InitInstance()
{
	xFrmSftp * f=new xFrmSftp(this, xParent,xIP
		, xPort
		,xUsername
		, xPassword);
	f->xTitle =xTitle;
	f->Create(IDD_xFrmSftp);
	f->SetWindowPos(NULL, 0, 0, xWidth * 0.8, xHeight * 0.8, SWP_NOZORDER );
	f->ShowWindow(SW_SHOW);
	return TRUE;
}

 

调用的时候:

//一定要通过指针方式实例化这一个子线程类,这将会让它可以在当前过程结束后,变量t中的实例不会被清理回收
xCThreadForSftpFrm* t = new xCThreadForSftpFrm(
	this, IP()
	, Port()
	, UserName_s()
	, Password
	, L"sftp>会话名称"
	, xWidth, xHeight
)
	;
t->m_bAutoDelete = 1; //需要在后面的子窗口关闭后,做出子线程结束的操作,子线程就能自动被清理,否则会出现内存泄漏
t->CreateThread(); //开始吧。
xCThreadForSftpFrm中还需要接收窗口的关闭消息,然后通过AfxEndThread(0);结束当前线程

void xCThreadForSftpFrm::xExit(WPARAM wParam, LPARAM lParam)
{
	ExitInstance();
	AfxEndThread(0);
}

最终实现的效果,可以下载VxTerm,然后打开sftp就可以看到。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不了阁-飞哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值