Rob
Your suggested code changes worked as advertised..
Best wishes Ed
--- In [email protected], Rob Kennedy <[EMAIL PROTECTED]> wrote:
>
> edsynergy wrote:
> > Here is a small function that extracts a string from a resource dll.
> > Works fine when the resource is there, and I get an EResNotFound When
> > one is not found. However when the code in the exception clause is run
> > (on EResNotFound do Result:= blank;) it immetiately gives an AV. In
> > fact it dos'nt matter what code I put in the exception I get the AV
> > I cant see what the problem is
> >
> > Best wishe Ed.
> >
> > function TformMainTasks.SetAnchorText(const ResString:string):string;
> > var
> > ls:Tstringlist;
> > ms:TresourceStream;
> > h:Thandle;
> > begin
> >
> > try
> > h := LoadLibrary(pchar('strings.dll'));
>
> Do not type-cast a string literal to PChar. The compiler already
> recognizes when a PChar is required. It only needs a hint like that
when
> overload resolution might pick the wrong function. LoadLibrary isn't
> overloaded.
>
> > try
> > ms:=TresourceStream.Create(h,ResString, RT_RCDATA);
> > if ( Assigned(ms)) then
>
> That conditional will never fail. The constructor of a class will never
> return nil. If there is a problem allocating an object, you'll get an
> exception, in which case no value gets assigned to the variable at all.
>
> > begin
> > try
> > ls:= TstringList.Create;
> > ms.Position:= 0;
> > ls.LoadFromStream(ms);
> > Result:= ls.Text;
> > finally
> > ls.Free;
> > // free resources
> > end; // try/finally
> > End
> > Else Result:= blank;
> > except
> > on EResNotFound do Result:= blank;
> > end; // try/except
> > finally
> > ms.Free;
> > FreeLibrary(h);
> >
> > // free resources
> > end; // try/finally
>
> Never ignore a compiler warning. In your code, you should have gotten
> warnings in the "finally" blocks suggesting that ls, ms, and h might
not
> be initialized. The problem stems from misusing the try-finally
block. A
> try-finally sequence should always have this structure:
>
> AcquireResource;
> try
> UseResource;
> finally
> ReleaseResource;
> end;
>
> In your code, you enter the try-finally block and *then* you acquire a
> handle to the DLL, and it's even later before you acquire a
> TResourceStream object. You mustn't enter a try-finally block until
> you've successfully acquired the thing that the try-finally block is
> meant to protect.
>
> Try this code instead:
>
> function TFormMainTasks.SetAnchorText(const ResString: string): string;
> var
> ls: TStringList;
> ms: TResourceStream;
> h: THandle;
> begin
> h := LoadLibrary('strings.dll');
> Win32Check(h <> 0);
> try
> try
> ms := TResourceStream.Create(h, ResString, RT_RCDATA);
> try
> ls := TStringList.Create;
> try
> ls.LoadFromStream(ms);
> Result := ls.Text;
> finally
> ls.Free;
> end;
> finally
> ms.Free;
> end;
> except
> on EResNotFound do
> Result := blank;
> end;
> finally
> FreeLibrary(h);
> end;
> end;
>
> --
> Rob
>