问题描述
我正在尝试为ATL COM对象构建日志记录窗口。我的目标是启动一个ATL CWorkerThread,它会打开一个模式对话框(从VS资源编译),该对话框包含一个子多行编辑框:
CLogProcessor实现IWorkerThreadClient接口:
class CLogProcessor : public IWorkerThreadClient
{
HANDLE m_hEvent;
HANDLE m_hLogReady;
CWorkerThread<Win32ThreadTraits> m_wtThread;
CMyDialog* m_pDlg;
public:
CLogProcessor();
~CLogProcessor();
HRESULT Execute(DWORD_PTR dwParam,HANDLE hObject);
HRESULT CloseHandle(HANDLE hHandle);
};
这是启动工作线程的Execute函数:
HRESULT CLogProcessor::Execute(DWORD_PTR dwParam,HANDLE hObject)
{
if (m_pDlg == 0)
{
m_pDlg = new CMyDialog();
m_pDlg->SetReadyHandle(m_hLogReady); //m_hLogReady is an event set at the end of InitDialog
m_pDlg->DoModal();
}
if (m_pDlg)
{
::ResetEvent(m_hLogReady);
delete m_pDlg;
m_pDlg = 0;
}
::ResetEvent(m_hEvent); //m_hEvent is the event which kicks off the thread
return S_OK;
}
这可以通过以下方式工作:当COM对象开始记录日志时,将创建工作线程并弹出模式对话框,并停留在该对话框中,直到其他代码关闭它为止。我想使用来自主客户端线程的日志信息字符串将消息发布到EditBox。
bool CLogProcessor::AddString(const string& strText,bool bCR)
{
if (m_pDlg)
{
string str = strText + (bCR ? "\r\n" : "");
std::wstring ws = std::wstring(str.begin(),str.end());
CWindow eb(m_pDlg->GetDlgitem(IDC_EDIT1)); //This is the EditBox
if (!eb.PostMessage(EM_REPLACESEL,(LParaM)ws.c_str()))
{
DWORD dwErr = 0;
const DWORD dwSize = 100 + 1;
WCHAR buffer[dwSize];
dwErr = GetLastError();
FormatMessage(FORMAT_MESSAGE_FROM_SYstem,dwErr,buffer,dwSize,NULL);
return false;
}
return true;
}
return false;
}
如果我用SendMessage()替换PostMessage(),那么事情就起作用了,并且日志字符串显示在EditBox中...但是它是同步的,这使拥有工作线程的点失去了作用。
但是PostMessage()失败,并显示“该消息只能用于同步操作。”
也许EditBox的EM_REPLACESEL消息不是向我的EditBox添加新行的正确消息?我想我可以在模式对话框中保留字符串的内部缓冲区,并轮询该字符串以查找要添加的新字符串,而不是使用Windows消息。
我愿意接受建议!
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)