1. Пользуйтесь тегами кода. - [code] ... [/code] 2. Точно указывайте язык, название и версию компилятора (интерпретатора). 3. Название темы должно быть информативным. В описании темы указываем язык!!!
Я поставил пакет win32ada, он создал папку include\win32ada Если написать первой строкой test.gpr with "win32ada", то среда ругается при открытии пакета:
[2011-02-08 16:25:57] C:\Program Files\ADA\projects\TEST\test.gpr:1:06: unknown project file: "win32ada" [2011-02-08 16:25:57] Error while loading project 'C:\Program Files\ADA\projects\TEST\test.gpr'. Loading the default project.
Ну я это убрал. Добавил в test.gpr строчку
for Source_Dirs use ("..\..\include\win32ada\**");
Пишу в test.adb with win32.winuser (вроде все основные функции, типа окно нарисовать итд, там). Компилирую.
gnatlink "C:\Program Files\ADA\projects\TEST\test.ali" -shared-libgcc -g -g -fprofile-generate -o "C:\Program Files\ADA\projects\TEST\test.exe" c:/program files/ada/bin/../libexec/gcc/i686-pc-mingw32/4.3.6/ld.exe: cannot find -lwin32ada collect2: ld returned 1 exit status gnatlink: error when calling C:\Program Files\ADA\bin\gcc.exe gnatmake: *** link failed.
[2011-02-08 16:28:19] process exited with status 4 (elapsed time: 06.26s)
вроде все основные функции, типа окно нарисовать итд, там
Вот на это я бы вообще не закладывался, некоторые вещи будут не там, где ты ожидаешь.
А по проводу ошибки линкера - в проектах, использующих WinAPI - вот здесь есть пример минимального Win32-приложения: http://users.ncrvnet.nl/gmvdijk/w32first.zip , скачай его, и вот с таким GPR-файлом у меня только что откомпилировалось и заработало:
with "win32ada";
project Test is
for Source_Dirs use ("."); for Main use ("first.adb");
package Builder is for Default_Switches ("ada") use ("-O2"); end Builder;
package Compiler is for Default_Switches ("ada") use ("-O3"); end Compiler;
package Linker is for Default_Switches ("ada") use ("-s"); end Linker;
end Test;
Очень странно, что тебе приходится прописывать пути вручную. Дело в том, что в папке \GNAT\версия\lib\gnat после установки Win32Ada должен появиться файл win32ada.gpr, имеющий следующее содержимое:
project Win32Ada is
for Languages use ("ada");
for Source_Dirs use ("../../include/win32ada");
for Library_Dir use "../../lib/win32ada"; for Library_Name use "win32ada"; for Externally_Built use "true";
end Win32Ada;
, вот строка with в твоем "test.gpr" подключает этот файл, и не надо вручную прописывать пути. У тебя что, нет этого файла? Каждый пакет, который ты устанавливаешь, должен создавать такой GPR, в котором содержатся "свои" настройки, чтоб пакет использовать - достаточно подключить его через With в своем проекте...
Попробуй создать новый проект, и когда он будет создан - правой кнопкой мыши щелкнуть на корневом узле в Project View (название твоего проекта), и в меню выбрать Project -> Dependencies. Откроется окошко, в котором никаких зависимостей не будет (ну, понятно, проект-то новый). Жмешь кнопку "Add from known projects". Если в появившемся списке известных проектов тоже нет Win32Ada - значит, установка не завершилась корректно, где-то что-то недопрописано в настройках. Если есть - просто отмечай его галочкой и IDE сделает все остальное сама...
> Если в появившемся списке известных проектов тоже нет Win32Ada - значит, установка не завершилась корректно, где-то что-то недопрописано в настройках.
А там нету. Странно, вроде винада запустилась, что-то в консольном окне с процентами долго показывала...
Снес ГНАТ, переставил всё. Если прямо из среды дописать with "win32ada", то пересобирается нормально, но потом при открытии опять ругается. Да, в том списке зависимостей опять пусто.
Хм... Как вариант попробуй в зависимостях добавить через "Add from file" (у тебя ж Win32Ada.gpr есть, ты говоришь) вот этот самый файл: GNAT\2010\lib\gnat\win32ada.gpr ... И сразу после того, как это сделал (и прогрессбар исчез) - жми Project -> Save All... Только что попробовал - тоже отработало. А потом попробуй закрыть среду, и посмотреть что записано в первой строке твоего GPR-файла.
И, если опять будет ругаться при переоткрытии проекта - сделай скриншот, чтоб было видно полный текст ошибки, и содержимое Project View...
> А потом попробуй закрыть среду, и посмотреть что записано в первой строке твоего GPR-файла.
with "..\..\lib\gnat\win32ada.gpr";
> И, если опять будет ругаться при переоткрытии проекта
Не, теперь нормально открылось. Всё, наконец-то я могу перейти к окнам.
> - сделай скриншот
Если бы я в прошлый раз, когда добавил полный путь к файлу, сделал снимок экрана, то на нём бы самой интересной деталью был выродившийся ползунок в списке ошибок (там строчек за 1000 было).
> А по проводу ошибки линкера - в проектах, использующих WinAPI - вот здесь есть пример минимального Win32-приложения: http://users.ncrvnet.nl/gmvdijk/w32first.zip , скачай его, и вот с таким GPR-файлом у меня только что откомпилировалось и заработало:
Странно. Значит, я не оттуда брал тот тестовый пример, которым пользовался (скачан он был давно). Или компилировал другой файл...
В любом случае - ничего страшного. Строкой ниже указано, что делать. Смотришь, с каким типом у компилятора вышла заминка (в данном случае это Interfaces.C.unsigned), и добавляешь либо локально в этой функции, либо глобально для всего пакета, если подобная ошибка встречается несколько раз
use type Interfaces.C.unsigned;
То же самое касается и 83 строки, там придется добавить use type Interfaces.C.unsigned_long
Хинт: чтобы не подключать пакет Interfaces.C, можно заменить тип из Interfaces.C соответствующим типом из Win32. Например, Interfaces.C.unsigned = Win32.UINT, а Interfaces.C.unsigned_long = Win32.DWORD
Программу я скомпилировал. Но окно белое. Новый вопрос: что надо написать, чтобы скомпилировалось Wnd_Class.hbrBackground := Win32.WinUser.Color_BtnFace + 1; ?
Вопрос: в каком модуле описаны константы wmsz_TopLeft итд? Я ещё много вопросов буду задавать вида "в каком модуле описано что-то там". Вообще взаимодействие с виндой сделано очень неудобно, на каждый чих свой тип, всех их надо приводить, а то и конвертировать, на каждый чих компилятора долго подбирать какой тип в какой надо преобразовать, чтобы это скомпилировалось, кошмар. Да ещё и куча функций, требующих параметр по ссылке, а давать ссылку на локальную переменную нельзя, приходится портить код и заводить глобальные переменные для того, чтобы применить их в локальной процедуре и передать ссылку на них, либо заводить указатель и выделять память при входе в процедуру, короче, одни костыли кругом. И это всё из-за того, что нет out -параметров для функций, почему их раньше не ввели?
в каком модуле описаны константы wmsz_TopLeft итд?
Не описаны они вообще. Кому надо - тот открывает MSDN -> WM_SIZING Message, смотрит там на значения констант, и пишет себе в пакет:
WMSZ_TOPLEFT : constant := 4; WMSZ_TOPRIGHT : constant := 5; -- и так далее ...
Цитата
Вообще взаимодействие с виндой сделано очень неудобно, на каждый чих свой тип, всех их надо приводить, а то и конвертировать
Взаимодействие сделано в стиле языка. То, что в WinAPI куча дублирующих друг друга типов - это только проблемы WinAPI. Ада не может позволить программисту взять тип Integer, и использовать его как HBRUSH. Потому, что это сегодня они совпадают по размеру. А завтра (с выходом новой версии Windows или нового сервис-пака) могут и перестать совпадать. Именно поэтому, кстати, в свое время перестали работать многие программы при переходе Win16 -> Win32. А пользовались бы правильными типами (а не уверенностью в том, что размер одного будет вечно совпадать с размером другого) - работало бы до сих пор, достаточно было бы просто перекомпилировать код.
Цитата
на каждый чих компилятора долго подбирать какой тип в какой надо преобразовать, чтобы это скомпилировалось, кошмар.
Ничего не надо подбирать. Достаточно посмотреть на тип переменной-приемника, и привести тип переменной-источника (или выражения) к нему.
Цитата
Да ещё и куча функций, требующих параметр по ссылке, а давать ссылку на локальную переменную нельзя, приходится портить код и заводить глобальные переменные для того, чтобы применить их в локальной процедуре и передать ссылку на них, либо заводить указатель и выделять память при входе в процедуру, короче, одни костыли кругом.
Пример костылей можно посмотреть? Что-то я особых костылей, связанных с необходимостью передать по ссылке второй параметр BeginPaint, не вижу:
function Window_Proc (hwnd : Win32.Windef.HWND; message : Win32.UINT; wParam : Win32.WPARAM; lParam : Win32.LPARAM) return Win32.LRESULT is
> Не описаны они вообще. Кому надо - тот открывает MSDN -> WM_SIZING Message, смотрит там на значения констант, и пишет себе в пакет:
Ну сегодня константы описаны так, а в другой системе иначе. И перекомпилированная программа неверно работает. Ну в МСДН-то посмотреть я догадался, но как-то это неправильно, по-моему.
> То, что в WinAPI куча дублирующих друг друга типов - это только проблемы WinAPI.
Ну при переводе заголовков-то можно было все нужные типы к одному свести?
> Пример костылей можно посмотреть?
Например, в том примере:
msg : Win32.Winuser.LPMSG := new Win32.Winuser.MSG; Result := TranslateMessage(ac_Msg_T(msg));
А потому, что если просто написать
message: aliased Msg; // локально Result := TranslateMessage(message'access);
то компилятор выдаёт "non-local pointer cannot point to local object".
Unchecked_Access скомпилировался и заработал, спасибо (я сразу передавал в процедуру Message'Unchecked_Access, без промежуточной переменной Message_Ptr).
Я таки не понял, что происходит с исключениями внутри оконной функции? Я зашил содержимое главного оконного цикла (while getmessage(...)) в блок begin-except-end, а в оконной функции на нажатие ЛКМ сделал деление на ноль. При нажатии ЛКМ прога вылетела.
Хм. Извини, а с каких пор исключение может покидать пределы оконных функций и Callback-ов? Этого никогда нельзя было делать, насколько я помню. То, что где-то это работало - не повод думать, что оно должно было там работать.
Исключение должно быть обработано до выхода из оконной функции, и не должно передаваться дальше. Иначе система возьмет на себя его обработку. К чему это приводит - ты уже видел...