2013-05-14 2 views
3

Ниже приведена DLL с XE3.ShowMessage в Delphi XE3 DllMain

library MyDLL; 

uses System.SysUtils, System.Classes, Vcl.Dialogs; 

{$R *.res} 

var 
    II: Integer; 

function Test: Integer; 
begin 
    Result := II; 
end; 

exports Test; 

begin 
    II := 5; 
    ShowMessage('DLL prolog'); 
end. 

Когда я вызываю функцию Test() из Delphi XE3 или Delphi программа 2007 я получаю правильный результат (5) в обоих случаях. Но сообщение «DLL пролог» отображается только с программой Delphi 2007, а не с программой Delphi XE3. Зачем?

Редактировать

И когда я "запустить" DLL из XE3 IDE с Delphi 2007 хост ShowMessage() также не работает.

+0

Вы пытались использовать стандартные окна ['MessageBox'] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms645505%28v=vs.85%29.aspx) вместо ? –

+0

Да 'MessageBox' работает нормально!? – Branko

+2

Вы знаете, что существуют серьезные ограничения на то, что вы можете сделать с DllMain? –

ответ

2

Ключа в этой функции:

function MessageDlgPosHelp(const Msg: string; DlgType: TMsgDlgType; 
    Buttons: TMsgDlgButtons; HelpCtx: Longint; X, Y: Integer; 
    const HelpFileName: string): Integer; 
begin 
    if TOSVersion.Check(6) and UseLatestCommonDialogs and 
    StyleServices.Enabled and StyleServices.IsSystemStyle then 
    Result := DoTaskMessageDlgPosHelp('', Msg, DlgType, Buttons, 
     HelpCtx, X, Y, HelpFileName) 
    else 
    Result := DoMessageDlgPosHelp(CreateMessageDialog(Msg, DlgType, Buttons), 
     HelpCtx, X, Y, HelpFileName); 
end; 

В некоторых случаях, в зависимости от того, имеет ли хост-приложение Comctl32 v6 манифест, различные ветви if заявлений выбраны.

Если вы выбрали ответвление DoTaskMessageDlgPosHelp, то следующий звонок TaskDialogIndirect не выполнен с HRESULT кодом $80070057. Это код ошибки Win32, ERROR_INVALID_PARAMETER.

Если выбрана ветка DoMessageDlgPosHelp, появится диалоговое окно.

Я не уверен, почему TaskDialogIndirect терпит неудачу при вызове из блока инициализации библиотеки, но я не совсем удивлен. Вы строго ограничены в том, что можно сделать с DllMain, и вы не должны пытаться показывать диалоги оттуда.

+0

Еще раз - спасибо! – Branko

+0

Да, это иллюстрированное ограничение DllMain – OnTheFly

+0

ComCtl32.TaskDialogIndirect вызывает ComCtl32.CTaskDialog.Show, который вызывает DUser.InitGadgets, который вызывает DUser.ResourceManager.InitContextNL. Последний явно проверяет, вызван ли он из DllMain, DUser.WinNT.IsInsideLoaderLock возвращает TRUE, поэтому вызывающий абонент возвращает жесткокодированный 0x80070057, который появляется до retvalue TaskDialogIndirect. – Alex