Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RusFAQ.ru: Программирование на Delphi


РАССЫЛКИ ПОРТАЛА RUSFAQ.RU

/ КОМПЬЮТЕРЫ И ПО / Языки программирования / Delphi

Выпуск № 607
от 30.09.2006, 12:35

Администратор:Калашников О.А.
В рассылке:Подписчиков: 381, Экспертов: 64
В номере:Вопросов: 7, Ответов: 20


Вопрос № 56537: Здравствуйте! Вот, на мой взгляд, очень простая программа: procedure TForm1.Button1Click(Sender: TObject); var k,s:integer; begin for s:=0 to 11 do k:=k+1; showmessage(inttostr(k)); end; но почему-то Delfi в...
Вопрос № 56543: Здравствуйте, уважаемые эксперты! Головная боль не дает мне покоя. Неужто Delfi и впрямь такой тяжелый язык программирования? Проблемма вот в чем: у меня есть массив: Bc34: array[0..11] of single; я его заполняю: Bc34[0]:=1.35; fo...
Вопрос № 56563: Здравствуйте, уважаемые эксперты! Подскажите, пожалуйста, как осуществить такое, чтобы в Edit нельзя было вводить не Integer. Заранее благодарен. /Iorpy$...
Вопрос № 56564: Здравствуйте, уважаемые эксперты! Можно ли HRgn заделать под TButton? Предположим, у меня имеется полигональный регион. Как сделать, чтобы он обрабатывал события OnMouseDown, OnMouseUp, OnClick, OnMOuseMove? Без вариаций на тему обработки события PtI...
Вопрос № 56566: Уважаемые эксперты! Опять вопрос. Пользователь вводит число с клавиатуры. Если вводит через точку(например 1.5 вместо 1,5), то компилятор выдает econverterror. Как обойти эту ошибку? Или можно как-то "переделать" его в "1,5"? И ещ...
Вопрос № 56567: Уважаемые эксперты. Подскажите, как средствами Delphi или WinApi из Delphi скопировать кучу файлов одного типа, например *.uni (а не содержимое их-нужно именно копирование, как в браузере по маске) из кучи разных папок в одну папку на другом диск...
Вопрос № 56630: Здравствуйте! Существует ли функция преобразования определенного количества секунд, прошедшего с момента 01.01.1970, в дату? Заранее благодарен. ...

Вопрос № 56.537
Здравствуйте!
Вот, на мой взгляд, очень простая программа:

procedure TForm1.Button1Click(Sender: TObject);
var k,s:integer;
begin
for s:=0 to 11 do k:=k+1;
showmessage(inttostr(k));
end;

но почему-то Delfi выдает: 9254496. Это что такое? Телефон, по которому нужно жаловаться? ЧТо здесь не так?
Отправлен: 24.09.2006, 15:36
Вопрос задал: Oricardo (статус: 1-ый класс)
Всего ответов: 3
Мини-форум вопроса >>> (сообщений: 0)

Отвечает: Morgen_krsk
Здравствуйте, Oricardo!
Потому что вначале надо инициализировать переменную k нулем. Delphi выдает то, что находится по адресу k, а там пока мусор
Ответ отправил: Morgen_krsk (статус: 2-ой класс)
Ответ отправлен: 24.09.2006, 16:45

Отвечает: Mexes
Здравствуйте, Oricardo!
Добавлю, что во избежания подобных проблем следует обращать внимание на warning-и (и hint-ы) компилятора. В данном случае, он должен был сообщить что-то вроде
Variable k might not be initialized
Ответ отправил: Mexes (статус: 3-ий класс)
Ответ отправлен: 24.09.2006, 16:55

Отвечает: CjJoker
Здравствуйте, Oricardo!
Вы просто забыли проинициализировать переменную, вот так:

var k,s:integer;
begin
//
k:= 0;
//
for s:=0 to 11 do k:=k+1;
Ответ отправил: CjJoker (статус: 1-ый класс)
Ответ отправлен: 25.09.2006, 12:51


Вопрос № 56.543
Здравствуйте, уважаемые эксперты!
Головная боль не дает мне покоя. Неужто Delfi и впрямь такой тяжелый язык программирования?
Проблемма вот в чем: у меня есть массив: Bc34: array[0..11] of single;
я его заполняю:
Bc34[0]:=1.35;
for i:=0 to 10 do Bc34[i+1]:=Bc34[i]+0.05;

с клавиатуры ввожу число и обрабатываю его так:
Bc:=roundto(strtofloat(form1.Edit1.Text),-2); т.е. число будет 1.35 до 1.9 с шагом 0.05
А затем начинается струпор:
for i:=0 to 11 do begin
if Bc=Bc34[i] then .... - они никогда не будут равны, какое бы ни было Bc!!
1) ввожу 1,45 или любое другое число - не работает. Хотя типы чисел одинаковы. Как я ни пробовал округлять - не получается.
2) если я обращаюсь к Bc34[12]. то мне дают 1,92. К Bc34[15] -показывается 2,08. Что это за числа? Ведь у меня только до 11?
Прошу, ответьте мне на эти вопросы. Искренне благодарен.

Отправлен: 24.09.2006, 16:30
Вопрос задал: Oricardo (статус: 1-ый класс)
Всего ответов: 1
Мини-форум вопроса >>> (сообщений: 0)

Отвечает: Mexes
Здравствуйте, Oricardo!
Не сравнивайте вещественные числа оператором = (равно). Это не проблема Delphi, а свойство их представления. В массе литературы этот факт освещен, поэтому не буду заострять внимание на сути, а посоветую написать собственную функцию сравнения:

const eps=1e-6;

function Eq(a,b:single):Boolean;
begin
Result:=abs(a-b)<eps;
end;

Функция будет истинна, если оба аргумента отличаются не более чем на eps (я установил его равным 10 в минус шестой степени). Замените
if Bc=Bc34[i] ...
на
if Eq(Bc,Bc34[i]) ...

Что касается Bc[12], то это следующая за Bc[11] область памяти. Естественно, обращаться к ней не корректно, вы, тем самым, можете случайно изменить значения других локальных переменных (могут быть и другие побочные эффекты). Чтобы отлавливать выход за границы массива, установите включенным опцию проекта Range checking (Project -> Options -> Compiler или напишите {$R+} в .dpr-файле. Тогда, при попытке обратиться к Bc[12] у Вас вылетит ошибка (Range check error), если Вы в среде Delphi, будет выделена строка, где это произошло.
Ответ отправил: Mexes (статус: 3-ий класс)
Ответ отправлен: 24.09.2006, 17:06
Оценка за ответ: 5
Комментарий оценки:
Все то, что мне нужно! Спасибо!


Вопрос № 56.563
Здравствуйте, уважаемые эксперты! Подскажите, пожалуйста, как осуществить такое, чтобы в Edit нельзя было вводить не Integer.
Заранее благодарен. /Iorpy$
Отправлен: 24.09.2006, 20:39
Вопрос задал: /Iorpy$ (статус: 1-ый класс)
Всего ответов: 3
Мини-форум вопроса >>> (сообщений: 4)

Отвечает: Н.В.
Здравствуйте, /Iorpy$!
Нужно следить за событием OnKeyPress. Пример в приложении.
Но, в примере не работает кнопка BacSpace. Если она нужна, добавьте то добавьте #8 после '0' (пример 2).

Удачи!

Приложение:

---------
http://TheDelphi.Ru

Ответ отправил: Н.В. (статус: 5-ый класс)
Ответ отправлен: 24.09.2006, 20:48
Оценка за ответ: 5
Комментарий оценки:
Спасибо!

Отвечает: UnRe@l
Здравствуйте, /Iorpy$!
Можно использовать компонент MaskEdit и задать шаблон ввода данных либо через редактор шаблонов Input Mask Editor, либо через свойство EditMask.
---------
Cogito, ergo sum (c) R. Descartes (1596-1650)
Ответ отправил: UnRe@l (статус: 1-ый класс)
Ответ отправлен: 25.09.2006, 06:37
Оценка за ответ: 5
Комментарий оценки:
Тоже интересно.

Отвечает: CjJoker
Здравствуйте, /Iorpy$!

Это решаеться просто:

procedure TEdit1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
if not (Key in ['0'..'9']) then key:= #0
end;
Ответ отправил: CjJoker (статус: 1-ый класс)
Ответ отправлен: 25.09.2006, 12:49
Оценка за ответ: 5
Комментарий оценки:
Спасибо!


Вопрос № 56.564
Здравствуйте, уважаемые эксперты! Можно ли HRgn заделать под TButton? Предположим, у меня имеется полигональный регион. Как сделать, чтобы он обрабатывал события OnMouseDown, OnMouseUp, OnClick, OnMOuseMove? Без вариаций на тему обработки события PtInRegion. В общем, чтобы HRgn работал как TButton.
Заранее благодарен. /Iorpy$
Отправлен: 24.09.2006, 20:44
Вопрос задал: /Iorpy$ (статус: 1-ый класс)
Всего ответов: 1
Мини-форум вопроса >>> (сообщений: 0)

Отвечает: Melamed
Здравствуйте, /Iorpy$
В событии OnCreate с помошью API функцией SetWindowRgn присваивай нужной кнопки регион. См прилощение

Приложение:

Ответ отправил: Melamed (статус: 5-ый класс)
Ответ отправлен: 24.09.2006, 22:11
Оценка за ответ: 5
Комментарий оценки:
Огромное спасибо! А я-то думал, что SetWindowRgn только для того, чтобы создавать нестандартные окна(хм).


Вопрос № 56.566
Уважаемые эксперты! Опять вопрос. Пользователь вводит число с клавиатуры. Если вводит через точку(например 1.5 вместо 1,5), то компилятор выдает econverterror. Как обойти эту ошибку? Или можно как-то "переделать" его в "1,5"? И еще если отслеживаю ошибку, то как остановить приложение в этом месте. Ну, чтобы юзер вновь попытался. Но, лучше бы конечно было сделать так, чтобы независимо от вида точки программа работала. Спасибо.
Отправлен: 24.09.2006, 20:47
Вопрос задал: Oricardo (статус: 1-ый класс)
Всего ответов: 5
Мини-форум вопроса >>> (сообщений: 2)

Отвечает: Н.В.
Здравствуйте, Oricardo!
Компилятор выдаёт ошибку, потому что в качестве разделителя целой и дробной частей в Delphi используется точка.
Можете просто получать строку с числом и заменять в ней точку на запятую (если введена точка) или оставлять строку как есть, есть запятой в ней нет.
Пример удаления запятой в приложении.
Удачи!

Приложение:

---------
http://TheDelphi.Ru

Ответ отправил: Н.В. (статус: 5-ый класс)
Ответ отправлен: 24.09.2006, 20:59

Отвечает: UnRe@l
Здравствуйте, Oricardo!
Используй конструкцию try-except для перехвата ИС:

try
Операторы, где возможна ИС;
except
Операторы, которые должны быть выполнены в случае ИС;
end;
---------
Cogito, ergo sum (c) R. Descartes (1596-1650)
Ответ отправил: UnRe@l (статус: 1-ый класс)
Ответ отправлен: 25.09.2006, 06:25

Отвечает: CjJoker
Здравствуйте, Oricardo!
Можно так:
procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
if Key = '.' then Key:= ','
end;
Ответ отправил: CjJoker (статус: 1-ый класс)
Ответ отправлен: 25.09.2006, 12:38

Отвечает: 3лоумышленник
Здравствуйте, Oricardo!
В приложении в LabelEdit можно ввести только корректный Float

Приложение:

---------
"Люди неизбежно умирают", A. Schwarzenegger (Terminator 3: Rise of the Machines)

Ответ отправил: 3лоумышленник (статус: Студент)
Ответ отправлен: 25.09.2006, 19:40

Отвечает: Prosto_Blackhowk
Здравствуйте, Oricardo!
function ReplaceStr(str:string):string; // замена запятой на точку
var
ix:integer;
sx:string;
res:string;
begin
ix:=Pos(',',str);
if ix<>0 then str[ix]:='.';
ReplaceStr:=str;
end;
Ответ отправил: Prosto_Blackhowk (статус: 2-ой класс)
Ответ отправлен: 27.09.2006, 08:39


Вопрос № 56.567
Уважаемые эксперты.
Подскажите, как средствами Delphi или WinApi из Delphi скопировать кучу файлов одного типа, например *.uni (а не содержимое их-нужно именно копирование, как в браузере по маске) из кучи разных папок в одну папку на другом диске? Спасибо.
Отправлен: 24.09.2006, 20:53
Вопрос задал: Alexela (статус: Посетитель)
Всего ответов: 3
Мини-форум вопроса >>> (сообщений: 0)

Отвечает: Сухомлин Кирилл Владимирович
Здравствуйте, Alexela!
FindFirst, FindNext, FindClose.
Рекурсивный обход по дереву каталогов (в смысле, если среди файлов встретилась папка, то сделать рекурсивный вызов для нее) - но это если дерево. Если у вас куча папок задана списком - пользуйтесь этим списком.
Маска передается в FindFirst.
Копировать FileCopy (или CopyFile) - должна быть какая-дь API функция. Либо посмотрите на delphiworld.narod.ru
---------
Не узнаешь - не попробуешь.
Ответ отправил: Сухомлин Кирилл Владимирович (статус: Практикант)
Ответ отправлен: 25.09.2006, 00:16

Отвечает: Савенко Вадим Иванович
Здравствуйте, Alexela!
На www.torry.net есть компонент FindFile. Он ищет файлы по маске, по дате, ио фразе и т.д. и выводит список найденных файлов с путями. Вам остается только скопировать их.
Для копирования применяйте SHFileOperation.

http://www.megalib.com/books/923/544.htm

Ответ отправил: Савенко Вадим Иванович (статус: Студент)
Ответ отправлен: 25.09.2006, 06:01

Отвечает: Arvist
Здравствуйте, Alexela!
Существует множество способов, предлагаю Вам свой. Сначала вызываете процедуру FindFiles и построить список файлов, а затем с помощью функции WindowsCopyFile скопировать найденные файлы куда Вам нужно. Тексты процедур и пример в приложении.

Приложение:

---------
В будущем определено одно - неопределенность будущего!

Ответ отправил: Arvist (статус: 2-ой класс)
Ответ отправлен: 25.09.2006, 18:03


Вопрос № 56.630
Здравствуйте! Существует ли функция преобразования определенного количества секунд, прошедшего с момента 01.01.1970, в дату? Заранее благодарен.
Отправлен: 25.09.2006, 11:21
Вопрос задал: Майтдинов Рашит (статус: Посетитель)
Всего ответов: 4
Мини-форум вопроса >>> (сообщений: 0)

Отвечает: Лукьяненко Алексей Валериевич
Здравствуйте, Майтдинов Рашит!

Uses DateUtils;

...
SecondsBetween(date1, date2);
Ответ отправил: Лукьяненко Алексей Валериевич (статус: 5-ый класс)
Ответ отправлен: 25.09.2006, 11:59
Оценка за ответ: 5

Отвечает: Сухомлин Кирилл Владимирович
Здравствуйте, Майтдинов Рашит!
В явном виде я такой функции не помню. Сейчас покопался в справке и все равно не нашел. Но ее легко можно напистаь самому!

function DateFrom1970InSeconds(seconds: single): TDateTime;
begin
// 86400 - кол-во секунд в сутках.
Result := seconds/86400 + StrToDate('01'+DateSeparator+'01'+DateSeparator+'1970');
end;

Ну и если надо потом обратно в строку - добавьте DateToStr()

DateSeparator - точка или слэш - в зависимости от локализации ОС(Ru или En). Здесь эта переменная использована, чтобы работало на всех виндах - и на русских, и на английских, и на турецких =)
---------
Не узнаешь - не попробуешь.
Ответ отправил: Сухомлин Кирилл Владимирович (статус: Практикант)
Ответ отправлен: 25.09.2006, 12:02
Оценка за ответ: 5

Отвечает: Bob Johnson
Здравствуйте, Майтдинов Рашит!
Что-то функцию я такую не вспомнил, но можно сделать так. в венде есть такое представление времени как FILETIME. в действительности это 64-х битное целое число, которое показывает сколько 100-наносекундных интервалов прошло с 1 января 1601 года. Значит если ты узнаешь количество секунд, прошедших с 01.01.1601 до 01.01.1970, прибавишь его в своему, после чего умножишь все на 10 миллионов, то получившееся число можно передавать как FILETIME в функцию FileTimeToSystemTime (не забудь вызвать только сначала FileTimeToLocalFileTime, чтобы перейти на локальное время).
Теперь осталось только узнать, сколько секунд прошло между 1601 и 1970 годами :) но тут тоже поможет венда - формируем структуру SYSTEMTIME на первое января 1960 года (время 00:00:00) и конвертируем ее в FILETIME (SystemTimeToFileTime).
Ответ отправил: Bob Johnson (статус: Академик)
Россия, Калуга
WWW: Программирование
----
Ответ отправлен: 25.09.2006, 12:02
Оценка за ответ: 4

Отвечает: Татьяна
Здравствуйте, Майтдинов Рашит!
Конечно есть такая функция, ибо количество секунд с 1.1.1970 - это так называемое, и кстати, достаточно широко распространненное Unix-time.
Существует функция, называемая
UnixToDateTime, находящаяся в модуле DateUtils. Хотя ее реализация и достаточно проста

Приложение:

---------
Возможно все. И ничего возможно тоже.

Ответ отправила: Татьяна (статус: Практикант)
Ответ отправлен: 27.09.2006, 11:13
Оценка за ответ: 5


Отправить вопрос экспертам этой рассылки

Приложение (если необходимо):

* Код программы, выдержки из закона и т.п. дополнение к вопросу.
Эта информация будет отображена в аналогичном окне как есть.

Обратите внимание!
Вопрос будет отправлен всем экспертам данной рассылки!

Для того, чтобы отправить вопрос выбранным экспертам этой рассылки или
экспертам другой рассылки портала RusFAQ.ru, зайдите непосредственно на RusFAQ.ru.


Форма НЕ работает в почтовых программах The BAT! и MS Outlook (кроме версии 2003+)!
Чтобы отправить вопрос, откройте это письмо в браузере или зайдите на сайт RusFAQ.ru.


© 2001-2006, Портал RusFAQ.ru, Россия, Москва.
Идея, дизайн, программирование: Калашников О.А.
Email: adm@rusfaq.ru, Тел.: +7 (926) 535-23-31
Авторские права | Реклама на портале
Версия системы: 4.36 от 06.09.2006
Яндекс Rambler's Top100

В избранное