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

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

  Все выпуски  

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


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

Программирование на DELPHI
Выпуск #40 (29 января 2006 г.) 

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

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



Связь:

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

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

Ситуация с форумом разрешились, причём в лучшую сторону! Теперь форум стал чист и ждёт новых тем. Права доступа к форуму ограничены, так что теперь количество спама на нём уменьшится в десятки раз (а может и совсем). Чтобы иметь возможность создавать новые темы и добавлять сообщения в существующие, нужно предварительно зарегистрироваться. Регистрация требует подтверждения по e-mail. Ждём Вас на нашем форуме!

Также произошли изменения в текстах ответов на вопросы. Теперь исходные коды выделяются специальной рамкой, а сам код подсвечивается и напоминает вид редактора Delphi! Отступы отныне тоже сохраняются. Всё это делает код очень читабельным. Желаю приятного чтения!

Внимание! Вопросы и ответы для следующего выпуска рассылки принимаются до 05.02.2006 12:00. Будьте внимательны. Письма, присланные позже откладываются для публикации в следующем выпуске.

Сайт рассылки: http://www.delphi.int.ru/.

До встречи!

В интернете появился новый Интернет-магазин для программистов, в котором есть большое количество программного обеспечения для разработчиков и дизайнеров. Цена одного DVD - 300 руб. Доставка осуществляется по всей России. Рекомендуем Вам приобрести следующие диски:

E-book - библиотека программиста (150 учебниковв по программированию);
DVD - Все для программиста 1,2;
DVD - обучение программированию;
DVD - Delphi;

Также в продаже имеется Microsoft Visual Studio 2005.

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

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


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


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

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


Подписаться почтой

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

Место
Имя
Баллы
Статус
1
Dron
313
Специалист
2
Ermakova Dasha
310
Специалист
3
Feniks
296
Практикант
4
Садовников Владимир
280
Практикант
5
Iron Monk
200
Практикант
6
Матвеев И.В.
187
Практикант
7
Лучников А.И.
127
Студент
8
Ершов Денис
125
Студент
9
mvp
125
Студент
10
Yurchik
100
Студент
11
Трапезников Антон
94
Эксперт: 10-ый класс
12
VeroLom
90
Эксперт: 10-ый класс
13
Igor Danilevych
81
Эксперт: 9-ый класс
14
PVS
81
Эксперт: 9-ый класс
15
SHKoder@deagnostic.ru
74
Эксперт: 8-ой класс

Некоторая статистическая информация:

Количество пользователей:
144
Общее количество баллов:
4420
Средний балл:
31
Максимальный балл:
313
Минимальный балл:
3
Адресов в зоне .RU:
107

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

Статус
Необходимое кол-во баллов
Прикрепление файлов
Форматирование текста
Посетитель
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-формы   |   Система "Эксперт"


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

Вопрос #224 (автор вопроса: Alex; вопрос отправлен: 16.01.2006 16:32):

Как создать программу, чтобы при нажатии на Button1 она загружала в Memo1 текстовый файл по адресу: http://www.myserver.com/news.txt?  [Ответить на вопрос]

Вопрос #225 (автор вопроса: breeze82@mail.ru; вопрос отправлен: 18.01.2006 17:38):

Есть к примеру такая строка: Books[1].WorkSheets[1].Rows[1].HorizontalAlignment := 3; Она, как Вы знаете, в Excel'е выравнивает по центру и по горизонтали. Подскажите, как включить перенос по словам в той же ячейке? Такая строка выдает ошибку: XLApp.WorkBooks[1].WorkSheets[1].Columns[1].Autosize := True;  [Ответить на вопрос]

Вопрос #226 (автор вопроса: Ярошук Ю.А.; вопрос отправлен: 18.01.2006 19:03):

Как напечатать TForm и все копмоненты на ней в альбомном формате А4?  [Ответить на вопрос]

Вопрос #227 (автор вопроса: Alex; вопрос отправлен: 19.01.2006 00:16):

Я не могу получить вложение в письме, программа его просто не видит. Вот текст:
IdPOP31.Retrieve(i,msg);
for n:=0 to msg.MessageParts.Count do
begin
if (msg.MessageParts.Items[n] is TIdAttachment) then
showmessage('There is attachment');
end;

Как получить все вложения и сохранить их на диске?  [Ответить на вопрос]

Вопрос #228 (автор вопроса: Захар; вопрос отправлен: 19.01.2006 12:44):

Здравствуйте. Есть такая проблема. Я пишу (на Delphi 7, мне он по душе, раньше имел опыт только на ZX-Spectrum :-)) программу по составлению сметы на строительные работы (нужно по работе). Сам являюсь начинающим, но хотелось бы довести до конца. И в смысле интересно, да и развиваться надо :-) Сделал основу. Таблица, в нее по кнопке добавляются услуги с ценой и количеством. Список услуг сохраняю в файл. Проблема в том, что цену приходится вводить вручную, как ее состыковать со списком услуг? И еще не могу придумать как сохранить готовую смету. Там пять столбиков плюс итоговая шапка ну и прочая лабуда. Если кто-нибудь возьмется отвечать, то прошу поподробнее. У меня мысли не успевают за текстом :-))) Был бы рад постоянной переписке с кем нибудь, в целях личного самообразования :-)  [Ответить на вопрос]

Вопрос #229 (автор вопроса: Ярошук Ю.А.; вопрос отправлен: 19.01.2006 14:33):

Как вывести TCalendar на один месяц с положением цифр не по центру ячейки, а в левый или правый угол?  [Ответить на вопрос]

Вопрос #230 (автор вопроса: trahten; вопрос отправлен: 27.01.2006 22:59):

Как ячейке StringGrid присвоить цвет или вставить рисунок?  [Ответить на вопрос]


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

Вопрос #205:
У меня такой вопрос: как можно написать DLL для нормального чтения mov и avi в кодировке DivX(Xvid), mpeg4, ну и др. какие-нибудь? Или есть какие компоненты? Использую MediaPlayer из Delphi7. Просто когда открываю такой файл, то нет звука, чёрный экран, или изображение идёт по ключевым фреймам.

1. [Отвечает: SHKoder@deagnostic.ru (статус: Эксперт: 8-ой класс), 15.01.2006 14:19]: П опробуйте обновить свои кодеки, или вы используете не ту длл для воспроизведения, проверьте версии, а вообще вы изобретаете велосипед - успехов вам в этом не лёгком труду.

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

Вопрос #216:
У меня такая ситуация: имеется форма и компоненты RadioButton (порядка 20) на ней, после компиляции (во время работы с написаной программой) некоторые RadioButton`ы переходят в состояние Disabled, как и задумано ранее. Вопрос такой: как сделать кнопку "сброс" (сам код) которая при нажати переводила бы все RadioButton`ы в Enabled, или же открывала форму заново? Желательно какое-нибудь "компактное решение", а не: RadioButton1.Enabled:= True; RadioButton2.Enabled:= True; ...

1. [Отвечает: SHKoder@deagnostic.ru (статус: Эксперт: 8-ой класс), 15.01.2006 14:15]:

procedure TfrmMDIChildMain.Button1Click(Sender: TObject);
var i : integer;
begin
for i := 1 to ComponentCount - 1 do begin
if Components[i].Name = 'cxLabel'+inttostr(i) then
   (Components[i] as TRadioButton).Enabled := false
end
end;

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

2. [Отвечает: Alex (статус: Эксперт: 2-ой класс), 15.01.2006 15:23]: Проще использовать компонент «RadioGroup». Записываешь названия радиобуттонов в «Items» (каждая строчка – отдельный бутон), А на кнопку клёпаешь:

procedure TForm1.Button1Click(Sender: TObject);
begin
  RadioGroup1.ItemIndex:= -1 ;
end;

Всё работает!

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

3. [Отвечает: Садовников Владимир (статус: Практикант), 15.01.2006 17:26]: Этот код врубает/вырубает все RadioButton'ы на форме:

procedute TForm1.SetupRadio(Enable:Boolean);
var
  I:Integer;
begin
  for I:=0 to ComponentCount-1 do
    if Components[I] is TRadioButton then
      TRadioButton(Components[I]).Enabled:=Enable;
end;

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

4. [Отвечает: sattar (статус: Эксперт: 1-ый класс), 15.01.2006 17:28]:

var
i:integer;
begin
for i:=0 to Form1.ComponentCount-1 do
if Form1.Components[i] is TRadioButton then
Form1.Controls[i].Enabled:=True;

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

5. [Отвечает: Ares (статус: Эксперт: 4-ый класс), 15.01.2006 20:23]: По-моему это можно сделать так:

for i := 0 to Form1.ControlCount - 1 do
  if Controls[i].Classtype = TRadioButton then Controls[i].Enabled := true;

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

6. [Отвечает: Aleksey Mayboroda (статус: Эксперт: 1-ый класс), 16.01.2006 8:42]:

for i := 0 to Form1.ControlCount - 1 do
  if Form1.Controls[i].ClassName = 'TRadioButton' then
    (Form1.Controls[i].Enabled := true;

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

7. [Отвечает: мэйл_рфдл2 (статус: Эксперт: 4-ый класс), 16.01.2006 8:49]: Примерно так:

   procedure XXX;
   var
     i:integer;
   begin
     for i:=0 to ComponentCount - 1 do
       if (Components[i] is TRadioButton) then
          (Components[i] as TRadioButton).Enabled := True;
   end;

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

8. [Отвечает: progger (статус: Эксперт: 1-ый класс), 16.01.2006 8:11]: В этом случае можна написать такую процедурку:

procedure clearRadioButton;
var i: Integer;
begin
for i:=0 to componentCount-1 do
  if (Components[i] is TRadioButton) then
    (components[i] as TradioButton).enabler:=true;
end;

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

9. [Отвечает: Трапезников Антон (статус: Эксперт: 10-ый класс), 16.01.2006 11:30]: Если имена RadioButton'ов отличаются только индексами, то можно использовать такой код:

var
  i: integer;
  RB: TRadioButton;

......

for i := 0 to 20 do
  begin
    RB := FindComponent('RadioButton'+IntToStr(i+1)) as TRadioButton;
    if RB <> nil then RB.Enabled := true;
  end

Если же вы используете нестандартные имена компонентов, то подойдет следующий код:

for i := 0 to ComponentCount - 1 do
    if Components[i] is TRadioButton then
      begin
        RB := Components[i] as TRadioButton;
        if RB <> nil then RB.Enabled := true;
      end;

Удачи!

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

10. [Отвечает: mihey (статус: Эксперт: 1-ый класс), 16.01.2006 9:52]:


procedure TForm1.Button1Click(Sender: TObject);
var i: integer;
begin
  for i:= 0 to ComponentCount-1 do
  if (Components[i] is TRadioButton) then
    (Components[i] as TRadioButton).Enabled:= False;
end;

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

11. [Отвечает: Романишин Виталий Юрьевич (статус: Эксперт: 1-ый класс), 16.01.2006 9:57]: Наверное вы ошиблись, не RadioButton(ы) а CheckBox(ы) то это просто:

procedure TForm1.Button1Click(Sender: TObject);
var   i  :  word;
begin
   for i:=0 to form1.ComponentCount-1 do begin
      if (form1.Components[i] is tcheckbox) then
         (form1.Components[i] as tcheckbox).Checked:=true;
   end;
end;

Примерно также можно работать со всеми компонентами.

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

12. [Отвечает: PVS (статус: Эксперт: 9-ый класс), 16.01.2006 10:04]:

for i:=1 to MyForm.ComponentCount do
if (MyForm.Components[i] is TRadioButton) then
  (MyForm.Components[i] as TRadioButton).Enable:=True;

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

13. [Отвечает: Матвеев И.В. (статус: Практикант), 16.01.2006 20:36]: Вот Вам кусок кода:

procedure TForm1.Button1Click(Sender: TObject);
var
  I : Integer;
begin
// Т.к. TRadioButton - наследник от TWinControl, ищем только
// среди контролов
for i := 0 to ControlCount -1 do
   if (Controls[i] is TRadioButton) then (Controls[i] as TRadioButton).Enabled := True;
end;

Примечание: Код изменит Enabled только для элементов, относящихся к форме, если на форме находится панель, а на ней RadioButton - его свойство Enabled изменено не будет.

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

14. [Отвечает: Ершов Денис (статус: Студент), 16.01.2006 16:47]: Приветствую, Jake.
1. Самое простое, если необходимо просто установить все кнопки в активное состояние, поступаем следующим образом:

  procedure ...;
  var i: integer;
  begin
    for i:=0 to Form1.ControlCount - 1 do
      if Form1.Controls[i] is TRadioButton then
         TRadioButton(Form1.Controls[i]).Enabled := true;
  end;

Можно также использовать для поиска свойства Components и ComponentCount, но необходимо четко представлять различия в компонентах родитель и владелец. Иначе в сложных формах можно дать маху.

2. Можно задать более жесткие критерии поиска. В каждом компоненте есть свойство Tag для хранения пользовательских данных. Его можно использовать для активации только определенной выборки компонентов, свойства Tag которых установлено в определенное значение.

const
    IndexForActive = 1;
  ...

  TRadioButton(Form1.Controls[i]).Enabled :=
               Form1.Controls[i].Tag = IndexForActive;

3. В конце концов эти значения можно хранить в файле формата:

<Имя компонента>=<Значение Enabled компонента>

procedure ...;
  var i: integer;
      sl: TStringList;
  begin
    sl := TStringList.Create;
    sl.LoadFromFile('Enabled.cfg');
    for i:=0 to Form1.ControlCount - 1 do
      if Form1.Controls[i] is TRadioButton then
         TRadioButton(Form1.Controls[i]).Enabled :=
                      sl.Values[Form1.Controls[i].Name] = 'true';
    sl.Free;
  end;

4. Есть и более экзотический способ - сохранить при запуске форму в поток:

BinStream.WriteComponent(Form1);

- а затем восстанавливать ее из этого потока:

BinStream.ReadComponent(Form1);

5. Кто-нибудь! Остановите меня... :)

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

15. [Отвечает: Деревянко Евгений (статус: Эксперт: 4-ый класс), 16.01.2006 19:54]: Если все компоненты лежат на форме (а не на панельке, например), то это можно сделать так:

procedure TForm1.Button1Click(Sender: TObject);
var
  i : integer;
begin
  for i := 0 to Form1.ComponentCount - 1 do
    if Form1.Components[i].ClassName = 'TRadioButton' then
      (Form1.Components[i] as TRadioButton).Enabled := true;
end;

Если анализ проводится для компонентов, лежащих на другом котейнере, не форме, то просто вместо Form1 следует просто писать имя контейнера.

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

16. [Отвечает: Ermakova Dasha (статус: Специалист), 17.01.2006 17:55]:

procedure TForm1.Button1Click(Sender: TObject);
var
i: integer;
begin
  for i:=0 to ControlCount-1 do
  if Controls[i].Classtype = TRadioButton then
  Controls[i].Enabled:=true;
end;

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

17. [Отвечает: Den (статус: Эксперт: 1-ый класс), 17.01.2006 20:09]:

for i:=1 to 20 do
    (FindComponent(format('CheckBox%d',[i]))as TCheckBox).Checked:=true;

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

18. [Отвечает: Лучников А.И. (статус: Студент), 18.01.2006 15:10]: Самый простой способ:

for i:=0 to ComponentCount-1 do
    begin
    if Components[i] is TRadioButton then
        TRadioButton(Components[i]).Enabled:=True;
    end;

P.S. Возможны вариации, если не всем RadioButton нужно менять значение. Например, проверять еще имя или устанавливать, к примеру Tag, отличный от 0.

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

19. [Отвечает: tmp (статус: Эксперт: 1-ый класс), 19.01.2006 0:39]: Здраствуй, Jake! Если хочешь работать сразу с большим количеством компонент, то создание их следует сделать динамическим. Т.е, создаешь массив, состоящий из 20 эл-тов TRadioButton, для каждого из них можно будет задать один и тот же обработчик события, при этом определять, какой же объект все-таки вызвал обработчик мы будем через объект Sender, который указывает на "Отправителя".

Например: есть массив:

a:array[1..n]of TRadioButton;

Это создает:

for i:=1 to n do
begin
a[i]:=TRadioButton.Create(Application);
a[i].Parent:=self;
a[i].Visible:=true;
a[i].top:=i*20;
a[i].Height:=15;
a[i].left:=10;
a[i].Width:=100;
a[i].Caption:='Text';
end;

Свойства меняем по вкусу. Теперь можно в цикле менять выборочно свойство a[i].enabled.

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

20. [Отвечает: Yurchik (статус: Студент), 20.01.2006 16:11]: Вот код, который переводит ВСЕ RadioButton`ы в Enabled:

procedure TForm1.Button1Click(Sender: TObject);
var
  i: Integer;
begin
  with Form1 do
    for i:= 0 to ComponentCount-1 do
      if Components[i] is TRadioButton then
        TControl(Components[i]).Enabled:= True;
end;

Если RadioButton`ы именуются как RadioButton1, RadioButton2, ..., то можно написать так:

procedure TForm1.Button1Click(Sender: TObject);
var
  i: Integer;
  Component: TComponent;
begin
  for i:= 1 to 4 do
  begin
    Component:= Form1.FindComponent('RadioButton'+IntToStr(i));
    if Component is TControl then
      TControl(Component).Enabled:= True;
  end;
end;

При этом можно управлять не всеми RadioButton`ами сразу, а группами.

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

21. [Отвечает: Dron (статус: Специалист), 20.01.2006 19:37]: Вариантов решения может быть несколько, но смысл один - использовать метод FindComponent(). Вот так например:

procedure TForm1.Button1Click(Sender: TObject);
var I: Integer;
begin
for I:=1 to 20 do
RadioButton(FindComponent('RadioButton'+IntToStr(I))).Enabled:=True;
end;

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

Вопрос #217:
Здравствуйте, уважаемые эксперты! С Новым 2006 Годом Вас!!! Подскажите пожалуйста: как используя объект TShellTreeView создать новый подкаталог и отобразить его в окне TShellTreeView? Заранее всем спасибо.

1. [Отвечает: мэйл_рфдл2 (статус: Эксперт: 4-ый класс), 16.01.2006 8:58]: Примерно так:

unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, ShellCtrls;
type
  TForm1 = class(TForm)
    ShellTreeView1: TShellTreeView;
    Button1: TButton;
    Label1: TLabel;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
    procedure ShellTreeView1Change(Sender: TObject; Node: TTreeNode);
  private
    { private declarations }
  public
    { public declarations }
  end;
var
  Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
   MKDIR(PChar(Label1.Caption + Edit1.Text+'\'));
   ShellTreeView1.Refresh(ShellTreeView1.Selected);
end;
procedure TForm1.ShellTreeView1Change(Sender: TObject; Node: TTreeNode);
begin
  label1.Caption :=  ShellTreeView1.Path + '\';
end;
end.

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

2. [Отвечает: midav.land.ru (статус: Эксперт: 8-ой класс), 16.01.2006 10:44]: Для создания нового каталога есть функции CreateDir, CreateDirectory. Они создают указаный каталог. Так как это функции, то они возвращают True если создать удалось. Но все каталоги, перечислены в пути должны существовать (естественно, кроме последнего). Для преодоления этой особенности пользуемся ForceDirectories. Он создаст весь каталог. Теперь к нашим баранам :) Берёшь текущий каталог, добавляешь имя нужного (можно в пользователя спросить) и вызываешь функцию создания каталога. Потом наверное придётся вызвать обновление для TShellTreeView, но кажется это уже не обязательно.

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

3. [Отвечает: Деревянко Евгений (статус: Эксперт: 4-ый класс), 16.01.2006 20:04]: А почему бы просто не создать новый каталог при помощи CreateDirectory или CreateDirectoryEx, затем отобразить его в TShellTreeView при помощи ShellTreeView.Refresh(Node: TTreeNode)?

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

4. [Отвечает: Лучников А.И. (статус: Студент), 19.01.2006 11:19]: Путь к выбранному каталогу: ShellTreeView1.Path или ShellTreeView1.SelectedFolder.PathName. Для того, чтобы изменения показывались сразу есть Свойство AutoRefresh // по-умолчанию False. Далее создаёшь новый каталог NewFolder:=ShellTreeView1.Path+'\New Folder'; CreateDir(NewFolder); или ForceDirectories(NewFolder). Рекомендую, перед созданием каталога проверить на тип выбранной папки, чтоб не попробовать создать каталог в папке "Мой компьютер" (я, например, не рискнул) ShellTreeView1.SelectedFolder.Properties вот кусок из ShellCtrls.pas
{
TShellFolderProperty = (fpCut, fpIsLink, fpReadOnly, fpShared, fpFileSystem, fpFileSystemAncestor, fpRemovable, fpValidate);
TShellFolderProperties = set of TShellFolderProperty;
}

Чтоб перейти на вновь созданную папку (как, в принципе и на любую папку) ShellTreeView1.Path:=NewFolder; { можно добавить ShellTreeView1.SetFocus; если добавление каталога было по кнопке, чтоб сразу было видно } З.Ы. У компонента TShellTreeView есть своя (точнее-шеловская) popup-менюшка, но она перекроется, если подключить свой PopupMenu. К сожалению, в ней нет пунктика "создать", а то было бы совсем просто.

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

5. [Отвечает: Dron (статус: Специалист), 20.01.2006 19:36]: Использовать TShellTreeView для создания каталогов не нужно - для этого существуют функции MkDir, CreateDirectory, ForceDirectories и др. Нужно просто воспользоваться ими, после чего обновить дерево каталогов:

MkDir(InputBox('New dir','Please enter the full dir path:','C:\temp'));
ShellTreeView1.Refresh(ShellTreeView1.Items[0]);

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

Вопрос #218:
Всем привет! Есть желание, но нет возможности замутить для своего чата банальные смайлики. Чат на сокетах для локальной сети. Что можно использовать в качестве отображения мессаджей и смайлов? Если есть компонент специальный, подскажите пожалуйста, где его взять. Спасибо заранее.

1. [Отвечает: Aleksey Mayboroda (статус: Эксперт: 1-ый класс), 16.01.2006 8:44]: Я для этой цели использовал TWebBrowser. В нем есть возможность добавлять html текст в конец, ну а там уже можешь добавлять что хочешь, хоть видеофайл вставить с киношкой :)

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

2. [Отвечает: Трапезников Антон (статус: Эксперт: 10-ый класс), 16.01.2006 11:41]: Здравствуйте, Олег. Т.е. как я понял проблема сводится к вставке изображения в RichEdit. Есть замечательный компонент - RXRichEdit (в библиотеке RXLib), с помощью него можно реализовать вставку изображений. Недавно наткнулся (на www.sources.ru , кажется) на такой код:

function BitmapToRTF(pict: TBitmap): string;
var
  bi,bb,rtf: string;
  bis,bbs: Cardinal;
  achar: ShortString;
  hexpict: string;
  I: Integer;
begin
  GetDIBSizes(pict.Handle,bis,bbs);
  SetLength(bi,bis);
  SetLength(bb,bbs);
  GetDIB(pict.Handle,pict.Palette,PChar(bi)^,PChar(bb)^);
  rtf := '{\rtf1 {\pict\dibitmap ';
  SetLength(hexpict,(Length(bb) + Length(bi)) * 2);
  I := 2;
  for bis := 1 to Length(bi) do
  begin
    achar := Format('%x',[Integer(bi[bis])]);
    if Length(achar) = 1 then
      achar := '0' + achar;
    hexpict[I-1] := achar[1];
    hexpict[I] := achar[2];
    Inc(I,2);
  end;
  for bbs := 1 to Length(bb) do
  begin
    achar := Format('%x',[Integer(bb[bbs])]);
    if Length(achar) = 1 then
      achar := '0' + achar;
    hexpict[I-1] := achar[1];
    hexpict[I] := achar[2];
    Inc(I,2);
  end;
  rtf := rtf + hexpict + ' }}';
  Result := rtf;
end;

А вот пример использования этой функции:


//SS это TStringStream, RE это TRxRichEdit, а BMP это TBitmap содержащий картинку.
SS := TStringStream.Create(BitmapToRTF(BMP));
RE.PlainText := False;
RE.StreamMode := [smSelection];
RE.Lines.LoadFromStream(SS);
SS.Free;

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

3. [Отвечает: PVS (статус: Эксперт: 9-ый класс), 16.01.2006 10:08]: Можно импортировать TBrowser (ActiveX от InternetExplorer'a) и тогда можно рисовать все, что могут HTML, JavaScript и другие Script-ы.

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

4. [Отвечает: Матвеев И.В. (статус: Практикант), 16.01.2006 20:36]: Если смайлики планируется делать анимированными - можно использовать InternetExplorer Control в виде TWebBrowser. Или использовать THTMLViewer - это VCL аналог WebBrowser'a - отображает чистый html, может отображать и анимационные Gif'ы, но там прийдется поработать - ищите его на www.torry.ru. Если смайлики делать анимационными не планируется - можно испрользовать TRichView. Смотрите на www.trichview.com.

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

5. [Отвечает: midav.land.ru (статус: Эксперт: 8-ой класс), 16.01.2006 10:55]: В компонентах JEDI (http://www.delphi-jedi.org) в примерах есть как сделать окошко со смайликами, и не только...

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

6. [Отвечает: Zeon (статус: Эксперт: 4-ый класс), 17.01.2006 0:16]: Я так понимаю у тебя клиент-сервер. С точки зрения экономии трафика лучше чтобы в базе каждого клиента уже имелись картинки с нужными смайликами (в любом виде, хоть ImageList, хоть просто пронумированные файлы). А передавать будешь только номер нужного смайлика. Или можно, конечно, тупо гнать по сокетам картинку через MemoryStreem. Но это имеет смысл только в случае регулярного обновления базы смайликов на сервере.

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

Вопрос #219:
Здравствуйте! Первый вопрос такой: Программа сканирует реестр, и когда дохожу к ключу HKEY_LOCAL_MACHINE\SYSTEM\ControlSet002\Services\lanmanserver\Shares, то функция RegQueryInfoKey выдает, NumSubKeys=1, а MaxSubKeyLen=0 и дальше пошла ошибка получения имени ключа. В чем причина? Открываю RegOpenKeyEx с атрибутом KEY_READ.
А вот и второй: В некоторых ключах RegOpenKeyEx выдает ошибку 2 или 5, хотя в ключе присутствуют данные, почему?

1. [Отвечает: Матвеев И.В. (статус: Практикант), 16.01.2006 20:32]: Я провел пару экспериментов - действительно подключ Security в ключе Shares не находился с помощью RegEnumKeyEx. А RegQueryInfoKey возвращала то что Вы говорили, но исключения у меня никакого не возникло. Я добавил еще один подключ в Shares, назвал его test, проверил работу - все работало нормально, только RegQueryInfoKey возвращало MaxSubKeyLen=15 почему-то. Тогда я удалил этот новый ключ. Программа работет - благополоучно определяет подключ Security.

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

2. [Отвечает: Yurchik (статус: Студент), 20.01.2006 16:46]: Не знаю, в чем может быть причина. Нужно посмотреть код. А Вы вовремя закрываете ключи реестра функцией RegCloseKey? Функции RegOpenKeyEx и RegQueryInfoKey возвращают значение ERROR_SUCCESS в случае успешного вызова. В противном случае они возвращают код ошибки. Описание ошибки по ее коду можно получить, используя функцию FormatMessage. Вот пример:

var
  lpMsgBuf: Pointer;
  dwErrorCode: DWORD;
begin
  dwErrorCode:= ...;

  if (FormatMessage(
      FORMAT_MESSAGE_ALLOCATE_BUFFER or
      FORMAT_MESSAGE_FROM_SYSTEM or
      FORMAT_MESSAGE_IGNORE_INSERTS,
      nil,
      dwErrorCode,
      LANG_NEUTRAL,
      @lpMsgBuf,
      0,
      nil) = 0) then
  begin
     // Handle the error.
  end;

  // Process any inserts in lpMsgBuf.
  // ...

  // Display the string.
  MessageBox( 0, lpMsgBuf, 'Error', MB_OK or MB_ICONINFORMATION );

  // Free the buffer.
  LocalFree( UINT(lpMsgBuf) );
end;

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

Вопрос #220:
Как на Delphi 7 создать красивую форму наподобие Winamp'a?

1. [Отвечает: Садовников Владимир (статус: Практикант), 15.01.2006 17:30]: 1. Сделай (не обязательно) BorderStyle у формы bsNone или MDIChild. 2. Используй событие OnPaint, в котором рисуй прямо на канве формы и контролов (property Canvas) всё, что только вздумается.

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

2. [Отвечает: мэйл_рфдл2 (статус: Эксперт: 4-ый класс), 16.01.2006 9:00]: Смотри в сторону www.alphaskins.com.

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

3. [Отвечает: Матвеев И.В. (статус: Практикант), 16.01.2006 20:31]: Вариант первый: Использование Skin библиотек - это могут быть библиотеки просто изменяющие внешний вид контролов в соответствии с настроечными файлами - скинами. Например FreeSkinEngine. Если Вы хотите сделать что-то наподобие WinAmp - чтобы в скинах можно было бы изменить не только вид контролов, но и их положение - используйте библиотеку BusinessSkin. Ее использует BSPlayer - можете посмотреть. Вариант второй: Вы можете реализовать свою "машину плагинов", это можно оформить в виде dll библиотек, обрабатывающих отрисовку окна. Этот вариант годится для небольших программ, например для простенького проигрывателя. Не думайте, что это очень сложно - такое и на "Великом и Могучем" Ассемблере пишут. Неоспоримое преимущество этого метода в том, что в скинах можно изменить не только внешний вид, но и особенности поведения - например сворачиваться не на панель Пуск, а в трей. Вариант третий: Если никакие скины не нужны, а требуется просто сделать красивое окно с красивыми контроломи - просто используйте TImage. Вы можете взять темы из Stardock WindowBlinds. Там много разных рисунков: границы, углы форм, кнопок, рисунки RadioButton, CheckBox и др.

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

4. [Отвечает: midav.land.ru (статус: Эксперт: 8-ой класс), 16.01.2006 10:57]: Использовать скины, например AlphaSkin (кажется так он называется). Но предупреждаю сразу - много библиотек компонент со скинами не смотрят на то, какую они создают загрузку процессора.

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

5. [Отвечает: Деревянко Евгений (статус: Эксперт: 4-ый класс), 16.01.2006 20:26]: В DesignTime ставишь свойство TransparentColor в True, TransparentColorValue таким же как и Color, BorderStyle в bsNone а потом кидаешь на форму TImage, грузишь в них весёлые картинки и всё. Кстати, TImage можно использовать как кнопку.

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

6. [Отвечает: Zeon (статус: Эксперт: 4-ый класс), 17.01.2006 0:23]: Хороший вопрос. Ты для начала спроси "Как написать программу?". А если серьёзно - часто можно добиться неплохих результатов при помощи обычных TImage, только надо посидеть над Фотошопом. Или ищи различные компоненты для визуального оформления(например на www.torry.net). Только не спрашивай как использовать компоненты, это уже отдельная тема.

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

7. [Отвечает: Ершов Денис (статус: Студент), 19.01.2006 14:27]: Приветствую, Роман. По умалчиванию окна программы имеют прямоугольную форму. Однако имеется возможность задать совершенно произвольную форму при помощи процедуры SetWindowRgn. При этом присваиваемый форме регион может быть прямоугольником, эллипсом, произвольным полигоном. В модуле Windows функции создающие регионы представлены семейством, содержащие в названии слова "Create" и "Rgn". Кроме того, с помощью функции CombineRgn можно производить комбинирование (сложение, вычитание) этих регионов. В общем для твоей задачи нужен рисунок, где один цвет должен принят как цвет фона. Анализируем изображение, создавая регион по контуру в рисунке. Применяем полученный регион к окну программы по событию OnCreate формы. Осталось по событию OnPaint выводить искомое изображение на полученную форму. Фон виден не будет, так как будет за пределами региона окна. Так как и формы и элементы управления на ней являются частными случаями окна, данный фокус можно провести с кнопкой, Мемо и пр. винконтролами. Данная тема очень хорошо представлена в книге "Делфи глазами хакера". В аттаче пример из этой книги, посвященный окну в виде "Тринити, анфас". Загрузить прикреплённый файл >>

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

Вопрос #221:
Нужно написать что-то вроде текстового чата. Для этого я решил использовать два консольных буфера (CreateConsoleBuffer), которые потом копируются на общую консоль. С выводом, вроде всё в порядке. Кто-нибудь может подсказать, как при помощи WinAPI написать функцию ввода строки в нужном месте главной консоли, используя один из буферов?

1. [Отвечает: Садовников Владимир (статус: Практикант), 15.01.2006 17:36]: Пожалуй, отвечу на свой вопрос, так как уже нашёл решение методом проб и ошибок. А надо было написать POSIX- и Win32-совместимый класс окна на C++. Привожу готовый код (к сожалению, на C++).

Компиляция осуществляется под управлением макроса __WIN32__. Я его определил как:

// System Macros Definitions
#ifndef __unix__
#ifndef __UNIX__
#ifndef __LINUX__
#ifndef __WIN32__
#define __WIN32__ /* Compile for Win32 by default */
#endif /* __WIN32__ */
#endif /* __LINUX__ */
#endif /* __UNIX__ */
#endif /* __unix__ */

Для организации консоли нам понfдобятся никсовые <curses> и <term>, под Винду - <windows>:

#ifndef __WIN32__ /* *nix */
#include <curses.h>
#include <term.h>
#else /* __WIN32__ */
#include <windows.h>
#endif /* __WIN32__ */

Теперь класс окна (!) консоли описывается так:

class TWindow
{
private:
int FX, FY, FWidth, FHeight;
#ifndef __WIN32__ /* *nix */
WINDOW *FWindow;
#else /* __WIN32__ */
HANDLE FWindow;
#endif /* __WIN32__ */

public:
// Конструктор
explicit TWindow(int X, int Y, int Width, int Height);

// Деструктор
~TWindow(void);

// Форматированный вывод
int VPrintF(const char *fmt, va_list args);
int PrintF(const char *fmt, ...);

// Вывод строки
void PutS(const char *str);

// Вывод символа
void PutChar(char ch);

// Обновление окна на общем экране
void Refresh(void);

// Очистка окна
void Clear(void);

// Считывание строки (!!!) с окна
int GetStr(char *string, int max);
};

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

explicit TWindow::TWindow(int X, int Y, int Width, int Height):
{
FX=X;
FY=Y;
FWidth=Width;
FHeight=Height;

#ifndef __WIN32__ /* *nix */
FWindow=subwin(stdscr,FHeight,FWidth,FY,FX);
#else /* __WIN32__ */
// Под виндой всё гораздо сложнее:
FWindow=CreateConsoleScreenBuffer(
GENERIC_READ | GENERIC_WRITE,
0,
0,
CONSOLE_TEXTMODE_BUFFER,
0);

SMALL_RECT rect={0, 0, FWidth-1, FHeight-1};
SetConsoleWindowInfo(FWindow,TRUE,&rect);

// Размеры буфера
COORD size;
size.X=FWidth;
size.Y=FHeight;
SetConsoleScreenBufferSize(FWindow,size);
SetConsoleActiveScreenBuffer(GetStdHandle(STD_OUTPUT_HANDLE));

// Параметры ввода с консоли
DWORD dwMode;
GetConsoleMode(
GetStdHandle(STD_INPUT_HANDLE),
&dwMode);
dwMode|=ENABLE_LINE_INPUT;
dwMode|=ENABLE_ECHO_INPUT;
dwMode&=(~ENABLE_WINDOW_INPUT);
SetConsoleMode(
GetStdHandle(STD_INPUT_HANDLE),
dwMode);
#endif /* __WIN32__ */
}

Деструктор тривиален и должен освобождать выделенные ресурсы^

TWindow::~TWindow(void)
{
#ifndef __WIN32__ /* *nix */
if (FWindow!=0)
delwin(FWindow);
#else /* __WIN32__ */
CloseHandle(FWindow);
#endif /* __WIN32__ */
}

Функции форматированного вывода также тривиальны:

int TWindow::VPrintF(const char *fmt, va_list args)
{
#ifndef __WIN32__ /* *nix */
int result=vwprintw(FWindow,fmt,args);
#else /* __WIN32__ */
char s[1024];
int result=vsnprintf(s,1023,fmt,args);
PutS(s);
#endif /* __WIN32__ */

Refresh();
return result;
}

int TWindow::PrintF(const char *fmt, ...)
{
va_list args;
va_start(args,fmt);
#ifndef __WIN32__ /* *nix */
int result=vwprintw(FWindow,fmt,args);
#else /* __WIN32__ */
int result=VPrintF(fmt,args);
#endif /* __WIN32__ */
va_end(args);

Refresh();
return result;
}

Вывод строки тоже вполне прост:

void TWindow::PutS(const char *str)
{
#ifndef __WIN32__ /* *nix */
waddstr(FWindow,str);
#else /* __WIN32__ */
DWORD written;
WriteConsole(FWindow, str, strlen(str), &written,0);
#endif /* __WIN32__ */
Refresh();
}

Вывод символа на консоль - частный случай вывода строки:

void TWindow::PutChar(char ch)
{
#ifndef __WIN32__ /* *nix */
waddch(FWindow,ch);
#else
DWORD written;
WriteConsole(FWindow, &ch, sizeof(char), &written,0);
#endif /* __WIN32__ */

Refresh();
}

Вот с обновлением окна под Win32 начинаются проблемы: приходится считать координаты, куда необходимо поместить скрытый буфер:

void TWindow::Refresh(void)
{
#ifndef __WIN32__ /* *nix */
wrefresh(FWindow);
#else /* __WIN32__ */
COORD buf_size={FWidth, FHeight};
COORD buf_coord={0, 0};
SMALL_RECT region={0, 0, FWidth-1, FHeight-1};

// Создаём временный буфер и считываем в него прямоугольную
// область окна
CHAR_INFO *data=new CHAR_INFO[FWidth*FHeight];
ReadConsoleOutput(
FWindow,
data,
buf_size,
buf_coord,
&region);

// Расчёт координат
region.Left=FX;
region.Top=FY;
region.Right=FX+FWidth-1;
region.Bottom=FY+FHeight-1;

// Теперь записываем прямоугольную область окна на консоль
WriteConsoleOutput(
GetStdHandle(STD_OUTPUT_HANDLE),
data,
buf_size,
buf_coord,
&region);

delete data;
#endif /* __WIN32__ */
}

То же самое и с очисткой окна: господа из компании Microsoft решили возложить всю рутину на обычных программистов:

void TWindow::Clear(void)
{
#ifndef __WIN32__ /* *nix */
wmove(FWindow,0,0);
wclear(FWindow);
wmove(FWindow,0,0);
#else /* __WIN32__ */
COORD buf_size={FWidth, FHeight};
COORD buf_coord={0, 0};
SMALL_RECT region={0, 0, FWidth-1, FHeight-1};

CHAR_INFO *data=new CHAR_INFO[FWidth*FHeight];
memset(data,0,FWidth*FHeight*sizeof(CHAR_INFO));
WriteConsoleOutput(
FWindow,
data,
buf_size,
buf_coord,
&region);

delete data;

// Устанавливаем положение курсора в позицию (0,0)
// в текущем окне
SetConsoleCursorPosition(
FWindow,
buf_coord);

#endif /* __WIN32__ */
Refresh();
}

И на закуску - считывание строки с консоли. Опять видна криворукость Windows.

int TWindow::GetStr(char *string, int max)
{
#ifndef __WIN32__ /* *nix */
int result = wgetnstr(FWindow, string, max);
#else /* __WIN32 */
// Перед тем, как что-то вводить, нужно поместить курсор
// консоли в нужную позицию
CONSOLE_SCREEN_BUFFER_INFO info;
GetConsoleScreenBufferInfo(FWindow,&info);
info.dwCursorPosition.X+=FX;
info.dwCursorPosition.Y+=FY;

SetConsoleCursorPosition(
GetStdHandle(STD_OUTPUT_HANDLE),
info.dwCursorPosition);

// Считываем строку
DWORD result=0;
ReadConsole(
GetStdHandle(STD_INPUT_HANDLE),
string,
max-1,
&result,
0);

// Какой умник сказал, что нам нужны символя CR и LF в
// конце строки???
while (result>1)
{
if ((string[result-1]=='\r') || (string[result-1]=='\n'))
result--;
else
break;
}
string[result]=0;

#endif /* __WIN32__ */
Refresh();
return result;
}

Этот класс консоли предназначен для SingleThreaded-приложений. Если потребуется использование окон несколькими нитями, то необходимо использовать объекты синхронизации - мьютексы, критические секции, семафоры. Но это уже совсем другая история...

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

2. [Отвечает: Трапезников Антон (статус: Эксперт: 10-ый класс), 16.01.2006 11:50]: Посмотрите здесь: http://www.helloworld.ru/texts/comp/lang/delphi/console/index.htm

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

Вопрос #222:
Уважаемые программисты, подскажите как из БД Access оперировать данными (числами) (арифметические действия), или вывести определённую ячейку? Заранее благодарен.

1. [Отвечает: SHKoder@deagnostic.ru (статус: Эксперт: 8-ой класс), 15.01.2006 14:18]: Слишком обширный вопрос. Если нужно получить данные то делайте скрипт получения данной select top 1 value from table. Затем ADOQuery.FeildByName('value').AsInteger; делайте с ней что хотите.

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

2. [Отвечает: Трапезников Антон (статус: Эксперт: 10-ый класс), 16.01.2006 11:06]: Здравствуйте, Ilay Babakov. Первое что Вам нужно сделать - настроить подключение к БД. Можно использовать BDE (но я рекомендую Вам навсегда забыть о ней), можно ADO (имхо, лучше всего использовать ADO), можно dbExpress (эту библиотеку приоритетней всего использовать если Ваша программа в основном читает, а не пишет в БД). Все вышеперечисленное штатно входит в Delphi, приведу пример для ADO.

Вы можете использовать компонент ADOTable и в его свойстве ConnectionString настроить (build) подключение как базе данных MS Access. Например:

Provider=Microsoft.Jet.OLEDB.4.0;
User ID=Admin;
Password=Password;
Data Source=D:\Path\dbname.mdb;
Mode=ReadWrite;
Extended Properties="";
Persist Security Info=False;
Jet OLEDB:System database="";
Jet OLEDB:Registry Path="";
Jet OLEDB:Database Password="";
Jet OLEDB:Engine Type=5;
Jet OLEDB:Database Locking Mode=1;
Jet OLEDB:Global Partial Bulk Ops=2;
Jet OLEDB:Global Bulk Transactions=1;
Jet OLEDB:New Database Password="";
Jet OLEDB:Create System Database=False;
Jet OLEDB:Encrypt Database=False;
Jet OLEDB:Don't Copy Locale on Compact=False;
Jet OLEDB:Compact Without Replica Repair=True;
Jet OLEDB:SFP=False

При этом будет открыта база данных D:\Path\dbname.mdb, будет использован драйвер ADO для базы данных Access (Microsoft.Jet.OLEDB.4.0). Имя пользователя будет Admin без пароля (эти значения присваиваются поумолчанию при создании базы Access). Если Вы всё-таки захотите использовать пароль, то его надо будет задать в ствойстве Jet OLEDB:Database Password. Если у Вас установлен режим безопасности, то необходимо указать файл .MDW или .MDA в свойстве Jet OLEDB:System database.

Взять что-то из БД можно так.

var
i: integer;
.....

i := AdoTable1['Имя поля'];

Операции с числами проводятся совершенно стандартно. Важно только учитывать особенности типов.

Советую Вам прочитать какую-нибудь книгу по программированию БД в Delphi, т.к. эта тема очень обширна и имеет множество подводных камней и нюансов.

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

3. [Отвечает: PVS (статус: Эксперт: 9-ый класс), 16.01.2006 11:09]: Ячейка в Access(как и в любой другой базе) определяется названием столбца и номером строки(который зависит от сортировки, так что говорить о ТОЧНОМ определении ячейки можно только при наличии уникального поля или набора полей - "ключа"). Если же надо делать вычисления в пределах одной строки, то к полям можно обращатся по имени myQuery.FieldByName("FLD_NAME").AsInteger или по номеру myQuery.Fields[i].AsInteger и проводить вычисления с ними или писать сразу нужный SQL: myQuery.SQL.Text:='select fld1+fld2 as fsumm, fld5*fld20 as fmult from accesstable';

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

Вопрос #223:
Есть поле редактирования RichEdit2, строки в котором переписываются через заданое время. Нужно, чтобы при перемещении над полем курсора мыши, строки, вернее текст в этих строках, который попадает под курсор мыши становился жирным и подчеркнутым, также чтобы менялся вид курсора мыши. И все это чтобы возвращалось в прежнее состояние при потере курсора мыши. Также нужно, чтобы при двойном нажатии клавиши мыши, текст находящийся под курсором мыши, сохранялся в какую то текстовую переменную, или заносился в поле редактирования Edit1. Как это все сделать?

1. [Отвечает: Трапезников Антон (статус: Эксперт: 10-ый класс), 16.01.2006 10:40]: Здравствуйте, Игорь. Для того чтобы определить слово под курсором добавтье следующий код в процедуру OnMouseMove RichEdit'a.

uses
RichEdit; // не забудьте добавить этот модуль
...
...
procedure TForm1.RichEdit1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
var
  iCharIndex, iLineIndex, iCharOffset, i, j: Integer;
  Pt: TPoint;
  s: string;
begin
  with TRichEdit(Sender) do
  begin
    Pt := Point(X, Y);
    iCharIndex := Perform(Messages.EM_CHARFROMPOS, 0, Integer(@Pt));
    if iCharIndex < 0 then Exit;
     iLineIndex  := Perform(EM_EXLINEFROMCHAR, 0, iCharIndex);
    iCharOffset := iCharIndex - Perform(EM_LINEINDEX, iLineIndex, 0);
    if Lines.Count - 1 < iLineIndex then Exit;
    s := Lines[iLineIndex];
    i := iCharOffset + 1;
    while (i > 0) and (s[i] <> ' ') do Dec(i);
    j := iCharOffset + 1;
    while (j <= Length(s)) and (s[j] <> ' ') do Inc(j);
    Caption := Copy(s, i, j - i);
  end;
end;

Как видите все на самом деле проще.

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

2. [Отвечает: мэйл_рфдл2 (статус: Эксперт: 4-ый класс), 16.01.2006 9:17]: Легче было бы использовать ListBox, там и функций для Вашей нужды валом. А так, примерно так (не полностью но что-то есть):

unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ComCtrls, ShellCtrls;
type
  TForm1 = class(TForm)
    RichEdit1: TRichEdit;
    Button1: TButton;
    Label1: TLabel;
    procedure RichEdit1MouseMove(Sender: TObject; Shift: TShiftState;
    X, Y: Integer);
  private
  public
  end;
var Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.RichEdit1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
var iY: Integer;
begin
  mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
  Application.ProcessMessages;
  mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
  iY := SendMessage(RichEdit1.Handle, EM_LINEFROMCHAR, RichEdit1.SelStart,0);
  Label1.Caption := RichEdit1.Lines[iY];
end;
end.

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

3. [Отвечает: Матвеев И.В. (статус: Практикант), 16.01.2006 20:26]: Высылаю пример, в этом примере при наведении курсора мыши на слово оно выделяется жирным шрифтом (остальное делайте сами). Работает довольно устойчиво, хотя некоторые глюки все-таки есть. Загрузить прикреплённый файл >>

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

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


Статья по Delphi.

Написание простого медиа-проигрывателя

Простейший медиа-проигрыватель можно создать стандартными средствами Windows. Существуют модули, которые доступны из любого языка программирования - это ActiveX. Delphi в этом плане не исключение. Встроенный в систему Windows Media Player имеет собственный ActiveX-модуль, который мы легко можем использовать в своей программе. Правда, кардинально изменить в нём что-либо не получится. В данной статье я покажу пример, как использовать этот компонент.

Для начала ActiveX-компонент (сокращённо AX) нужно интегрировать в оболочку Delphi. Делается это легко: открываем диалоговое окно Component - Import ActiveX Control. В разных версиях Delphi этот пункт меню может называться по-разному, но ключевым остаётся слово ActiveX. В открывшемся окне в списке компонент найдите строку Windows Media Player. Нажмите кнопку Install. В появившемся окне можно указать, в какой пакет следует установить компонент. Можно оставить всё по умолчанию и нажать ОК. После этого на вкладке ActiveX палитры компонент появится кнопка WindowsMediaPlayer. Теперь можно приступить к созданию проигрывателя.

Для начала поместите компонент на форму - щёлкните по его значку и затем по форме. Вы увидите знакомое изображение - изображение проигрывателя. Его внешний вид зависит от версии установленного в системе компонента. Примерный вид того, что вы увидите, изображён на рисунке 1.


рис. 1

рис. 2

Для начала давайте сделаем возможность открытия нужного файла. За путь к файлу, который нужно воспроизводить, отвечает свойство URL типа WideString (строка). Давайте сделаем для программы меню, куда и добавим нужный нам пункт. Поместите на форму TMainMenu (страница Standard). Дважды щёлкните по значку TMainMenu, лежащему на форме. Откроется дизайнер меню. Выделите единственный пункт в заголовке меню и в его свойстве Caption напишите "Файл". Затем щёлкните по созданному пункту и снизу появистя ещё одна пустая строка. Там и введите название нашего пункта - "Открыть". Следующей строкой давайте создадим разделитель для меню - в свойстве Caption поставьте один-единственный символ - минус ("-"). Следующей строкой сделайте пункт "Выход". Ну вот, программа уже имеет меню, хотя и небольшое. Теперь нужно связать пункт меню с диалогом открытия файла. Найдите компонент TOpenDialog на странице Dialogs и поместите его на форму. Активируйте свойство Filter и нажмите на кнопку с тремя точками ("..."). В появившемся окне введите желаемые типы файлов. В поле Filter Name нужно ввести описание типов файлов, а в поле Filter - сам фильтр. Пример на рисунке 2.

Чтобы с компонентом было удобно работать, измените его свойство Name на MediaPlayer.

Выделите компонент и перейдите в окно Object Inspector. Свойств (Properties) у компонента не очень много, а вот событий (Events) гораздо больше. Но мы используем лишь некоторые из них.

Для удобства, компонент MainMenu1 переименуем в MainMenu, а OpenDialog1 - в OpenDialog.

Пришло время запрограммировать пункт меню "Открыть". Откройте дизайнер меню и дважды щёлкните по нужному пункту - откроется редактор кода. В этом месте следует написать:

if OpenDialog.Execute then
    MediaPlayer.URL:=OpenDialog.FileName;

Метод Execute открывает диалог и, если пользователь не нажал "Отмена", то функция возвращает значение True, а в FileName записывается путь к выбранному файлу. Затем мы присваиваем свойству URL проигрывателя выбранный файл. Запустите программу и попробуйте открыть файл. Всё должно работать, файл должен воспроизводиться.

Теперь давайте приведём окно проигрывателя к нормальному виду. Сам проигрыватель нужно растянуть на всю ширину окна - измените его свойство Align на alClient. Саму форму стоит сделать поменьше, т.к. наш проигрыватель пока что воспроизводит только аудио-файлы. На мой взгляд, для формы можно установить ширину (Width) равной 300, а высоту (Height) - 200. Наконец, можно изменить вид окна и установить BorderStyle в значение bsSizeToolWin, а заголовок (Caption) - "Simple Media Player".

Теперь запрограммируем пункт "Выход" - для этого следует написать в его обработчике всего одну строку:

Self.Close;

Этот метод закрывает текущую форму (Self - объект, выбранный по умолчанию, форма) и завершает приложение.

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

Для начала добавьте в заглавную строку меню (туда, где "Файл") пункт "Управление". Затем добавьте два пункта - "Старт / Стоп" и "Пауза". Запрограммировать эти команды легко. Для управление воспроизведением служит набор методов Controls, а узнать текущее состояние проигрывателя можно из свойства PlayState. Вот как выглядит обработчик пункта "Старт / Стоп":

if MediaPlayer.PlayState =wmppsPlaying then
    MediaPlayer.Controls.Stop
else
    MediaPlayer.Controls.Play;

А вот обработчик "Паузы":

if MediaPlayer.PlayState =wmppsPlaying then
    MediaPlayer.Controls.Pause;

Запустите программу и проверьте её работоспособность.


рис. 3

Как видите, мы создали сравнительно простой, но рабочий проигрыватель. В следующий раз мы продолжим его разработку. Примерное изображение окна программы после выполнения всех действий, описанных в статье, показано на рисунке 3.

Автор: Ерёмин Андрей

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


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

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

Новые файлы на сайте:

Название / описание файла
Категория
Объём
Ссылки
CyrLat - Программа предназначена и будет удобна для тех, кому требуется быстрое преобразование текста из кириллицы в латиницу и наоборот. Я её писал для себя и мне она очень помогала, когда я общался с друзьями из Германии, ведь у них ОС не поддерживает русский язык... (автор: MiG)
Программы
368 Кб
Crazy Mouse - Программа-прикол. Меняет положение курсора на экране каждые пол-секунды. (автор: mitvoh)
Исходники
7.70 Кб
Crazy CD - Программа, которая периодически открывает и закрывает каретку CD/DVD привода. Можно довести пользователя до инфаркта, особенно в сочетании с программой Crazy Mouse :) (автор: mitvoh)
Исходники
7.46 Кб
Пример приложения с непрямогоульной формой, созданной на основе картинки (из книги "Delphi глазами хакера").
Исходники
17.6 Кб

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

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

Здесь представлены ссылки на дружественные сайты. Обмен ссылками и баннерами всегда приветствуется. Здесь представлены самые последние ссылки:

http://romodos.pp.ru/ Romodos Software - Лучшие бесплатные программы, игры, музыка, рассылки, анекдоты, статьи, учебники по Delphi, HTML, JavaScript, Windows.
http://www.sassoft.narod.ru/ На данном сайте вы сможете найти разные полезные программы. Также имеется подписка на рассылку и разная полезная информация программисту.
http://www.excode.ru/ Статьи, исходники, компоненты, книги, кодерский магазин.
Рассылки Subscribe.Ru
Интернет для Delphi-программиста
Visual Basic для новичков и профессионалов
   
 

Юмор.

Голосование на веб-странице:
"Пользовались ли вы когда-нибудь интернетом?"...

:))

Если Microsoft начнет выпускать автомобили то ...
1. Когда на дорогу нанесут новую разметку, вам придется покупать новую машину;
2. Иногда на скоростных шоссе машина вдруг будет глохнуть, и Вам придется ее перезаводить;
3. В том случае, если машина не будет перезаводиться, вам придется поменять мотор;
4. На машине можно будет ездить только поодиночке, пока вы не купите "Машину97" или "МашинуNT", но тогда вам придется покупать дополнительные сидения;
5. Macintosh тоже начнет выпускать автомобили, они будут заряжаться от солнца, будут в два раза быстрее, ими будет легче управлять, но ездить они будут только по 5% дорог;
6. Индикаторы топлива, двигателя и масла будут объединены в один "главный машинный индикатор";
7. Во время аварии подушки безопасности прежде чем сработают - спросят: "Are you sure?" .

:))

Жизнь подобна зависанию в интернете - занятие бесполезное, а уходить жалко.

:))

Вначале был бит, потом байт, и только потом появилось слово...

:))

Microsoft выпустила свой первый вирус, работающий без активации 30 дней, по проществии 30 дней вирус перестает действовать... цена новинки: $50.

:))

Прочитал программист сказку про репку и говорит:
- Не знаю что они называют жучкой! Но итак понятно что без мышки никакая игрушка работать не будет!

:))

Встречаются два кореша, ну и один говорит другому:
- Что за фигня? Скачиваю с интернета windows, а когда устанавливаю, то получаю dos.
- А у тебя модем с коррекцией ошибок?
- Да...
- Так вот он их и исправляет...

:))

Чем отличается моряк от интернетчика? У моряка девушка в каждом порту, у интернетчика - в каждом портале.

:))

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

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

Наши реквизиты в системе WebMoney: R379291065219, Z165075684614.


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

В избранное