最近在公司寫乙個外殼程式,呼叫dll外掛程式把form嵌入到exe中的乙個panel中,其中遇到了不少的問題,大部分已經解決,還有幾個至今沒有找到解決方法,有待研究,也希望知道解決方法的富翁共享一下研究成果.
以下列出的問題及解決方法僅針對我寫的程式(dll外掛程式把form嵌入到exe中的乙個panel中),和自己的解決方法.
從遇到的問題看出,delphi封裝了太多的東西,有時候直接使用api會有意想不到的效果.
經驗:dll與exe之間的通訊應該全部使用訊息.
第乙個問題:tab鍵和enter鍵在dll的form中無效
原始程式:
//frmdll為dll中的form,frmexe為exe主窗體,下同
//下面的**為什麼直接引用exe中的form又引用dll中的form?只是為了方便閱讀,實際只是傳遞乙個控制代碼,下同
//panworkspace為exe中的乙個tpanel,dll中的窗體要嵌入其中
frmdll.windowstate := wsmaximized;
frmdll.borderstyle := bsnone;
windows.setparent(frmdll.handle,frmexe.panworkspace.handle);
發現tab及enter鍵在嵌入的form中無效,去掉
frmdll.borderstyle := bsnone;
後正常,但我不需要標題,就用api解決
frmdll.windowstate := wsmaximized;
setwindowlong(frmdll.handle,gwl_style,getwindowlong(frmdll.handle,gwl_style) and not (ws_caption or ws_thickframe));
windows.setparent(frmdll.handle,frmexe.panworkspace.handle);
其中ws_caption和ws_thickframe分別表示標題欄和邊框,問題解決.
第二個問題:dll窗體的resize
exe主窗體改變尺寸時,窗體中的panel也會跟著變(panel.align設為了alclient),但其中嵌入的dll窗體不會跟著變,解決方法:
//exe視窗接收訊息並改變子窗體大小
//fchildwindowlist為tlist,子窗體的結構資訊列表
type
//子窗體一些資訊的結構體
pforminfo = ^tforminfo;
tforminfo = record
handle : hwnd;
parent : hwnd;
style : hwnd;
end;
tfrmexe = class(tform)
private
procedure wmsize(var message:twmsize);message wm_size;
end;
procedure tfrmexe.wmsize(var message: twmsize);
//resize訊息
vari : integer;
rc : trect;
begin
inherited;
if getwindowrect(panworkspace.handle,rc) then
if assigned(fchildwindowlist) then
for i := 0 to fchildwindowlist.count - 1 do
setwindowpos(pforminfo(fchildwindowlist[i]).handle, 0,
0, 0, rc.right - rc.left, rc.bottom - rc.top,
swp_noactivate);
end;
第四個問題:speedbutton在dll中滑鼠離開不會恢復平面(showmodal時不會出現)(未解決)
speedbutton.flat設為真時,在dll中滑鼠離開不會恢復平面狀態,而showmodal時不會出現,不知道原因,應該是訊息處理得不好,不知道有沒有人解決過
又乙個焦點問題:焦點在dll窗體時,按alt+tab,對話方塊裡出來的程式中竟然沒有exe程式!
焦點在exe窗體上時沒問題,焦點在dll窗體上時,用alt+tab不會出現exe應用程式的圖示,切換到其它任務後,也不能用alt+tab切換回來!這是個比較大的bug,還未找到原因
用spy++看了一下,按下alt+tab鍵,窗體收到了乙個wm_cancelmode訊息,我想,既然焦點在exe窗體上時可以看到圖示,而在dll上看不到,那麼我在收到這個訊息時把焦點給設到exe上不就可以了?
事實證明這點是可行的,**如下:
tdllform = class(tform)
private
procedure wmcancelmode(var message : tmessage);message wm_cancelmode;
end;
procedure tdllform.wmcancelmode(var message: tmessage);
//處理alt+tab鍵彈出的對話方塊中沒有應用程式圖示問題
begin
setforegroundwindow(exeform.handle); //把exe窗體設為當前有焦點的窗體
end;
現在不論焦點在exe的窗體上還是dll的窗體上,按alt+tab出現的對話方塊中都有應用程式的圖示,但不同的是,焦點在exe的窗體上時按alt+tab,預設啟用的是下乙個應用程式,而焦點在dll窗體上時按alt+tab,預設啟用的是第乙個,也就是應用程式本身,實際啟用的是exe窗體.
雖然還是不怎麼習慣,但總算把它給弄出來了,以後有好的解決方法再貼上來.
hint的問題(未解決)
alt+tab解決了,但是那是鍵盤,滑鼠操作還是有問題
焦點在dll中時,用滑鼠點其它應用程式,失去焦點了,再按alt+tab,那個該死的應用程式圖示又沒了,焦慮中....
VC呼叫Delphi的DLL時遇到的問題及解決
在開發的過程,有時會遇到用vc呼叫delphi的dll的時候 1 呼叫過程 delphi的dll不是標準的dll,所以,vc呼叫時會有限制。大致包括過程 1 宣告指向函式的指標,並定義函式指標 typedef bool stdcall lpplatetemplatefun double pwchar...
delphi中dll運用的例子
dll工程檔案testdll.pas library testdll uses sysutils,classes,dllfrm in dllfrm.pas 輸出showdllmodalform,showdllform,showcalendar介面方法,以便外部程式呼叫 exports showdll...
Delphi中DLL庫的建立
在delphi環境中,編寫乙個dll同編寫乙個一般的應用程式並沒有太大的區別。事實上作為dll主體的dll函式的編寫,除了在記憶體 資源的管理上有所不同外,並不需要其它特別的手段。一般工程檔案的格式為 program 工程標題 uses 子句 程式體而dlls工程檔案的格式為 library 工程標...