特殊问题,请助我.(100分)

  • 主题发起人 主题发起人 txiuq
  • 开始时间 开始时间
T

txiuq

Unregistered / Unconfirmed
GUEST, unregistred user!
写了一个组件:
type
TResItem = class(TComponent)
private
{ Private Declarations }
FResTypeStr: string;
FresNameStr: string;
FSize: Integer;
FRawData: Pointer;
FResType: PChar;
FItems: TresItem;
FOffset: integer;
FResName: PChar;
protected
{ Protected Declarations }

public
{ Public Declarations }
constructor Create(AOwner: TComponent;H:THandle;Rtype:Pchar;RName:Pchar;langid:word);
destructor Destroy; override;
property Size: Integer read FSize;
property Offset: Integer read FOffset;
property RawData: Pointer read FRawData;
property ResName: Pchar read FResName;
published
{ Published Declarations }
end;
TResList = class(TComponent)
private
{ Private Declarations }
FHandle: THandle;
FLangId: Word;
FResType: PChar;
Flist:Tlist;

protected
{ Protected Declarations }
procedure Loaded; override;
function GetItems(Index: Integer): TResItem;
function GetCount: Integer;
function GetResTypeStr: string;
public
{ Public Declarations }
constructor Create(AOwner: TComponent;H:THandle;Rtype:pchar;langid:word);
destructor Destroy; override;
property Items[Index: Integer]: TResItem read GetItems ;
property Handle: Thandle read FHandle;
property Count: Integer read GetCount ;
property LangId: Word read FLangId;
property ResType: PChar read FResType;
property ResTypeStr: string read GetResTypeStr ;
published
{ Published Declarations }
end;
implementation
constructor TResItem.Create(AOwner: TComponent;H:THandle;Rtype:Pchar;RName:Pchar;langid:word);
Var
Resinfo,hres:THandle;
begin
inherited Create(AOwner);
FResType:=Rtype;
FResName:=Rname;
resinfo:=FindResourceex(H,RType, RName,LangId);
hres:=LoadResource(H, ResInfo);
FRawData:=LockResource(hres);
Foffset:=integer(Hres)-H;
Fsize:=sizeofresource(H,resinfo);
{Add any other initialization code here}
end;{Create}
function TResList.GetItems(Index: Integer): TResItem;
begin
Result := FList[Index];
end;{GetItems}
function TResList.GetCount: Integer;
begin
Result := FList.Count;
end;{GetCount}
constructor TResList.Create(AOwner: TComponent;H:THandle;Rtype:pchar;langid:word);
function EnumResProc(hMod: THandle; Restype:Pchar;ResName: PChar;parm:integer): Boolean; stdcall;
Var
Fitem:TresItem;
begin
Fitem:=Tresitem.create(self,Hmod,ResType,ResName,FlangId);------1
Flist.Add(Fitem);-----2
result:=true;---------3
end;
begin
inherited Create(AOwner);
Fhandle:=H;
FresType:=Rtype;
FLangId:=Langid;
FList:=Tlist.Create;
EnumResourceNames(Fhandle, Frestype, @EnumResProc,integer(self));
{Add any other initialization code here}
end;{Create}

在主程序中使用如下代码:
procedure TForm1.Button1Click(Sender: TObject);
var
i,j:integer;
Rlist:Treslist;
hTemp:THandle;
begin
if opendlg.Execute then
begin
hTemp := LoadLibraryEx (PChar(opendlg.filename), 0, Load_Library_As_DataFile);
if hTemp <> 0 then begin ----------------4
rlist:=Treslist.Create(self,htemp,rt_rcdata,2048);
for I:=0 to Rlist.count-1 do
begin
memo1.lines.Add(string(rlist.Items.ResName));
end;
rlist.Free;
end;
end;
END;
程序中rlist.count始终为0,跟踪到位置1处便不能再跟踪了,并且程序立即跳到4处.
2,3语句好象根本未执行.不知我哪些语句有问题,谢谢你的帮助
编程环境(delphic/s4.0- update3);
 
你的代码我试了:

你的callback函数 EnumResProc 不能放在 Treslist.Create 里面
把它放出来。不要把它作为类的方法(method),要作为独立的函数

放出来后self是不能用了,不过:
因为你在EnumResourceNames把 integer(self) 作为参数,
和EnumResProc里面传来的parm是一样的值,
因此 TResList(parm) 就相当于原来在类里面时的self
 
成为独立函数后怎样实现
Fitem:=Tresitem.create(self,Hmod,ResType,ResName,FlangId);------1
Flist.Add(Fitem); -----2
第 1 句中Flangid参数怎样传递
还有 第2 句中的Flist.
 
self就是 TResList(parm) 嘛,

TResList(parm).FLangId

TResList(parm).FList

虽然这2个属性是 prvivate(私有的)
不过在同一个unit里面,你可以直接访问他

 
原来的self就是现在的 TResList(parm) 嘛,

原来的 FLangId 就是原来的 self.FLangId 的简称,
也就是现在的 TResList(parm).FLangId

还有 : TResList(parm).FList 也一样

另外虽然FLangId和FList这2个属性是 prvivate(私有的)
不过在同一个unit里面,你可以直接访问他
 
谢谢Pipi,前面问题已解决,可是我发现另外一个问题:
memo1.lines.Add(string(rlist.Items.ResName))语句中ResName的值不正确
是不是Tresitem.ResName属性有关代码有问题,可我却找不到错在哪里.
能否赐教.
 
EnumResProc 送过来的 ResName 是个指针PChar ,指向的地址是临时的
不是永远保留的,送来了一次可能下次送来的还是这个地址

所以你的 TResItem 的 FResName :
1、可以使用 string 类型
2、可以使用 array[0..50] of char,在FResItem.create中
lstrcpy(FResName,rname)
 
还有啊,有些资源是字符串名字的,有些是数字id的,
你要在EnumResProc 判断一下 resname 的值
if DWORD(resname)<$10000 then
是数字id ,他的资源id 的名字实际是 IntToStr(DWORD(resname))
else
resname是真正的字符串型的资源名字
 
接受答案了.
 
后退
顶部