Вниз
Скачать: 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 вся ветка

Скачать: CL | DM;



Память: 0.46 MB
Время: 0.024 c
4-1118096374
Gopher
2005-06-07 02:19
2005.08.07
команда GetWindowsDir


10-1098782958
Sash
2004-10-26 13:29
2005.08.07
excel


14-1121141992
DelphiN!
2005-07-12 08:19
2005.08.07
Как моей программе узнать, что под столом нажали на кнопку


14-1121319792
pavel_guzhanov
2005-07-14 09:43
2005.08.07
Delphi 2005 & Delphi 7


4-1118037280
Руслана
2005-06-06 09:54
2005.08.07
Подскажите, как запустить обновление устройств




   Наверх