高手求教:VCL 的怪现象
说明:该问题原登录在大富翁论坛上,却少有人答复,只得再求救于 CSDN
的高手了....
===================================================================
MDI 应用,一个子窗体,是作为容器用的,加载的内容同样是一个窗体,
不过是在 DLL 中。基本过程如下:
1、子窗体调用入口(D5E):
function ShowDllForm(hParentWnd: HWND, ...): HWND; stdcall;
{
DllForm := TDllForm.CreateParented(hParentWnd);
Result := DllForm.Handle;
...
}
2、主调用(BCB5E)
在子窗体 OnShow 及 OnResize 中同时处理,
其中 hDllWnd 为调用窗体(DLL窗体)的句柄:
HWND __fastcall XXXMDI::ShowDllForm(void)
{
HMODULE hDllModule = theApp->hDllModule;
HWND hWnd = NULL;
if (FAttachProject != NULL && hDllModule != NULL)
{
typedef HWND (DLL_PROC)(HWND, const char*, int);
DLL_PROC* lpDllProc = (DLL_PROC*)GetProcAddress(hDllModule, "ShowDllForm");
if (lpDllProc != NULL)
hWnd = (*lpDllProc)(Handle, AFileName.c_str(), dwFlag); }
}
return hWnd;
}
void __fastcall XXXMDI::OnFormResize(...)
{
//如果 DLL 窗体没有加载,则加载
if (hDllWnd == NULL)
hDllWnd = ShowDllForm();
//调整窗体大小
if (hDllWnd != NULL)
SetWindowPos(hDllWnd, HWND_TOP,
0, 0, ClientWidth, ClientHeight,
SWP_SHOWWINDOW);
}
问题说明:在加载及程序本身运行过程全部正常,在退出程序时,
如果先把 XXXMDI 子窗体关闭,然后再关闭主窗体,也正常,但
如果先不关闭该子窗体而直接关闭程序,则出错,看 CPU 调试,
出现调试地址的内容全部为 ??? 。要说明的是,出错肯定是在该
载有 DLL 的窗体上,其他过程全部正常。
现在调试点发现:
在 XXXMDI 子窗体关闭过程中,单步进行,一直能够进行到函数结束,
但随后就显示出错!用 try{}__finally{}也无法屏蔽,可以说已经是
系统内存读写错。为什么会这样呢???
还有一点:在 DEBUG 状态下,MDI 窗体的 OnResize 事件处理
的 DLL 窗口大小调整有效(即能正常最大化);而在 RELEASE
状态下,却发现 DLL 窗口总是不断被重新创建(很明显,所有
的状态全部被回复!真奇怪),而且根本不响应 SetWindowPos
函数的调整!
继续调试发现:
如果强制发出 WM_DESTROY,关闭每个窗体,则程序可以正常退出(调试状态),
即关闭子窗体过程中,先发 WM_CLOSE, 继续再发 WM_DESTROY。程序就完全正常了。
但 ---------- 更大的问题在后面(Release 状态):
1、如果 stack frames (C 编译) 关闭(未核选),则出现每次 MDI 窗体大小调整时,都会重新创建 DLL 窗体!而且窗体位置根本就不动(挂在右下脚,就是不能正常最大化);
2、如果打开全部 stack frames 选项,窗体最大最小化正常,但这时出现:
priviledge instruction 错误信息,叫什么?我还是第一次遇到,强制权限?
最后关闭程序时,出现无效内存调用!同以前一样!不知道为什么?
如果关闭 PASCAL 中的stack frames ,则出现 external exception XXXXXXXX,
外部异常!到这儿,可以肯定是 RTTI 出现问题,估计 BCB 在处理
DLL 中的 VMT 和应用中的 VMT 时,用了什么“VCL”的手法,
导致数据交换出现严重异常!VCL 在宿主问题上,到底有什么特殊
的方法(但显然是不安全的,或者说是不干净的!)呢?
==========================================================================
急死了,请教各位大侠帮帮我分析一下错误原因吧...