CLR FORM接收窗口消息并处理. SendMessage WndProc RegisterWindowMessage

问题的引入:

我希望在程序中有一个日志输出的窗口。最简单的就是在FORM上放一个LISTVIEW。然后程序各地调用日志输出的时候,在这个LISTVIEW中可以将日志写上去。

就像

LogForm1->WriteLog("系统消息...");

但是...由于感觉Form比较重,因为输出日志的地方很多(可能漫山遍野都输出日志),而且还不是一个工程里,而且还不一定是Form程序。如果要求写日志就要别人include个LogForm1.h什么的也太过分了吧。

就像我有三个工程:

MainUI :界面展示

DataProc :数据和业务的处理

msql :mysql封装

其构建关系和依赖关系是mysql独立,DataProc依赖于mysql, MainUI依赖于DataProc。

出于洁癖的考虑,DataProc没有界面。MainUI中可以放一个输出日志的Form。

显然DataProc再扭过头来use MainUI实在是强人所难。

so,DataProc发送一个WindowsMessage给界面,通过SendMessage让界面展示就好了。

这里边涉及System::String转换,new一个buffer,然后由接收端收到后展示完free。

CmdbLog::CmdbLog(void *pHwnd,UINT wm_id)
{
	m_MainHwnd = (HWND)pHwnd;
	m_MessageID = wm_id;
}

void CmdbLog::WriteLog(System::String ^ pString,...array<System::Object ^>^pOArray)
{
	pin_ptr<const wchar_t> wch = PtrToStringChars(pString);
	char			*pc;
	int				 ipc;
	System::String ^ o;
	o = System::String::Format(pString,pOArray);

	ipc = wcslen(wch) + 1;
	ipc *= sizeof(wchar_t);
	pc	= new char[ipc];
	memcpy(pc,wch,ipc);

	::SendMessage(m_MainHwnd,m_MessageID,0,(LPARAM)pc);
}

主Form(LogForm中响应这个消息)


	const UINT wm_LogMessageID = ::RegisterWindowMessageA( "LOGEVENT" );
		[SecurityPermission(SecurityAction::Demand, Flags=SecurityPermissionFlag::UnmanagedCode)]
        virtual void WndProc( Message% m ) override   //重载窗口过程处理消息
        {
            if( m.Msg == wm_LogMessageID)
            {
				System::String^ m_sShowMessageString;


				m_sShowMessageString = gcnew System::String((const wchar_t*)(void*)m.LParam);
                MessageBox::Show(m_sShowMessageString); //接收自定义消息 并处理
				AddLogRow(m_sShowMessageString);
				delete [] (char*)(void*)m.LParam;	// 释放这个buffer
            }
            Form::WndProc( m );
        }
	m_vars->InitCmdbLog((void*)this->Handle,wm_LogMessageID);
void Form1::AddLogRow(System::String^ pString)
{
	array<System::String^> ^ pItem = pString->Split(',',':');
	array<System::String^> ^ps = gcnew array<System::String^>(2);
	System::Windows::Forms::ListViewItem^pListViewItem;


	if (pItem->Length > 1)
	{
		ps[0] = pItem[0];
		ps[1] = pString->Substring(pItem[0]->Length + 1,
			pString->Length - pItem[0]->Length -1);
	}
	else
	{
		ps[0] = "缺省";
		ps[1] = pString;
	}
	pListViewItem = gcnew System::Windows::Forms::ListViewItem(ps,-1);
	listView1->BeginUpdate();
	listView1->Items->Add(pListViewItem);
	listView1->EndUpdate();
}










你可能感兴趣的:(mysql,String,ListView,System,buffer,Forms)