2 / 2 / 0 Регистрация: 25.09.2012 Сообщений: 148 |
|
1 |
|
26.09.2014, 22:42. Показов 13530. Ответов 2
Как исправить?
__________________
0 |
2649 / 2270 / 279 Регистрация: 24.12.2010 Сообщений: 13,725 |
|
26.09.2014, 23:02 |
2 |
Следует объявить класс Tform1 или сделать его объявление корректным.
0 |
пофигист широкого профиля 4602 / 3062 / 850 Регистрация: 15.07.2013 Сообщений: 17,660 |
|
27.09.2014, 01:21 |
3 |
Как исправить? Создай новую форму Меню File-New-VCL Form и сравни структуру своего модуля с тем что тебе создаст Дельфи. Найди 10 различий и исправь свой код.
0 |
Содержание
- Простые вопросы
- Error in module unit 1 declaration
- Здравствуйте, я ошибка 217 и я вам ничего не скажу
- Теория и анализ проблемы
- Отключаем финализацию модулей
- Пытаемся причесать хорошую мысль
- А не развить ли идею?
Простые вопросы
Пример
Delphi 7
FileNewApplication
Создал, далее удаляю весь старый текс и вставляю из примера и компилирую F9 — Ругается! — «Error in module Unit1: Declaration of class TForm1 is missing or incorrect»
Есть книга потихоньку читаю.
Но пока ни могу в голове уложить принцип вот в сети выкладывают исподники, как ими пользоваться?
Пример
Delphi 7
FileNewApplication
Создал, далее удаляю весь старый текс и вставляю из примера и компилирую F9 — Ругается! — «Error in module Unit1: Declaration of class TForm1 is missing or incorrect»
Есть книга потихоньку читаю.
Но пока ни могу в голове уложить принцип вот в сети выкладывают исподники, как ими пользоваться?
Прежде всего Delphi (object pascal) — структурный, подчёркиваю, структурный язык программирования. И для начала изучения тебе необходимо разобраться с этой структурой. Она очень проста и в любом нормальном учебнике по основам дельфина тема займёт страниц 5 не больше. Учить сейчас не чему не буду, а просто напишу как тебе воспользоваться тем примером, что ты написал в первом посте:
смотри код. найди «uses . » удали точку с запятой и напиши: ,ShlObj, ClipBrd;
это список подключённых модулей к проекту
теперь кинь с палитры компонентов (это там наверху =)) компонент кнопки — Button на форму. Кинул, да? Теперь иди сново в код. Найди что то в этом роде: <$R *.dfm>. Ставь туда курсор мышки, жми ENTER, даже для красоты оформления два раза жми и пиши
procedure CopyFilesT. и что там дальше у тебя в исходнике до //
теперь иди на форму. Щелкай два раза по кнопочке, которую ты положил на форму и пиши:
CopyFilesToClipboard(‘C:Bootlog.Txt’#0’C:AutoExe c.Bat’);
сверся с исходником — форум может некоторые символы игнорировать.
Запускай проект (F9).
Ни чяго не гарантирую, т.к. я не имею представления как ты это всё сделаешь по моему «уроку».
Источник
Error in module unit 1 declaration
Да что ты говоришь ?!
А как по твоему «люди жили» во времена, когда никакого «рефакторинга» в помине не было (BCB 6 и ниже, Дельфи 7 и ниже) ?
Добавлено 30.03.09, 17:47
PS: Хотя фиг его знает, чего там в суперновых версиях наворочали.
Добавлено 30.03.09, 17:48
Вот как я понял из того что делает Билдер 2007-й:
Caption — ну это понятно что — имя формы в шапке;
Name — это имя указателя на класс формы (по умолчанию совпадает с именем класса (TForm1)), при этом поменяв это имя у меня поменялось и значение Caption (чего не происходит при обратном действии)
Ну а название класса можно поменять только рефакторингом ибо х.з., но переименование вручняк вызывает ошибку (причём ошибку не компиляции, а просто окошко (компиляр даже не начинает работать. )), хотя переименовывал в тех же файлах.
Добавлено 30.03.09, 18:03
Перехожу на Билдер с ВС++, сюрпризов много
Просто если есть интерес переименовывать руками — то надо переименовывать везде, а то у тебя во всяких там dfm просто отсаётся и всё.
А вообще забавно, повеселил
Источник
Здравствуйте, я ошибка 217 и я вам ничего не скажу
Вероятно многие встречались с таким вот «партизаном» при старте или завершении приложения:
Очень информативное сообщение, сразу понятна причина ошибки, место и способ ее решения.
Впрочем, если без шуток, что это вообще такое?
Конечно-же это исключение, но ни тип исключения, ни его описание нам не доступны — просто «Runtime error 217» и адрес, а дальше сами…
Если честно, раньше я как-то даже не задумывался по поводу данного исключения, т.к. в моих проектах оно явление редкое, пока однажды у целой череды пользователей не начала воспроизводится именно 217-я ошибка.
Впрочем, даже тогда я не пошел по правильному пути и просто добавил дополнительный уровень логирования в проект, по результатам которого достаточно оперативно нашел причину и исправил ее.
Но, по сути, я просто потратил свое время…
И тратил бы его в дальнейшем, если бы на днях со мной не связался Виктор Федоренков и не рассказал о своих мыслях по поводу ошибки за номером 217.
Теория и анализ проблемы
Без теории нам никуда, иначе можем уткнуться в пределы собственных знаний.
Поэтому начнем, конечно, с теоретической части.
Для начала я немного освежил мои представления об ошибках в принципе, перечитав часть статьи «Обработка ошибок — глава 1.2.2» за авторством Александра Алексеева, откуда вынес информацию о том, что ошибка 217 будет отображена в том случае, если не инициализирован модуль SysUtils, причем это у Александра проиллюстрированно достаточно наглядно:
Открыть картинку в полный размер…
На основании данной картинки можно сделать грубый вывод: пока SysUtils жив — все исключения должны отображаться в нормальном виде, о чем идет отдельное упоминание:
Например, если вы видите сообщение о runtime-ошибке, то, судя по приведённой схеме, маловероятно, чтобы ошибка возникла в обработчиках событий на форме. Зато гораздо вероятнее, что она возникает, скажем, в какой-то секции finalization (которая выполняется после секции finalization модуля SysUtils) или в назначенной процедуре ExitProcessProc. Но, разумеется, причина ошибки может сидеть где угодно — в том числе и в упоминаемых обработчиках событий.
Ну что-ж давайте проверим, пишем код, в котором SysUtils должна быть финализирована позже модуля Unit1, в котором искусственно генерируем исключение:
Билдим, запускаем, закрываем форму и… Runtime error 217.
Утверждение о том, что 217 отображается после финализации SysUtils полностью верное, но давайте-ка посмотрим на сам код финализации:
Смотрите что происходит: в процедуре FinalizeUnits вызываются все финализирующие процедуры, адреса которых расположены в массиве InitContext.InitTable^.UnitInfo в том порядке, в котором происходила их инициализация, т.е. самые первые расположены в начале массива (а финализация идет с конца).
Где-то в самом низу расположен и SysUtils + System, ну а мы, с нашим модулем Unit1 где-то в самом верху.
Но вдруг происходит исключение в нашем модуле и «бабах», порядок катарсиса нарушен.
После «бабах» FinalizeUnits вызывается повторно, пропуская наш модуль, вызвавший исключение, вследствие чего разрушается SysUtils и разные, встречающиеся по пути, class destructor-ы, до кучи грохается System с менеджером памяти (сидящий одним из первых в начале списка), после чего идет контрольный выстрел в лоб — RAISE, вот тут-то мы и приплыли — здравствуй 217.
А что если произойдет исключение в секции инициализации любого модуля?
Да все тоже самое:
Делаем вывод: любое необработанное исключение в секциях инициализации или финализации будет приводить к потере описания исключения и приводить к ошибке 217.
На этом с теорией, думаю, закончим.
Имея на руках понимание о причине возникновения Runtime error 217, попробуем получить на руки более привычный нам вариант сообщения об исключении.
Отключаем финализацию модулей
В самом начале обсуждения Виктором был предложен достаточно эффективный способ обхода данной ошибки.
Его анализ заключался в следующем: общая инициализация обработчика исключений производится в процедуре InitExceptions модуля SysUtils, а финализация вызовом DoneExceptions.
Если каким либо образом отключить вызов DoneExceptions плюс не дать разрушиться менеджеру памяти, заблокировав вызов блока финализации System — на руки мы получим сообщение об исключении в приемлимом виде.
Как вариант решения был предложен следующий код, который нужно подключить к файлу проекта самым первым модулем (будет работать начиная с D2005 и выше):
Если честно — аплодировал стоя.
Вот он: хак в самом грязном виде как он есть — такие вещи могут делать только те, кто действительно понимает, чем это грозит 🙂
И данный модуль вывел работу нашего IT отдела примерно на три часа — это была жесткая дискуссия 🙂
Но, впрочем, давайте разберем логику работы данного кода:
Суть его проста, необходимо выйти на данные о загруженных модулях (включая BPL) в том виде, в котором их понимает Delphi приложение. Это было сделано посредством доступа к началу однонаправленного списка структур TLibModule. Первым элементом списка будет структура, описывающая текущий образ, откуда нам нужно всего-то и получить данные о структуре UnitInfo, которая содержит в себе данные как о количестве инициализированных модулей, так и об адресах их процедур инициализации и финализации в виде записи PackageUnitEntry.
Блокирование финализации модулей происходит посредством присвоения параметру FInit значения nil у каждой записи PackageUnitEntry.
При обниливании данного параметра FinalizeUnits не сможет произвести вызов обработчика и в итоге тот самый raise, о котором я писал выше, сможет достаточно корректно произвести отображение возникшего исключения.
Но вот дальше все сложнее.
Пытаемся причесать хорошую мысль
Идея здравая и причины понятны, но вот как-же так, ресурсы все-же не освобождены, FastMem перестанет нормально работать (она собирает утечки как раз при финализации), да и совместимости маловато, к примеру, как я и сказал выше, под Delphi 7 данный код вообще работать не сможет.
После первого часа обсуждений в IT отделе мы даже умудрились прийти и к такому выводу: «да и хрен с ними с SysUtils и System — что-то критичного они за собой не несут».
А потом, опять начали спорить — ну не устраивал нас этот подход, вроде все хорошо, но не аккуратненько как-то.
Рассматривались даже варианты прямого сплайсинга блоков финализации и до кучи деструктора Exception — но дополнительный хак, на уже существующий хак не устраивал вообще никого.
И тут, сидя в отладчике и прогоняя код по 70-му разу пришла мысля.
Дык эта… а как вообще выводится сообщение о произошедшем исключении?
А выводится оно посредством передачи управления на ExceptHandler, в коде которого нет ничего секретного.
А что мы делаем убирая финализацию модулей?
Правильно, заставляем вызваться его-же.
Попробуем-ка проэмулировать вызов ExceptHandler.
Пишем тестовый юнит и подключаем его к проекту самым первым:
Запускаем на выполнение и…
Получилось.
Встроившись в цикл финализации, мы отобразили произошедшее исключение и продолжили финализацию дальше вызовом Halt(1).
В итоге задача решена, грамотно и документировано, и совместимо с Delphi 7, но…
А не развить ли идею?
Есть такое понятие, как «наведенные ошибки», т.е. ошибки произошедшие из-за того что перед ними тоже произошла ошибка.
Ну к примеру, функция А, которая должна возвращать экземпляр некоего класса и функция Б, использующая этот экземпляр в работе. К примеру в функции А произошло необработанное исключение (например нет доступа к файлу) и она не создала класс, а потом где-то гораздо позже по коду приложения процедура Б выполняет обращение к этому экземпляру и в итоге происходит Access Violation.
Тоже самое может произойти и в процедурах инициализации/финализации, причем исключение, произошедшее в финализации скроет от нас саму причину.
Для демонстрации напишем вот такой код, в котором при инициализации приложения будет создаваться некий логер, в который будут писаться этапы работы приложения, а в финализации будет запись о завершении работы.
Для генерации исключения заставим логер создаваться по несуществующему пути:
Мало у кого в системе присутствует диск «А» поэтому результатом этого кода будет либо «Runtime error 216» (именно 216, а не 217), либо, если подключим код из предыдущей главы:
Exception EAccessViolation in module Project2.exe at 001B1593.
Access violation at address 005B1593 in module ‘Project2.exe’. Read of address 00000000.
А ведь причина то кроется в самом первом исключении, которое нами не отображается и с наскока разобраться в причине ошибки не получится.
Для того чтобы исправить эту несправедливость, можно немного причесать код и довести его до вот такого состояния:
Здесь идея проста, функция GetNextException по сути повторяет вызов AcquireExceptionObject, но после своего вызова не теряет ссылку на следующее в очереди исключение, а запоминает адрес следующего фрейма во внешней переменной.
После чего все исключения заносятся в список (самое последнее будет первым в списке) и выводятся программисту с соблюдением очередности, в результате чего нам будет сразу понятно, что сначала произошло вот это:
И уже только после него пошли всякие там AV.
Теперь по поводу остальных кодов ошибок.
Почему я начал именно с «Runtime error 217»?
Ну потому что она наиболее легко воспроизводима, а так технически, используя выше приведенный модуль, мы получим на руки вполне нормальное описание всех возможных Runtime ошибок, коих в наличии у нас вон сколько:
Вот таким небрежным кодом, мы можем получить то, о чем нам не хочет говорить ошибка под кодом 217.
Впрочем, я не думаю что этот подход будет незнаком опытным программистам.
Скорее всего это — здравствуй велосипед, ибо вероятнее всего данная проблема кем-то уже решалась ранее, но я просто не знал о данном решении.
А если нет — значит буду вторым.
Отдельный респект соавтору и вдохновителю данной статьи — Виктору Федоренкову.
Источник
|
|
|
[!] Как относитесь к модерированию на этом форуме? Выскажите свое мнение здесь
Как переименовать класс TForm1?
- Подписаться на тему
- Сообщить другу
- Скачать/распечатать тему
|
|
Как правильно переименовать создаваемый по умолчанию класс TForm1? Обычным образом я его не могу переименовать (правкой в Unit.h и Unit.cpp файлах) компилёр сразу начинает ругаться: типа «Declaration of class TForm1 is missing or incorrect». |
leo |
|
Просто измени св-во Name формы в инспекторе объектов |
Hyperman |
|
Сам себя и выручил. Методом «тыка». Оказывается, когда нажимаешь правой клавишей на имени класса, можно выбрать пункт Refactoring. Вот он то и позволяет правильно переименовать класс. Для новичков это знание очень полезно, а в книгах этого совсем не освещают — считают что переименовывать создаваемый класс просто незачем (хотя я могу привести пример когда программа не будет работать должным образом при стандартном имени класса). Добавлено 30.03.09, 17:42 Цитата leo @ 30.03.09, 17:38 Просто измени св-во Name формы в инспекторе объектов Это всего лишь меняет надпись на форме сверху, а я говорил про класс. (У меня класс называется «TTForm1», а название формы при этом «TForm12») Сообщение отредактировано: Hyperman — 30.03.09, 17:44 |
leo |
|
Цитата Hyperman @ 30.03.09, 17:40 Это всего лишь меняет надпись на форме сверху, а я говорил про класс
Да что ты говоришь ?! Добавлено 30.03.09, 17:47 Добавлено 30.03.09, 17:48 Цитата Hyperman @ 30.03.09, 17:40 Это всего лишь меняет надпись на форме сверху, а я говорил про класс. (У меня класс называется «TTForm1», а название формы при этом «TForm12») А ты случаем Name с Caption не путаешь ? Сообщение отредактировано: leo — 30.03.09, 17:49 |
Hyperman |
|
Вот как я понял из того что делает Билдер 2007-й: Caption — ну это понятно что — имя формы в шапке; Добавлено 30.03.09, 18:03 Сообщение отредактировано: Hyperman — 30.03.09, 18:03 |
brother79 |
|
Full Member Рейтинг (т): 13 |
Просто если есть интерес переименовывать руками — то надо переименовывать везде, а то у тебя во всяких там dfm просто отсаётся и всё. А вообще забавно, повеселил |
leo |
|
Цитата Hyperman @ 30.03.09, 17:59 Name — это имя указателя на класс формы (по умолчанию совпадает с именем класса (TForm1))
То, что рефакторингом можно поменять название любого класса — это понятно. Но в BCB 6 название класса формы также автоматически изменяется и при изменении ее св-ва Name, т.е. если вместо стандартного Form1 ввести MyForm, то название класса автоматом изменится на TMyForm во всех файлах юнита (*.h, *.cpp, *.dfm). |
0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
0 пользователей:
- Предыдущая тема
- Borland C++ Builder/Turbo C++ Explorer
- Следующая тема
[ Script execution time: 0,0275 ] [ 16 queries used ] [ Generated: 9.02.23, 13:59 GMT ]
Запускаю программу, которая рисует график по заданному уравнению в среде delphi с использованием opengl. выдает ошибку….не могу понять в чем дело, помогите пожалуйста!!
Заранее спасибо
Код:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
OpenGL;
type
TformGL = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormPaint(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
hrc: HGLRC;
end;
var
formGL: TformGL;
implementation
{$R *.DFM}
procedure TformGL.FormPaint(Sender: TObject);
const
a = 1;
var
x,y,r : GLfloat;
f : GLint;
begin
wglMakeCurrent(Canvas.Handle, hrc);
glViewPort (0, 0, ClientWidth, ClientHeight);
glClearColor (1, 1, 1, 1.0);
glClear (GL_COLOR_BUFFER_BIT);
glEnable (GL_POINT_SMOOTH);
glColor3f (0, 0, 0);
glBegin (GL_POINTS);
For f := -3000 to 3000 do begin
x := f/1000;
y := 8*a*a*a/(x*x+4*a*a);
glVertex2f (x/3,y/3);
end;
glEnd;
glBegin(GL_LINE_STRIP);
glVertex2f(-1,0);
glVertex2f(1,0);
glEnd;
glBegin(GL_LINE_STRIP);
glVertex2f(0,-1);
glVertex2f(0,1);
glEnd;
SwapBuffers(Canvas.Handle);
wglMakeCurrent(0, 0);
end;
procedure SetDCPixelFormat (hdc : HDC);
var
pfd : TPixelFormatDescriptor;
nPixelFormat : Integer;
begin
FillChar (pfd, SizeOf (pfd), 0);
pfd.dwFlags := PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER;
nPixelFormat := ChoosePixelFormat (hdc, @pfd);
SetPixelFormat (hdc, nPixelFormat, @pfd);
end;
procedure TformGL.FormCreate(Sender: TObject);
begin
SetDCPixelFormat(Canvas.Handle);
hrc := wglCreateContext(Canvas.Handle);
end;
procedure TformGL.FormDestroy(Sender: TObject);
begin
wglDeleteContext(hrc);
end;
end.
[COLOR=»Red»]___
Вот так оформляется код!
Модератор.[/COLOR]
-
#1
По сути говоря вылетает вот такая ошибка
procedure TForm1.Button2Click(Sender: TObject);
begin
idFTP1.Host:='aiochat.eu5.org';
idFTP1.Port:=21;
idFTP1.Username:='aiochat.eu5.org';
idFTP1.Password:='пароль; \ заменил тут
idFTP1.Connect;
IdFTP1.Put('c:chatlog.txt','chatlog.txt' ,false);
idFTP1.Disconnect;
end;
procedure TForm1.IdFTP1Connected(Sender: TObject);
begin
ShowMessage('Готово!');
end;
procedure TForm1.IdFTP1Disconnected(Sender: TObject);
begin
ShowMessage('чет не то');
end;
-
#2
Кажись кривую delphi скачал… Скачай лучше 10 Seattle
-
#3
Кажись кривую delphi скачал… Скачай лучше 10 Seattle
Благодарю