Закрыть ... [X]

Как сделать кнопку для делфи

Уроки Delphi

  1.  Первая программа

  2.  Использование компонентов

  3.  События Delphi

  4.  Типы данных Delphi

  5.  Создание своих типов данных

  6.  Выражения и операторы

  7.  Работа с файлами в Delphi

  8.  Дополнительные формы

  9.  Подпрограммы в Delphi

  10. Исключительные ситуации

  11. Взаимодействие приложения с пользователем

  12. Указатели в Delphi

  13. Обзор компонентов

  14. Работа со строками

  15. Создание интерфейса

  16. Графика в Delphi

  17. Многопоточность в Delphi

  18. Динамическое создание
        компонентов

Поиск по сайту


 Это важно:

   Метод Application.ProcessMessages;


 Это полезно:

   Параметр Sender в обработчиках событий;

Processmessages Работа с параметром Sender в обработчиках событий

Бояться не надо

   Редкая программа обходится одной формой. Мы можем с лёгкостью создавать дополнительные формы Delphi, предоставляющие возможность, например, вести диалог с пользователем, принимать и выводить любую необходимую информацию. В этом уроке научимся создавать несколько форм Delphi дополнительно к основной.

   Ввести новую форму в программу проще всего нажатием на кнопочку на главном окне Delphi. Также есть и соответствующая команда меню File -» New -» Form

Новая Форма в Delphi

  Форма создаётся вместе с новым модулем, описывающим её работу. Сразу же покажем, как удалить Форму из программы. Для этого также есть кнопочка, и команда меню Project -» Remove from project.... Так как Форма создаётся вместе с её модулем, то в появившемся окошке нужно выбрать модуль, который и будет удалён из проекта вместе с Формой:

Удаляем Форму из проекта Удаляем модуль из проекта

   Сразу возникает вопрос, а что будет, если попытаться удалить и модуль Unit1, что останется?. Выполните команду Project -» View Sourse. В редакторе кода появится новая вкладка, на которой будет отображён код Главного Окна программы (не Главной Формы, а именно Окна. В Windows ведь все объекты рассматриваются как окна.) Главное окно невидимо, но управляет всем проектом, и может работать вообще без Форм. Туда можно вставлять свой код, и писать нехилые программы, как в классическом Паскале.

   Все новые формы автоматически заносятся в разряд автосоздаваемых, то есть в начале работы программы они будут автоматически создаваться сразу, одновременно с первой, главной Формой проекта. Нам не придётся этим заниматься в программе, но одновременное создание многих форм занимает ресурсы и время программы. Поэтому предлагаю сразу научиться создавать нужные формы только в нужный момент.

   Во-первых, нужно отменить автосоздание форм. Выполните команду меню Project -» Options... В появившемся окошке отображаются Main form (главная Форма), Auto-create (автосоздаваемые) и Available (доступные) формы проекта. Нам нужно перевести Форму из разряда автосоздаваемых в разряд доступных Форм. Делается это нажатием кнопки " > " (обратная операция - нажатием кнопки " <</b> "):

Список Auto-Create форм Список Available форм

Таким образом, главная Форма Form1 создаётся сама, а дополнительную форму Form2 мы создадим в программе при необходимости.

   Если этого ничего мы не предприняли (что вполне допустимо при малом количестве дополнительных форм), то для появления новой Формы на экране достаточно написать:

   Form2.Show; // в случае обычной Формы
   Form2.ShowModal; // в случае модальной Формы

Если же мы перевели дополнительные Формы в разряд доступных, то перед каждым вызовом такой Формы необходимо делать проверку на существование Формы (оператором Assigned) таким образом:

   if (not Assigned(Form2)) then   // проверка существования Формы (если нет, то
       Form2:=TForm2.Create(Self);    // создание Формы)
   Form2.Show; // (или Form2.ShowModal) показ Формы

   Теперь разберёмся в разнице между обычными и модальными Формами. Обычные Формы позволяют свободно переходить между всеми Формами, находящимися в данный момент на экране. Модальная Форма в момент вызова блокирует переход между Формами проекта до тех пор, пока не будет закрыта, и работа возможна только в ней.

   При попытке компилирования программы, содержащей вызов второй формы, Delphi выдаст такой запрос:

вызов дополнительной формы

означающий:

Форма Form1 содержит вызов формы Form2, которая объявлена в модуле Unit2, но который отсутствует в списке используемых модулей. Вы хотите добавить его?

Нужно разрешить, и в начале модуля перед директивой
{$R.dfm}
будет добавлена фраза
uses Unit2;
В принципе, можно добавить её туда перед компиляцией "ручками", и тогда запроса не будет. Но смысл? Отвечаем "Yes" и снова жмём F9.

   Первым делом введём в форму операцию её закрытия! Сделать это можно несколькими способами. Возьмём кнопку, напишем "Закрыть" и в обработчике OnClick напишем:

Form2.Close; // В принципе, достаточно просто Close;

   Этот же оператор работает при вызове его из меню формы, если меню, конечно, туда ввести (компонент MainMenu на вкладке Standard), о чём в дальнейшем обязательно поговорим!

   Теперь же необходимо рассмотреть способ закрытия Формы, который относится именно к модальным формам. Он используется диалоговыми окнами с вопросом, требующим подтверждения, и в других аналогичных случаях. На Форме нужно расположить несколько кнопок, нажатие которых предполагает соответствующий ответ: "Да", "Нет", "Отмена", и т.д.
   У каждой кнопки есть свойство ModalResult, среди значений которой mrYes, mrNo, mrCansel и другие (посмотрите!). Значение ModalResult выбранной кнопки передаётся свойству ModalResult Формы. Это свойство отсутствует в списке свойств Формы, которые можно увидеть в Инспекторе Объектов, но программно оно доступно (напишите " Form2 ", поставьте точку и поищите в появившемся списке!).
   Нажатие кнопки со значением свойства ModalResult, отличного от mrNone, приводит к закрытию Формы, даже если у кнопки отсутствует обработчик нажатия! Затем можно проанализировать свойство ModalResult Формы и выяснить, какой же ответ на поставленный вопрос дал пользователь:

procedure TForm1.Button1Click(Sender: TObject);
begin
Form2.ShowModal;
if Form2.ModalResult=mrYes then   // Этот оператор будет доступен только после закрытия Form2
  Form1.Caption:='Пользователь ответил положительно!';
end;

   Как видно из этого примера, для доступа из одной Формы как к свойствам другой Формы, так и к свойствам её компонентов необходимо указывать имя Формы, к которой мы обращаемся. Мы также имеем доступ к данным, использующимся в модуле, описывающим её работу. Для этого необходимо указывать уже имя модуля. Например, для обращения к переменной X из модуля Unit2 пишем так: Unit2.X.
   Имеющейся возможности укрыть данные от использования в других модулях касаться пока не будем.

   В момент закрытия Формы часто в программе необходимо выполнить определённые операции. Делается это в обработчике события OnClose Формы. А теперь рассмотрим блокировку закрытия Формы. Если вдруг понадобится заставить пользователя выполнить определённые действия перед закрытием Формы (это касается как дополнительных форм, так и основной Формы программы), нужно воспользоваться обработчиком события OnCloseQuery. В этом обработчике определена переменная логического типа CanClose. Форма будет закрыта только в том случае, когда
   CanClose:=True;
Например, если создать такой обработчик OnCloseQuery основной Формы программы:

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  CanClose:=False;
end;

то пользователь просто не сможет закрыть программу иначе как через Диспетчер задач Windows!

Вопросы и комментарии (162)      Решение задач в Delphi

Виктор Евсеев, добавлено 23.08.09, 00:21:50 
Вообще, когда видишь такое, посещает мысль, а ведь это ж так просто, ну почему я это не смог придумать Респект автору :)
Адам, добавлено 17.10.09, 20:58:59 
На Ваш блог знакомый в аську ссылку кинул. Оказалось,что не зря :) Понравилось. Тепрь все время читать буду :)
CBИTOШA, добавлено 28.10.09, 14:48:30 
Скажите, а у вас есть RSS поток в этом блоге?
Автор, добавлено 28.10.09, 16:14:08 
Честно говоря, пока нет. Арнольд, добавлено 12.11.09, 05:09:32 
Не совсем уловил некоторые моменты, но в общем занятно :)
Святослав, добавлено 2.12.09, 18:36:12 
Познавательная статья, кстати автору хочу предложить установить от яндекс.денег полезную фишку на сайт "Дай рубль". Я бы дал, так сказать на поддержание. ;)
Виталий, добавлено 3.12.09, 16:09:34 
Вот запускаю я делфи у меня стоит первая форма, я ставлю на нее кнопку, создаю вторую форму. Какой код надо прописать для кнопки чеб при нажатии на нее открывалась вторая форма???????? Автор, добавлено 3.12.09, 16:58:23 
Издеваетесь? Вышенаписанное почитать не пробовали?
Валентин Родионов, добавлено 22.12.09, 22:46:09 
И как автору не влом столько времени на написание статей тратить, мы конечно Вам очень благодарны, но вот я на такой альтруизм не способен :)
Автор, добавлено 23.12.09, 08:31:27 
Ну, это не совсем альтруизм! По крайней мере, пока себя окупает. Anatoliy Tomskih, добавлено 27.12.09, 13:22:59 
Уважаемые авторы! Так и не нашёл ответа на отказы
программы Delphi 7 выводить текстовые файлы в Поле
TMemo операторами AssignFile(F,S),Reset(F) и
Memo1.Text := S. Delphi 7 сообщает о невозможности
найти путь к указанному файлу. С диалогами же работать умею, но хотел бы освоить файловую систему в Delphi 7. А. Томских, Забайкалье. Мой
ящик:. 27.12.09. Автор, добавлено 27.12.09, 13:51:27 
Можно, конечно, и так извратиться, но проще сразу считать текстовый файл самим компонентом TMemo:
Memo1.Lines.LoadFromFile('имя файла'); Влдимир, добавлено 30.05.10, 17:27:43 
А как присвоить переменной первой формы значение переменной второй формы ) Автор, добавлено 30.05.10, 18:29:54 
Я написал об этом выше, но повторю. Если модуль второй формы имеет имя Unit2, и в ней определена переменная Y, то переменной Х из первой формы её значение присваивается так:
Х := Unit2.Y;
То есть, для использования в другом модуле, перед именем переменной должно стоять стоять имя того модуля, где она определена. Артем, добавлено 3.06.10, 19:01:58 
А как можно использовать переменные первой формы во второй, если в коде первой формы уже написано uses Unit2? Автор, добавлено 4.06.10, 09:52:55 
Всё аналогично. Напишите в коде второй uses Unit1 и переменные первой формы станут доступны во второй. С указанием имени модуля первой формы, естественно. Аноним, добавлено 4.06.10, 17:10:20 
ситуация решилась сама. Нужно было всего-лишь записать uses Unit2 отдельной строкой, иначе компилятор выдавал ошибку circular unit reference. sitystroyinfo, добавлено 19.07.10, 10:11:18 
Очень хорошее и полезное сообщение. Сам недавно искал в интернете данную тему и все обсуждения связанные с ней.
Никита, добавлено 25.07.10, 23:15:09 
У Вас написано: if (not Assigned(Form5)) then // проверка существования Формы (если нет, то
Form5:= Form5.Create(Self); // создание Формы)
Form5.Show; // (или Form2.ShowModal) показ Формы
Пока не заменил строчку на
Form5:= TForm5.Create(Self);
Работать не хотело. А так заработало. ))) Автор, добавлено 26.07.10, 03:38:14 
Да, это моя ошибка, спасибо. Исправляю! Дмитрий, добавлено 5.09.10, 17:32:27 
Спасибо за статью!!! Я и не думал что все так просто :) spikeden, добавлено 20.09.10, 11:01:35 
Вопрос!)) Допустим у меня есть проект в дэлфаке и мне надо что бы в этом проекте открылась форма совесем из другого проекта, как бы мне её туда прикрепить что ли? Автор, добавлено 20.09.10, 11:36:35 
При работе в среде Delphi можно открывать формы и модули из любых других проектов. Они имеют расширение.pas и свободно открываются, даже если имеют одноимённое название с собственными модулями проекта. Однако ошибкой будет попытка открыть файл другого проекта (.dpr). Тогда текущий проект будет закрыт. spikeden, добавлено 20.09.10, 18:23:11 
хм, тогда ещё вопрос)) возможно ли как то обьеденить 2 проекта в один, просто у меня как то так получается, что одна часть программы писалась в моём проекте, а вторая дорабатывалась по скачанным исходникам, или мне проще будет создать новую форму и скопировать листинг программы? Автор, добавлено 20.09.10, 19:21:24 
Копируем нужный модуль в нашу новую папку. Затем жмём кнопочку с жёлтой папочкой и синим плюсиком, подсказка выскакивает "add file to project (shift+F11)" - ну или сразу shift+F11 и добавляем модуль в проект. Можно сразу из папки где он лежит, но потом запутаемся... spikeden, добавлено 20.09.10, 19:50:31 
спосибо за помощь))) и за ресурс тоже спасибо большое, хорошая помощь для студентов, таких как я, которые только начинают учить delphi)) Вадим Мошев, добавлено 12.11.10, 13:44:54 
У меня возникли вопросы. Один из которых звучит так.
Чем чревато то, что я поступаю следующим образом: Я создаю дополнительную форму, в её модуле, разделе Implementation пишу uses unit1;
Где Unit1 - модуль главной формы проекта, где в свою очередь я пишу тоже в разделе Implementation uses unit2;
Потом, для того, чтобы работать с дополнительной формой я пишу form2.show;
Вопрос: кроме съедания памяти (и вркмени) это червато чем-нибудь? Может это привести к ошибкам при дальнейней работе? Спасибо заранее! Автор, добавлено 12.11.10, 14:18:20 
Ничем это не грозит. Именно так и подключаются дополнительные Формы. Но если их много, то лучше создавать их по мере необходимости, а не сразу в момент старта программы. Для этого нужно убрать их из разряда автосоздаваемых, как написано выше. А если дополнительных форм 2-3 штуки, то можно не заморачиваться. Чайник, добавлено 26.12.10, 20:19:58 
Здравствуйте! Огромное спасибо за статью! Всё понятно. Вопрос такой: как сделать так, чтобы при открытии второй формы закрывалась первая? Автор, добавлено 26.12.10, 20:53:04 
Элементарно - именно, при открытии второй формы, по событию OnActivate, выполняйте FormN.Close, где N - номер предыдущей формы. Однако, если вы попытаетесь закрыть форму №1, то закроется вся программа, так как она обычно бывает Главной Формой программы. Поэтому форму №1 делайте невидимой, а программу выполняйте в форме №2, тогда третьей формой вы сможете закрыть форму №2. Чайник, добавлено 27.12.10, 05:15:08 
Спасибо! Всё очень понятно! Опять чайник, добавлено 27.12.10, 18:36:42 
Уважаемый автор! По ходу работы с формами возникла еще одна проблема. Запустила в форме фоновую музыку,по Вашему совету форму 1 сделала невидимой. По возвращению к форме 1 после закрытия других форм музыка не воспроизводится. Как сделать повтор? Спасибо за Ваши советы! Чайник, добавлено 27.12.10, 19:43:47 
А ведь дошло! Событие OnShow. Выполняю всё то же, что и при FormCreate. Музыка снова запускается. Всё очень просто благодаря Вам. Ещё раз спасибо! Вадим Мошев, добавлено 30.12.10, 16:30:15 
Мысли вслух: поскольку я НЕ досконально владею средой программирования и Делфи, эта конструкция
Form2:=TForm2.Create(Self)
кажется мне странной. TForm2 - это же тип. Ладно бы мы обращались к свойству ОБЪЕКТА этого типа, а так, как мне кажется, мы обращается к свойству самого ТИПА... Автор, добавлено 30.12.10, 17:49:18 
Да, действительно, как же можно использовать методы объекта, если самого объекта ещё нет!.. Дело в том, что есть методы, которые работают ещё до создания объекта - это методы класса (тип объекта может быть некоторого "класса") объекта. Например, такие как конструкторы Create и деструкторы Destroy. Всё это является областью объектно-ориентирванного программирования - ООП. Новичкам пока лучше с этим не заморачиваться. Хотя те, кто, как говорится, с молоком матери это впитал, потом чувствуют себя в ООП как рыба в воде. Вадим Мошев, добавлено 2.01.11, 15:58:47 
Здравствуйте (и с Новым годом), вопрос такой.
У меня есть форма (допустим Form1), на которой располагается кнопка, при нажатии на которую, открывается другая форма (например, Form2).
Код, стоящий в обработчике нажатия открывающей форму 2 кнопки, выглядит следующим образом, как и у вас написано:
Form2:=TForm2.Create(Self);
(кстати, я довольствуюсь одной это строкой, поскольку моя программа организована так, что повторно нажать на кнопку вызова формы 2 не получится, я просто прячу форму 1 после вызова).
Вот... Значит, всё работает замечательно.
По моему замыслу при вызове формы 2 у меня должна ещё и открываться и форма 3 (то есть при нажатии кнопки с формы 1 вызывается две формы, а не одна). (Кстати, на самом деле не форма 3, а форма 5, просто я так написал, чтобы вам было легче читать и понять меня, это не суть важно, мы будем называть её формой 3).
Форма 3 является модальной, это тоже не то, о чём я хотел говорить.
Проблема была в следующем, программа, когда натыкалась на строку
Form3:=TForm3.Create(Self);
Возникала ошибка Access violation.....
Я долго парился, в чём же тут дело, пробовал много вариантов, но ошибка не хотела уходить...
И тут я посмотрел на слово CREATE, и вспомнил, что у меня стоит обработчик события создания формы 3 (FormCreate). Я пошёл, закомментировал его тело с помощью комбинации //, то есть у меня этот обработчик после этого фактически перестал выполняться, ибо выполняться было нечему. После этого всё заработало.
Вопросы такие:
1. Обработчик события создания формы выполняется раньше её создания??
2. Что делать в том случае, если всё-таки мне необходимо выполнить комплекс каких-либо действий при создании формы с помощью обработчика FormCreate, а создаваемую форму я создаю посредством конструкции Form3:=TForm3.Create(Self);
Заранее спасибо за ответ.
Автор, добавлено 2.01.11, 17:32:48 
Не совсем понятно, как у вас вызываются эти формы 2 и 3. Я попробовал. Кнопкой на первой форме создаю и вызываю обе. И при событии onCreate третьей формы пишу
 Caption:='Изменение заголовка'; // Не важно что
Почему-то всё отрабатывает, при нажатии на кнопку выскакивают обе дополнительные формы, третья с изменённым заголовком... Каким образом вы прячете первую форму, может, дело в этом? Я просто написал перед вызовом форм Form1.Visible:=False. Или всё же используете объекты третьей формы, которые пока не существуют.
Попробуйте вместо onCreate выполнять действия в onActivate третьей формы. Вадим Мошев, добавлено 2.01.11, 18:04:27 
Сейчас объясню, как вызываю формы.
У меня есть форма 1. На ней стоит кнопка. При её нажатии у меня создаётся и показывается форма 2.
При наступлении события OnCreate у ВТОРОЙ формы у меня создание и показ третьей формы.
Надо бы попробовать так как вы этио сделали.
Да, кстати, ПРЯЧУ формы я методом form1.hide (я показываю form1.show) Автор, добавлено 2.01.11, 18:22:32 
А вот я попробовал сделать как у вас. В результате, как и следовало ожидать, вторая форма не появляется, так как третья форма создаётся в обработчике onCreate второй, а так как она модальная - вы сами написали, то её появление блокирует дальнейший ход программы. И - с изменённым заголовком. Кстати, Visible:=False и Hide - один эффект. Но ошибок нет никаких. Вадим Мошев, добавлено 2.01.11, 18:54:50 
Я виноват, немного кое-что неверно указал в своём вопросе.
По моему замыслу, когда я с формы 1 вызываю 2 и 3-ю, пользователь программы сначала должен поработать с 3-й формой, причём во время работы с ней 2-я форма должна быть ему недоступна. И только когда работа с 3-й формой завершена, он начинает работать со второй. То есть, на момент работы с 3-й формой работа всей остальной программы должна быть заблокирована.
А писал я о другом. У меня возникала ошибка Access Violation. В этом я виню обработчик события OnCreate. Как мне кажется, он вызывался раньше, чем форма была создана, то есть формы ещё не было, а обработчик мы уже вызываем, вот моё мнение. Бытовой пример: мы ставим стеклянную вазу на стол, которого ещё нет. Или же мы заселяем жильцов к квартиры дома, который ещё не построен.
Автор, добавлено 2.01.11, 19:33:38 
Ну я же промоделировал эту ситуацию, и всё сработало именно так, как вы и написали, непонятно, откуда у вас ошибка. И onCreate никак не может вызываться раньше создания формы. Итак, берём ваш вариант, когда третья форма создаётся в обработчике OnCreate второй. При этом вторая форма не только недоступна, но и пока не видна. В моём варианте - вторая уже видна, и так же недоступна. Саня, добавлено 24.01.11, 20:53:28 
Благодарю автора за труд, очень помогло!!!!! Антон, добавлено 26.01.11, 21:09:33 
Вопрос1: Как сделать форму модальной?
Вопрос2: Как сделать так, чтобы при нажатии кнопки в форме2 происходило событие в форме1? Автор, добавлено 26.01.11, 23:19:09 
1. Как сделать форму модальной
Нужно её вызвать как модальную - Form2.ShowModal;
2. Как сделать так, чтобы при нажатии кнопки в форме2 происходило событие в форме1
Никак. По-любому, при нажатии кнопки в форме 2 будет происходить событие нажатия кнопки в форме 2. А уж что вы будете делать по этому событию - от вас зависит, управляйте объектами и переменными в любых формах. Как - описано в тексте урока. Антон, добавлено 27.01.11, 19:33:41 
Премногоблагодарен.)) Евгений, добавлено 7.03.11, 14:33:54 
дравствуйте, у меня вопрос:
при записи
procedure TForm1.Button5Click(Sender: TObject);
begin
 if edit1.Clear = true then msg.show;
end;
вылетает куча ошибок и ворма не открывается, как быть? Автор, добавлено 7.03.11, 17:02:22 
Конструкция Edit1.Clear=true - бессмыслица. Edit1.Clear - это процедура очистки. Если вам нужна проверка на пустой Edit1, то это просто: Edit1.Text='', без пробела в кавычках. Евгений, добавлено 7.03.11, 17:11:07 
так я тоже пробовал, абсолютно тоже самое Аноним, добавлено 7.03.11, 17:25:36 
автор, скажи пожалуйста, как бы мне создать новый юнит (без формы) и перенести туда некоторые процедуры из основного юнита?
а именно, как сделать так, чтобы процедурам нового юнита были доступны переменные и компоненты основного юнита?
и еще конкретней: у меня на form1 лежит StringGrid1, как бы мне до него достучаться из unit2? Димон, добавлено 7.03.11, 17:26:16 
и кстати, я не аноним )) Димон, добавлено 7.03.11, 17:42:16 
и я же и отвечаю на свой вопрос:
в новом юните прописываем ссылку на основной не в первом uses,
а в uses после implementation.
я хз почему так, и как это работает, но работает (рекурсия, она повсюду 0.0)
Динарочка, добавлено 15.06.11, 07:52:50 
Очень интересный урок. Помогает при работе с данными компонентами! Мария, добавлено 27.06.11, 19:33:28 
Здравствуйте, подскажите, пожалуйста, есть две формы, на панели задач только первая, как добавить туда вторую, чтобы иожно было её менять( скажем, кнопки добавлять и тд)?
заранее спасибо) Автор, добавлено 27.06.11, 21:12:03 
На самом деле, на панели задач не первая форма, а главное окно приложения, которое управляет всеми формами, в том числе и первой. Просто ему придаются нулевые размеры, и оно невидимо. Попробуйте изменить заголовок первой формы, но на панели задач изменений не произойдёт, ведь главное окно вы не трогали. Теперь к сути вопроса.
ДЛя того, окна имели кнопку на панели задач, нужно изменить стиль окна. Вот как это делается, на примере второй формы:
type
  TForm2 = class(TForm)
  private
{ Private declarations }
procedure CreateParams(var Params: TCreateParams);
override;
...
procedure TForm2.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  with Params do
    ExStyle := ExStyle or WS_EX_APPWINDOW;
  end; Мария, добавлено 27.06.11, 22:30:16 
кажется, я не совсем правильно описала задачу
в моей программе есть 2 формы, при нажатии на кнопку на первой форме открывается вторая форма а первая скрывается,так вот, первая форма TForm1 = class(TForm), т.е. задана как главная форма, её я могу менять добавляя на неё всякие элементы
( кнопки, мемо и тд) и меняя их размер и положение, а вторую форму после создания я менять не могу, она вылезает в программе всегда в первоначальном виде, к ней у меня нет доступа, как исправить? помогите пожалуйста Автор, добавлено 27.06.11, 22:53:05 
Так вы хотите делать это программно, т.е. из первой формы создавать во второй форме компоненты динамически?
Тогда нужно создавать компоненты как переменные, и для ссылки на них использовать не Form2 а Unit2. Вот пример создания компонента TMemo:
procedure TForm1.Button2Click(Sender: TObject);
begin
  Unit2.Memo:=TMemo.Create(Self);
  Unit2.Memo.Parent:=Form2;
  Unit2.Memo.Top:=0;
  Unit2.Memo.Left:=0;
  Unit2.Memo.Visible:=True;
end;
Но предварительно эту переменную (var Memo: TMemo;) нужно объявить в модуле Unit2. Мария, добавлено 27.06.11, 23:11:56 
нет, насколько я поняла, это не обязательно
вот смотрите
я сохранила и закрыла программу, а при открытии заново файла.dpr не могу больше менять вторую форму, т.к. она не показывается, я к ней перехожу только при выполнении программы, но она уже остаётся в первоначальном виде
но мне нужно менять её не при выполнении программы, а при повторном открытии.dpr,т.е. необходим доступ к обеим формам, т.к. я выполняю часть программы, проверяю действии или закрываю программу, а потом открываю заново и возвращаюсь к редактированию форм, но ко второй при этом перейти уже не могу, могу редактировать только первую Автор, добавлено 27.06.11, 23:18:21 
Не можете открыть форму командой File - Open...? Откроется окошко, выбирайте форму (по имени её модуля: Unit2) и она откроется. То есть сначала открываете проект, при этом открывается и первая форма, а остальные открываете дополнительно. Мария, добавлено 27.06.11, 23:25:51 
получилось))
спасибо огромное!!!!)
просто только 2 дня назад начала дружить с Delphi ^^ Колян, добавлено 28.06.11, 00:03:30 
Привет. спасибо за статью, очень полезна оказалась)))))
не поможете в решение задачи:
Используя запись с вариантами ( или с классами, как будет проще), в которой хранятся значения основных параметров геометрических фигур( для треугольника – длина 3-х сторон, для прямоугольника – длина 2-х сторон, для окружности – радиус), а также координаты X,Y их положения на плоскости, нарисовать эти фигуры, поместив в центр каждой из них значение предварительно вычисленных площадей.
очень нужно совсем скоро сдавать (((((
буду очень благодарен!!!!!
Автор, добавлено 28.06.11, 09:00:05 
Вам сюда: programmersforum.ru
И то вряд-ли кто возьмётся. Ведь предполагается помощь, а не решение с нуля...
Иначе говоря, показываете ваш вариант, и спрашиваете, что не получается. тогда помогут. Дима, добавлено 21.07.11, 08:53:09 
При попытке компилирования программы, содержащей вызов второй формы, Delphi не выдает вопрос на связывание форм, приходится прописывать в ручную, может где-то что-то настроить надо? Автор, добавлено 21.07.11, 09:43:16 
Не встречал ничего подобного в настройках. Проводим эксперимент. Новый проект. Жмём кнопку для создания второй формы (New Form, или выполняем команду File - New - Form). Ставим на Форму1 кнопку, в обработчике нажатия пишем Form2.Show; и жмём F9. Неужели не вышло? Дима, добавлено 21.07.11, 10:13:21 
Эффект присутствия, видимо, сейчас все получилось ;-) Сергей, добавлено 19.10.11, 16:01:12 
Здравствуйте.
Помогите разобраться: у меня есть форма (Form1) из неё, при нажатии на кнопку, вызывается вторая форма (Form2), как сделать так, что бы при нажатии на кнопку на второй форме (Form2) вызывалась обратно первая форма (Form1).
Если можно с примером кода...
Заранее благодарен. Автор, добавлено 19.10.11, 21:59:29 
А как вы вызываете вторую Форму?
Form2.Show; - так?
Что мешает написать на второй форме то же самое:
Form1.Show; Сергей, добавлено 20.10.11, 09:29:36 
Вторую форму вызываю: Form2.Visible:=true, аналогично пробовал первую так вызывать, но без результатов. Дело в том, что пишу не в Delphi, а в FastReport (Скрипт Pascal) - аналогично Delphi.
Пробовал Form1.ShowModal - работает, но Form2 потом уже не вызывается, дело в том, что ShowModal - это модальный режим, после нажатия кнопки сразу закрываются все формы и выдается результат. Может как-то цикл попробовать?... незнаю что и делать.
procedure Button1OnClick(Sender: TfrxComponent); // нажатие на кнопку первой формы
begin
 DialogPage2.Visible:=true // вызываем вторую форму
end
 
procedure Button3OnClick(Sender: TfrxComponent); // нажатие на кнопку второй формы
begin
  DialogPage1.ShowModal // открываем первую форму в модальном режиме
 // DialogPage1.Visible:=true - так не работает
end; Автор, добавлено 20.10.11, 10:01:30 
Я про FastReport ничего не знаю, но вообще модальный режим это не когда закрываются все окна, а когда переход в исходное окно невозможен, пока модальное окно открыто. Нужно его закрыть. Тогда автоматически окажешься в исходном окне. Так может первое окно закрыть, и окажешься во втором? Но в Delphi этого представить не могу, ведь первое - главное окно, и его закрытие = закрытие всего приложения...
(PS, Окно - читайте Форма) Сергей, добавлено 20.10.11, 12:22:31 
Спасибо и на этом - трудиться и ещё раз трудиться... Алексей, добавлено 8.11.11, 21:04:01 
Привет, статья очень полезная
помогите в решение задачи:
как изменить курсор при нажатой лев. клавиши мыши, а при отпускании обратно?
Спасибо Автор, добавлено 8.11.11, 22:05:39 
Нужно воспользоваться таким глобальным объектом как Screen. Он создаётся для любого приложения автоматически. Так вот,
Screen.Cursor - текущий курсор для данного приложения.
Его значения можно посмотреть в свойстве Cursor любого компонента. Кроме них, можно также нарисовать любой свой курсор, с помощью специальных программ.
Вопрос ещё вот в чём. По какому событию вы будете менять курсор! Вы написали - нажати левой кнопки мыши, значит - OnMouseDown, а возвращать - OnMouseUp. НО!!! Для какого компонента будет это событие? Если нужно чтобы это не зависело от месторасположения указателя мыши, то можно создать обработчики этих событий например для Формы, а остальным компонентам просто присвоить их в Инспекторе Объектов. Для обработчика OnMouseDown такой код:
Screen.Cursor:=crDrag;//Значение для примера
Для обработчика OnMouseUp такой:
Screen.Cursor:=crDefault;
Вообще, конечно, нужно работу с курсорами описать как отдельную статью. А пока получилось так, что я стал делать ещё сайт про компонент StringGrid, про все его свойства, и т.д. Так вот, про свойство Cursor я там довольно подробно написал. Алексей, добавлено 10.11.11, 09:29:15 
Спасибо Автору за ответ.
Все сделал. Суть прог. такая:
СкролБокс делает прокрутку большого изображения (оно не умещается в него целиком) только когда мышкой передвигаешь ползунки по вертикали и горизонтали, при этом изображение не двигается вместе с ползунком, а двигается только после отпускания кл. мыши! (или я не до конца знаю все свойства СкролБокс)
Надо чтобы прокрутка была при движении колесика мыши (писал программу, сделал),
и чтобы прокрутка была при нажатой лев. кл. мыши и соответственно движении мыши в разные стороны (писал программу, сделал), а курсор сразу не удалось изменить при нажатой лев. кл. мыши на изображении, а при отпускании возвращать обратно. Автор, добавлено 10.11.11, 10:10:27 
То есть вам нужно было не по всему приложению изменить курсор, а только на изображении. Это проще. Я рад, если помог. Олег, добавлено 14.11.11, 11:11:18 
у меня есть форма на которой в StringGride происходят вычисления и если какое-то поле не заполненно то выбивается ошибка, как мне сделать так чтобы если поле не заполненно выскакивало сообщение Введены не все значения
Автор, добавлено 14.11.11, 14:09:20 
Есть тема - исключительные ситуации в Delphi. Делаем так:
try
  //Здесь вычисления
except
  ShowMessage('Введены не все значения');
end;
Короче, почитайте про исключительные ситуации. Денис, добавлено 16.11.11, 09:25:21 
У меня есть две формы на первой множество кнопок (button1, button2,...buttonN).
На второй форме есть компонент StringGrid,в третьей колонке (ColCount) каторого прописаны имена кнопок. Как сделать так, чтоб при двойном нажатии по строке компонента StringGrid нажималась кнопка первой формы с именем равным значению третьей колонки StringGrid Автор, добавлено 16.11.11, 21:43:45 
Если бы был один тип кнопок, то просто (для простоты у меня всё на одной Форме):
(Form1.FindComponent(Stringgrid1.Cells[3, Stringgrid1.Row]) as TButton).Click;
А если кнопки разных классов, то сначала нужно определить класс. Предлагаю простым перебором - у вас же не 100500 разных видов кнопок, ну максимум штук пять. Просто нужно этот оператор заключить в секцию try/except - итого штук пять таких секций, какая-то одна и сработает верно. А если это кажется вам извратом, то сначала проверяйте класс оператором is. Итого штук пять проверок. Вам выбирать. Денис, добавлено 17.11.11, 04:43:35 
Спасибо! Все работает! Только для третьей колонки нужно Stringgrid1.Cells[2, Stringgrid1.Row] писать. Олеся, добавлено 17.11.11, 10:25:03 
у меня не получается связвть переменные 2-х форм(( делаю все как написано выше(пишу во второй форме uses Unit1, n:=Unit1.a1; StringGrid2.Cells[1, 2] := IntToStr(n);) компилятор ошибки не выдает, но в итоге записывается в ячейку просто 0(хотя должно быть 10). 2 дня уже голову ломаю:-( Олеся, добавлено 17.11.11, 13:40:33 
я сделала кнопку на второй форме и все заработало)))))))а можно чтоб без кнопки,а сразу когда форма2 создается? Автор, добавлено 17.11.11, 13:56:29 
Ну да, только по событию OnCreate не получается - возьмите OnActivate. Аноним, добавлено 17.11.11, 14:04:21 
так тоже не получаетс(((ну ладно,придется дополнительно кнопку нажимать)))Спасибо за помощь)) Автор, добавлено 17.11.11, 14:10:42 
Получается с кнопкой? Ну напишите в обработчике OnActivate
Button1Click(Sender); - ну или как у вас кнопка называется. Наташа, добавлено 8.01.12, 15:28:52 
Прочитала статью, большое спасибо, но при работе ( у меня 7 версия) дополнительные формы не открываются.
это код основного юнита:
unit telo;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Grids, ExtCtrls;
type
  TForm1 = class(TForm)
  Button1: TButton;
  Button2: TButton;
  Label1: TLabel;
  Button3: TButton;
  procedure Button1Click(Sender: TObject);
  procedure Button2Click(Sender: TObject);
  procedure Button3Click(Sender: TObject);
  private
  { Private declarations }
  public
  { Public declarations }
  end;
var
  Form1: TForm1;
implementation
uses Unit21, Unit31;
{$R.dfm}
 procedure TForm1.Button1Click(Sender: TObject);
 begin
 try
  Hide;
  form2.Show;
  show;
  finally
  form2.Free;
  end;
 end;
procedure TForm1.Button2Click(Sender: TObject);
begin
try
  Hide;
  form3.Show;
  show;
  finally
  form3.Free;
  end;
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
  close;
end;
end. Автор, добавлено 8.01.12, 18:03:18 
Отвечу утром, как вернусь... Наташа, добавлено 9.01.12, 13:52:38 
жду, очень нужна помощь( Автор, добавлено 11.01.12, 05:56:21 
А чего у вас в секции uses написано Form21, Form31 a в программе Form2, Form3 - без единички? Наташа, добавлено 11.01.12, 12:30:02 
испарвила, но все равно не открываются.
на основной форме 2 кнопки, на которые нажимаю и должна выходить другая форма и дальше ввожу данные и считаю, но не получается( посотрела имена форм, изменила, но все равно Автор, добавлено 11.01.12, 15:51:29 
Вчитался. Вот у вас чего написано: открыть форму, а потом сразу закрыть - в секции финалли. Вот мы её и не видим. Финалли же исполняется в любом случае. Читаю с телефона, вот и проглядел. Наташа, добавлено 12.01.12, 14:31:54 
То есть финалли убрать нужно и что останется?( все равно ерунда какая - то( Наташа, добавлено 12.01.12, 15:18:19 
и еще пишу: k:=m/ptg(pt-ps)/Unit21.v0;
  u1:= piunit21.u/180;
  выдает ошибку:Undeclared identifier'v0' и 'u' Автор, добавлено 12.01.12, 15:25:48 
Наташа, если вам нужно открыть форму, так и пишите Form2.Show и не извращайтесь - зачем вам финалли??? А насчёт переменных, может, у вас форма называется Form21 а юнит просто Unit2 или переменная локальная? Я сам не угадаю. Наташа, добавлено 12.01.12, 16:27:05 
я и оставила только с Show и имена совпадают( но все равно не открывается...Спасибо, может придумаю другое оформление)а переменные были локальные, исправила) Павел, добавлено 17.01.12, 10:34:15 
Здравствуйте.
У меня такой вопрос:создаются 3 дополнительных формы.Первая создаётся в файле проекта. Её название- TitleForm.
  Application.Initialize;
  TitleForm:=TTitleForm.create(application);
  titleForm.showmodal;
  Application.CreateForm(TMainForm, MainForm);
  Application.Run;
При запуске программы выходит ошибка Access violation at adress, затем только появляется TitleForm.
Со 2-й и 3-й формами другие проблемы:при нажатии на кнопку в главной форме выходит 2-я форма.3-я форма должна выводиться при нажатии "Enter",но вместо неё снова выводится 2-я форма.Если же выводить 3-ю форму не по "Enter", а по нажатию на мышь, то выходит как надо 3-я форма. Автор, добавлено 17.01.12, 15:11:56 
Возможно, вначале нужно создавать MainForm, а уже потом дополнительные формы? А если вам нужно чтобы появлялись сразу и основная и дополнительная - TitleForm, то нужно всего лишь добавить ShowModal к тому коду, который генерирует Delphi, и всё. Зачем что-то выдумывать и создавать формы по-своему? У меня вот как это выглядит:
  Application.Initialize;
  Application.CreateForm(TMainForm, MainForm);
  Application.CreateForm(TTitleForm, TitleForm);
  TitleForm.ShowModal;
  Application.Run;
С другими формами мне вообще непонятно. Кода нет, о чём гадать?
Павел, добавлено 17.01.12, 15:24:53 
Всё, проблемы решились.Access violation at adress выходило из-за ошибки в TitleForm.FormCreate.А во втором случае неправильно был установлен фокус. Елена, добавлено 28.01.12, 20:30:24 
не совсем по теме вопрос. подскажете.может быть какие задачи можно реализовать в делфи в качестве научной работы в 11 классе? чтобы не сверх сложно, но графику можно было применить:) Автор, добавлено 29.01.12, 10:07:05 
Ой, я не в курсе, что в 11 классе научные работы выполняют! Вот одной студентке помогал домашнее задание делать: рассчитать функцию f=n!/n^n (n факториал делить на n в степени n). Но это без графики, одни расчёты. А с графикой можно придумать, например, сделать компьютерную модель чего-либо, чтобы как-то двигалось, менялось, взаимодействовало. Например, город. Несколько улиц. На перекрёстках светофоры. Работают с определёнными интервалами переключения. Сделать модель движения транспорта, и можно анализировать оптимальные интервалы в зависимости от количества машин в городе. (Машина на перекрёстке меняет направление движения случайным образом.) Это будет действительно научная работа. Сам придумал только что! Так что не взыщите, я же не препод. Аноним, добавлено 10.02.12, 16:03:48 
можете помочь. как сделать, что бы при при нажатие на кнопку открывалась следущая форма, если в edit написан определенный текст? а то я уже кучу сайтов облазил и нигде найти не могу(
примерно так:
 если edit1.text='1337(например)' то Form2.show Автор, добавлено 10.02.12, 19:49:41 
Ну, всё вы уже сами написали. Создаём обработчик нажатия на кнопку и там пишем:
if Edit1.Text='Нужный_Текст' then Form2.Show; Аноним, добавлено 11.02.12, 18:14:50 
Точно!
я оказывается в дельфи писал - if Edit1.text:=... с двоеточием, а тут почемуто без ))
Автор, добавлено 11.02.12, 18:35:27 
Путаете. Присвоение значения - с двоеточием, а в условном операторе - просто сравнение, без двоеточия. Глеб, добавлено 3.05.12, 21:33:55 
Добрый день!
У меня программы состоит из двух форм, я хочу сделать так что, когда одно форма находиться рядом с другой они объединялись в одну т.е. вплотную прилегали рамка к рамке и если я буду двигать одну то и другая должна двигаться
как это сделать, помогите плз. Автор, добавлено 3.05.12, 23:36:32 
Ребят, я конечно могу всё это, ну а сами-то... В Инспекторе Объектов посмотрите событие, отвечающее за движение Формы, расстояние между краями Форм наверное сможете найти - всё же студент, а не пятиклассник! Если оно меньше определенного значения, подвиньте до нуля. Ну и дальше так же двигайте. Утром я попробую расписать. Глеб, добавлено 4.05.12, 03:27:28 
Автор, если вы говорите про "ScreenSnap, нужно поставить его в TRUE и окно будет прилипать к крям экрана на количество пикселей указанное в свойстве SnapBuffer (по умолчанию 10)" то это не то, что мне нужно. Мне нужно если одна ФОРМА находиться рядом с другой ФОРМОЙ то она должна привязываться к форме, как в тех св-ва, что вам выше описал. Теперь сложнее, после того как одна форма привязалась к другой мне надо, что если я начну двигать одну форму то все формы, которые повязаны двигались за ней т.е. склеивались, как клеим и превращались в одну.
Автор, добавлено 4.05.12, 04:39:25 
С чего вы взяли про снап? Если бы я хотел про снап, то так бы и написал. Да понял я вас - вторая форма как бы дополнение первой с соответствующей стороны, и двигаются обе как одна. Чего тут сложного? Подождём утра. Автор, добавлено 4.05.12, 13:15:14 
Да, всё оказалось несколько сложнее, чем представлялось, так как в Инспекторе Объектов нет события, отвечающего за перемещение Формы. И что? Лезем в интернет, задаём гуглу вопрос: "событие движение формы delphi". И получаем нужный ответ. Это событие отлавливается через сообщение системы. Далее высчитываем растояние между краями Форм и подвигаем на это расстояние соответствующую форму. И вот тут возникает конфликт взаимовлияния, так как движение одной формы вызывает изменение в движении второй, а это изменение тут же сказывается на первоначальном движении - возникает "мерцание". Хотя формы всё же движутся вслед друг за другом. Правда, если резко двинуть, то произойдёт отрыв. Скачайте, посмотрите, может, сможете улучшить. Глеб, добавлено 4.05.12, 17:44:17 
Автор, спасибо за информацию сейчас посмотрю, что можно сделать Александр, добавлено 5.05.12, 18:26:13 
подскажите пожалуйста, а как одну форму сделать по верх другой? Автор, добавлено 5.05.12, 18:42:40 
Form1.FormStyle:=fsStayOnTop; Александр, добавлено 28.05.12, 16:00:14 
Подскажите, а как вписать новую форму по размерам в основную. (при раскрытии допустим wsMaximized). Так чтобы меню основной формы всегда оставалось видимым. Автор, добавлено 28.05.12, 16:09:49 
Не совсем понимаю вопрос. Ну просто поддерживайте значение Form.Top таким чтобы меню первой формы было видно... Аноним, добавлено 29.05.12, 15:15:54 
в этом и проблема если воспользоваться свойством onResize или can.... то он размеры начнёт изменять пока форма не исчезнет, если отслеживать wsMaximized то событие происходит до изменения размеров. Автор, добавлено 29.05.12, 15:20:32 
Не, не могу врубиться в то что вы делать хотите. Если есть код, копируйте сюда. Александр, добавлено 29.05.12, 15:22:33 
пример по событию onResize
procedure TForm2.FormResize(Sender: TObject);
begin
if WindowState=wsMaximized then
 begin
  if ClientHeight>=form1.ClientHeight then
  begin
  form2.Top:=form2.Top+25;
  ClientHeight:=ClientHeight-25;
  end;
 end;
end;
и второй
procedure TForm2.WMSysCommand;
begin
  case Msg.CmdType of
  SC_MINIMIZE:
  begin
 
  end;
  SC_MAXIMIZE:
  begin
  form2.Top:=form1.Top+25;
  form2.Height:=form1.Height-25;
  end;
  end;
  inherited;
end;
1й пример срабатывает только 1й раз далее если форму сворачивать и разворачивать то он перестаёт работать. Второй просто не работает.
пробовал задать выброс сообщения так он мне его при смене размера формы раз по 20 выдавал, а понять почему не могу (скорее всего изменение размера программно тоже приводит к событию onResize.? Автор, добавлено 29.05.12, 16:39:56 
Попробуйте вот так:
procedure TForm2.FormCanResize(Sender: TObject; var NewWidth,
  NewHeight: Integer; var Resize: Boolean);
begin
if Top < Form1.Top+90 then
  begin
  Resize:=False;
  Top:=Form1.Top+90;
  end;
end;
Правда, первая форма при этом отрисовывается не полностью (первый раз!). Что с этим делать пока не придумал. Может, сами? СанЁк, добавлено 20.06.12, 02:52:21 
Наконец то русским языком написано. Спасибо большое! Евгений, добавлено 27.03.13, 05:51:32 
Здравствуйте подскажите пожалуйста у меня возникла проблема.
Я пытаюсь сделать в программе автозапуск с системой по CheckBox1 точнее сделал, но он работает только с главной формы, а у меня в программе настройки находятся на другой форме при этом автозапуск не работает подскажите как решить проблему? Автор, добавлено 27.03.13, 07:23:07 
Я пытаюсь выделить инфу из вашего сообщения и... не могу. Ничего не понятно.
1. Автозапуск с системой по CheckBox - это что?
2. При чём здесь настройки и то где они находятся? Аноним, добавлено 27.03.13, 11:49:37 
Вот код
procedure TSetings1.CheckBox5Click(Sender: TObject);
var
  reg: TRegistry;
begin
  reg := TRegistry.create;
  reg.rootkey := hkey_current_user;
  reg.lazywrite := false;
  If CheckBox1.Checked then
  begin
  If reg.OpenKey('Software\Microsoft\Windows\CurrentVersion\Run', true) then
  begin
  reg.WriteString('progrmma', application.exename);
  reg.CloseKey
  end;
  end
  else
  begin
  If reg.OpenKey('Software\Microsoft\Windows\CurrentVersion\Run', false) then
  begin
  if reg.ValueExists('progrmma') then
  reg.DeleteValue('progrmma');
  reg.CloseKey;
  end;
  end;
  reg.free;
end;
Setings1 форма 3
Clock1 Главная форма программы
Программа компилируется, но автозапуск не происходит Евгений, добавлено 27.03.13, 11:52:34 
Имя программа это Clockv210
Евгений, добавлено 27.03.13, 11:56:03 
Извиняюсь с кодом напутал
Вот верный
procedure TSetings1.CheckBox5Click(Sender: TObject);
var
  reg: TRegistry;
begin
  reg := TRegistry.create;
  reg.rootkey := hkey_current_user;
  reg.lazywrite := false;
  If CheckBox1.Checked then
  begin
  If reg.OpenKey('Software\Microsoft\Windows\CurrentVersion\Run', true) then
  begin
  reg.WriteString('Clockv210', application.exename);
  reg.CloseKey
  end;
  end
  else
  begin
  If reg.OpenKey('Software\Microsoft\Windows\CurrentVersion\Run', false) then
  begin
  if reg.ValueExists('Clockv210') then
  reg.DeleteValue('Clockv210');
  reg.CloseKey;
  end;
  end;
  reg.free;
end;
Setings1 форма 3
Clock1 Главная форма программы
Программа компилируется, но автозапуск не происходит Автор, добавлено 27.03.13, 12:45:23 
Ну вот, сразу бы так.
Эксперимент: берём приложение из двух форм, на второй сажаем CheckBox, в его обработчик OnCklick копируем ваш код. Вуаля, всё работает - редактор реестра показывает что по щелчку по чекбоксу запись в реестре появляется и исчезает. Ну и, собственно, автозагрузка происходит, что и требовалось доказать. Евгений, добавлено 27.03.13, 13:52:42 
Странно я сделал новую программу и всё работает, а в той с которой код писал нет и понять не могу почему ошибок нет!? Евгений, добавлено 27.03.13, 16:32:21 
Спасибо за помощь, я разобрался наконец то всё работает!
У меня всё так и было только с цифрой CheckBox'а ошибся в коде выше это видно. Сергей, добавлено 24.04.13, 13:25:04 
Доброе время суток.
Я хочу, чтобы по нажатии кнопки CanClose меняло свое значение на True и выполнялась команда Close. Пробовал так:
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
CanClose:=False;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
TForm1.FormCloseQuery(TObject, True);
Close;
end;
end.
Пишет: Incompatible types:'TObject' and 'Class reference' и указывает на TObject. Что нужно сделать, чтобы заработало? Автор, добавлено 24.04.13, 15:08:43 
Так вообще делать нельзя. Процедура CloseQuery вызывается при закрытии Формы, её не нужно вызывать вручную. И просто в этой процедуре прописываете условие закрытия Формы, для этого приравниваете CanClose True или False. В вашем случае вводите глобальную переменную типа Boolean, нажатием кнопки меняете её значение, и пытаетесь закрыть Форму. А в процедуре CloseQuery анализируете вашу переменную, или просто приравниваете к ней CanClose:
var MyClose: Boolean=False;//глобальная переменная
procedure TForm1.Button1Click(Sender: TObject);
begin
MyClose:=not MyClose;
Close;
end;
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
CanClose:=MyClose;
end;
Аноним, добавлено 24.04.13, 16:08:40 
Понял. Большое спасибо работает.
То есть встроенные процедуры Delphi типа TForm1.Button1Click, TForm1.FormCloseQuery и т.п. лучше вручную не вызывать? Автор, добавлено 24.04.13, 17:45:27 
Ну почему, Button1Click очень даже нужно вызывать при необходимости. Да и CloseQuery можно вызвать иногда. Но в данном случае закрытие формы и так происходит, поэтому дополнительно вызывать CloseQuery будет ошибкой. К тому же, эта процедура не вызывает события закрытия Формы, наоборот - закрытие Формы вызывает эту процедуру. Евгений, добавлено 26.04.13, 12:09:46 
Здравствуйте! Подскажите пожалуйста у меня возникла проблема.
дело в том что я сделал программу, которая сворачивается в трей при запуске и запускает одну из форм, когда главная свёрнута, но при повторном написании такой - же программы у меня этого сделать не получается сначала выдавала ошибку, а теперь не выдаёт, но и запуска формы3 не происходит, а в пробном экземпляре выдаёт ошибку Аноним, добавлено 26.04.13, 15:02:10 
Я не в силах разобраться в этом вопросе... Аноним, добавлено 18.07.13, 16:58:29 
Читай литературу! Олжас, добавлено 24.10.13, 23:50:23 
классный урок!!! :) Сергей, добавлено 5.11.13, 13:04:19 
Спасибо, тема очень помогла. Но возник вопрос: мне необходимо передать данные из главного окна во второе, чтобы уже во 2-м окне обработать эти данные, как это можно сделать? Автор, добавлено 5.11.13, 14:44:37 
С данными можно будет работать, если в секции uses будет ссылка на Unit1. А что, у вас не получается? Павел, добавлено 11.11.13, 16:18:38 
Пишу что-то аську локального масштаба.
Вопрос такой: нужно динамически создать форму с несколькими компонентами (на счет компонентов нет проблем), и добавить свойство форме.
Пытался сделать копию класса:
  TMyForm кнопку = class(TForm)
  Memo2: TMemo;
  private
  { Private declarations }
  public
  UserId: Integer;
  { Public declarations }
  end;
var
  MyForm: TMyForm;
  i: Integer;
//создаем форму, чтоб инициализировать счетчик
procedure TForm1.FormCreate(Sender: TObject);
begin
  i:=0;
end;
//нажимаем кнопку для создания новой формы и присвоения ей номера
procedure TForm1.ButtonClick(Sender: TObject);
begin
  FormChat:=TMyForm.Create(Application);
  FormChat.UserId:=i;
  FormChat.Show;
  Inc(i);
end;
Но почему-то выдает Resource TMyForm not found.
Подскажите, что я сделал не так, и что нужно сделать, чтоб эта форма была независимой от первой (в плане сворачивания в панель задач) и отдельной кнопкой на панели задач?
P.S.: Если я знаю Handle объекта, то можно ли обратиться к этому объекту по Handle?
Спасибо.
Павел, добавлено 11.11.13, 16:19:30 
Возможно новых свойств в форме будет больше. Павел, добавлено 11.11.13, 16:33:33 
к P.S...
Точнее не объекта, а процесса. Правильно ли я понял, что у всего, что создано в Application есть свой Handle? У формы, у Thread`а, у Socket`а... Автор, добавлено 11.11.13, 17:32:56 
У каждого окна свой Handle. В данном случае имеется в виду, что окно это не только Форма.
Далее. Я, конечно, не большой знаток ООП, но так создавать тип TMyForm нельзя - вместе с объектами. Типы создаются на основе готового типа - прародителя. А у нас в наличии нет готовых типов с Memo и другими объектами в комплекте. Так что вначале создайте пустую Форму, а потом на ней уже объекты. Ну или спроектируйте в среде Delphi (не динамически, обычно) Форму с объектами, это будет тип - прародитель. Ну и далее можно на основе этой Формы наделать динамически таких Форм сколько нужно. Павел, добавлено 11.11.13, 17:42:44 
Спасибо за ответ.
Но еще один вопрос: можно ли в форму, которую я буду копировать, добавить еще какие-либо свойства? Хотя бы тот же самый UserId (integer) или Login (string)... Павел, добавлено 11.11.13, 17:47:15 
И еще все-таки вернусь к Handle.
У каждого Socket`а есть Handle. Хотя это не визуальный компонент.
И в случае с сервером (когда на него коннектятся много клиент-сокетов) я хочу Handle сокет-соединения использовать для идентификации пользователя. Чтоб знать в какой сокет сервер должен ответить в каком-либо случае.
И вопрос соответственно такой: можно ли как-то обратиться к сокету с данным Handle? А не перебирать все Socket.Connection[i] в поисках их Handle`ов... Автор, добавлено 11.11.13, 18:05:26 
Вы можете спроектировать любую форму, со свойствами, переменными, объектами. И на основе типа этой формы динамически делать её копии.
Насчёт сокетов ничего сказать не могу, я далёк от этого. Павел, добавлено 12.11.13, 08:19:10 
И снова я попытаюсь вернуться к моим баранам... :)
Я все-таки сделал так, чтоб на панели задач были отдельные кнопки для каждого окна.
Однако они не совсем отдельные, как могло бы показаться на первый взгляд.
При сворачивании основной формы (основного окна), сворачиваются и исчезают с панели задач и остальные дочерние кнопки...
Как мне от этого избавиться?
Буду премного благодарен за помощь... Павел, добавлено 12.11.13, 08:44:52 
И снова это я. :)
А вопрос на этот раз такой: Как мне при создании n-ного количества форм через
var
  FormChat: TForm;
FormChat:=TForm.Create(Application);
FormChat.Show;
обратиться ко всем созданным формам поочередно (неизвестно, сколько будет созданных форм)? FindComponent для самих форм не подходит, т.к. он только с визуальными компонентами внутри формы работает. Автор, добавлено 12.11.13, 13:42:58 
1. Так как вы сделали, наверное никак. При сворачивании главной Формы другие свернутся. Значит, что? Первую Форму не нужно использовать! Начинайте сразу со второй, она и будет главная. Тогда при её сворачивании остальные останутся.
2. А по имени не пробовали, свойство Name. При создании форм задайте им имена, да? Павел, добавлено 12.11.13, 14:21:24 
Спасибо за советы, но я на citforum`е попросил помощи по данным вопросам...
По поводу первого вопроса мне посоветовали то же самое.
По поводу второго есть такое решение (по перебору всех форм):
Сами формы перечислены в списке Screen.Forms
В частности пример:
procedure TForm1.Button1Click(Sender: TObject);
var
  I: Integer;
  s: string;
begin
  for I := 0 to Screen.FormCount-1 do
  begin
  Memo1.Lines.Add(Screen.Forms[I].Name);
  Screen.Forms[I].Height:=600;
  end;
end;
(может кому и пригодится...)
Мне осталось только в динамически создаваемые формы научиться добавлять несколько свойств, чтоб можно было там хранить какие-либо идентификационные данные. Павел, добавлено 12.11.13, 14:23:41 
Точнее на cyberforum`е... Автор, добавлено 12.11.13, 14:47:04 
Ну задайте несколько переменных при конструировании формы, не пойму в чём проблема. Павел, добавлено 12.11.13, 15:05:51 
Мне нужно, чтоб можно было обращаться к этим данным как-то так: :)
Screen.Forms[I].MyVar1:=num1;
if (Screen.Forms[I].MyVar2=num2) then
begin
  что-то делать
end;
А еще я у вас на сайте видел, что есть такие типы переменных, как Point.
Можно ли их приспособить под формы?
Что-то вроде этого:
User32^[4]:=Screen.Forms[I];
и потом использовать:
User32^[4].Height:=600;
Чтоб таким образом сокращать имена форм и без перебора всех форм обращаться по поинтам?
Спасибо за терпение. :) Автор, добавлено 12.11.13, 15:16:56 
1. Вы что никогда к переменным других форм не обращались? Ну да, как-то так.
2. В Delphi нужно стремиться всеми способами избегать использование указателей. Это потенциальный источник ошибок. И уж точно, не в данном случае. Перебор форм нужно использовать, если только ищете форму с конкретным значением некоего свойства. И указатель вам здесь никак не поможет. Также будете перебирать указатели. Павел, добавлено 12.11.13, 15:33:53 
А что мне тогда можно использовать, чтоб обращаться к нужной форме без перебора всех форм?
Создавать массив, в котором порядковый номер формы будет ассоциироваться с каким-нить идентификатором (id)?
Но формы можно закрыть. Тогда добавится геморрой по поиску в этом массиве номера закрытой формы, и удаление его из этого массива со смещением индексов всех позжеоткрытых идентификаторов в сторону единицы. Если я в чем-то не прав, то прошу меня поправить. Или дать совет, в какую сторону лучше рыть...
P.S.: как я уже говорит -- неизвестно, сколько будет форм. В каждой форме будет общение с определенным человеком (как в аське). Поэтому надо как-то их идентифицировать, и при нужде обращаться без перебора всех форм. Автор, добавлено 12.11.13, 17:57:48 
А что будет если форму F[i] как элемент массива закрыть? Если обратиться к ней, что будет? Допустим, ошибка. Тогда воспользоваться блоком обработки ошибок try/except. Автор, добавлено 12.11.13, 18:02:39 
А строго говоря, здесь работает однонаправленный список указателей! Если какая-то форма пропадает, просто в предыдущем элементе списка указатель на следующую перемещается с закрытой на ту, на которую указывал указатель закрытой формы. Этим экономится память. Пока я это освоил, голову сломал. Автор, добавлено 12.11.13, 18:09:44 
А обращаться без перебора, опять же по имени. Когда создаётся форма для диалога, она-то знает, кого она соединяет. Или вот я хочу кому-нибудь послать сообщение. Я-то знаю кому, имя его или как вы их различаете. Если при посылке сообщения человека нет в сети, это должно быть как-то понятно, ошибка ли происходит или некое сообщение приходит. Вот и всё. Павел, добавлено 14.11.13, 17:26:00 
Я пока разбирался с созданием событий для динамически созданных форм.
Но пришлось вернуться к вопросу об обращении к определенной форме.
Динамические формы создаются с именами User+n, где n -- целое число, начиная с 0
unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
type
  TForm1 = class(TForm)
  Button1: TButton;
  Memo1: TMemo;
  procedure Button1Click(Sender: TObject);
  procedure FormCreate(Sender: TObject);
  private
  { Private declarations }
  public
  { Public declarations }
  end;
  TFChat = class(TForm)
  Memo2: TMemo;
  Button2: TButton;
  procedure Button2Click(Sender: TObject);
  procedure FormCreate(Sender: TObject);
  private
  { Private declarations }
  public
  { Public declarations }
  end;
var
  Form1: TForm1;
  FChat: TFChat;
  i: Integer;
implementation
{$R.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
  i:=0;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
  FChat:=TFChat.CreateNew(Application);
  FChat.Name:='User'+IntToStr(i);
  Form1.Memo1.Lines.Add(FChat.Name);
  FChat.OnClose:=FChat.FormClose;
  //создаю динамические объекты на динамической форме
  FChat.Memo2:=TMemo.Create(FChat);
  FChat.Memo2.Parent:=FChat;
  FChat.Button2:=TButton.Create(FChat);
  FChat.Button2.Parent:=FChat;
  FChat.Button2.Top:=100;
  FChat.Show;
  i:=i+1;
end;
procedure TFChat.FormCreate(Sender: TObject);
begin
  Form1.Memo1.Lines.Add('FormCreate'+(Sender as TFChat).Name);
end;
end.
Что мне надо написать, чтоб в форму с именем User0 в Memo2 добавилась строчка "bla-bla-bla"?
Пытался сделать так: User2.Memo2.Lines.Add('bla-bla-bla'); но не прокатило, т.к. User2 в программе четко нигде не описано.
Спасибо. Павел, добавлено 14.11.13, 17:28:41 
Поправочка...
Что мне надо написать, чтоб в форму с именем User2 в Memo2 добавилась строчка "bla-bla-bla"?
Хотя цифра после User может быть любая. Вплоть до 1000. Автор, добавлено 14.11.13, 17:41:18 
Я всё же когда-то создавал формы как элементы массива (динамического, конечно). Тогда нет необходимости добавлять их в секцию uses, а обращаться как к переменной.
Так-то вот просто добавьте новую форму в проект, и при попытке использовать её система добавит её в uses. Динамически сделать это наверное не удастся. Так что пока я вижу только способ с массивом, или другой переменной типа TForm.
В принципе, была у вас мысль с указателями, я сразу не понял, но если бы получилось, наверное, наилучший вариант. Автор, добавлено 14.11.13, 17:47:40 
Всё, сегодня уже не могу отвечать. До завтра. Степан, добавлено 7.02.14, 19:41:12 
procedure TForm1.N11Click(Sender: TObject);
begin
Form1.Hide;
Form2.Show;
end;
У меня на delfi7 пишет ошибку на строчке открытия новой формы Form2.Show; Можете сказать почему так? Автор, добавлено 7.02.14, 19:54:11 
Какая ошибка?
Может, у вас эта форма ещё не существует, то есть метод Create ещё не работал. Так бывает, когда форма в свойствах приложения убрана из разряда автосоздаваемых. И это правильно. Но создавать эту форму нужно тогда так:
if (not Assigned(Form2)) then // проверка существования Формы (если нет, то
  Form2:=TForm2.Create(Self); // создание Формы)
Form2.Show;
Кстати, всё это описано в тексте статьи...



Поделись с друзьями



Рекомендуем посмотреть ещё:



Выборы приближаются: Путин указывает лояльным губернаторам на Шкаф для вяления рыбы своими руками

Как сделать кнопку для делфи Обучение программированию с нуля пошаговое руководство для
Как сделать кнопку для делфи Диагностическое оборудование для автомобилей. ELM327, K-Line
Как сделать кнопку для делфи Миллиметровка, система координат, лист в клеточку
Как сделать кнопку для делфи Работа с ADO в Delphi. Часть 1 Блог Delphi-программиста
Как сделать кнопку для делфи Работа с Excel в Delphi. Основы основ. Delphi в Internet
Как сделать кнопку для делфи Расширенный фильтр и немного магии
Как сделать кнопку для делфи Дополнительные формы Delphi


ШОКИРУЮЩИЕ НОВОСТИ