delphi 開發中遇到的DLL問題思考及解決方法

2021-06-12 17:33:04 字數 2989 閱讀 6169

最近在公司寫乙個外殼程式,呼叫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 工程標...