Надо разробраться с EnumResourceTypes (перечесление типов ресуров)

Тема в разделе "WASM.BEGINNERS", создана пользователем amvoz, 30 янв 2012.

  1. amvoz

    amvoz Member

    Публикаций:
    0
    Регистрация:
    12 ноя 2008
    Сообщения:
    653
    (последнее- перечисление типов ресурсов модуля)

    Друзья! Прдолжаю воевать с ресурсами; имею маленький исполняемый экзешник с иконкой и мечтаю получить имя типа этой иконки, пишу исходник экзешника ra.cpp:

    Код (Text):
    1. #include <windows.h>
    2. #include <iostream>
    3. #include <stdio.h>
    4. using namespace std;
    5.  
    6. //ЭТо вот функция обратного вызова
    7. BOOL EnumTypesFunc(HANDLE hModule, LPTSTR lpType, LONG lParam) {
    8.  printf ("Между этой\n");
    9.  printf ("lpType= %s\n", lpType);
    10.  printf ("и этой штукой должно быть имя типа ресурса\n");
    11. };
    12.  
    13.  
    14. int main () {
    15.  
    16.  SetConsoleCP (1251);
    17.  SetConsoleOutputCP (1251);
    18.  
    19.  
    20.  EnumResourceTypes(0,(ENUMRESTYPEPROC)EnumTypesFunc,0)
    21.  getchar();
    22.  
    23. }
    кропаю файл ресурсов: menu.rc
    Код (Text):
    1. main ICON "file.ico"
    тут же в идректории есть файл file.ico, командую:
    Код (Text):
    1. windres -o MENU.o MENU.rc
    2. g++ ra.cpp MENU.o -o ra.exe -static
    3. del MENU.o
    получаю ra.exe с иконкой, запускаю, но вижу только
    Код (Text):
    1. Между этой
    В чём дело? Что есть LPTSTR lpType? По факту указатель на char, что и подтверждает приведённый код. А значит, формат вывода
    Код (Text):
    1.  printf ("lpType= %s\n", lpType);
    верен, но почему же ничё не выводится? Спасибо, кто откликнется!

    (а вот и определение LPTSTR из winnt.h )
    Код (Text):
    1. typedef CHAR TCHAR;
    2. typedef TCHAR *LPTCH,*PTSTR,*LPTSTR,*LP,*PTCHAR;
     
  2. amvoz

    amvoz Member

    Публикаций:
    0
    Регистрация:
    12 ноя 2008
    Сообщения:
    653
    никто не знал? Странно...
    Код (Text):
    1. #include <windows.h>
    2. #include <iostream>
    3. #include <stdio.h>
    4. using namespace std;
    5.  
    6.  
    7. BOOL WINAPI EnumTypesFunc(HMODULE hModule,LPTSTR lpType, LONG lParam){
    8.  if ((ULONG)lpType & 0xFFFF0000){
    9.   printf("++ %s\n", lpType);    
    10.  }    
    11.  else {        
    12.   printf("-- %d\n", lpType);    
    13.  }  
    14.  
    15.  return true;
    16. }
    17.  
    18. int main() {
    19.  SetConsoleCP (1251);
    20.  SetConsoleOutputCP (1251);
    21.  EnumResourceTypes(0,(ENUMRESTYPEPROC)EnumTypesFunc,0);                              
    22.  getchar ();
    23. }
     
  3. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    amvoz
    Вообще ожидалось, что Вы таки осилите заглянуть в MSDN (хотя бы по ссылке из параллельной темы) и воспользуетесь макросом IS_INTRESOURCE. Но, по секрету, подобные комментарии отбивают охоту отвечать на вопросы.
     
  4. amvoz

    amvoz Member

    Публикаций:
    0
    Регистрация:
    12 ноя 2008
    Сообщения:
    653
    Так-то, если чё: я пользуюсь всем на свете, макросами, пакросами, ещё чем. Ссылками там разными. Вы чё, на самом деле думаете, что я по Вашей ссыли не ходил? Это несерьёзно.

    И если бы я знал, что тем макросом надо воспользоваться (опять же, как?), я бы им воспользовался.

    И да, кстати, в коде выше я им не пользовался, а результат получил. Так что полезность его для меня остаётся под большим сомнением.

    ...Я вот до сих пор не понял, напрмер, какой сакральный смысл скрывает
    MAKEINTRESOURCE

    Я понимаю, удобно когда глядишь на такую строку:
    #define RT_ICON MAKEINTRESOURCE(3)

    Ну да, я вижу, что 3 это икона. А программно-то им как пользоваться? Никак. Только чисто смотреть и знать. Тоже не смогу им воспользоваться, вот какая загогулина, понимаешь...
     
  5. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    amvoz
    Если бы прочитали статью по ссылке, которую я дал, то и знали бы, и воспользовались.
    А я за ухом ногой почесал. Можно было бы и рукой, но я же и ногой смог. И результат получил. Так что полезность рук для меня остаётся под большим сомнением.

    Полезность макроса в том, что у него есть имя, описывающее его функциональность. А если захотите завтра использовать вот это:
    Код (Text):
    1. if ((ULONG)lpType & 0xFFFF0000)
    то поставите одной F больше. Или меньше. А через неделю вообще неясно будет, что за маска тут зашифрована. А для 64-битных програм это вообще в любом случае баг.
    Это бред. Макросом MAKEINTRESOURCE можно и нужно пользоваться. Например, создание модального диалогового окна на основе ресурса с номером IDD_MAINDLG:
    Код (Text):
    1. DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_MAINDLG), NULL, MainDialog);
     
  6. amvoz

    amvoz Member

    Публикаций:
    0
    Регистрация:
    12 ноя 2008
    Сообщения:
    653
    прочитал и вот перевод:
    http://www.vsokovikov.narod.ru/New_MSDN_API/Resourse/fn_enumresnameproc.htm
    Я не гений, а простой человек о двух руках, двух ногах и одной голове. Люди много умнее меня предпочитают конструкцию, которую я привёл, а не пользуются этим макросом. Я-то почему дожен имользоваться? Где код с ним? Нет кода.
    Продолжим сравнение- Вы знали и про руки и про то как им и можно чесать. А я до сих пор не могу понять, куда его сюда можно засунуть с пользой- (так что ситуации разнятся и здорово разнятся.)
    Код (Text):
    1. if ((ULONG)lpType & 0xFFFF0000){
    2.   printf("++ %s\n", lpType);    
    3.  }    
    4.  else {        
    5.   printf("-- %d\n", lpType);    
    6.  }
    А Вы знаете, но молчите. Ну, дело ваше. Кто знает, тот молчит- проверено.
    .......................................................................................................
    Дальше вообще ничё не понял. Почему я должен ставить одной больше или одной меньше F? Повторюсь, код не мой, его умные люди писали.
    Код (Text):
    1. Полезность макроса в том, что у него есть имя, описывающее его функциональность
    ну допустим, не буду придираться к словам, но дальше:
    Код (Text):
    1. DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_MAINDLG), NULL, MainDialog);
    ОК, лезу в файл winuser.h, вижу:
    Код (Text):
    1. #define RT_CURSOR MAKEINTRESOURCE(1)
    2. #define RT_FONT MAKEINTRESOURCE(8)
    3. #define RT_BITMAP MAKEINTRESOURCE(2)
    4. //ну и так далее
    ....................
    Так, а у меня в учебнике написано, что надо писать в код то, то, что в левом столбике, то есть
    Код (Text):
    1. RT_CURSOR
    И вместо него препроцессор поставит то, что в правом столбике, то есть:
    Код (Text):
    1. MAKEINTRESOURCE(1)
    У вас же наблюдаю совсем иное вы пишите текст_для_замены
    Код (Text):
    1. MAKEINTRESOURCE(IDD_MAINDLG)
    в код, делаете то есть работу препроцессора и считаете, что это правильно (IDD_MAINDLG только запутывает всё дело). Всё! Я ничего не понимаю, мир поменялся с тех пор, как я изучил макросы, а мне не сказали.
     
  7. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    amvoz
    Я не молчу. Просто посчитал, что его использование очевидно и не требует пояснений. Хотя бы даже исходя из его названия: IS_INTRESOURCE — "ресурс обозначен целым числом"
    Код (Text):
    1. if ((ULONG)lpType & 0xFFFF0000){
    2.   printf("++ %s\n", lpType);    
    3.  }    
    4.  else {        
    5.   printf("-- %d\n", lpType);    
    6.  }
    для 32-битного кода эквивалентно
    Код (Text):
    1. if (IS_INTRESOURCE(lpType))    //если ресурс обозначен целым числом
    2.     printf("-- %d\n", lpType);    //вывести это число
    3. else                           //иначе
    4.     printf("++ %s\n", lpType);    //вывести строку
    Для 64-битного кода верен только второй вариант.

    Ошибка/Опечатка. Ошибки, знаете ли, случаются. Опечатка в имени макроса приведёт к ошибке компиляции. Опечатка в числе приводит к трудновылавливаемым багам.
    Да уж не очень.
    RT_ICON, RT_CURSOR и т.д. надо использовать там, где это соответствует смыслу программы. Я привёл пример (к которому они не имеют отношения) использования MAKEINTRESOURCE. А вот в параллельной теме, где я указал на EnumResourceNames, Вам нужно как раз наоборот: передавать в EnumResourceNames вторым параметром RT_ICON, а не MAKEINTRESOURCE(3), т.к. RT_ICON (дословный перевод: "тип ресурса — иконка") более подходит по смыслу (нужно перечислить иконки) и помимо прочего не содержит числовых констант.
     
  8. amvoz

    amvoz Member

    Публикаций:
    0
    Регистрация:
    12 ноя 2008
    Сообщения:
    653
    я вообще первый раз столкнулся с тем, что макрос выполняет роль функции. Вам вот понятно, а я щас буду долго переваривать!

    +++++++++++++++++++++++++++++++++++++

    Так-то всё вернулось с чего и начиналось. Вы упорно продолжаете писать сюда
    MAKEINTRESOURCE(сюда)
    какой-то хитрый идентифиткатор, а где его брать не говорите

    IDD_MAINDLG у меня нет такого определения в инклудах
     
  9. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    amvoz
    steelfactor в параллельной теме показал, откуда такие идентификаторы берутся: в заголовочном файле resource.h объявляется константа вроде #define IDD_MAINDLG 5 (обычно её объявляет редактор ресурсов студии, но можно и вручную самому вписать любое не слишком большое значение). Эта же константа должна использоваться в файле ресурсов любое_имя.rc для описания ресурса, будь-то иконка, диалог или левый набор бинарных данных (этим тоже обычно занимается редактор ресурсов). При компиляции файла ресурсов этот идентификатор будет использоваться, как идентификатор ресурса. Поэтому из своей программы константу IDD_MAINDLG (или любую другую, используемую в файле любое_имя.rc) можно указывать напрямую, ссылаясь на соответствующий ресурс. Если же Вы разбираете ресурсы некоторого чужого готового исполняемого файла, то этих констант у Вас, естесственно нет; соответственно необходимо перечислять все ресурсы чужого файла функцией EnumResourceNames.