Форум: "WinAPI";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.01.31;
Скачать: [xml.tar.bz2];




Вниз

Как работать с этим проклятым PChar? 


Cobalt   (2001-11-25 19:44) [0]

Перебираю ресурсы модуля функцией EnumResourceNames, и получаю какие-то странные имена ресурсов(в непечатных символах - т.е. видны только при отладке, а при попытке записи в напр.Мемо - ничего не видно), тип - PChar.

for i:=1 to 22 do
begin
EnumResourceNames(Hmod,windows.MakeIntResource(i),@MyEnumNameFunc,0));
----
end;
Function MyEnumNameFunc(HNDL:hModule; lpszType:LPSTR; lpszName:LPTSTR; lParam:LONGINT):BOOL;
var s:string;
begin
inc(NamesCnt);
if lpszName<>nil then DropForm.Memo1.Lines.Add(strPas(lpszName));
s:=StrPas(lpszName);
b.Add(S);
result:=true;
end;

В результате - ничего(NIL)З;(
Модуль перебираю свой же, сделанный Дельфёй



Иван Шихалев   (2001-11-25 19:54) [1]

Наверное, ресурсы имеют вместо имен целочисленные идентификаторы, тогда:

HiWord(Cardinal(lpszName)) = 0
LoWord(Cardinal(lpszName)) = ID

Ну и, соответственно, ссылается PChar на совершенно левую память.



Cobalt   (2001-11-25 23:49) [2]

Вряд ли, ведь, например Restorator показывает имена ресурсов, типа TDropForm (RCData), MAINICON (Icon) и т.п.



Adder   (2001-11-26 01:43) [3]

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls, ExtCtrls;

type
TForm1 = class(TForm)
ListView1: TListView;
Panel1: TPanel;
Button1: TButton;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
ListItem:TListItem;

// Declare callback functions.
Function EnumTypesFunc(
hModule:THANDLE;
lpType:LPTSTR;
lParam:LONGINT):LONGBOOL;stdcall;

Function EnumNamesFunc(
hModule:THANDLE;
lpType:LPCTSTR;
lpName:LPTSTR;
lParam:LONGINT ):LONGBOOL;stdcall;

implementation

{$R *.DFM}
Function EnumTypesFunc(
hModule:THANDLE;// module handle
lpType:LPTSTR;// address of resource type
lParam:LONGINT):LONGBOOL;stdcall;
var Name:string;
begin
ListItem :=Form1.ListView1.Items.Add;
if (DWORD(lpType) and $FFFF0000)<>0 then
begin
ListItem.Caption:=lpType;
ListItem.SubItems.Add("")
end
else
begin

ListItem.Caption:=IntToStr(DWORD(lpType));
case DWORD(lpType) of
{RT_NEWRESOURCE}$2000: Name:="RT_NEWRESOURCE";
{RT_ERROR}$7FFF: Name:="RT_ERROR";
{RT_CURSOR}1: Name:="RT_CURSOR";
{RT_BITMAP}2: Name:="RT_BITMAP";
{RT_ICON}3: Name:="RT_ICON";
{RT_MENU}4: Name:="RT_MENU";
{RT_DIALOG}5: Name:="RT_DIALOG";
{RT_STRING}6: Name:="RT_STRING";
{RT_FONTDIR}7: Name:="RT_FONTDIR";
{RT_FONT}8: Name:="RT_FONT";
{RT_ACCELERATORS}9: Name:="RT_ACCELERATORS";
{RT_RCDATA}10: Name:="RT_RCDATA";
{RT_MESSAGETABLE}11: Name:="RT_MESSAGETABLE";
{RT_GROUP_CURSOR}12: Name:="RT_GROUP_CURSOR";
{RT_GROUP_ICON}14: Name:="RT_GROUP_ICON";
{RT_VERSION}16: Name:="RT_VERSION";
{RT_NEWBITMAP}$2002: Name:="RT_NEWBITMAP(RT_BITMAP|RT_NEWRESOURCE)";
{RT_NEWMENU}$2004: Name:="RT_NEWMENU(RT_MENU|RT_NEWRESOURCE)";
{RT_NEWDIALOG}$2005: Name:="RT_NEWDIALOG(RT_DIALOG|RT_NEWRESOURCE)";
else Name:="";
end;
ListItem.SubItems.Add(Name)
end;
EnumResourceNames(hModule,
lpType,
ENUMRESNAMEPROC(@EnumNamesFunc),
0);
Result:=true;
end;

Function EnumNamesFunc(
hModule:THANDLE;
lpType:LPCTSTR;
lpName:LPTSTR;
lParam:LONGINT ):LONGBOOL;stdcall;

begin
ListItem :=Form1.ListView1.Items.Add;
ListItem.SubItems.Add("");
if (DWORD(lpName) and $FFFF0000)<>0 then
begin
ListItem.SubItems.Add(lpName)
end
else
begin
ListItem.SubItems.Add(IntToStr(DWORD(lpName)))
end;
Result:=true;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
ModuleHandle:THandle;
begin
try
ModuleHandle := LoadLibraryEx(pchar(Edit1.Text), 0, LOAD_LIBRARY_AS_DATAFILE);
EnumResourceTypes(modulehandle,
ENUMRESTYPEPROC(@EnumTypesFunc), // callback function
0); // extra parameter
finally
FreeLibrary(ModuleHandle);
CloseHandle(ModuleHandle);
end;
end;
end.



paul_shmakov   (2001-11-26 03:13) [4]

2 Cobalt:
кроме всего, что уже сказано, не забывайте, что Ваша MyEnumNameFunc должна быть stdcall



Cobalt   (2001-11-26 08:58) [5]

По-видимому, всё дело было в if (DWORD(lpName) and $FFFF0000)<>0 then

2 paul_shmakov © (26.11.01 03:13)
У меня было
Function MyEnumTypesFunc(HNDL:hModule; lpszType:LPSTR; lParam:LONGINT):BOOL;far;
Function MyEnumNameFunc (HNDL:hModule; lpszType:LPSTR; lpszName:LPTSTR; lParam:LONGINT):BOOL;far;


В чём разница между FAR и stdcall?

Теперь вроде заработало



Иван Шихалев   (2001-11-26 16:53) [6]

far вообще игнорируется - т.е. остается умолчательное для Delphi register



Cobalt   (2001-12-04 20:42) [7]

Я использую эти функции в потоке.
Т.е., получаю несколько имён файлов, и для каждого запускаю свой поток.

type
EnumFile = class(TThread)
private
{ Private declarations }
FFName:TFileName;
protected
procedure Execute; override;
procedure AddToTree;
public
ResTypes:array of MyRes;
Hmod:HMODULE;
ResCnt,TekRes:integer;
Constructor Create(FFileName:TFileName);

end;


А в своих функциях использую поля ResCnt и
TekRes.
И всё компилируется без к-либо сообщений об ошибках.
Function MyEnumNameFunc(HNDL:hModule; lpszType:LPSTR; lpszName:LPTSTR; lParam:LONGINT):BOOL;
begin
with EnumFile(lParam)do
begin
inc(NamesCnt);
{!!!Функция не является методом класса потока
Однако использует его поля}

SetLength(ResTypes[TekRes].RNames, NamesCnt);
ResTypes[TekRes].RNames[NamesCnt-1]:=lpszName;
end;

inc(NamesCnt);
result:=true;
end;



Почему? Хоть функции и вызываются из потока, но они-то понятия не имеют о потоке, и о его полях.
А, может быть, поля потока доступны для всех функций модуля, в котором он описывался?
Тогда как быть, если в модуле описывается несколько потоков(классов)?

Насклолько я понимаю, данные и код модуля, в ко-м описан поток, являются данными и кодом потока. Или как?!



Иван Шихалев   (2001-12-04 22:44) [8]

> Почему? Хоть функции и вызываются из потока,
> но они-то понятия не имеют о потоке, и о его
> полях.


А кто with написал? Дядя? И все-таки stdcall писать обязательно.




Форум: "WinAPI";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.01.31;
Скачать: [xml.tar.bz2];




Наверх





Память: 0.74 MB
Время: 0.024 c
3-99854           Jony                  2001-12-25 09:26  2002.01.31  
Как по нажатию на ENTER сделать переход с DBEditEh1 на DBEditEh2


1-99964           shelest               2002-01-14 11:34  2002.01.31  
Grid и его разновидность.


3-99841           EternalWonderer       2001-12-25 15:47  2002.01.31  
Размер поля NUMBER в ORACLE


4-100127          Anton Hadeev          2001-12-01 13:12  2002.01.31  
Добавить пользователя в NT


1-99978           Leviathan             2002-01-01 04:27  2002.01.31  
Много таймеров