你好,当前我写了一个功能处理的DLL,DLL调用者通过DLL提供的接口CreateWnd()创建并返回窗体指针。代码大概是:extern "C" __declspec( dllexport ) CWnd * CreateWnd( bool ( * OnShare )( void * pContext , CWnd * pShareWnd , char * buffer , int size ) , void * pContext, BOOL bServerFlag = FALSE )
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
//创建窗口
CMainFrame * frame = new CMainFrame( );//CMainFrame 派生于CFrameWnd
return frame;
}
接着,在DLL中创建的框架会启动一个线程,线程中会另外创建一个窗体。//DLL中的框架会启动线程
::AfxBeginThread(CMainFrame::ClientThread, this);
//DLL中的线程函数创建窗体
void RCClient::CreateDisplay()
{
// Create the window
WNDCLASS wndclass;
wndclass.style = 0;
wndclass.lpfnWndProc = WndProc;//窗体的消息处理函数
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = NULL;
wndclass.hCursor = LoadCursor(NULL, MAKEINTRESOURCE(IDC_DOTCURSOR));
wndclass.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
wndclass.lpszMenuName = (const TCHAR *) NULL;
wndclass.lpszClassName = VWR_WND_CLASS_NAME; RegisterClass(&wndclass); const DWORD winstyle = WS_VSCROLL | WS_HSCROLL | WS_CHILDWINDOW;
m_hwnd = CreateWindow(VWR_WND_CLASS_NAME,
_T("远程桌面"),
winstyle,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT, // x-size
CW_USEDEFAULT, // y-size
m_hParentWin, // Parent handle
NULL, // Menu handle
NULL,
NULL);
//SetParent(m_hwnd, m_hParentWin);
ShowWindow(m_hwnd, SW_HIDE);
// record which client created this window
SetWindowLong(m_hwnd, GWL_USERDATA, (LONG) this);
}
问题在于,DLL所创建的框架的更新事件无法影响到DLL线程中创建的那个窗体,就是当框架最小化或给某个窗体挡住或发生ON_SIZE等重绘窗体事件时,CreateWindow()出来的那个窗体里显示的内容无法正常显示。但是这并不是CreateWindow()那个窗体无处理ON_PAINT事件,因为如果把CreateWindow()的窗体属性指定为WS_OVERLAPPED即创建的窗体不附加在框架上而是处于最顶层窗体的时候,窗体能正常显示。DLL的框架无作ON_PAINT()消息的处理,因为我不知道要重绘什么,我的理解是所有绘制操作已经交给了CreateWindow()出来的那个窗体了。请问我要怎么解决这个问题呀?
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
//创建窗口
CMainFrame * frame = new CMainFrame( );//CMainFrame 派生于CFrameWnd
return frame;
}
接着,在DLL中创建的框架会启动一个线程,线程中会另外创建一个窗体。//DLL中的框架会启动线程
::AfxBeginThread(CMainFrame::ClientThread, this);
//DLL中的线程函数创建窗体
void RCClient::CreateDisplay()
{
// Create the window
WNDCLASS wndclass;
wndclass.style = 0;
wndclass.lpfnWndProc = WndProc;//窗体的消息处理函数
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = NULL;
wndclass.hCursor = LoadCursor(NULL, MAKEINTRESOURCE(IDC_DOTCURSOR));
wndclass.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
wndclass.lpszMenuName = (const TCHAR *) NULL;
wndclass.lpszClassName = VWR_WND_CLASS_NAME; RegisterClass(&wndclass); const DWORD winstyle = WS_VSCROLL | WS_HSCROLL | WS_CHILDWINDOW;
m_hwnd = CreateWindow(VWR_WND_CLASS_NAME,
_T("远程桌面"),
winstyle,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT, // x-size
CW_USEDEFAULT, // y-size
m_hParentWin, // Parent handle
NULL, // Menu handle
NULL,
NULL);
//SetParent(m_hwnd, m_hParentWin);
ShowWindow(m_hwnd, SW_HIDE);
// record which client created this window
SetWindowLong(m_hwnd, GWL_USERDATA, (LONG) this);
}
问题在于,DLL所创建的框架的更新事件无法影响到DLL线程中创建的那个窗体,就是当框架最小化或给某个窗体挡住或发生ON_SIZE等重绘窗体事件时,CreateWindow()出来的那个窗体里显示的内容无法正常显示。但是这并不是CreateWindow()那个窗体无处理ON_PAINT事件,因为如果把CreateWindow()的窗体属性指定为WS_OVERLAPPED即创建的窗体不附加在框架上而是处于最顶层窗体的时候,窗体能正常显示。DLL的框架无作ON_PAINT()消息的处理,因为我不知道要重绘什么,我的理解是所有绘制操作已经交给了CreateWindow()出来的那个窗体了。请问我要怎么解决这个问题呀?
解决方案 »
- 如何让程序在vista和xp上都能运行?
- CString类的 Mid函数 ,如果发生异常,如何扑捉这个异常,谢谢.
- 运行到第4982次出错?? 为什么???
- 愁啊愁!毕业设计的问题!望高手指点!!
- 2个小时了,还是不知道哪的问题!!!
- 请问如何随机的显示数据库中的信息?VC6.0+Access+ado?
- ->>>在LISTCTRL中,如果有某行数据为异常,我想将这行数据标为红色,怎么办呢?!
- 完成端口的客户端异常断开检测
- 如何在一个主窗口下显示另一个不同风格的窗口?
- 在SDK中,获得一个文件大小或长度的API函数是多少?
- 数据库的!这个要怎么写?
- 在CHtmlView下如何添加或修改http请求头部的信息?
大概代码:
DLL接口接收到事件,开启线程://在DLL中的框架
LRESULT CMainFrame::OnStartThread(WPARAM wParam, LPARAM lParam)
{
static BOOL bOpened = FALSE;
if( !m_bIsServer && !bOpened)
{
m_pRCClient = new RCClient(this, this->GetSafeHwnd());
::AfxBeginThread(CMainFrame::ClientThread, this); }
return TRUE;
}
UINT CMainFrame::ClientThread(LPVOID pVoid)
{
CMainFrame *pMainFrame = (CMainFrame *)pVoid;
try
{
pMainFrame->m_pRCClient->Run();
}
catch (Exception &e)
{
e.Report();
delete pMainFrame->m_pRCClient;
} return TRUE;
}//RCClient是一个继承于线程的类。
void RCClient::Run()
{
CreateDisplay(); start_undetached();//RCClient内部的一个线程处理。 //这里就是线程内创建的窗体的消息循环了。
MSG msg;
try
{
while ( GetMessage(&msg, NULL, 0,0) )
{
if (msg.message == WM_QUIT)
{
break;
}
else if (msg.message == WM_CLOSE)
{
break;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
} catch (WarningException &e)
{
e.Report();
} catch (QuietException &e)
{
e.Report();
}
}
MSG msg;
while(GetMessage(&msg, NULL, 0,0) )
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
这些代码在
ClientConnection::WndProc(....)
{....
case WM_DESTROY:
...
PostQuitMessage(0);//找对位置,加这一行就搞定。
return 0;
...
}
MSG msg;
while(GetMessage(&msg, NULL, 0,0) )
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
这些代码在
ClientConnection::WndProc(....)
{....
case WM_DESTROY:
...
PostQuitMessage(0);//找对位置,加这一行就搞定。
return 0;
...
}
我已经把求救信发到你的EMAIL了,你有空时,记得救救我,指导指导下喽!