怎样使用API enumresource
这是我的程序
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
ListBox1: TListBox;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
function proc(H:THandle;lpszType:LPTSTR;Data:Pointer):Boolean;
var
Lst:TStrings;
begin
Lst:=TStrings(Data);
Lst.Add(lpszType);
Result:=true;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if not EnumResourceTypes(HInstance,@proc,LongInt(ListBox1.Items)) then
ShowMessage('failed');
end;
end.
请问错误在那里??
问题点数:30、回复次数:27Top
1 楼BCB(天下三分明月夜,二分无赖是扬州)回复于 2000-12-26 12:40:00 得分 0
可能错在TStrings,改成TStringList,
TStrings不能有实例,另外调用方法也不对
Top
2 楼BCB(天下三分明月夜,二分无赖是扬州)回复于 2000-12-26 12:47:00 得分 0
除此外,
回调函数 proc写得不对,不符合API参数要求;
要注意,API参数不允许用DELPHI的高级类型,
必须API的低级类型;
Top
3 楼detroit()回复于 2000-12-26 12:50:00 得分 0
难道你没有看出这个TStrings对象是在ListBox1创建时创建的吗?确实TStrings这个类有点奇怪,只能继承一个类来创建,比如用Lst:=TStringList.Create来创建,而从TListBox的源码中也可以看出Borland的程序员也是这样使用的,至于调用方法有没有错误,你可以看一看TScreen的源码中的Fonts属性的函数,它是怎样获得字体的列表值的,它的调用方法跟我的是一样的,而且,我的调用方法对EnumFontFamilies,EnumDataFormats,EnumWindows都是正确的,怎么对这个API就错误了呢?Top
4 楼detroit()回复于 2000-12-26 12:56:00 得分 0
至于proc参数的类型,你可以看一看比如诸如LPTSTR,LPSTR,LPCTSTR之类的类型是什么,在Delphi中都是PAnsiChar,在API中的Long,DWORD实际的类型都是LongInt,看来这位仁兄对Delphi的源码还不太了解呀!!!Top
5 楼BCB(天下三分明月夜,二分无赖是扬州)回复于 2000-12-26 12:59:00 得分 0
对不起,上面我说错了!
List.Items不能做成参数,回调函数Proc中,
对Data或Lst的操作不能影响到List.Items,
稍改到一下:将List作为参数传到回调函数proc中,
就可直接对List.Items送类型串;
Top
6 楼detroit()回复于 2000-12-26 13:04:00 得分 0
这样还是不行啊!虽然不会再Failed了,但是proc根本没有运行啊!Top
7 楼atuchina(耶,系统报错了哦)回复于 2000-12-26 13:09:00 得分 0
当你在EnumResourceTypes中最后一个参数传递给PROC时,参数不够,如果把PROC 的参数改为一个X:LONGINT,x就是最后一个参数的值,就可以成功!Top
8 楼atuchina(耶,系统报错了哦)回复于 2000-12-26 13:14:00 得分 0
PROC错误!Top
9 楼BCB(天下三分明月夜,二分无赖是扬州)回复于 2000-12-26 13:23:00 得分 0
BOOL CALLBACK Proc(HANDLE hModule,
LPTSTR lpszType,
LONG lParam)
{
TListBox *ListBox1=(TListBox *)lParam;
if (lpszType!=0)
{
ListBox1->Items->Add(lpszType);
return(true);
}
else
return(false);
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
if (!EnumResourceTypes(HInstance,(ENUMRESTYPEPROC)Proc,(LONG)ListBox1))
ShowMessage("fail");
}
改进后,我能显示出一批类型,
但仍显示fail,正在查why
Top
10 楼detroit()回复于 2000-12-26 13:25:00 得分 0
我调试了一下,错误出在这句
Lst.Items.Add(StrPas(lpszType));
其中Lst的类型是TListBoxTop
11 楼BCB(天下三分明月夜,二分无赖是扬州)回复于 2000-12-26 13:28:00 得分 0
完全成功了,我将条件搞反了,非0就是成功;
改成DELPHI很简单!
BOOL CALLBACK Proc(HANDLE hModule,
LPTSTR lpszType,
LONG lParam)
{
TListBox *ListBox1=(TListBox *)lParam;
if (lpszType!=0)
{
ListBox1->Items->Add(lpszType);
return(true);
}
else
return(false);
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
if (!EnumResourceTypes(HInstance,(ENUMRESTYPEPROC)Proc,(LONG)ListBox1))
ShowMessage("成功");
else
ShowMessage("fail");
}
Top
12 楼Kingron(单身走我路……)回复于 2000-12-26 13:28:00 得分 0
function proc(H:THandle;lpszType:LPTSTR;Data:longint):Boolean;
begin
form1.ListBox1.Items.Add(lpsztype);
Result:=true;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
da:integer;
begin
da:=0;
listbox1.Items.Clear;
EnumResourceTypes(HInstance,@proc,da);
end;
Top
13 楼detroit()回复于 2000-12-26 13:32:00 得分 0
这是我改过后的函数,还是不能成功
function proc(H:THandle;lpszType:LPTSTR;lParam:LongInt):Boolean;
var
Lst:TListBox;
begin
Lst:=TListBox(lParam);
if lpszType<>nil then
begin
Lst.Items.Add(StrPas(lpszType));
Result:=true;
end
else
Result:=false;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if not EnumResourceTypes(HInstance,@proc,LongInt(ListBox1)) then
ShowMessage('failed');
end;Top
14 楼BCB(天下三分明月夜,二分无赖是扬州)回复于 2000-12-26 13:33:00 得分 0
改了两点:
1.向回调函数送ListBox1,而不能ListBox1.Items
2.回调函数proc中,若已类型列完(即lpszType为0),必须返回false;
Top
15 楼BCB(天下三分明月夜,二分无赖是扬州)回复于 2000-12-26 13:34:00 得分 0
你还是将条件弄反了,去掉not
Top
16 楼BCB(天下三分明月夜,二分无赖是扬州)回复于 2000-12-26 13:39:00 得分 0
另外,你要把资源准备好,我用的资源test.rc定义如下:
id1 dbf "c:\gb.dbf"
id2 test "c:\jsj.xls"
并要将test.rc Add Procject到工程中,
结果ListBox1显示:
dbf
test
Top
17 楼detroit()回复于 2000-12-26 13:42:00 得分 0
lpszType始终都是为nilTop
18 楼detroit()回复于 2000-12-26 13:52:00 得分 0
这个结果恐怕不太对,因为Delphi程序本身就自动会向资源里添加一些东西,比如用ID来表示的话,32761到32767都是CURSOR,他们的类别是Cursor,还有,Delphi程序会自动向资源文件里ICON类里添加一个名称为MAINICON的图标,你的程序里面没有反映出这些来Top
19 楼BCB(天下三分明月夜,二分无赖是扬州)回复于 2000-12-26 13:52:00 得分 0
俺兴奋后,又不对了;
结果出来了,却显示"fail"
难道忽略它?
Top
20 楼BCB(天下三分明月夜,二分无赖是扬州)回复于 2000-12-26 14:00:00 得分 0
这些标准类型的值可能小于一定的范围,
不会与串的地址冲突!可显示一下这些常数就知道了。
RT_ACCELERATOR Accelerator table
RT_ANICURSOR Animated cursor
RT_ANIICON Animated icon
RT_BITMAP Bitmap resource
RT_CURSOR Hardware-dependent cursor resource
RT_DIALOG Dialog box
RT_FONT Font resource
RT_FONTDIR Font directory resource
RT_GROUP_CURSOR Hardware-independent cursor resource
RT_GROUP_ICON Hardware-independent icon resource
RT_ICON Hardware-dependent icon resource
RT_MENU Menu resource
RT_MESSAGETABLE Message-table entry
RT_RCDATA Application-defined resource (raw data)
RT_STRING String-table entry
RT_VERSION Version resource
你的lpszType 始终为空,说明你的'资源'并没有啊!
有没有象我那样定义一下test.rc,并加到工程中;
Top
21 楼detroit()回复于 2000-12-26 14:04:00 得分 0
有倒是有,但是lpszType是空的,因为proc运行了8次,说明程序总共找到了七个类别,但是没有办法显示出来,跟踪的时候它却是nil,而且我现在也加入了自定义的RC文件
id1 test1 "DreamGBC.txt"
id2 test2 "FRUNLOG.TXT"Top
22 楼detroit()回复于 2000-12-26 14:16:00 得分 0
这是我写的取字体的函数,为什么这个可以成功呢?
function proc(var LogFont: TLogFont; var TextMetric: TTextMetric;
FontType: Integer; Data: Pointer): Integer; stdcall;
var
S: TStrings;
Temp: string;
begin
s:=TStrings(Data);
Temp := LogFont.lfFaceName;
s.Add(Temp);
result:=1;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
LFont: TLogFont;
begin
FillChar(LFont, sizeof(LFont), 0);
LFont.lfCharset := DEFAULT_CHARSET;
EnumFontFamiliesEx(GetDC(0),LFont,@proc,LongInt(ListBox1.Items),0);
end;Top
23 楼BCB(天下三分明月夜,二分无赖是扬州)回复于 2000-12-26 14:43:00 得分 30
终于查出来了,当((int)lpszType)<32(可能为界限),不能以串形式显示,
我就将转换成整数值显示,这是标准类型;>32,是用户定义的,显示成串,
程序又改动了一下,就对了:
BOOL CALLBACK Proc(HANDLE hModule,
LPTSTR lpszType,
LONG lParam)
{
TListBox *ListBox1=(TListBox *)lParam;
if (lpszType!=NULL)
{
if (((int)lpszType)<32)
ListBox1->Items->Add(String((int)lpszType)); // 标准资源类型
else
ListBox1->Items->Add(lpszType); // 用户定义资源类型
return(true);
}
else
return(false);
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
if (EnumResourceTypes(HInstance,(ENUMRESTYPEPROC)Proc,(LONG)ListBox1))
ShowMessage("ok");
else
ShowMessage("fail");
}
结果:
dbf
test
1
3
6
10
12
14
原因如比
Top
24 楼detroit()回复于 2000-12-26 14:44:00 得分 0
谢谢Top
25 楼BCB(天下三分明月夜,二分无赖是扬州)回复于 2000-12-26 14:47:00 得分 0
是不是以32为界限,我就不清楚,要查API,
并将几个标准常数显一显;
Top
26 楼BCB(天下三分明月夜,二分无赖是扬州)回复于 2000-12-26 14:48:00 得分 0
你好象也一直在线。
先下班了,明白再谈!
Top
27 楼BCB(天下三分明月夜,二分无赖是扬州)回复于 2000-12-27 08:14:00 得分 0
ListBox1的地址其实可以不作为参数
直接对ListBox1操作,但要加上对象Form1BOOL CALLBACK Proc(HANDLE hModule,
LPTSTR lpszType,
LONG lParam)
{
if (lpszType!=NULL)
{
if (((int)lpszType)<32)
Form1->ListBox1->Items->Add(String((int)lpszType)); // 标准资源类型
else
Form1->ListBox1->Items->Add(lpszType); // 用户定义资源类型
return(true);
}
else
return(false);
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
if (EnumResourceTypes(HInstance,(ENUMRESTYPEPROC)Proc,0))
ShowMessage("ok");
else
ShowMessage("fail");
}
Top




