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

Программирование на Delphi

  Все выпуски  

Программирование на Delphi (выпуск 34)


Информационный Канал Subscribe.Ru

Программирование на DELPHI
Выпуск #34 (23 октября 2005 г.) 

Разделы сайта:

Новости сайта
Система "Эксперт"
Вопросы и Ответы

Отправить вопрос
Файловый архив
Статьи
Компоненты
Plug-in's
Документация
Исходники
Изображения
Игры
Программы
Форум
Гостевая книга
F.A.Q.
Архив рассылки
Каталог сайтов
Обратная связь
Хостинг



Связь:

Администратор
Система "Эксперт"
Информация


Доброго времени суток , уважаемые читатели!

В этот раз мне хотелось бы рассказать о том, что я терпел долгие месяцы... А именно - все присылаемые ответы на вопросы. Обращаюсь ко всем Вам, дорогие читатели: прежде чем отправить свой ответ на вопрос, прочтите его самостоятельно и подумайте: поможет ли человеку, задавшему вопрос этот ответ, или нет. В прошлом выпуске рассылки было 12 вопросов, а ответов пришло очень-очень много. Полдня у меня ушло на то, чтобы собрать это в единое целое и соответствующим образом отредактировать. Сейчас перед Вами готовенькие листы, но сколько моих нервов, друзья, ушло на подготовку этих строк... Многие ответы настолько безолаберны, что прочитав его я приходил в ужас. Огромное количество грамматических ошибок - первый и самый главный фактор. Скажу Вам по секрету - практически всё время, до этого выпуска я редактировал все ответы, исправлял там ошибки. Да и вопросах делал тоже самое, а иногда полностью их переформулировал... Особенно беда со знаками препинания - у некоторых их вообще не существует. Это что касается орфографии и пунктуации (как в школе, честно слово!). А теперь несколько слов по информативности. Некоторые ответы представляют собой несколько слов. Забавно... Подготовив данный выпуск и просмотрев поставленные за ответы оценки, я понял, что эти самые оценки некоторой частью незаслуженные. В самом деле, ответы оцениваются от 1 до 5 баллов, но ниже тройки, как правило, оценки не ставятся... Так вот, с этого момента все ответы будут оцениваться максимально объективно. За ответы в "несколько слов" будут присваиваться 1 и ли 2 балла. Также строго будет учитываться информативность ответа. Если ответ представляет несколько строк, но он совсем неинформативен, оценка также будет соответствующая. Кроме того, письма с большим кол-вом ошибок (см. выше) будут просто-напросто отсеиваться. Да, отсеиваться! Всё это время публиковались все ответы. Теперь будет фильтр. Так что, если хотите получать высокие баллы (а скоро за них начнут выдаваться призы), отвечайте на вопросы информативно и не поленитесь скопировать текст ответа в Word и сделать проверку правописания...

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

А вот сейчас уже пора подвести результаты опроса...

Вопрос 1: Какой у Вас доступ в интернет (полный / только почта) ?
Вопрос 2: Хотели-ли бы Вы, чтобы на сайте существовала автоматизированная система получения файлов по почте (да / нет) ?

Полный доступ в интернет; система нужна.
68
67.3 %
Только почта; система нужна.
26
25.7 %
Полный доступ; система не нужна.
6
6 %
Только почта; система не нужна.
1
1 %
Всего голосов:
101
100 %

Что же, я в результате и не сомневался. Когда будет свободное время - начнём делать эту систему для сайта. Сроки пока не определены.

Ждём Вас на нашем форуме! Там Вам могут быстро помочь с возникшей проблемой и дать ответ.

М-да... Выпуск большой получился... Приятного Вам чтения и программинга! До встречи!

Разделы рассылки:

Авторское слово
Новые вопросы
Ответы на вопросы
Статья по Delphi
Файловый архив
Друзья
Юмор


Количество читателей рассылки: 3477.


Подписка на рассылку:


Лидеры по количеству баллов:


Место
Имя
Баллы
Статус
1
Feniks
281
Практикант
2
Dron
265
Практикант
3
Ermakova Dasha
230
Практикант
4

Садовников Владимир

211
Практикант
5
Iron Monk
200
Практикант
6

Ершов Денис

101
Студент
7

Андрей Лучников

93
Эксперт: 10-ый класс
8
mvp
90
Эксперт: 10-ой класс
9
Igor Danilevych
81
Эксперт: 9-ый класс
10
VeroLom
79
Эксперт: 8-ой класс

Статусы экспертов и их возможности:

Статус
Необходимое кол-во баллов
Прикрепление файлов
Форматирование текста
Посетитель
0
нет
нет
Эксперт 1-го класса
1
нет
нет
Эксперт 2-го класса
10
нет
нет
Эксперт 3-го класса
20
нет
нет
Эксперт 4-го класса
30
нет
нет
Эксперт 5-го класса
40
нет
нет
Эксперт 6-го класса
50
до 250 Кб
нет
Эксперт 7-го класса
60
до 250 Кб
нет
Эксперт 8-го класса
70
до 250 Кб
нет
Эксперт 9-го класса
80
до 250 Кб
нет
Эксперт 10-го класса
90
до 250 Кб
нет
Студент
100
до 250 Кб
нет
Практикант
150
до 250 Кб
нет
Специалист
300
до 250 Кб
да
Профессионал
500
до 1 Мб
да
Профессор
800
до 1 Мб
да
Академик
1000
до 1 Мб
да

Примечание: Под форматированием текста понимается возможность оформлять ответы с использованием html-тегов.

Если Вы хотите, чтобы Вашего имени (ника) не было в данной таблице, отправьте письмо по этой ссылке с зарегистрированного у нас адреса. В теле письма, пожалуйста, укажите причину удаления имени из таблицы. Нам важно ваше мнение.


Основные правила нашей рассылки:

1. Не присылайте ответов на вопросы вроде "да я не знаю" или "да/нет". Такие ответы не публикуются.
2. Вопросы, не касающиеся Delphi, не принимаются (для этого существуют другие рассылки).
3. Запрещено присылать вложенные файлы, объёмом выше установленного ограничения (ограничения указаны в правилах).
4. Не изменяйте тем присылаемых писем. Письма с "неправильными" темами не обрабатываются! Используйте текстовый (не HTML) формат писем. HTML-теги применяйте только в том случае, если Вы уже достигли статуса, где это разрешено (см. правила).
5. Запрещено задавать вопросы, содержащие два (или несколько) вопросов разной тематики. Каждый из таких вопросов должен быть оформлен отдельным письмом.


Задать вопрос в рассылку
   |   Задать вопрос с помощью web-формы   |   Система "Эксперт"


Новые вопросы.


Вопрос #169 (автор вопроса: Сафронов А.Н.; вопрос отправлен: 06.10.2005 13:27):

Скажите пожалуйста, каким образом заполнение ProgressBar можно связать с выполнением процедуры CopyFile? Спасибо. [Ответить на вопрос]


Вопрос #170 (автор вопроса: SHKoder@deagnostic.ru; вопрос отправлен: 06.10.2005 15:44):

Имея WebBrowser пытаюсь его распечатать. Делаю так:

begin
Webbrowser1.Navigate('file:///c:\your_name.html');
end;
...
begin
try
WebBrowser1.ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_PROMPTUSER);
except on E:Exception do ShowMessage(E.message);
end;

end;
Если выключить принтер, то по идее, я должен получить сообщение о том, что печать страницы не была выполнена, но в своём приложении этого сообщения я не отлавливаю, а хотелось бы. прошу помощи у всезнающего all. Заранее благодарен за правильный код и действительно работающий. За уникальность кода (Win 9x/XP) буду вдвойне признателен. [Ответить на вопрос]


Вопрос #171 (автор вопроса: Nikan; вопрос отправлен: 06.10.2005 21:25):

Добрый день!
1. Подскажите, как можно текстовый файл, загруженный в Memo порезать на куски и те данные занести в базу данных, например dbf?
2. Как в текстовом файле сделать поиск не по первому в строке символу а по произвольному из строки? [Ответить на вопрос]


Вопрос #172 (автор вопроса: jeni; вопрос отправлен: 07.10.2005 10:53):

Здравствуйте! У меня такой вопрос: как определить, какой процесс использует данную папку и как он ее использует (для чтения(самое важное) для записи и т.д.) ? Т.е. если пользователь открыл папку или смотрит ее в Total Comander'e (осуществляет доступ к папке), то показывается сообщение. Ну что-то наподобие FileMon'a, только мне нужен код на Delphi 7. Т.е мне нужно узнать какой процесс читает данную папку. Заранее спасибо. [Ответить на вопрос]


Вопрос #173 (автор вопроса: GENEMI; вопрос отправлен: 08.10.2005 15:47):

Привет всем!

Как сохранить (а потом и загрузить) данные переменной типа WideString? Делаю я так:

//---[save]---
var
Size: Integer;
URL: WideString;
begin
URL := 'West-Test';
Size := Length(URL);
Stream.Write(Size, SizeOf(Size));
Stream.Write(PWideChar(URL)^, Size);
end;

//---[load]---
var
Size: Integer;
URL: WideString;
begin
Stream.Read(Size, SizeOf(Size));
SetLength(URL, Size);
Stream.Read(PWideChar(URL)^, Size);
end;

После загрузки вместо долгожданного тест слова "West-Test" появляется какой то мусор :-(( Что тут можно сделать? [Ответить на вопрос]


Вопрос #174 (автор вопроса: Sadowsky Vladimir T; вопрос отправлен: 10.10.2005 22:29):

Здравствуйте! Подскажите, пожайлуста, как создать "Cаption" в TButton или TBitBtn, короче в любом TWinControl вертикально? [Ответить на вопрос]


Вопрос #175 (автор вопроса: Сергей Урбанович; вопрос отправлен: 10.10.2005 22:50):

Имеется текстовый файл, кодировка - ANSI. Как его перекодировать в Юникод? Заранее спасибо. [Ответить на вопрос]


Вопрос #176 (автор вопроса: Тимур; вопрос отправлен: 12.10.2005 13:58):

Нужно программно узнать температуру процессора. Мать Abit NF7-S (или любая другая) с микросхемой мониторинга Winbond W83627HF. [Ответить на вопрос]


Вопрос #177 (автор вопроса: PWL; вопрос отправлен: 15.10.2005 17:53):

Привет народ... К вам такой вопросик, может кто знает или встречался с таким, короче нужна помощь... Суть моей проблемы такова. Я разрабатываю программу-каталог с наименованием товара, с подключаемыми файлами, в которых находится только один товар и все с ним связано: в смысле, я беру DLL в котором фотки этого товара и какое-то описание, лучше всего в txt, но вот тут меня берут смятения, как лучше, или базу данных или то, что я задумал? Вообще-то я задумал якобы в одном файле под названием определенного товара лежат jpg`шки и txt`шки о товаре, мысль состоит в том, чтобы на форме имелся список всех этих dll`ок и при нажатии на данным товаром на форме выводились фотки и описание из dll (jpg и txt находятся в dll файлах). Короче, нужно, чтобы delphi их отображал на форме... Если у кого есть другие варианты решения этого трабла, плиииз помогите и поделитесь мыслёй... [Ответить на вопрос]


Вопрос #178 (автор вопроса: Eltorn; вопрос отправлен: 17.10.2005 01:40):

Я хотел бы узнать, как из буфера обмена, в котором находится рисунок в jpeg формате, вставлять его в компонент TImage? [Ответить на вопрос]


Вопрос #179 (автор вопроса: Eltorn; вопрос отправлен: 17.10.2005 01:49):

Есть массив, описывающий введенный алгоритм в виде записей вершина(имя),связи(TStringList имена связанных с ней вершин). Так вот, очень бы хотелось увидеть процедуру разбора такого алгоритма, а точнее выявление всех путей между операторными вершинами. Заранее благодарен. [Ответить на вопрос]


Вопросы, оставшиеся без ответа:

Вопрос #88 (автор вопроса: Sergey; вопрос отправлен: 15.03.2005 19:57):

Вопрос по TChart. Как осуществить привязку указателя мыши к линии LineSeries? И еще. По оси X - время (DateTime). Как "вытащить" значение Y в любой точке LineSeries? [Ответить на вопрос]


Вопрос #90 (автор вопроса: Nanny_Jagg; вопрос отправлен: 17.03.2005 07:56):

Как в DBGrid из библиотеки Ehlib 3.6 добавить Lookup-поле, чтобы оно действительно работало? Поле вроде сделано, но ключевое поле, оставленное рядом для контрола не меняется, по какому событию обработчик писать? [Ответить на вопрос]

 


Ответы на вопросы.


Вопрос #105:
Как прочитать под WinXP MBR?

1. [Отвечает: Валерий Рум, 06.10.2005 16:09]: Боюсь что без дров не обойтись.

Оценка за ответ: 2.


Вопрос #144:
Пишу программу "Редактор настроек Windows" наподобие "WinSEr". Подскажите, пожалуйста, как в свойствах "Пароли" под Win98 в закладке "Удаленное управление" программно добавить определенного пользователя или удалить его?

1. [Отвечает: Костюков В., 12.10.2005 19:12]: В общем, ответ таков: чтобы добавить юзера необходимо выполнить следующее: net user username password /add - добовляет пользователя, net localgroup Администраторы username /add - права админа... а для того чтобы удалить тоже самое - только вместо add - delete/// а чтобы выполнить программно это так - ShellExecute(Application.Handle, 'open', 'net user username password /add', nil, nil, SW_SHOWNORMAL); что-то такое по-моему..... рытся надо, пробуйте..... спасибо за внимание..

Оценка за ответ: 4.


Вопрос #149:
Добрый день. Подскажите пожалуйста, каким образом программа (пишу в Delphi 5) может изменить параметры электропитания WindowsXP (или хоть какой-то)? Конкретно – время выключения монитора. Заранее благодарю, Александр Прохода.

1. [Отвечает: Валерий Рум, 06.10.2005 16:12]: SendMessage(Application.Handle,WM_SYSCOMMAND,SC_MONITORPOWER,X);

X=0 Потушить.
X=1 Зажечь.
Надеюсь что тебе это надо, если нет, то извини.

Оценка за ответ: 4.

2. [Отвечает: mfred, 15.10.2005 17:55]: Привет. Вот код выключения и включения монитора через каждые 5 секунд, работает под XP.

procedure TForm1.FormCreate(Sender: TObject);
begin
Timer1.Interval := 5000;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
SendMessage(Application.Handle, WM_SysCommand, SC_MonitorPower,
Form1.Tag);
Form1.Tag := 1 - Form1.Tag;
end;

Оценка за ответ: 4.


Вопрос #157:
Здравствуйте! У меня имеется StayOnTop-окно с картинкой (TImage), в котором отображаются координаты мышиного курсора. Как мне сделать чтобы при щелчке мышью в любом месте экрана картинка заменялась на другую? С помощью SetWindowsHookEx(WH_GETMESSAGE, @SysMsgProc, HInstance, 0); у меня не получилось...

1. [Отвечает: Spider, 06.10.2005 16:04]: При щелчке даже вне окна программы? Если да, то не знаю, но если просто щелчок на форме, тогда это очень легко: Image1.Picture.LoadFromFile('car.bmp');

Оценка за ответ: 4.

2. [Отвечает: jeni, 06.10.2005 16:38]:
var
Form1: TForm1;
HookHandle: hHook;

implementation

{$R *.dfm}

function HookProc(Code: integer; WParam: word; LParam: Longint): Longint; stdcall;
var
msg: PEVENTMSG;
begin
if Code >= 0 then begin
result := 0;
msg := Pointer(LParam);
with Form1 do
case msg.message of
WM_LBUTTONDOWN: ShowMessage('Левая кнопка мыжи нажата');
WM_RBUTTONDOWN: ShowMessage('Правая кнопка мыжи нажата');
end;
end else
result := CallNextHookEx(HookHandle, code, WParam, LParam);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
HookHandle := SetWindowsHookEx(WH_JOURNALRECORD, @HookProc, HInstance, 0);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
if HookHandle <> 0 then
UnhookWindowsHookEx(HookHandle);
end;

Вместо ShowMessage подставляешь изменение картинки.

Оценка за ответ: 5.


Вопрос #158:
Здравствуйте. Подскажите пожалуйста, что за параметр Sender: Tobject в событиях? На какой объект он ссылается? (Ведь можно наверно явно указать имя контрола на который он предположительно ссылается)

1. [Отвечает: Alexey Lukyanenko, 06.10.2005 13:36]: Дело в том, что один обработчик можно повесить на несколько контролов. И параметр Sender будет содержать ссылку именно на тот объект (контрол), который вызвал событие - для того, чтобы, например, обратиться к свойству Text того Edit, в который сейчас пользователь вводит текст - а Edit'ов у тебя, к примеру, десяток.

Оценка за ответ: 5.

2. [Отвечает: Иван, 06.10.2005 13:39]: В этом параметре передается объект вызвавший событие. Если ты предположим задал кнопке Button1 событие OnCLick, то параметр Sender будет указывать на эту кнопку (т.е. Sender будет равен Button1). Зачем вообще нужен этот параметр? Чтобы написать предположим один обработчик для всех кнопок, а не 10 обработчиков с одинаковым кодом, отличающимся только тем, что работает с разными контролами... Конкретный класс объекта можно проверить с помощью оператора is. Например: кинь на форму TButton и TLabel, событие OnClick для обоих задай Button1Click.

procedure TForm1.Button1Click(Sender: TObject);
begin
if Sender = nil then
begin
showmessage('sender = nil');
end else begin
if Sender is TControl
then begin
showmessage('кликнули на ' + TControl(Sender).Name + ' ['+Sender.ClassName+']');
end;
end;
end;

Оценка за ответ: 5.

3. [Отвечает: Матвеев И.В., 06.10.2005 14:54]: Sender в событиях это тот объект, который собственно вызвал данное событие (Event). Например, у вас имеется несколько кнопок на форме, вы выделяете несколько кнопок и в инспекторе объектов дважды щелкаете на событии OnClick. Теперь несколько кнопок при щелчке на них вызывают одно и то же событие, и при этом в Sender храниться указатель именно на ту кнопку, по которой щелкнули в данный момент. Как это можно использовать: в обработчике OnClick напишите TButton(Sender).Caption := 'Щелкнули по мне'; И вам сразу все станет ясно...

Оценка за ответ: 5.

4. [Отвечает: timka05, 06.10.2005 16:58]: Sender - это объект, вызвавший событие. Тип объекта TObject - родительский объект для объектов всех остальных типов (визуальных и невизуальных). Класс объекта можно изнать из свойства ClassName (для кнопки это например, TButton). Для приведения Sender к нужному классу можно использовать след. код:

(Sender as TButton).<имя_свойства_или_метода>

или старый (паскалевский) способ приведения типов:

TButton(Sender).<имя_свойства_или_метода>.

Оценка за ответ: 5.

5. [Отвечает: Садовников Владимир, 06.10.2005 19:22]: Представь себе, у тебя имеется менюшка с (примерно) 100 пунктами (одни - вложенные, другие - нет, третьи - подобие радиокнопок и т.д.). Естественно, создавать для каждого пункта свой обработчик OnClick будет муторно и нечитабельно. Зато это легко решается созданием одного общего обработчика для конкретного набора пунктов меню, в котором проверяется, что являлось причиной вызова обработчика. В данном случае в качестве Sender будет играть роль указатель на соответствующий объект твоего TMenuItem. Почему именно TObject - да потому, что это полиморфный базовый класс для любого объекта Delphi. Даже при объявлении пользовательского родительского класса последний становится наследником TObject без нашей на то воли. Зато мы выигрываем мощный механизм полиморфных классов и RTTI, которая хранит информацию о всех родительских классах и наследниках, что упрощает доступ к искомому объекту благодаря динамическому преобразованию типов, которое порой бывает очень-очень нужным.

Оценка за ответ: 5.

6. [Отвечает: mvp, 06.10.2005 19:29]: Он ссылается на объект, который вызал событие. Введён, скорее всего, для универсальности, ведь все классы наследуются от TObject. Ещё возможна ситуация, когда несколько объектов используют один обработчик события, и чтобы различить, кто именно его вызвал, используют TObject. Например, имеется 5 checkBox'ов, и у всех у них один обработчик события: checkboxClicked. И 5 label'ов, которые вкл/выкл. при клике на соответствующем checkbox'е:

procedure TForm.checkboxClicked(Sender: TObject);
var
_ :integer;
s : string;
begin
s := 'Label' + (Sender as TCheckBox).name[Length((Sender as
TCheckBox).name) - 1];
for _:= 0 to controlCount - 1 do if (controls[_].name = s) and
(Controls[_] is TLabel) then
begin
TLabel(controls[_]).enabled := (sender as TCheckBox).checked;
break
end
end;
//-------

И не надо в 5-и обработчиках писать одну и туже строку. Пример этот исскуственный, но такие ситуации встречаются достаточно часто, особенно когда компоненты создаются динамически.

Оценка за ответ: 5.

7. [Отвечает: alexlazer, 06.10.2005 20:10]: Все компоненты Delphi являются лишь частью иерархической структуры, которая называется VCL. Базовый класс этой структуры - класс TObject, который используется Delphi по умолчанию при создании всех остальных классов. Следовательно, класс TObject является базовым классом, от которого "произошли" все остальные классы Delphi. Класс TObject инкапсулирует (включает в себя) общие черты поведения всех объектов VCL - библиотеки. Это включает: 1. Создание, управление и разрушение экземпляра объекта путем выделения ему памяти, инициализации и последующего освобождения выделенной памяти; 2. Доступ во время выполнения к информации о типе экземпляра объекта и его published-свойствам; 3. Поддержку управления событиями; 4. Поддержку реализуемых объектами интерфейсов. Если при создании нового объекта не указан базовый класс, то Delphi автоматически использует как предка класс TObject. Объявление type TMyClass = class равнозначно объявлению type TMyClass = class(TObject).

Оценка за ответ: 5.

8. [Отвечает: Ершов Денис, 07.10.2005 07:59]: Любое Delphi-событие по сути своей представляет собой указатель одного объекта (инициатор события) на метод (обработчик события) какого-либо другого объекта. Наиболее распространенным типом события является TNotifyEvent. Они имеет формат:

TNotifyEvent = procedure(Sender: TObject) of object;

, где Sender - указатель на объект-инициатор события. Однако ничто не мешает определить любой другой формат событий.

Событие типа TNotifyEvent чаще всего реализовано следующим способом:

type
T_Объект = class(...)
private
FEvent: TNotifyEvent; //поле для хранения указателя на
обработчик
...
protected
procedure DoEvent; dynamic;
...
published
...
property OnEvent: TNotifyEvent read fEvent write fEvent;
end;

Метод DoEvent - это метод диспетчеризации события. Он обычно бывает реализован динамическим и в секции protected, чтобы в будущих потомках этого класса его можно было перекрыть, с целью построить другой порядок инициации события. В простейшем случае данный метод реализуется следующим способом:

procedure T_Объект.DoEvent;
begin
if Assigned(FEvent) then
FEvent(Self); //указатель на самого себя
end;

Если событие определено в published-секции то оно будет отображаться в закладке Events Инспектора Объектов, что сильно облегчает их использование. Кроме того можно определять обработчики самостоятельно.

TForm1 = class(TForm)
...
procedure FormMyEvent(Sender: TObject);
...
end;

...

procedure Form1.FormCreate(Sender: TObject);
begin
...
_Объект1.OnEvent := FormMyEvent;
...
end;

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

Как было пояснено выше, в качестве параметра параметра Sender в обработчик обычно передается указатель на объект-инициатор события. В Инспекторе Объектов для события можно выбрать уже готовый обработчик из выпадающего списка. Данный механизм позволяет назначить один и тот же обработчик на несколько объектов, а при помощи параметра Sender обработчик может определить каким именно объектом было инициировано событие.

Например, необходимо в меню программы встроить выбор COM-порта.

|... |-------
|COM-порт >|*COM 1 |
|... | COM 2 |
| | COM 4 |
-------

Количество портов на ПК может быть разное, кроме того можно произвольно задать их номера.

TForm1 = class(TForm)
...
ComPort: TApdComPort; //Компонент управления портом
N1: TMenuItem; //пункт меню выбора портов
...
procedure SelectPortClick(Sender: TObject);
//выбор одного из пунктов списка портов
...
end;

...

procedure FormCreate(Sender: TObject);
var i: integer;
s: string;
Item: TMenuItem;
PortAction: TAction;
Reg: TRegIniFile;
...
begin
...
ComPort.ComNumber := Reg.ReadInteger(rgKey, rgComNumber, ComPort.ComNumber);
//Узнаем номер порта с предыдущей сессии
PortOpen; //Открытие порта
//Создаем пункт меню для отмены выбора порта
Item := TMenuItem.Create (Self); //Пункт меню
PortAction := TAction.Create (Self);
PortAction.Caption := 'Отключить';
PortAction.Tag := 0;
PortAction.OnExecute := SelectPortClick; //Присваиваем
действию обработчик
if not comPort.Open then //Если порт не открыт, выбираем этот пункт
PortAction.Checked := true;
Item.GroupIndex := 1;
Item.RadioItem := true;
Item.Action := PortAction;
n1.Add(Item); //включаем пункт в
меню

for I := 1 to MaxComHandles do //Перебираем все возможные порты
if IsPortAvailable(I) then begin //Если такой существует
S := Format('COM %d', [I]);
Item := TMenuItem.Create (Self); //Создаем пункт
PortAction := TAction.Create (Self);
PortAction.Caption := S;
PortAction.Tag := I; //Номер порта
PortAction.OnExecute := SelectPortClick;
if I = ComPort.ComNumber then
PortAction.Checked := true;
Item.GroupIndex := 1;
Item.RadioItem := true;
Item.Action := PortAction;
N1.Add(MainItem);
...
end;
...
end;

...

//Функция включения порта
Function TForm1.PortOpen;
begin
Result := true;
try
if ComPort.ComNumber <> 0 then
ComPort.Open := true
except
MessageDlg(meErrorPort, mtError, [mbOK], 0);
ComPort.ComNumber := 0;
Result := false
end;
end;

Procedure TFormTerm.SelectPortClick (Sender: TObject);
var i:byte;
begin
//Отключаем текущий порт и гасим выбор в меню
ComPort.Open := false;
for i := 0 to N1.Items.Count-1 do
N1.Items[i].Action.Checked := false;
//Переводим объект-инициатор события к типу TAction
with Sender as TAction do begin
{присваиваем номер порта, пытаемся открыть. Если удалось,
выбираем данный пункт иначе пункт "Отключить"}
ComPort.ComNumber := Tag;
if PortOpen then
Checked := true
else
N1.Items[0].Action.Checked := true
end;
end;

Вкратце дело обстоит так. :)

Оценка за ответ: 5.

9. [Отвечает: Вадим Фурив, 07.10.2005 08:54]: В сендере обычно указываю Self. Тогда событие указывает на свой объект. Т.е.: N1Click(Self);

Оценка за ответ: 3.

10. [Отвечает: PVS, 07.10.2005 10:40]: Sender обычно указывает на компонент, который вызвал событие. Только находится он не в событии, а в процедуре - ОБРАБОТЧИКЕ события, потому что один и тот же обработчик может реагировать на разные события от разных объектов. Кроме того обработчик события - обычная процедура и его можна вызвать самому со своими параметрами (в.т.ч. и с Sender'ом). Если обработчик реагирует только на события одного объекта - да Sender известен заранее и обычно не используется, если же он реагирует на события нескольких объектов иногда нужно знать от кого оно пришло. Простейший пример - цифровые кнопки "калькулятора". Каждой кнопке в OnClick указываем Digit1Click, а сам код такой:

procedure TCalculatorForm.Digit1Click(Sender:TObject);
begin
DisplayEdit.Text:=DisplayEdit.Text+(Sender as TButton).Caption;
end;

И не надо писать 10 разных процедур.

Оценка за ответ: 5.

11. [Отвечает: Trojan, 07.10.2005 13:07]: Параметр Sender указывает на контрол, исполняющий данный event…

Оценка за ответ: 3.

12. [Отвечает: Dron, 07.10.2005 14:46]: Параметр Sender в процедурах указывает на объект, который вызвал данное событие. Это удобно в случаях, когда несколько контролов должны выполнять аналогичные действия. Например, если есть 5 TLabel и каждый из них должен изменять цвет текста при наведении курсора, то можно выделить их все, переключиться на вкладку Events в Object Inspector и двойным щелчком создать событие OnMouseEnter и вписать:

(Sender as TLabel).Font.Color:=clRed;

Аналогично создаём событие OnMouseLeave:

(Sender as TLabel).Font.Color:=clBlack;

Теперь каждый из TLabel будет выделяться при наведении. Очень часто Sender помогает принимать обработчики пунктов меню (когда их много). Также этот Sender можно "заглушить":

Button1.OnClick(nil);

Оценка за ответ: 5.

13. [Отвечает: PiRAT, 07.10.2005 16:08]: Это переменная хранит объект который вызвал данный обработчик. Фишка в том, что несколько объектов могут иметь один и тот же обработчик. Например у тебя есть 20 полей ввода и ты хочешь по нажатию на определенную клавишу чистить в них текст. Согласись, что создавать 20 обработчиков просто неудобно (хотя можно). Вот красивый пример по изменению картинки у BitBtn (у всех у них один обработчик события):

procedure TMFrm.sBitRenderMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
with Sender as TsBitBtn do ImageIndex:= Tag + 21;
end;

Оценка за ответ: 5.

14. [Отвечает: VeroLom, 07.10.2005 17:00]: Это ссылка на объёкт, который вызвал событие т.е. можно использовать одно событие дня нескольких объектов. Использовать можно так:

Form1.OnClickHandler(Sender: TObject);
Begin
If Sender is TButton Then
Case TButton(Sender).Tag of
1: ...
2: ...
3: ...
End;
End;

Оценка за ответ: 5.

15. [Отвечает: halk2, 07.10.2005 21:07]: В параметре Sender передаётся ссылка на компонент, вызвавший Это событие (т.е событие где находится Sender). Например имеются пять кнопок c Caption'ами - 1 , 2 , 3 , 4 , 5 соответственно и Edit1: TEdit; И чтоб не писать в каждой кнопке практически один и тот же код, с помощью Sender делаем сделующее:
1: Обрабатываем событие Клик у любой из кнопки, например у Button1 ( Caption - "1" ) Там Пишем: Edit1.Text := ( Sender as TButton ).Caption
2: Переходим на форму, выделяем те кнопки где мы обработчик события не писали т.е Button2 , Button3 , Button4 , Button5
3: В инспекторе переходим на вкладку "Events" и делаем активный пункт "OnClick" там развертываем комбобокс и нажимаем на то что вышло т.е присваиваем процедуру обработки Клика как у Button1.

Оценка за ответ: 5.

16. [Отвечает: Лучников А.И., 13.10.2005 13:53]: Sender, как явствует из названия, - это объект, который послал сообщение о событии. Например, при нажатии кнопки Button1 возникает событие onClick и Sender у него будет Button1. Можно использовать Sender для обработки одинаковых событий от разных объектов, например обработка введенных данных в TEdit. Предположим есть несколько экземпляров TEdit: Edit1, Edit2,Edit3 и у каждого одинаковая проверка на значение. Тогда пишем один обработчик (Edit1Exit) и задаем его всем трем Edit'ам. Только в обработчике будем использовать: TEdit(Sender), а не явное указание объекта. При вызове процедуры из программы вместо Sender'а можно указать nil, но только если в самом обработчике нет ссылок на Sender.

Оценка за ответ: 5.

17. [Отвечает: dasha ermakova, 13.10.2005 16:39]: Это класс компонента, который вызывает событие (например TButton при нажатии на кнопку). Присвоить его нельзя, можно только посмотреть.

Оценка за ответ: 3.

18. [Отвечает: Yurchik, 14.10.2005 00:40]: Параметр Sender определяет объект, который порождает данное событие. Sender удобно использовать для выполнения одинаковых операций над определенным множеством однотипных объектов, когда конкретный обрабатываемый экземпляр точно неизвестен. Поясню на примере. Размести на формочке несколько меток. Создай обработчик события OnClick для первой метки и пропиши такой код:

procedure TForm1.Label1Click(Sender: TObject);
begin
with Sender as TLabel do
Color:= not Color;
end;

Остальным меткам выставь обработчик события OnClick в Label1Click. Теперь при клике на любую метку будет меняться ее цвет. Согласись, такой код более наглядный и короткий, чем прописывание соответствующего кода в каждом обработчике OnClick для каждой метки.

Оценка за ответ: 5.

19. [Отвечает: Alexey, 14.10.2005 08:15]: Положите на форму две кнопки и назначте им обоим следующий обработчик

procedure TForm1.Button1Click(Sender: TObject);
begin
showmessage((sender as twincontrol).name);
end;

Думаю после этого все станет на свои места :)

Оценка за ответ: 4.

20. [Отвечает: dicking@rambler.ru, 14.10.2005 19:56]: Переводи Sender - отправитель, т.е. это объект, вызвавший событие. Например, ты в design-time 2 раза щелкаешь мышью на кнопке и у тебя автоматом создается обработчик события TForm.Button1Click(Sender: TObject). В этом обработчике можешь явно указать имя контрола - Button1. Но бывают случаи, когда на форме много компонентов и при нажатии на каждый выполняются похожие действия. В этом случае ты в Button1Click не пишешь явно имя Button1, а пишешь (Sender as TButton), остальное все то же самое. Остальным же компонентам назначаешь это же событие, выбирая его в списке в Object Inspector'e, тем самым значительно сокращая код.

Оценка за ответ: 5.


Вопрос #159:
Здравствуйте. Подскажите, как объявить функцию API? И где она объявляется?

1. [Отвечает: Константин Ситников, 06.10.2005 14:21]: Просто обратиться к API-функции. Пример:

SetMenuItemBitmaps(File1.Handle, 1, MF_BYPOSITION, BMP1.Handle, BMP2.Handle);

Оценка за ответ: 5.

2. [Отвечает: Матвеев И.В., 06.10.2005 14:54]: Существует несколько методов вызова API функций от простых Статического и Динамического вызова, до вычисления адресов API функций по их CRC и т.д. Самый простой способ вызвать API функцию - Статический:

function ZwUnmapViewOfSection(SectionHandle: THandle;
p: Pointer): DWord; stdcall; external 'ntdll.dll';

эта недокументированная функция будет вызвана из библиотеки ntdll.dll, обратите внимание на тип передачи параметров stdcall - библиотеки Windows всегда используют такой тип передачи.

Оценка за ответ: 5.

3. [Отвечает: Валерий Рум, 06.10.2005 16:01]: Часть функций прописана в Delphi и их не надо объявлять. Если же нет той функции в pas-файлах что вам нужно, то зная dll где она расположена можно воспользоваться функциями LoadLibrary и GetProcAddress. Есть ещё один вариант:
в раздел var пишем
procedure ProcedureName(var) stdcall;
external 'dll name.dll'(или другой файл, напр.exe) index N;
но в этом варианте необходимо знать под каким индексом(номером) функция находится в dll.

Оценка за ответ: 5.

4. [Отвечает: mvp, 06.10.2005 19:34]: Следует подключить модуль windows, shellApi для явного использования API-функций. Просто uses windows, shellApi - и используйте. А зачем объявлять чужие функции? Ничего не нужно объявлять. Скорее всего вы некоректно сформулировали вопрос.

Оценка за ответ: 5.

5. [Отвечает: Садовников Владимир, 06.10.2005 19:50]: Объявить функцию WinAPI можно также, как и обычную функцию. Надо только знать, каким способом она вызывается (stdcall, fastcall, cdecl, pascal), какие аргументы принимает и в каком модуле находится. Используется директива external, после корой указывается либо имя библиотеки непосредственно, либо имя строковой константы. Вот пример объявления функций-расширений библиотеки OpenGL в отдельном модуле.

unit GLExtensions;

interface

uses Windows, OpenGL;

const
GL_VERTEX_ARRAY=$8074;
GL_NORMAL_ARRAY=$8075;
GL_COLOR_ARRAY=$8076;
GL_INDEX_ARRAY=$8077;
GL_TEXTURE_COORD_ARRAY=$8078;
GL_EDGE_FLAG_ARRAY=$8079;
GL_VERTEX_ARRAY_SIZE=$807A;
GL_VERTEX_ARRAY_TYPE=$807B;
GL_VERTEX_ARRAY_STRIDE=$807C;
GL_VERTEX_ARRAY_COUNT=$807D;
GL_NORMAL_ARRAY_TYPE=$807E;
GL_NORMAL_ARRAY_STRIDE=$807F;
GL_NORMAL_ARRAY_COUNT=$8080;
GL_COLOR_ARRAY_SIZE=$8081;
GL_COLOR_ARRAY_TYPE=$8082;
GL_COLOR_ARRAY_STRIDE=$8083;
GL_COLOR_ARRAY_COUNT=$8084;
GL_INDEX_ARRAY_TYPE=$8085;
GL_INDEX_ARRAY_STRIDE=$8086;
GL_INDEX_ARRAY_COUNT=$8087;
GL_TEXTURE_COORD_ARRAY_SIZE=$8088;
GL_TEXTURE_COORD_ARRAY_TYPE=$8089;
GL_TEXTURE_COORD_ARRAY_STRIDE=$808A;
GL_TEXTURE_COORD_ARRAY_COUNT=$808B;
GL_EDGE_FLAG_ARRAY_STRIDE=$808C;
GL_EDGE_FLAG_ARRAY_COUNT=$808D;
GL_VERTEX_ARRAY_POINTER=$808E;
GL_NORMAL_ARRAY_POINTER=$808F;
GL_COLOR_ARRAY_POINTER=$8090;
GL_INDEX_ARRAY_POINTER=$8091;
GL_TEXTURE_COORD_ARRAY_POINTER=$8092;
GL_EDGE_FLAG_ARRAY_POINTER=$8093;

procedure glArrayElement(ind:GLInt);stdcall;
procedure glColorPointer(size:GLInt;atype:GLEnum;stride:GLSizei;data:Pointer);stdcall;
procedure glDisableClientState(aarray:GLEnum);stdcall;
procedure glDrawArrays(mode:GLEnum;first:GLInt;count:GLSizei);stdcall;
procedure glDrawElements(mode:GLEnum;count:GLSizei;atype:GLEnum;data:Pointer);stdcall;
procedure glEdgeFlagPointer(stride:GLSizei;data:Pointer);stdcall;
procedure glEnableClientState(aarray:GLEnum);stdcall;
procedure glGetPointerv(pname:GLEnum;var data:Pointer);stdcall;
procedure glIndexPointer(atype:GLEnum;stride:GLsizei;data:Pointer);stdcall;
procedure glNormalPointer(atype:GLEnum;stride:GLSizei;data:Pointer);stdcall;
procedure glTexCoordPointer(size:GLInt;atype:GLEnum;stride:GLSizei;data:Pointer);stdcall;
procedure glVertexPointer(size:GLint;atype:GLenum;stride:GLsizei;data:pointer);stdcall;

implementation

procedure glColorPointer(size:GLInt;atype:GLEnum;stride:GLSizei;data:Pointer);stdcall;external OpenGL32;
procedure glArrayElement(ind:GLInt);stdcall;external OpenGL32;
procedure glDrawArrays(mode:GLenum;first:GLint;count:GLsizei);stdcall;external OpenGL32;
procedure glDrawElements(mode:GLEnum;count:GLSizei;atype:GLEnum;data:Pointer);stdcall;external OpenGL32;
procedure glEdgeFlagPointer(stride:GLSizei;data:Pointer);stdcall;external OpenGL32;
procedure glGetPointerv(pname:GLEnum;var data:Pointer);stdcall;external OpenGL32;
procedure glIndexPointer(atype:GLEnum;stride:GLsizei;data:Pointer);stdcall;external OpenGL32;
procedure glNormalPointer(atype:GLEnum;stride:GLSizei;data:Pointer);stdcall;external OpenGL32;
procedure glTexCoordPointer(size:GLInt;atype:GLEnum;stride:GLSizei;data:Pointer);stdcall;external OpenGL32;
procedure glEnableClientState(aarray:GLEnum);stdcall;external OpenGL32;
procedure glDisableClientState(aarray:GLEnum);stdcall;external OpenGL32;
procedure glVertexPointer(size:GLint;atype:GLenum;stride:GLsizei;data:pointer);stdcall;external OpenGL32;

end.

Оценка за ответ: 5.

6. [Отвечает: Ершов Денис, 07.10.2005 08:15]: Насколько я знаю все API представляет собой просто функции из различных DLL Windows. Программы сами должны находить эти DLL и обращаться к их функциям. Можешь ради интереса открыть исходник модуля "Windows", заметишь все API там описываются как external функции. Если тебе необходимо создать новую функцию просто создаешь новую DLL и записываешь ее в {%WindowsDir%}/System32. Если же тебе необходимо заменить стандартную API на собственную, то я даже не знаю как помочь твоему горю. У самого возникает живой интерес: Как можно перехватить вызов определенной функции из определенной DLL и выполнить вместо нее свою?

Оценка за ответ: 5.

7. [Отвечает: PVS, 07.10.2005 10:56]: Функции API можно объявлять в любом месте, где допустимо объявление функций. Сама же функция API есть ничто иное как внешняя функция из динамической библиотеки:

function CASESensitiveName(Param1:PChar):Integer;stdcall;external 'library.dll';

Функции API oбычно требуют stdcall (или cdecl) чтобы указать способ передачи параметров и очистки места за собой принятый в С вместо Pascal'евского. А вместо library.dll надо писать kerhel32.dll, user32.dll или чего-то еще, где спрятано API. Обычно в help'e указана нужная dll.

Оценка за ответ: 5.

8. [Отвечает: Dron, 07.10.2005 14:49]: Чтобы объявить API-функцию, нужно создать dll, содержащую эту функцию и поместить её в системый каталог (system32 или system). После этого функцию можно будет вызывать примерно так:

function MyFunc(Param1,Param2,Param3: Integer):Integer; stdcall; external 'myfunc.dll';

А чтобы использовать в своей программе все API-функции, объявлять их, конечно, не нужно. Большинство из них прописаны в модуле Windows.pas, который по умолчанию подключён к программе.

Оценка за ответ: 5.

9. [Отвечает: PiRAT, 07.10.2005 16:12]: Ее не нужно объявлять все они описаны в стандартном модуле Windows. Например GetCursorPos(var Pos: TPoint); выдает в пременную текущие координаты курсора. Просто найди себе справочник по API функциям и используй его.

Оценка за ответ: 5.

10. [Отвечает: Иван, 06.10.2005 17:48]: Есть два способа - статистическое связывание и динамическое.

Статическое связывание:

function MapDialogRect; external user32 name 'MapDialogRect';
procedure DoSomething; external 'MYLIB.DLL';
//а здесь API функция MessageBoxA переименовывается в MessageBox
function MessageBox(HWnd: Integer; Text, Caption: PChar; Flags: Integer): Integer; stdcall; external 'user32.dll' name 'MessageBoxA';

Динамическое:

type
TOpenThemeData = function(hWnd: HWND; pszClassList: PWideChar): THandle; stdcall;
var
OpenThemeData: TOpenThemeData;
ThemeLibrary: HMODULE ;
// код
ThemeLibrary := LoadLibrary('UxTheme.dll');
if ThemeLibrary <> 0
then OpenThemeData := GetProcAddress(ThemeLibrary, 'OpenThemeData')
else showmessage('ошибка загрузки dll');
//дальше юзаешь OpenThemeData(...)

Где объявлять? Там же где и все остальные функции... Советую создать отдельный юнит...

Оценка за ответ: 5.

11. [Отвечает: halk2, 07.10.2005 21:14]: Обьявлять ёе не надо, если подключён модуль Windows.

Оценка за ответ: 3.

12. [Отвечает: Yurchik, 14.10.2005 00:41]: Все основные функции WinAPI уже объявлены в модулях Windows и ShellAPI. Объявление какой-либо функции из внешней библиотеки не отличается от обычного объявления функции, а ее тело заменяется директивой external. Например:

function MyFunc(A: Integer): Integer; stdcall; external <LibNm>
или
function MyFunc(A: Integer): Integer; stdcall; external <LibNm> name <FuncNm>;
Здесь <LibNm> - строка, указывающая имя твоей dll'ки
Необязательный параметр <FuncNm> указывает имя функции в библиотеке.
Если его опустить, то в данном примере будет искаться функция с именем 'MyFunc'

ЗЫ. Все экспортируемые функции библиотеки должны компилироваться в режиме stdcall. Соответственно, и при объявлении функции нужно указывать эту директиву.

Оценка за ответ: 5.


Вопрос #160:
Записываю из своей проги в Аcces запись, с помощью SQL (INSERT INTO...), но в ответ выдается сообщение, типа "Текущий проводник не поддерживает возврат нескольких записей одновременно", хотя реально новую запись в базу добавляет. Вопрос: Как подавить это сообщение, или что является причиной такого сообщения? Спасибо...

1. [Отвечает: SHKoder@deagnostic.ru, 06.10.2005 13:23]: А ты в квери делай так: QueryInsert.ExecSQL, а не QueryInsert.Open.

Оценка за ответ: 4.

2. [Отвечает: dasha ermakova, 13.10.2005 16:47]: Подавить сообщение можно с помощью:

try
...INSERT INTO...
except
end;

Тогда сообщение будет выдаваться только при компиляции, а во время работы программы - нет.

Оценка за ответ: 5.

3. [Отвечает: Alexey, 14.10.2005 08:10]: Здравствуйте, Сергей! Здесь телепатов нет, описывайте через что подключаетесь, каким образом выполняете запрос, желательно полностью код - это на будущее! А так скорее всего пытаетесь выполнить query.open вместо execSQL;

Оценка за ответ: 4.


Вопрос #161:
Использую QuantumGrid 4 для отображения и редактирования данных. Проблема в том, что эти данные я хочу вводить самостоятельно, а не использовать базы данных, т.е. мне нужно добавлять колонки и строки в grid и получать доступ к ячейкам. Проблема с доступом и добавлением строк. Может есть альтернативы (но не StringGrid)? Заранее спасибо.

1. [Отвечает: SHKoder@deagnostic.ru, 06.10.2005 13:35]: Там же в OptionsData есть свойства Appending, Deleting, Editing, Inserting. Будь внимательнее.

Оценка за ответ: 5.

2. [Отвечает: Ершов Денис, 07.10.2005 14:30]: Подобный вопрос уже был. Мой ответ - AdvStringGrid. Уже давно включен в список файлового архива.

Оценка за ответ: 5.


Вопрос #162:
Уважаемые, подскажите компонент для работы с CD (а-ля Nero - как он меня достал).

1. [Отвечает: SHKoder@deagnostic.ru, 06.10.2005 13:36]: CD-Burning:

{-----------------------------------------------------------------------------}
{ Copyright (c) Rocket Division Software 2001-2004. All rights reserved. }
{ Module Name: }
{ StarBurn.pas }
{ Abstract: }
{ CD/DVD Burning, Grabbing and Mastering Toolkit main user header. }
{ Author: }
{ Anton A. Kolomyeytsev }
{ Alexey Popov }
{ Environment: }
{ Windows 95/98/ME/NT/2K/XP/2003 UserMode only }
{ Notes: }
{ Known bugs/Illegal behavior: }
{ ToDo: }
{-----------------------------------------------------------------------------}

Оценка за ответ: 3.

2. [Отвечает: Матвеев И.В., 07.10.2005 14:54]: Если вам нужен компонент для записи CD/DVD дисков советую посмотреть Magic CD DVD Burner v1.1.7 (http://www.binarymagics.com).

Оценка за ответ: 5.


Вопрос #163:
Подскажите пожалуйста, как поместить в ComboBox картинки BMP и считать номер выбранного элемента ниспадающего списка (ComboBox)?

1. [Отвечает: SHKoder@deagnostic.ru, 06.10.2005 13:38]: Используй TImageComboBox.

Оценка за ответ: 3.

2. [Отвечает: Трапезников Антон, 06.10.2005 13:42]: Делается это при помощи стиля ownerdraw, который присутствует в TComboBox. Тебя должно интересовать два свойства этого стиля:
1) csOwnerDrawFixed - используется, если все битмапы имеют одинаковую высоту;
2) csOwnerDrawVariable - используется для битмапов с разной высотой;

После того как стиль будет установлен на один из вышеперечисленных, то можно воспользоваться событием onDrawItem. Это событие возникает каждый раз, когда приложению необходимо нарисовать пункт в выпадающем списке (combo box). Событие определяется следующим образом:

procedure TForm1.ComboBox1DrawItem(Control: TWinControl; index: Integer; Rect: TRect; State: TOwnerDrawState)
, где:

Control - Элемент управления, содержащий пункт списка
Index - Номер элемента списка
Rect - прямоугольник, в котором будет отображён элемент списка
State - Состояние элемента: выбран, заблокирован или имеет фокус (odSelected, OdDisabled или OdFocused)

Если выпадающему списку был присвоен стиль csOwnerDrawFixed, то всё, что надо сделать, это написать процедуру, которая будет рисовать битмап и текст в событии onDrawItem.

procedure TForm1.ComboBox1DrawItem(Control: TWinControl; index:Integer;
Rect: TRect; State: TOwnerDrawState);
begin
(* Заполняем прямоугольник *)
combobox1.canvas.fillrect(rect);
(* Рисуем сам битмап *)
imagelist1.Draw(comboBox1.Canvas,rect.left,rect.top,index);
(* Пишем текст после картинки *)
combobox1.canvas.textout(rect.left+imagelist1.width+2,rect.top,
combobox1.items[index]);
end;

Для выпадающего списка со стилем csOwnerDrawVariable необходимо пройти ещё одну дополнительную стадию. Заключается эта стадия в создании обработчика для события onMeasureItem. Это событие вызывается перед DrawItem, для того, чтобы Вы могли установить фактическую высоту для каждого элемента списка. Вот его определение:

procedure TForm1.ComboBox1MeasureItem(Control: TWinControl; index: Integer; var Height: Integer);

Control - Элемент управления, содержащий пункт списка
Index - Номер элемента списка
Height - Собственно высота элемента списка с номером Index.

Оценка за ответ: 5.

3. [Отвечает: mvp, 06.10.2005 19:44]: В ComboBox просто так не поместишь рисунок. Используйте TComboBoxEx (вкладка Win32). Бросаете ImageList на форму, заполняете его рисунками. В ComboBoxEx Свойству Images присваиваете тот ImageList. При добавлении вручную или програмно нужно знать порядковые номера рисунков в ImageList. Рисунки могут менятся в зависимости от состаяния строки (выбрана, не выбрана). Узнать индекс выбранного элемента можно с помощью itemIndex. Если он =-1, то отображение не соответствует ни одному элементу в списке.

Оценка за ответ: 5.

4. [Отвечает: Ершов Денис, 07.10.2005 08:27]: Приветствую, TERRARIUM. По событию OnDrawItem можно перерисовать пункт ниспадающего списка как душе угодно. А номер выбранного элемента содержится в свойстве ItemIndex.

Оценка за ответ: 4.

5. [Отвечает: Вадим Фурив, 07.10.2005 09:11]: Компонент TComboBox не поддерживает по-моему вставку картинок. Для этого нужно использовать компонент TComboBoxEx в закладке Win32 (в Delphi 7 по крайней мере). В ComboBoxEx.Images добавляются методом Add картинки. Затем в ComboBoxEx.ItemsEx добавляются пункты меню с указанием требуемой картинки. Я сом этого не делал, так что добавить текст программы не могу. Все это Прочитал только что в Help по Дельфи. Чего и Вам желаю. Там все подробно и доходчиво описано. А считать номер выбранного компонента: ComboBox.InemIndex. Если равен -1, то в текст в ComboBox.Text не из списка. Иначе возвращает номер выбранного компонента. Нумерация начинается с нуля. Такая же система и в TComboBoxEx.

Оценка за ответ: 5.

6. [Отвечает: jeni, 07.10.2005 11:41]: Кидаешь на форму ImageList, заполняешь его картинками. У ComboBox'a на событии OnDrawItem пишешь

procedure TForm1.ComboBox1DrawItem(Control: TWinControl; Index: Integer;
Rect: TRect; State: TOwnerDrawState);
begin
(* Заполняем прямоугольник *)
combobox1.canvas.fillrect(rect);
(* Рисуем сам битмап *)
imagelist1.Draw(comboBox1.Canvas,rect.left,rect.top,index);
(* Пишем текст после картинки *)
combobox1.canvas.textout(rect.left+imagelist1.width+2,rect.top,
combobox1.items[index]);
end;

А чтобы узнать по какой строке кликнули вот это:

procedure TForm1.ComboBox1Change(Sender: TObject);
var
i:integer;
begin
i:=ComboBox1.ItemIndex;
end;

Оценка за ответ: 5.

7. [Отвечает: Dron, 07.10.2005 14:52]: Для этого нужно использовать компонент TComboBoxEx со страницы Win32. Следует создать TImageList (тоже с Win32) и поместить в него необходимые изображения. Затем в ComboBoxEx установить свойство Images равным созданному ImageList. После этого каждой из строк (ItemsEx) можно ассоциировать изображения (порядок счёта начинается с нуля). Чтобы узнать индекс выбранного элемента списка, следует обратиться к ComboBoxEx.ItemIndex.

Оценка за ответ: 5.

8. [Отвечает: dasha ermakova, 13.10.2005 16:49]: Возьми компонент ComboBoxEx1 в Win32, там предусмотрены картинки. Номер выбранного элемента: ComboBoxEx1.ItemIndex;

Оценка за ответ: 5.

9. [Отвечает: Yurchik, 14.10.2005 00:42]: Количество строк Items должно быть равно количеству элементов в выпадающем списке. Style выставлен в csOwnerDrawFixed или csOwnerDrawVariable. Обработчик события OnDrawItem должен рисовать элемент с заданным индексом. Событие OnMeasureItem возникает только если style="csOwnerDrawVariable" и используется для определения высоты каждого элемента. Пример:

procedure TForm1.ComboBox1DrawItem(Control: TWinControl; Index: Integer;
Rect: TRect; State: TOwnerDrawState);
begin
TComboBox(Control).Canvas.TextRect(Rect, Rect.Left, Rect.Top, IntToStr(Index));
end;

procedure TForm1.ComboBox1MeasureItem(Control: TWinControl; Index: Integer;
var Height: Integer);
begin
Height:= Height+Index;
end;

Номер выбранного элемента ниспадающего списка доступен, как обычно, через ItemIndex.

Оценка за ответ: 5.

10. [Отвечает: vet, 15.10.2005 00:18]: 1. Создаешь компонент TImageList, в который помещаешь картинки, которые тебе надо рисовать. Заполняешь ComboBox строками, свойство Style устанавливаешь в csOwnerDrawFixed (или csOwnerDrawVariable - для разной высоты строк) и описываешь обработчик события ComboBox'a OnDrawItem, например:

procedure TForm1.ComboBox1DrawItem(Control: TWinControl; Index: Integer;
Rect: TRect; State: TOwnerDrawState);
var
Bitmap: TBitmap;
begin
Bitmap := TBitmap.Create;
// Загружаем картинку, соответственно индексу строки Index
ImageList1.GetBitmap(Index, Bitmap);
// Рисуем картинку на канве и выводим текст
with Control as TComboBox do
begin
Canvas.Draw(Rect.Left + 5, Rect.Top, Bitmap);
Canvas.TextOut(Rect.Left + 30, Rect.Top, Items.Strings[Index]);
end;
Bitmap.Free;
end;

2. Номер выделенного элемента - ComboBox.ItemIndex.

Оценка за ответ: 5.


Вопрос #164:
Запускаю прогу, которая завершается. Как добраться до её кода возврата?

1. [Отвечает: Садовников Владимир, 06.10.2005 19:31]: Так дебаггером. Если обычный дельфовский отладчик не справляется, поможет Turbo Debugger, который вызывается View->Debug Windows->CPU, но после этого придётся разбираться уже с ассемблером.

Оценка за ответ: 5.

2. [Отвечает: Alexey Lukyanenko, 07.10.2005 12:39]: Для этого нужно запустить программу функцией CreateProcess, дождаться окончания ее работы, и получить результат из функции GetExitCodeProcess:

var
SA: _STARTUPINFOA;
PI: _PROCESS_INFORMATION;
ExitCode: LongWord;
begin
ZeroMemory(@SA, SizeOf(SA));
SA.cb := SizeOf(SA);

CreateProcess('program.exe', '', nil, nil, False, 0, nil, nil, SA, PI);

if WaitForSingleObject(PI.hProcess, INFINITE) = WAIT_OBJECT_0 then
GetExitCodeProcess(PI.hProcess, ExitCode);
end;

Оценка за ответ: 5.


Вопрос #165:
Как отследить, когда explorer.exe (проводник) перезагружается в результате ошибки? Дело в том, что иконка проги в трее перестаёт отображаться.

1. [Отвечает: Alexey Lukyanenko, 06.10.2005 13:43]: Зарегистрировать системное событие 'TaskbarCreated', и обрабатывать его:

WM_TBCreated := RegisterWindowMessage('TaskbarCreated');
...
if Message.msg = WM_TBCreated then
// Explorer перезагрузился - выполняем действия

Оценка за ответ: 5.

2. [Отвечает: Константин Ситников, 06.10.2005 14:23]: Советую просто обновлять иконку в трее через определенный интервал времени (1 минута к примеру).

Оценка за ответ: 4.

3. [Отвечает: Сергей, 06.10.2005 19:22]: Я в своих программах делаю так: Кидаешь на форму Timer и пишешь:

//----trey------
TrayIcon.hIcon := Form2.Image2.Picture.Icon.Handle;
Shell_NotifyIcon(NIM_ADD,@TrayIcon);
//----trey------

При перезагрузке проводника через некоторое время в трее появится иконка.

Оценка за ответ: 5.

4. [Отвечает: Dron, 07.10.2005 14:53]: Рекомендую воспользоваться компонентом CoolTrayIcon. Он автоматически восстанавливает иконку при перезагрузке explorer.exe. Это одно из его достоинств.

Оценка за ответ: 4.


Вопрос #166:
Проблема с TMainMenu: пишу &Файл, в итоге получается быстрый вызов именно с заглавной Ф (Alt, затем Shift+Ф). А хотелось бы и с просто ф (Alt+ф), не только с заглавной. Кто-нибудь знает, как?

1. [Отвечает: SHKoder@deagnostic.ru, 06.10.2005 13:40]: Bспользуй TActionList, он ловит любые события или TApplicationEvents из закладки Additional.

Оценка за ответ: 4.

2. [Отвечает: Nickolay Antipov, 06.10.2005 14:57]: MainMenu1.OwnerDraw = false и все будет ок.

Оценка за ответ: 3.

3. [Отвечает: Сергей Азачем, 06.10.2005 22:04]: Нормальным образом никак. Проблема в функции обработки акселераторов в VCL.

unit Forms.
function IsAccel(VK: Word; const Str: string): Boolean;

Можно написать свою функцию и во время выполнения приложения прописать в IsAccel JMP на свою функцию. Как это сделать можно посмотреть в функции MakeObjectInstance;

Оценка за ответ: 4.

4. [Отвечает: Вадим Фурив, 07.10.2005 09:26]: У меня в TMainMenu не имеет значения регистр нажимаемой буквы. Срабатывает как заглавная, так и прописная. Могу посоветовать назначить горячие клавиши HotKey. Компонент это позволяет.

Оценка за ответ: 4.

5. [Отвечает: Yurchik, 14.10.2005 00:42]: Впервые слышу о таком. Работает как Alt+ф, так и Alt+Shift+ф. Единственное - должна быть включена русская или украинская раскладка клавиатуры.

Оценка за ответ: 4.


Вопрос #167:
Подскажите компонент для архивирования Rar? Или как из програмы можно вызвать WinRar?

1. [Отвечает: SHKoder@deagnostic.ru, 06.10.2005 13:42]:
const ParametrsCMD = 'a -ep1 -x*.exe -x*.dll -x*.~* -x*.bak -x*.sql';
FileArchives = 'ArchiverFile.rar';
begin
WinShellExecute('open',
'rar.exe',
ParametrsCMD +' '+ FileArchives +' "'+bedPathFolder.Text+'"',
'',
SW_HIDE);
end;

Но тогда нужен консольный rar.exe.

Еще есть вариант Unrar.dll как использовать его можно посматреть на офиц. сайте rarlabs.com там вроде с примерами на C#, VB, Delphi.

Оценка за ответ: 4.

2. [Отвечает: Матвеев И.В., 06.10.2005 14:54]: Насколько я понимаю создавать Rar архивы может только WinRar/RAR, т.е. алгоритмы сжатия не публиковались, а вот распаковывать RAR архивы из своей программы довольно легко - существует специальная библиотека UnRar.dll (см. www.rarlab.com) именно для этой цели. Однажды я использовал ее для создания инсталляционного дистрибутива своей программы, т.е. из ресурсов извлекал в temp библиотеку, динамически подгружал ее и использовал для распаковки архива с файлами программы. Не очень красивое решение, но всеже работало. Если же вы хотите именно сжимать, вы можете использовать RAR - консольную версию архиватора (rar.exe - поставляется вместе с WinRar), как им пользоваться довольно подробно описано в документации WinRar.

Оценка за ответ: 5.

3. [Отвечает: mvp, 06.10.2005 19:53]: В uses добавьте shellApi. А так вот вызывается winrar:

ShellExecute(Application.Handle, 'open', 'winrar', 0, 0, 0);

Изучите руководство по командной строке WinRar - очень много функций. Если же вы хотите ему передать параметры командной строки, то так:

ShellExecute(Application.Handle, 'open', 'winrar', pchar(par1 + ' ' + ..
+ ' ' + parN), 0, 0);

Учтите, что если вы будете указывать пути к файлам, то там могут встретиться пробелы и такой параметр должен начинаться с двойных кавычек и ими же заканчиваться.

Оценка за ответ: 5.

4. [Отвечает: Сергей Азачем, 06.10.2005 22:10]: В поставку WinRar входит консольная версия Rar.exe. Для ее запуска можно воспользоваться ShellExecute(GetDesktopWindow, nil, 'C:\Program Files\WinRAR\Rar.exe', 'параметры командной строки' nil, SW_ShowNormal);

Параметры командной строки отображает сам Rar при его запуске без параметров.

Оценка за ответ: 5.

5. [Отвечает: Ершов Денис, 07.10.2005 09:00]: Не совсем компонент. DLL и интерфейс к ней. Загрузить прикреплённый файл >>

...Дополнение к ответу.

По запуску WinRAR'а. Открой его справку, в содержании есть раздел"Режим командной строки". Там все подробнейше расписано как его запускать. Запустить программу можно функцией WinExec.

UINT WinExec(
LPCSTR lpCmdLine, // address of command line
UINT uCmdShow // window style for new application
);

Return Values

If the function succeeds, the return value is greater than 31.
If the function fails, the return value is one of the following error values:

Value Meaning
0 The system is out of memory or resources.
ERROR_BAD_FORMAT The .EXE file is invalid (non-Win32 .EXE or error in .EXE image).
ERROR_FILE_NOT_FOUND The specified file was not found.
ERROR_PATH_NOT_FOUND The specified path was not found.

Оценка за ответ: 5.

6. [Отвечает: Dron, 07.10.2005 14:56]: В состав WinRAR входит командный архиватор - rar.exe и unrar.exe. Запустив его без параметров, можно увидеть список всех достпуных команд (их там много). После этого остаётся только запускать rar.exe с параметрами:

WinExec('rar.exe e archive.rar',1);

Оценка за ответ: 4.

7. [Отвечает: VeroLom, 07.10.2005 17:03]: Можешь использовать unrar.dll. Описание есть на http://www.RarLab.com.

Оценка за ответ: 3.

В одном ответе RarLab.com, в другом - RarLabs.com... Где же истина? ;-) (прим. редактора)

8. [Отвечает: Лучников А.И., 13.10.2005 13:58]: WinRar.exe так и вызывается, только нужно ввести параметры (см. rar.txt). А если архиватор не критичен, то рекомендую ТVclZip - очень полезная вещь.

Оценка за ответ: 5.

9. [Отвечает: dasha ermakova, 13.10.2005 16:50]: Хороший компонент ZipForge. Хотя называется Zip, но создает любые архивы.

Оценка за ответ: 4.

10. [Отвечает: mfred, 15.10.2005 18:48]: Привет. WinRar можно запустить из программы с помощию этого кода:

uses ShellAPI;

procedure TForm1.Button1Click(Sender: TObject);
begin
ShellExecute(Application.Handle, nil, 'C:\Program Files\WinRAR\WinRAR.exe', nil, nil, SW_SHOWNORMAL);
end;

Оценка за ответ: 4.


Вопрос #168:
Такой вопрос: как организовать поиск в ListBox? Нужно также, как и в Блокноте - Найти и Найти далее. Заранее спасибо.

1. [Отвечает: Валерий Рум, 06.10.2005 16:08]: Попробуй почитать Help по функции SendMessage с параметром LB_FINDSTRING.

Оценка за ответ: 3.

2. [Отвечает: mvp, 06.10.2005 20:07]: Ну, по поиску много теории наработано :) Если по простому, то:

procedure FindInListBox(lb : TListBox; text : string; caseSencitive :
boolean = false);
var
_, __: integer;
s, t1: String;

begin
if caseSencitive then t1 := text else t1 := lowercase(t1);
for _:= 0 to lb.count - 1 do
begin
s := lb.items[_];
if not caseSencitive then s := lowercase(s);
while pos(t1, s) > 0 then
begin
lb.itemindex := _;
//нашли
//каким-то образом выделяем подстроку (так как вопрос стоит об
организации поиска, а не визуализации, то //это я упускаю)
//выдаём диалог (дальше, стоп). Если стоп, то пишем exit, иначе:
s := copy(s, pos(t1, s) + length(t1), length(s) - pos(t1, s) -
length(t1) + 1);
if s = '' then break
end
end
end;

Оценка за ответ: 5.

3. [Отвечает: Вадим Фурив, 07.10.2005 09:45]: Для этого нужно использовать цикл. Данные в ListBox расположены в ListBox.Items : TStrings. Свойство ListBox.Items.Count показывает количество строк. Организуем цикл:

for I:=1 to ListBox.Items.Count do

В этом цикле по очереди сравниваем с нужными нам условиями строки: ListBox.Items[I-1]. I-1 потому что нумерация идет с нуля.

Оценка за ответ: 4.

4. [Отвечает: Dron, 07.10.2005 14:59]: Самый простой способ - в цикле проверить все строки ListBox, попутно сравнивая их с заданным образцом. Проверять соответствие строк по маске можно с помощью функций из модуля Masks.pas (нужно подключить в Uses). Вот пример поиска строк (без масок):

Var I: Integer; Search: String;
begin
Search:='23';
For I:=0 To ListBox1.Items.Count-1 Do
If Pos(Search,ListBox1.Items[I]) > 0 Then
ShowMessage(Найдено в строке: '+ListBox1.Items[I]);

Оценка за ответ: 5.

5. [Отвечает: dasha ermakova, 13.10.2005 16:51]: В Edit1 пишем текст, который надо найти.

...
var
num: integer;

implementation
{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
i: integer;
begin
if num = -1 then
begin
num:=ListBox1.Items.IndexOf(Edit1.Text);
ListBox1.ItemIndex:=num;
end
else
for i:=num+1 to ListBox1.Count-1 do
if ListBox1.Items[i] = Edit1.Text then
begin
num:=i;
ListBox1.ItemIndex:=num;
break;
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
num:=-1;
end;

Оценка за ответ: 5.


Все вопросы и ответы на них Вы всегда можете найти на нашем сайте в разделе "Эксперт": http://www.delphi.int.ru/modules/expert/.


Статья по Delphi.

Добавляем компонент в стандартный Message Dialog

Источник: http://www.ReadCoding.net/

Пример показывает стандартное диалоговое окно, которое обычно используется для подтверждения дальнейших действий в любой программе с галочкой "Don't show this message again".

Используем функцию CreateMessageDialog и добавляем любой компонент до того как будет вызвана ShowModal.

Например:

procedure TForm1.Button1Click(Sender: TObject); 
 Var 
   AMsgDialog: TForm; 
   ACheckBox: TCheckBox; 
 begin 
   AMsgDialog := CreateMessageDialog('This is a test message.',
          mtWarning, [mbYes, mbNo]); 
   ACheckBox := TCheckBox.Create(AMsgDialog); 
   with AMsgDialog do 
   try 
     Caption := 'Dialog Title' ; 
     Height := 169; 
 
     With ACheckBox do 
     begin 
       Parent := AMsgDialog; 
       Caption := 'Don''t show me again.'; 
       top := 121; 
       Left := 8; 
     end; 
 
     Case ShowModal of 
       ID_YES: ; //здесь Ваш код после того как диалог будет закрыт 
       ID_NO:  ; 
     end; 
     If ACheckBox.Checked then 
     begin 
       //... 
     end; 
   finally 
     ACheckBox.Free; 
     Free; 
   end; 
 end;  

Также Вы можете изменить диалог по Вашему усмотрению. Эти изменения основаны на том, что функция CreateMessageDialog создаёт форму, на которой располагаются компоненты стандартного диалога (небольшая иконка, текст сообщения, кнопки). На эту форму можно добавить любой компонент и, соответственно, изменить внешний вид диалога.


Присылайте свои статьи по адресу info@delphi.int.ru с темой 'Articles' (без кавычек), и они будут опубликованы в ближайших выпусках рассылки и на сайте. Также вы можете заполнить вот эту форму. Большая просьба: статью оформляйте в -txt или -doc формате и используйте -zip или -rar сжатие (без самораспаковки).


Файловый архив.

Из данного раздела Вы можете скачать различные файлы: компоненты, plug-in'ы для Delphi, документацию по программированию, программы, игры, написанные на Delphi и всё остальное... Вы можете добавить свои файлы в данный раздел. Чтобы сделать это, пожалуйста, заполните форму на сайте. Новые файлы на сайте:

Название / описание файла
Категория
Объём
Ссылки
UnRarDLL - Небольшой набор для использования архиватора RAR в программах.
Файлы ответов
97.6 Кб
Добавляем компонент в стандартный Message Dialog.
Статьи
2.34 Кб
WebLabel - компонент, представляющий собой гипертекстовую ссылку с возможностью открытия web-страницы при щелчке.
Компоненты
4.31 Кб
WinampControl - Компонент, позволяющий управлять медиа-проигрывателем Winamp прямо из программы.
Компоненты
46.5 Кб
GhostMemo - Компонент, основанный на TMemo, но позволяющий запретить копирование/вырезку/вставку текста из/в него с помощью мыши или клавиатуры.
Компоненты
8.60 Кб

SpkFileListBox - Компонент, основанный на TListBox, позволяющий просматривать содержимое каталогов и файлов. Основные возможности:

  • Просмотр содержимого директорий;
  • Изменение вида: добавление разделитилей, градиентного фона и др.
  • Автоматическое изменение директории при двойном щелчке или нажатии <Enter>
  • Выделение разных типов файлов разными цветам
  • FTP-соединения и просмотр содержимого удалённых директорий
  • Загрузка и выгрузка файлов с/на FTP-сервер
  • Некоторые полезные события, например OnFileSelected, OnError, OnPathChanged и т.д.
Компоненты
7.12 Кб
PanelPicture - Панелька, на которой можно разместить изображение с красивой рамкой и дополнительными эффектами.
Компоненты
9.68 Кб
PHPInspector Unit - Модули позволяют анализировать PHP-файлы: функции, классы, интерфейсы, а также другие включаемые скриптовые блоки. Полностью поддерживается PHP5.
Plug-in's
129 Кб

PGP Components - эти модули предоставляют возможность использовать PGP-интерфейсы. Возможности:

  • Кодирование и декодирование (шифрование/расшифровка/подписка/проверка)
  • Создание файлов подписей и проверка сигнатур
  • Импорт, экспорт, отмена и удаление ключей
  • Несколько ключевых функций управления
  • Генерация ключей (DH/DSS, RSA)
  • Поддержка сертификата X509
  • Некоторые утилиты
Компоненты
332 Кб
KMAlert - Позволяет плавно выдвигать окошко из произвольных краёв экрана, аналогично его скрывать, а также выводить в любом месте экрана с разными эффектами появления/исчезновения. Окошко может содержать небольшую картинку и информационный текст.
Компоненты
214 Кб

Чтобы перейти к разделу "Файловый архив" на сайте, нажмите на эту ссылку.


Дружественные сайты.

Здесь представлены ссылки на дружественные сайты нашего портала. Если вы тоже хотите стать нашим другом, разместите наш баннер на своём сайте. Подробнее о том, как это сделать, можно прочитать на странице данного раздела на нашем сайте. Узнать о всех наших друзьях более подробно вы сможете на той же странице...


http://infomania2004.webhost.ru/ - Этот сайт создан для того, чтобы вы могли получить интересующую вас информацию с минимальными затратами сил и времени. Если вы не нашли здесь нужной информации, вы можете оставить заявку на ее поиск. Как только информация будет найдена, она появится на сайте, а вам сообщат об этом.


http://www.visualbasic.noka.ru/ - Программирование на Visual Basic & Basic. На сайте Вы найдете множество примеров, статьи, исходники, ActiveX, а также многое другое!


http://www.sashook.hut1.ru/ - Игры, коллекция флешек, обои и заставки, компьютерные приколы, картинки, тосты и алкогольные присказки, смешные истории и анекдоты.


http://www.ssgroup.fatal.ru/ - Delphi 39. Ресурс для программистов. Статьи, исходники, компоненты, учебники, справочники, FAQ, программы и многое другое.


http://www.hkdsoft.narod.ru/ - H.K.D. Soft - Программирование на Delphi, C/C++, Assembler, Pascal, Basic/VB/VBA/VBS. Компоненты, статьи, исходники, множество е-книг, форум. Бесплатный софт. Скачать программу GamesBase - базу данных по играм содержащую описания, скриншоты, коды, прохождения игр.


Дружественные рассылки:

Рассылки Subscribe.Ru :: Программирование
Интернет для Delphi-программиста
X-Program ПО, новости сайта и программирование в Delphi7
Visual Basic для новичков и профессионалов
Поиск текстов, переводов и аккордов песен
   

 


Юмор.

Приходят друзья к новому русскому, а тот хвастается новым ремонтом: гостиная вся в золоте, кухня забита дорогущей техникой, в спальня огромная кровать 6 на 6 метров. Спрашивает он у гостей: «ну как?», те: «все просто супер, но что-то у тебя в туалете плитка очень мелкая», он возмущенно: «вы чё в натуре, там одна плитка 100 баксов стоит, Пентиум называется!»

:))

Магазин по пpодаже компьютеpов. Пpодавец подбиpает богатой, но не понимающей в комьютеpах даме:
- Hу вот, я вам подобpал жесткий диск получше...
- Получше - это пожестче?

:))

Папа-программист сидит за компьютером, работает. В комнату вбегает маленькая дочка:
- Папа, папа, посмотри, у нас под окнами НЛО висит!!!
Папа, не поворачиваясь:
- Кто ж его под окнами ставит?! Надо было под Linux'ом, тогда б не зависло...

:))

Тонет программист, и орёт во всю глотку:
- f1,f1,f1. Фу ты, чёрт: помогите! помогите! помогите!

:))

Встречаются два квакера:
- Ты знаешь, по-моему квейк сильно на психику влияет. Вот сегодня ночью кошмарный сон снился: будто я в аду, а вокруг монстры, лава, кровь...
- Hу и как?
- Как, как, до пятого уровня дошел!

:))

Визит министpа здравоохранения в одну из психиатрических лечебниц. Осмотpев палаты, пpоцедуpные залы, столовую, министр изъявляет желание пpовеpить, как содеpжатся буйнопомешанные больные, опасные для окpужающих. Спускаются на 0-й этаж, главвpач отпиpает стальную кованую двеpь. За двеpью длинный коpидоp. Министр пеpеходит от камеpы к камеpе, читает таблички, иногда заглядывает внутpь. Около одной из камеp:
- Так-так. Остpая паpанойя, OS/2 Warp, мания величия... Заглядывает в окошко. Угpюмый тип, увидев министра, начинает метаться по камеpе, кpича:
- Ла-а-меpы!!! Ла-а-а-меpы!!! Суксь, суксь МастДайная!!!
Министр: (Обpащаясь к главврачу)
- Часто он так?
Главврач:
- Как новое лицо увидит, сpазу пpиступ...
Идут дальше. Министр:
- Так-так. Остpая паpанойя. UNIX, мания величия...
Заглядывает в окошко. Угpюмый тип, отpываясь от созеpцания собственных pук, повоpачивается, pасплывшись в улыбке, изpекает:
- Истинная многозадачность, полный контpоль, Рулезь Фоpева!
Министр: (Обpащаясь к главврачу)
- Тихий такой! Выздоpавливает?
Главврач:
- Hет, вpеменное улучшение. - (повеpнувшись к окошку) - NT!
Больной, вскочив с кpовати, начинает метаться по камеpе, кpича:
- А-а-а!!! Вытесняющая многозадачность!!! Исходные тексты!!! Суксь!!! Ла-а-а-меpы!!!
Идут дальше. Министр:
- Так-так. Остpая паpанойя. Windows'95, мания величия...
Заглядывает в камеpу: Камеpа пуста. Министр (недоуменно повоpачивается к главврачу):
- А где же больной? Hа пpоцедуpах?
Главврач:
- Видите ли... Только поймите нас пpавильно... Бухгалтеpия у нас на Excel, личные дела больных на Access...

:))

Анекдоты прислал: Масалов Андрей. Спасибо тем, кто прислал другие анекдоты! Они будут опубликованы в следующих выпусках.


Пожалуйста, присылайте свои анекдоты по этой ссылке: info@delphi.int.ru и они обязательно будут опубликованы! Желательно на компьютерную тему.

Товарищи программисты! Проявляйте свою активность. Давайте помогать друг другу!
Если вы не нашли ответа на свой вопрос, не отчаивайтесь! Количество подписчиков постоянно растёт и, наверняка, найдётся тот человек,
который поможет вам! На сегодня всё. До встречи через неделю!
Ведущий рассылки, Ерёмин Андрей.

Вы можете оказать помощь нашему проекту через систему WebMoney: R379291065219, Z165075684614. Будем очень признательны!

 

Subscribe.Ru
Поддержка подписчиков
Другие рассылки этой тематики
Другие рассылки этого автора
Подписан адрес:
Код этой рассылки: comp.soft.prog.delphifaq
Архив рассылки
Отписаться
Вспомнить пароль

В избранное