Zitat von
chrschn:
Was allerdings (noch) nicht funktioniert:
- [TAB] innerhalb des DLL-Fensters wechselt nicht den Focus innerhalb desselben, sondern springt zum nächsten Control der Hostanwendung
- Der Focuswechsel durch [TAB] in der Hostanwendung überspringt das DLL-Fenster
- MenuAccels im DLL-Fenster funktionieren nicht, also z. B. Button-Captions wie '&OK' können nicht mit [ALT]+[O] aktiviert werden
Eher zufällig bin ich noch auf eine Lösung für das letzte der genannten Probleme gestoßen, nämlich die Menu-Accelerators. Ich habe meine Prozedur zum anzeigen des
DLL-Fensters um einen var-Parameter erweitert. Dieser liefert der Host-Anwendung das
Handle des
DLL-Fensters zurück. In der
DLL sieht das so aus:
Delphi-Quellcode:
procedure ShowConfigDlg(const ID: Integer; const ParentWindow: THandle;
const Left: Integer; const Top: Integer; const Width: Integer;
const Height: Integer; var DlgHandle: THandle);
begin
if not Assigned(ConfigForm) then
begin
ConfigForm := TConfigForm.Create(NIL);
ConfigForm.ParentWindow := ParentWindow;
end;
DlgHandle := ConfigForm.Handle;
ConfigForm.Left := Left;
ConfigForm.Top := Top;
ConfigForm.Width := Width;
ConfigForm.Height := Height;
ConfigForm.Visible := true;
end;
exports ShowConfigDlg;
Wenn das
DLL-Fenster angezeigt wird, dann weise ich in der Host-Anwendung die Eigenschaft Application.DialogHandle zu (siehe Delphi-Hilfe von TApplication.DialogHandle). Der Code der Host-Anwendung:
Delphi-Quellcode:
type
TShowConfigDlgProc =
procedure(
const ID: Integer;
const ParentWindow: THandle;
const Left: Integer;
const Top: Integer;
const Width: Integer;
const Height: Integer;
var DlgHandle: THandle);
var
ShowCfgDlg: TShowConfigDlgProc;
DlgHandle,
Handle: THandle;
begin
Handle := LoadLibrary(PChar(FileName));
@ShowCfgDlg := GetProcAddress(fHandle, '
ShowConfigDlg');
ShowConfigDlg(ConfigPanel.Handle, 0, 0, ConfigPanel.ClientWidth,
ConfigPanel.ClientHeight, DlgHandle);
Application.DialogHandle := DlgHandle;
end;
Und siehe da -- die MenuAccels funktionieren
. Das TApplicationEvents-Objekt auf dem Form der Host-Anwendung ist aber immer noch nötig, wie schon zuvor beschrieben. Wenn das
DLL-Fenster wieder ausgeblendet wird, muss Application.DialogHandle := 0 gesetzt werden.
Den Umweg über das hin- und her mit dem
Handle muss man leider gehen. Wenn in der
DLL die
Unit "Forms" eingebunden wird und dort Application.DialogHandle gesetzt wird, funktioniert es scheinbar nicht. Ich vermute mal, weil die höhere Instanz (in dem Fall die Host-Anwendung) die Message-Queue für die
DLL entsprechend anpassen muss, und nicht umgekehrt.
Schönen Gruß,
Christian