Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.08.07;
Скачать: CL | DM;

Вниз

_Release и VCL   Найти похожие ветки 

 
SeLarin ©   (2004-10-25 08:33) [0]

Привет, Мастера! Начал изучать COM и возникла проблема.
Есть код:

procedure TForm1.Button1Click(Sender: TObject);
var
 iShLnk: IShellLink;
 iPersFile: IPersistFile;
 Path: array[0..MAX_PATH] of Char;
 pfd: TWin32FindData;
 hr: HRESULT;
begin
 CoInitialize(nil);
 iShLnk:=nil;
 iPersFile:=nil;
 hr:=CoCreateInstance(CLSID_ShellLink,nil,CLSCTX_INPROC_SERVER,IID_IShellLinkA,iShLnk);
 if SUCCEEDED(hr) then
 begin
   hr:=iShLnk.QueryInterface(IID_IPersistFile,iPersFile);
   if SUCCEEDED(hr) then
   begin
     iPersFile.Load("Path_To_Some_Lnk_File", STGM_READ); // загружаем данные из ярлыка
     iPersFile._Release;
   end;
   if iShLnk.GetPath(Path,MAX_PATH,pfd,SLGP_UNCPRIORITY)=NOERROR then // считывает путь
     Application.MessageBox(Path,"Hi!!!",0); // показывает путь из ярлыка
   iShLnk._Release;
 end;
 CoUninitialize;
end;

Формально код написан без ошибок (руки в этом плане вроде бы растут из того места, откуда надо). При запуске на исполнение все работает и сообщение с путем из ярлыка показывается (путь правильный), но при этом при завершении процедуры возникает "External exception C000001D". В модуле Windows значению C000001D соответствует только одна константа - STATUS_ILLEGAL_OPERATION, смысл которой мне установить не удалось. Опытным путем установил, что исключение связано с вызовами метода _Release. Если убрать оба вызова, то исключения не возникает, если любой один - возникает только "Access violation...", но ведь _Release убрать вообще нельзя! Причем исключения странные: отловить и обработать их с помощью try..except не удается.
В связи с этим возникают вопросы: 1) почему возникает исключение? 2) как его избежать?

Кроме того, если данный код использовать (без изменений) в консольной программе, то никаких исключений не происходит. Значит, возникновение исключений каким-то образом связано с VCL?


 
VMcL ©   (2004-10-25 10:35) [1]

>>SeLarin ©  (25.10.04 08:33)

В Object Pascal экземпляры интерфейсов являются объектами с управляемым временем жизни. Вызов Release компилятор вставляет автоматически в том месте, где переменная интерфейсного типа выходит из области видимости.


 
VMcL ©   (2004-10-25 10:38) [2]

P.S.
Для того, чтобы явно освободить экземпляр интерфейса (это не так уж часто нужно) следует просто присвоить переменной интерфейсного типа константу nil:
SomeIntf := nil;  // Здесь компилятор автоматически вставит вызов Release при необходимости.


 
SeLarin ©   (2004-10-25 14:06) [3]

Спасибо. Просто и ясно!



Страницы: 1 вся ветка

Текущий архив: 2005.08.07;
Скачать: CL | DM;

Наверх




Память: 0.47 MB
Время: 0.045 c
4-1118341798
Dot
2005-06-09 22:29
2005.08.07
hangUp


14-1121246501
kai
2005-07-13 13:21
2005.08.07
Список предметов, которые можно/нельзя посылать почтой в Украину


3-1120361092
serguncho
2005-07-03 07:24
2005.08.07
Проблема с представление информации в Firebird


9-1113965646
Xeno
2005-04-20 06:54
2005.08.07
Отсечение объектов вне обзора камеры в GLScene


11-1104578339
N0th!ng
2005-01-01 14:18
2005.08.07
Помогите с KOL!