請在DLL中使用過MDI窗體的朋友來看下!(200分)

  • 主题发起人 主题发起人 82625741
  • 开始时间 开始时间
8

82625741

Unregistered / Unconfirmed
GUEST, unregistred user!
我在系統中動態調用DLL中MDI窗體,如果主窗體只調用一個DLL的話就不會有地址錯誤,但如果你同時調用多個DLL的MDI窗體就會出現地址錯誤,並且不知是什么地址出錯,無法單調,請各位做過的朋友提示一下,都有哪些情況會出現這種錯誤!謝謝<br>動態庫調用方式如下<br>procedure ProdDllShow(PApplication: TApplication; PForm: TForm;FormName:String;FHandle:Hwnd;PCn:TSocketConnection;PUm:TUserMessage); export; stdcall;<br>begin<br> &nbsp; Application:=PApplication;<br> &nbsp; FormName := UpperCase(FormName);<br> &nbsp; FormHandle := FHandle;<br> &nbsp; Cn := PCn;<br> &nbsp; Um := PUm;<br> &nbsp; if not Assigned(Data) then<br> &nbsp; &nbsp; Data := TData.Create(nil);<br> &nbsp; if FormName='FRMPR_PRODMOSUBSEARCH' then<br> &nbsp; begin<br> &nbsp; &nbsp; if not Assigned(frmPR_ProdMOSubSearch) then<br> &nbsp; &nbsp; &nbsp; frmPR_ProdMOSubSearch := TfrmPR_ProdMOSubSearch.Create(PForm);<br> &nbsp; &nbsp; frmPR_ProdMOSubSearch.Show;<br> &nbsp; end;<br>end;<br>procedure DLLUnloadProc(Reason: Integer); register;<br>begin<br> &nbsp;if Reason = DLL_PROCESS_DETACH then<br> &nbsp;begin<br> &nbsp; &nbsp;if Assigned(frmPR_ProdMOSubSearch) then<br> &nbsp; &nbsp; &nbsp;frmPR_ProdMOSubSearch.Free;<br> &nbsp; &nbsp;Data.free;<br> &nbsp; &nbsp;Application := SaveApplication;<br> &nbsp;end;<br>end;<br>exports<br> &nbsp; ProdDllShow;<br>begin<br> &nbsp; SaveApplication := Application;<br> &nbsp; DllName := 'ProdDll';<br> &nbsp; DLLProc := @DLLUnloadProc;<br>end.
 
兄弟,你把参数中的FormName:String;变成pchar类型看看,<br>包好使
 
你把frmPR_ProdMOSubSearch定义成数组,每次调用都重新赋值,这样就可以了:<br>type<br> &nbsp;TfrmBaseForm = class of TForm;<br><br>frmPR_ProdMOSubSearch: Array[1..FMax] of TfrmBaseForm; <br><br>原因是只有FreeLibrary时才执行DLLUnloadProc,在没有释放DLL之前frmPR_ProdMOSubSearch只能赋值一次
 
TO:yanzhaozhizi<br>按老兄的說法,用戶不是每次點擊菜單都要新建一個?<br>我在窗體的destory事件中加入了frmPR_ProdMOSubSearch:=nil;這樣的話我每次點菜單都會去判斷一次frmPR_ProdMOSubSearch是否為空,如果是就新建,如果不是就顯示,這應該與老兄的方法一樣吧!如果不是,我要怎麼設定最大窗體數,不會是65536吧!
 
82,可是你是要同时打开多个MDI窗口呀,你那种方法单只判断是否为空就不行了<br>我的方法是,你建一个队列TStringlist,然后你把每次不同的打开不面的DLL及窗口写到里面,保存起来,你每次打开,就把相应的DLL名称和子窗口名称传递过去,如果在队列里发现发就不要再新建了,直接激活就成,如果没有,你再打开DLL窗口。<br>即然关闭一个DLL的子窗口没有问题,那问题肯定是出在上面了,这样就应该不会出现你那种错误提示了。如果关闭窗口你还要做的动作是要把队列TStringList的相关值也删除就OK了!
 
TO:ProLove<br>我在同一個DLL中是沒問題的,但如果我調用多個DLL就可能會出地址錯誤,但不一定會出錯,我想不是你所說的原因吧!
 
ProLove的说法与我的处理相同
 
是否是释放机制的问题?
 
要建一个队列TStringList,每次新增时自动加进队列,下次打开先在队列中找,没有就建.
 
為什么一定要建立一個隊列呢?沒有更好的方法嗎?我如果把打開的窗體一個個手動關閉是沒有任何問題的,只有在我打開多個窗體的時候直接關閉主程序才會出現地址錯誤!這應該不是隊列的問題吧!
 
把窗体Free改成FreeandNil呢?
 
TO:ProLove<br>不行,一樣的地址錯誤,如果只打開同一個DLL的多個MDI子窗體就不會報地址錯誤,但如果是同時打開多個DLL中多個MDI子窗體就會報地址錯誤!
 
現在發現,如果DLL中所打開的窗體沒有按顯示的先後順序關閉就會報錯誤,但如果是按先後順序關閉的話就不會,我試著在主窗體發送消息給DLL中的子窗體,但出現DLL接收不到的情況,系統一直處於循環等待狀態,但如果發送完消息就不管了,直接關閉主窗體就會出現地址錯誤?
 
謝謝各位,問題未解決,結貼了!
 
多人接受答案了。
 
后退
顶部