关于DLL中创建窗口,实现消息处理的问题

HeartHeart 2007-07-19 03:23:13
问题描述:我创建了一DLL工程,需要在DLL中创建一个窗口,然后实现其窗口消息处理。用InitMsgWindow注册窗口类、创建窗口,经过调试,创建窗口成功(g_wndMsg不为空,GetLastError返回0)。在窗口消息处理函数MyWinProc中需要对自定义消息SCS_MSG_DVBDATA等做处理。在DLL导出函数中模拟了一个函数MyFun,不断向窗口发送自定义消息和WM_TIMER消息。可是问题出来了,为何在调试过程中MyWinProc函数不响应呢?或者说窗口捕获不到任何消息了。请高手指教!急!!
HWND g_wndMsg;//用于保存消息窗口的句柄
BOOL InitMsgWindow()
{
//注册消息处理窗口类
WNDCLASS wc;
wc.style = CS_NOCLOSE|CS_HREDRAW | CS_VREDRAW; //窗口类型
wc.lpfnWndProc = (WNDPROC)MyWinProc; //消息处理的回调函数
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = AfxGetApp()->m_hInstance;
wc.hIcon = NULL;
wc.hCursor = NULL;
wc.hbrBackground = (HBRUSH )GetStockObject(BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = "MsgWindow";
if (!::RegisterClass(&wc))
return FALSE;
//创建消息处理窗口
g_wndMsg = ::CreateWindow("MsgWindow","",WS_OVERLAPPEDWINDOW,0,0,50,50,NULL,NULL,AfxGetApp()->m_hInstance,NULL);
long err = ::GetLastError();
if(!g_wndMsg)
return FALSE;
}

//窗口消息处理函数
LRESULT CALLBACK MyWinProc( HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam )
{
switch(message) {
case SCS_MSG_DVBCFG:
{
break;
}
case SCS_MSG_DVBDATA:
{
break;
}
default:
return DefWindowProc(hWnd,message,wParam,lParam);
}
return 0;
}

//DLL导出函数:
void MyFun()
{
for(int i=0;i<100;i++){
PostMessage(g_wndMsg,SCS_MSG_DVBDATA,NULL,NULL);
PostMessage(g_wndMsg,WM_TIMER,NULL,NULL);
}
}
...全文
556 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
HeartHeart 2007-07-19
  • 打赏
  • 举报
回复
多谢各位大哥指点,有些眉目了,呵呵
龙凤呈祥焱 2007-07-19
  • 打赏
  • 举报
回复
这样做,
不是在DLL中加一个线程循环,
而是调用DLL的这个函数(创建窗口那个)的时候,不直接创建窗口,而是创建一个线程,
然后在线程里面,先创建窗口,再进入消息循环。
这时,DLL的函数已经返回,不会阻塞调用者执行。窗口也有消息循环了。工作就正常了。那你随便发消息就可以了。
superarhow 2007-07-19
  • 打赏
  • 举报
回复
注意GetMessage的定义,它只能取本线程创建的窗口的消息。当然你可以把窗口创建也放到线程函数中。
HeartHeart 2007-07-19
  • 打赏
  • 举报
回复
Up,如果我在DLL加一个消息循环的处理,可否解决呢?思路:单独生成一个线程,然后在该线程里进行消息循环处理,代码如下:

DWORD ThdDealMessage(LPDWORD param)
{
MSG Msg;
while (::GetMessage(&Msg,NULL,0,0)) {
//处理SCS_MSG_DVBDATA消息
if(Msg.message == SCS_MSG_DVBDATA){
// Do Something
}
if(Msg.message == WM_TIMER){
// Do Something
}

// TranslateMessage(&Msg);
// DispatchMessage(&Msg);
}
return 0;
}
}

::CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)TimerThread,0,0,NULL);

可是结果还是失败啊。怎么回事?
superarhow 2007-07-19
  • 打赏
  • 举报
回复
即使Dll创建了窗口,主程序如果没有消息循环的话Dll的窗口过程也没有机会得到调用。
举个例子,你在exe里面写:
MyFunc();
Sleep(30000);
那么在这30秒钟内你的消息都不可能得到执行。
但如果你写:
MyFunc();
while ( GetMessage(0, 0, 0, &msg) ) {
DispatchMessage(&msg);
}
就可以得到执行。
当然如果主程序不是你自己写的就比较麻烦了,因为消息循环的代码很多种,甚至可以只取自己认识的窗口消息,忽略掉别的窗口的。

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧