CreateDialog падает с ошибкой RESOURCE_TYPE_NOT_FOUND

Тема в разделе "WASM.BEGINNERS", создана пользователем AndreyMust19, 28 май 2009.

  1. AndreyMust19

    AndreyMust19 New Member

    Публикаций:
    0
    Регистрация:
    20 окт 2008
    Сообщения:
    714
    Здравствуйте.
    И снова тот же проект WindowWork, где я тренируюсь с работой над интерфейсом.
    Решил опробовать CreateDialog-функции. Так вот, все они почему-то возвращают ноль, а в качестве номера ошибки - 8131 (точно не помню) - "RESOURCE_TYPE_NOT_FOUND". Я в очередной раз не знаю в чем дело, ибо уже целый день пробовал все, что приходило в голову.
    И еще. Сегодня вечером решил попробывать еще раз. И VC+ 6 озадачил меня, но теперь уже другой ошибкой. Возвращает что-то вроде
    Из-за чего бы это могло быть? Места на диске достаточно, выходить / входить из учетной записи пробывал. Из-за этой ошибки я ни один проект теперь не могу слинковать!

    В приложении - проект WindowWork.
     
  2. AndreyMust19

    AndreyMust19 New Member

    Публикаций:
    0
    Регистрация:
    20 окт 2008
    Сообщения:
    714
    Забыл - ошибка возникает в функции WinMain (там, где вызывается CreateDialog). Она находится в самом конце файла (остальные функции смотреть не надо).
     
  3. featurelles

    featurelles New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2009
    Сообщения:
    562
    AndreyMust19
    Пробовал из под админа компилить?

    У меня вчера что-то подобное произошло, только на линексе. Появились ошибки похожие на это link.exe: cannot open "TEMPFILE" Тоже не мог создать временной файл. chmod из под рута помогло.
     
  4. AndreyMust19

    AndreyMust19 New Member

    Публикаций:
    0
    Регистрация:
    20 окт 2008
    Сообщения:
    714
    На следующий день я еще раз попробовал слинковать. На этот раз все получилось и никаких 'cannot open "TEMPFILE"' не возникало. Наверное потому что место на диске 'С' освободил - было свободно ~10 Мб, стало 20 Мб (на самом деле свободного места больше, это ограничения квоты).
    Изучал еще раз CreateDialog-функции и пришел в к выводу:
    CreateDialog - создает пустой диалог на основе созданного класса (по имени) или взятого из ресурсов. Почти как CreateWindow.
    А вот функции CreateDialog, оканчивающиеся на Inderect и/или Param, это совсем другие вещи. Этим функциям надо передавать адрес структуры типа DIALOG(EX). В ней должны быть указаны данные о самом диалоге, о надписи, шрифте и о всех элементах управления диалога. То есть, эта ф-я создает диалог уже со всеми элементами управления.
    Решил попробывать первую (просто CreateDialog). Похоже тут тоже надо регистрировать класс. Но структура WMDCLASS(EX) не подходит - если передать имя зарегистрированного класса, то CreateDialog возвращает 1813 (не найден тип ресурса). Если использовать CreateDialogIndirect и передать ей адрес инициализированной DLGTEMPLATE(EX), (первые 3 переменных структуры == 0), то ф-я возвращает 1813 (ресурс не найден). В итоге, ни то, ни другое не работает.
    Как создавать классы для диалогов для ф-и CreateDialog?
    Почему не работает CreateDialogIndirect?
     
  5. slavanap

    slavanap Вячеслав

    Публикаций:
    0
    Регистрация:
    10 сен 2008
    Сообщения:
    300
    Адрес:
    Смоленск, Россия
    зачем извращаться.
    1. создаёшь ресурс типа Dialog/DialogEx (можно в Restorator'е, можно ещё где...),
    2. в редакторе ресурсов размещаешь на нем необходимые элементы: кнопки, поля и т.п.
    2. в своей проге вызываешь сначала InitCommonControls из ComCtl32.dll (если на диалоге есть элементы оттуда (SysTreeView, SysList ...), иначе не создастся).
    3. вызываешь CreateDialogParam (он отличается от CreateDialog всего одним параметром на конце. Этот последний параметр придет параметром lParam с сообщением WM_INITDIALOG (WM_CREATE не придёт!) в очередь сообщений окна.)
    Вызов: CreateDialogParam (<твой hInstance>, <имя диалога в ресурсе. если номер - придётся передать вместо строки в DWORD'е именно номер (не знаю, как сделать это в Си, извини)>, <HWND_DESKTOP или 0, что, вобщем-то одно и то же..>, <MainProc функция обработки сообщений диалога>, <заветный дополнительный параметр. не хочешь - можно 0> );

    да и, внимание!, в функции обработки сообщений вызов DefWindowProc(hWnd, message, wParam, lParam); придётся убрать.

    Да простят меня админы за то, что не могу прикрепить файлы. Рабочий пример: http://rghost.ru/267760

    p.s. DialogBoxParam отличается от CreateDialogParam только тем, что в DialogBoxParam сразу реализована очередь обработки сообщений (DispatchMessage, TranslateMessage...)
     
  6. Bazhan

    Bazhan Андрей

    Публикаций:
    0
    Регистрация:
    8 янв 2008
    Сообщения:
    71
    Адрес:
    Украина
    old:
    hWnd_dlg = CreateDialog(hInstance, (LPCTSTR)&dltt, hWnd_wind, (DLGPROC)Frm_MainProc);
    new:
    hWnd_dlg = CreateDialog(hInstance, (LPCSTR)Frm_Main, hWnd_wind, (DLGPROC)Frm_MainProc);
     
  7. AndreyMust19

    AndreyMust19 New Member

    Публикаций:
    0
    Регистрация:
    20 окт 2008
    Сообщения:
    714
    Я говорил зачем извращаться. Я тренируюсь в интерфейсных функциях. Конечно хорошо что вы отзываетесь, но вы говорите не про то, что надо. Про это я уже знаю:
    - это первое, что я попробывал сделать с диалоговым окном. Работает.
    Это я тоже уже знаю. Пробовал DialogBox вместо CreateDialog и цикл поставленный после не работал. Вы лучше помогите с созданием диалога без ресурсов, а с передачей структуры DIALOG(EX) ф-ии CreateDialogParam/Indirect.
    Про то что оказывается CreateDialog работает с ресурсами или именем класса я уже сказал в 4-м посте. Повторяю,меня интересует CreateDialogIndirect с его структурой DIALOG(EX). Почему она не работает?
     
  8. slavanap

    slavanap Вячеслав

    Публикаций:
    0
    Регистрация:
    10 сен 2008
    Сообщения:
    300
    Адрес:
    Смоленск, Россия
    GlobalAlloc, GlobalLock, запись данных DLGTEMPLATE, указатель на handle, полученный при GlobalAlloc передать в lpTemplate.... вроде бы так, хотя это изврат, конечно..
     
  9. AndreyMust19

    AndreyMust19 New Member

    Публикаций:
    0
    Регистрация:
    20 окт 2008
    Сообщения:
    714
    slavanap
    Да,
    судя по всему нужно попробывать GlobalAlloc и GlobalLock.

    Теперь диалог создается (смотри аттач). Кстати, адрес блока возвращает GlobalLock, а не GlobalAlloc. Вот смотри:
    Если в 3-ем параметре функции передать ((LPCDLGTEMPLATE)hg), где hg = GlobalAlloc(...), то возниканет ошибка 1407 (не найден WNDCLASS).
    Только в функцию CreateDialogIndirect надо передавать не возвращаемый адрес, а адрес адреса. Дело в том, что если 2-ой аргумент буфет такой:

    (LPCDLGTEMPLATE)addr

    то ф-я умрет из-за нарушения доступа:

    7E3767E3 nop
    7E3767E4 nop
    7E3767E5 nop
    7E3767E6 mov edi,edi
    7E3767E8 push ebp
    7E3767E9 mov ebp,esp
    7E3767EB mov eax,dword ptr [ebp+8]
    7E3767EE cmp word ptr [eax],0FFh // <- здесь

    Это начало функции. Команда 'cmp' проверяет - не является ли WORD по адресу, на который указывает 2-ой аргмент функции значением 'FF00h'. Это и должна делать ф-я в самом начале. Выходит, надо передать адрес указателя!
    Меняем:

    (LPCDLGTEMPLATE)addr -> (LPCDLGTEMPLATE)&addr

    Теперь наша CreateDialogIndirect все равно возвращает ноль (hWnd_dlg == 0), но зато Frm_mainProc получает сообщения типа 48, 2, 130.
    48 - это WM_SETFONT
    2 - WM_DESTROY
    130 - WM_NCDESTROY
    Почему нет WM_INITDIALOG? Диалоговое окно не появляется.

    Ковырялся, ковырялся, теперь наша процедура обработки сообщений дейстивтельно получает WM_INITDIALOG. Только вот окно не появляется и в его заголовке какие-то иероглифы написаны. Посмотри аттач.
    Осталось заставить показать созданный диалог.
    http://exfile.ru/44212