![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
ActiveX библиотека [Delphi, Windows]
Jackers © (2005-04-07 15:47:00)Помогите пожалуйста!!! Имеется следующая функция в библиотеке ActiveX
HRESULT COpen (int comport_index),
а Делфи интерприетирует ее как
procedure PosOpen(nComPort: SYSINT); safecall;
В описании написано, что на выходе функция возвращает код завершения, т.е. HRESULT, а при работе, как с процедурой результат отследить невозможно. При HRESULT, отличным от нуля программа выдает ошибку типа Unknown OLE Error
Jackers (2005-04-12 12:12:00) [1]Вот еще одна интересная вещь: при просмотре библиотеки при помощи OLE/COM Object Viewer в описании диспинтерфейсов следующее:
[uuid(EFA160AC-6EBB-11D8-8ED8-B87A66FC103A),
helpstring("IAxECRClass98 Interface"),
dual]
dispinterface IAxECRClass98 {
properties:
methods:
...
[id(0x00000004), helpstring("method PosOpen")]
void PosOpen([in] int nComPort);
...};
А в описании интерфейсов:
[ odl,
uuid(EFA160AC-6EBB-11D8-8ED8-B87A66FC103A),
helpstring("IAxECRClass98 Interface"),
dual,
oleautomation]
interface IAxECRClass98 : IDispatch {
...
[id(0x00000004), helpstring("method PosOpen")]
HRESULT PosOpen([in] int nComPort);
...};
Кроме того в описании каких-то Inherited interfaces тоже присутствуют возвращаемые результаты
Jackers (2005-04-12 09:45:00) [2]Не могли бы вы подсказать, смогу ли я переделать имеющийся файл idl в TLB при помощи утилиты idl2pas? Заранее спасибо
Jackers (2005-04-12 09:43:00) [3]>>Jackers (11.04.05 10:16) [6]
>>> Набережных С. © (08.04.05 18:49) [5]
>>
>> Попроповал как вы говорили, но эффект тот же:
> Так не бывает.
Я имел в виду, что при изменении опций IDE, в результате TLB-файлик ничем не отличался от того, что был, т.е.
procedure PosOpen(nComPort: SYSINT); safecall;
А насколько я понял, должно было получиться:
function PosOpen(nComPort: SYSINT): HResult;
Набережных С. (2005-04-11 12:54:00) [4]
> Jackers (11.04.05 10:16) [6]
> > Набережных С. © (08.04.05 18:49) [5]
>
> Попроповал как вы говорили, но эффект тот же:
Так не бывает.
> Если пойти вторым путем, то должно так получиться?
Почти.
IAxECRClass98 = interface(IDispatch)
['{EFA160AC-6EBB-11D8-8ED8-B87A66FC103A}']
function PosOpen(nComPort: SYSINT): HResult; stdcall;
...
end
...
IAxECRClass98Disp = dispinterface
['{EFA160AC-6EBB-11D8-8ED8-B87A66FC103A}']
...
procedure PosOpen(nComPort: SYSINT); dispid 2;
...
end;
...
TAxECRClass98 = class(TOleControl)
...
public
function PosOpen(nComPort: SYSINT): HResult;
end;
...
function PosOpen(nComPort: SYSINT): HResult;
begin
// Result:=DefaultInterface.PosClose; ????
Result:=DefaultInterface.PosOpen(nComPort);
end;
Jackers (2005-04-11 10:16:00) [5]> Набережных С. © (08.04.05 18:49) [5]
Попроповал как вы говорили, но эффект тот же:
IAxECRClass98 = interface(IDispatch)
['{EFA160AC-6EBB-11D8-8ED8-B87A66FC103A}']
procedure PosClose; safecall;
...
end
....
IAxECRClass98Disp = dispinterface
['{EFA160AC-6EBB-11D8-8ED8-B87A66FC103A}']
..
procedure PosClose; dispid 2;
..
end;
...
TAxECRClass98 = class(TOleControl)
...
public
procedure PosClose;
end;
...
procedure TAxECRClass98.PosClose;
begin
DefaultInterface.PosClose;
end;
...
Если пойти вторым путем, то должно так получиться?
IAxECRClass98 = interface(IDispatch)
['{EFA160AC-6EBB-11D8-8ED8-B87A66FC103A}']
function PosOpen(nComPort: SYSINT): HResult; stdcall;
...
end
...
IAxECRClass98Disp = dispinterface
['{EFA160AC-6EBB-11D8-8ED8-B87A66FC103A}']
...
function PosOpen(nComPort: SYSINT): HResult; dispid 2;
...
end;
...
TAxECRClass98 = class(TOleControl)
...
public
function PosOpen(nComPort: SYSINT): HResult;
end;
...
function PosOpen(nComPort: SYSINT): HResult;
begin
Result:=DefaultInterface.PosClose;
end;
...
Набережных С. (2005-04-08 18:49:00) [6]
> Jackers (08.04.05 16:45) [4]
Дело в том, что после измениний указанных в [1] настроек нужно обязательно сменить открытый в IDE проект, либо закрыть открытый, если он есть, либо открыть нрвый.
Сделай так:
-Закрой открытый проект.
-Отметь пункт "Do not map", как написано в [1].
-Открой любой проект.
-После этого закрой текущий проект( File->Close all).
-И только теперь заново импортируй свой ActiveX.
Или можешь просто после изменения настройки перезапустить среду.
Jackers (2005-04-08 16:45:00) [7]Вот конкретно опыта работы с интерфейсами и нет, а первый способ не помог. Структура файла TLB никак не изменилась, т.е. я опять не могу отследить результат выполнения функции. А при изменении интерфейсов и диспинтерфейсов компилятор выдает ошибку уже в теле функции на
Result:=DefaultInterface.PosOpen(nComPort);
таким сообщением: неизвестній идентификатор DefaultInterface. Это вообще меня завело в тупик. Если можно, подскажите, где можно прочитать про эти интерфейсы.
Набережных С. (2005-04-08 14:09:00) [8]
> Jackers (08.04.05 13:31) [2]
Исправлять нужно и в объявлении интерфейсов, и диспинтерфесов, и в коде классов, где идет обращение к DefaultInterface, но тут нужны хотя-бы минимальный опыт работы с интерфейсами. Просто воспользуйся первым способом.
Jackers (2005-04-08 13:31:00) [9]Попробовал, но ничего не выходит, компилятор выдает ошибку функция function PosOpen(nComPort: SYSINT): HResult; stdcall; не найдена. Вот еще интересноая вещь: у меня есть некий файлик с расширением idl, в котором описаны методы этой библиотечки, так вот там все эти методы идут с типом HRESULT. Насколько я понял, это С++, но как его переделать в Delphi я не знаю. При импорте этой же библиотечки в Билдер он формирует точно такой же файлик, как и Делфи, т.е.
void __fastcall TAxECRClass98::PosOpen(int nComPort)
а проследить ошибки, возвращаемые функцией я не могу. Помогите, если можно пожалуйста.
Набережных С. (2005-04-07 16:58:00) [10]SafeCall - внутреннее дельфийское соглашение о вызовах. И его как раз можно применять к функциям, возвращающим тип HResult. Это соглашение применяется для включения внутренней дельфийской поддержки интерфейсов ISupportErrorInfo and IErrorInfo. Если объектом не реализуется ISupportErrorInfo, то и нет смысла использовать SafeCall для его методов.
Хотя ты в коде имеешь дело с процедурой, реально код компилятором генерится как для функции. И если внутри этой процедуры не будет возбуждено исключение, то в качестве результата будет возвращено S_OK, т.е. 0.
Судя по тексту сообщения этот ActiveX не поддерживает ISupportErrorInfo, следовательно SafeCall здесь бессмысленна. У тебя есть два пути:
1) Можно в опциях IDE(Tools->Environment options->Type library), в разделе SafeCall function mapping отметить пункт Do not map, после чего заново импортировать этот ActiveX.
2) Можно вручную внести исправления, убрав SafeCall. Приведенную выше процедуру нужно переправить так:
function PosOpen(nComPort: SYSINT): HResult; stdcall;