И снова о EnumResourceNames()
От: Аноним  
Дата: 31.08.05 08:54
Оценка:
Люди, не могу понять, почему не работает???!!!
Пишу в Delphi 2005.
У меня файл ресурсов есть, там два ресурса ICON.

function foo(hModule: HMODULE; lpszType: LPCTSTR; lpszName: LPCTSTR;
lParam: Longint): Boolean;
begin
Application.MessageBox(PAnsiChar(lpszName), 'Название ресурса');
Result := true;
end;

...
EnumResourceNames(hMod, RT_ICON, @foo, 0);
...

Функция foo вызывается 2 раза, однако в мессажбоксе первый раз вижу белиберду какую-то вместо названия ресурса, а вторай раз вообще пусто (видимо такой участок памяти считывается, что преобразуется в пустую стороку). В общем, вместо идентификатора ресурса получаю хрень. В чем причина????

Если же foo сделать stdcall, то то foo вызывается всего лишь один раз, мессага не выводится. Читаю после вызова
ошибку (GetLastError) — пишет: "Invslid access to memory location".

Спасибо, Александр.
Re: И снова о EnumResourceNames()
От: SergH Россия  
Дата: 31.08.05 09:01
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Люди, не могу понять, почему не работает???!!!

А>Пишу в Delphi 2005.
А>У меня файл ресурсов есть, там два ресурса ICON.

А>function foo(hModule: HMODULE; lpszType: LPCTSTR; lpszName: LPCTSTR;

А> lParam: Longint): Boolean;
А>begin
А> Application.MessageBox(PAnsiChar(lpszName), 'Название ресурса');
А> Result := true;
А>end;

А>...

А>EnumResourceNames(hMod, RT_ICON, @foo, 0);
А>...

А>Функция foo вызывается 2 раза, однако в мессажбоксе первый раз вижу белиберду какую-то вместо названия ресурса, а вторай раз вообще пусто (видимо такой участок памяти считывается, что преобразуется в пустую стороку). В общем, вместо идентификатора ресурса получаю хрень. В чем причина????


А>Если же foo сделать stdcall, то то foo вызывается всего лишь один раз, мессага не выводится. Читаю после вызова

А>ошибку (GetLastError) — пишет: "Invslid access to memory location".

The EnumResNameProc function is an application-defined callback function used with the EnumResourceNames ..

BOOL CALLBACK EnumResNameProc( HMODULE hModule,
LPCTSTR lpszType,
LPTSTR lpszName,
LONG_PTR lParam
);
Parameters

hModule
...
[in] Specifies the name of a resource of the type being enumerated. For more information, see the Remarks section.
...

Remarks

If IS_INTRESOURCE(x) is TRUE for lpszName or lpszType, x specifies the integer identifier of the given resource. Otherwise, it is a pointer to a null-terminated string. If the first character of the string is a pound sign (#), the remaining characters represent a decimal number that specifies the integer identifier of the resource. For example, the string "#258" represents the identifier 258.

Делай что должно, и будь что будет
Re[2]: И снова о EnumResourceNames()
От: Аноним  
Дата: 31.08.05 10:36
Оценка:
Здравствуйте, SergH, Вы писали:

SH>The EnumResNameProc function is an application-defined callback function used with the EnumResourceNames ..


SH>BOOL CALLBACK EnumResNameProc( HMODULE hModule,

SH> LPCTSTR lpszType,
SH> LPTSTR lpszName,
SH> LONG_PTR lParam
SH>);
SH>Parameters

SH>hModule

SH>...
SH>[in] Specifies the name of a resource of the type being enumerated. For more information, see the Remarks section.
SH>...

SH>Remarks


SH>If IS_INTRESOURCE(x) is TRUE for lpszName or lpszType, x specifies the integer identifier of the given resource. Otherwise, it is a pointer to a null-terminated string. If the first character of the string is a pound sign (#), the remaining characters represent a decimal number that specifies the integer identifier of the resource. For example, the string "#258" represents the identifier 258.

SH>[/q]

Спасибо за содержательный copy-paste, однако MSDN я читал, прежде чем задать вопрос.IS_INTRESOURCE — макрос и, естественно, он отсутствует в Дельфи. Нельзя ли объяснить по-русски, если Вы знаете, в чем моя ошибка?

Привожу, на всякий случай, содержание моего тестового файл ресурсов

res1 ICON "ico\DBServer.ico"
res2 ICON "ico\fet.ico"

С уважением, Александр
Re[3]: И снова о EnumResourceNames()
От: SergH Россия  
Дата: 31.08.05 10:46
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Спасибо за содержательный copy-paste, однако MSDN я читал, прежде чем задать вопрос.


А>IS_INTRESOURCE — макрос и, естественно, он отсутствует в Дельфи. Нельзя ли объяснить по-русски, если Вы знаете, в чем моя ошибка?


Макрос определён так:

#define IS_INTRESOURCE(_r) (((ULONG_PTR)(_r) >> 16) == 0)


Идея в том, что если значение от 0 до 0x0000ffff, оно считается числом, если от 0x00010000 и больше — указателем на строчку с именем.
Делай что должно, и будь что будет
Re[4]: И снова о EnumResourceNames()
От: Аноним  
Дата: 31.08.05 11:14
Оценка:
Здравствуйте, SergH, Вы писали:

SH>Макрос определён так:


SH>
SH>#define IS_INTRESOURCE(_r) (((ULONG_PTR)(_r) >> 16) == 0)
SH>


SH>Идея в том, что если значение от 0 до 0x0000ffff, оно считается числом, если от 0x00010000 и больше — указателем на строчку с именем.


Попробовал сделать нечто подобное:

function foo(hModule: HMODULE; lpszType: LPCTSTR; lpszName: LPCTSTR;
lParam: Longint): Boolean;
begin
if (Cardinal(lpszName) shr 16) = 0 then
// Integer
Application.MessageBox( PChar( IntToStr( Integer(lpszName) ) ), 'Название ресурса' )
else
// null-terminated string
Application.MessageBox(lpszName, 'Название ресурса');

Result := true;
end;

программа выполняется по ветке else, т.е. lpszName — строка, заканчивающаяся нулем. Та же хрень в мессажбоксе
Re[5]: И снова о EnumResourceNames()
От: SergH Россия  
Дата: 31.08.05 11:21
Оценка:
Здравствуйте, Аноним, Вы писали:

А>function foo(hModule: HMODULE; lpszType: LPCTSTR; lpszName: LPCTSTR;

А> lParam: Longint): Boolean;
А>begin
А> if (Cardinal(lpszName) shr 16) = 0 then
А> // Integer
А> Application.MessageBox( PChar( IntToStr( Integer(lpszName) ) ), 'Название ресурса' )
А> else
А> // null-terminated string
А> Application.MessageBox(lpszName, 'Название ресурса');

А> Result := true;

А>end;

А>программа выполняется по ветке else, т.е. lpszName — строка, заканчивающаяся нулем. Та же хрень в мессажбоксе


Ну не знаю. Запустить под отладчиком и посмотреть лично?
Делай что должно, и будь что будет
Re[6]: И снова о EnumResourceNames()
От: Danchik Украина  
Дата: 31.08.05 16:50
Оценка:
Здравствуйте, SergH, Вы писали:

SH>Здравствуйте, Аноним, Вы писали:


А>>function foo(hModule: HMODULE; lpszType: LPCTSTR; lpszName: LPCTSTR;

А>> lParam: Longint): Boolean;
А>>begin
А>> if (Cardinal(lpszName) shr 16) = 0 then
А>> // Integer
А>> Application.MessageBox( PChar( IntToStr( Integer(lpszName) ) ), 'Название ресурса' )
А>> else
А>> // null-terminated string
А>> Application.MessageBox(lpszName, 'Название ресурса');

А>> Result := true;

А>>end;

А>>программа выполняется по ветке else, т.е. lpszName — строка, заканчивающаяся нулем. Та же хрень в мессажбоксе


SH>Ну не знаю. Запустить под отладчиком и посмотреть лично?


Баганул он чудно. Аж в двух местах сразу:

function EnumResourceNamesCallback(hModule: HMODULE; lpType, lpName: PAnsiChar; 
  lParam: Longint): BOOL { не Boolean } ; stdcall { должно быть, правильная конвеция обязательна!! };
begin
  if (Cardinal(lpName) shr 16) = 0 then
    Application.MessageBox(PChar(IntToStr(Integer(lpName))), 'Название ресурса')
  else 
    Application.MessageBox(lpName, 'Название ресурса');
  Result := True;
end;


procedure TForm1.Button1Click(Sender: TObject);
var
  aResInstance: THandle;
begin
  aResInstance := FindResourceHInstance (HInstance);

  if not EnumResourceNames(aResInstance, RT_GROUP_ICON {скорее всего тебе это нужно}, @EnumResourceNamesCallback, 0) then
    RaiseLastOSError;
end;
Re[7]: И снова о EnumResourceNames()
От: Аноним  
Дата: 01.09.05 07:29
Оценка:
Здравствуйте, Danchik, Вы писали:

D>Здравствуйте, SergH, Вы писали:


SH>>Здравствуйте, Аноним, Вы писали:


А>>>function foo(hModule: HMODULE; lpszType: LPCTSTR; lpszName: LPCTSTR;

А>>> lParam: Longint): Boolean;
А>>>begin
А>>> if (Cardinal(lpszName) shr 16) = 0 then
А>>> // Integer
А>>> Application.MessageBox( PChar( IntToStr( Integer(lpszName) ) ), 'Название ресурса' )
А>>> else
А>>> // null-terminated string
А>>> Application.MessageBox(lpszName, 'Название ресурса');

А>>> Result := true;

А>>>end;

А>>>программа выполняется по ветке else, т.е. lpszName — строка, заканчивающаяся нулем. Та же хрень в мессажбоксе


SH>>Ну не знаю. Запустить под отладчиком и посмотреть лично?


D>Баганул он чудно. Аж в двух местах сразу:


D>
D>function EnumResourceNamesCallback(hModule: HMODULE; lpType, lpName: PAnsiChar; 
D>  lParam: Longint): BOOL { не Boolean } ; stdcall { должно быть, правильная конвеция обязательна!! };
D>begin
D>  if (Cardinal(lpName) shr 16) = 0 then
D>    Application.MessageBox(PChar(IntToStr(Integer(lpName))), 'Название ресурса')
D>  else 
D>    Application.MessageBox(lpName, 'Название ресурса');
D>  Result := True;
D>end;


D>procedure TForm1.Button1Click(Sender: TObject);
D>var
D>  aResInstance: THandle;
D>begin
D>  aResInstance := FindResourceHInstance (HInstance);

D>  if not EnumResourceNames(aResInstance, RT_GROUP_ICON {скорее всего тебе это нужно}, @EnumResourceNamesCallback, 0) then
D>    RaiseLastOSError;
D>end;
D>


Огромное спасибдо!!! Все работает правильно!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.