Часть [1] - Часть [2]
1. Как сохранить положение и размеры формы, а потом их восстановить ?
2. Почему при выходе из программы не сохраняются данные в Базе Данных ?
3. Каким образом можно обработать нажатия кнопок различных диалогов ?
4. Как отображать подсказки (Hint) в строке состояния StatusBar ?
5. Как можно занести в Базу Данных информацию из текстового файла ?
6. Как создать загрузочный компакт-диск ?
7. Почему в отчете QuickReport отображается только текущая запись ?
8. Как сделать чтобы программа закрывалась при нажатии клавиши Esc ?
9. При вызове файла справки выдается ошибка, что данного раздела не существует ?
10. Как найти нужное место в документе Word ?
11. Как время вида 1:02:45 вывести словами 1ч. 02мин. 45сек. ?
12. Как из Базы Данных удалить записи помеченные на удаление ?
13. Как программно скопировать файл ?
14. Как можно анимировать нажатие кнопки ?
15. Как из своей программы перейти на сайт или на e-mail ?
16. В нескольких программах видел, что при нажатии на пункт меню...
17. Как вывести текст поверх картинки загруженной в Image ?
18. При выполнении большого цикла мое приложение как бы замирает. Как это исправить ?
19. При удалении записи в БД выдается запрос на английском языке, хотя...
20. Как написать свой ScreenSaver ?
21. Во многих программах выдаются диалоги для ввода некоторых значений...
22. При вводе текста в Memo и достижении правого края контрола текст автоматически...
23. Как можно программно управлять открытием и закрытием компонента ComboBox...
24. В программе 1С я заметил, что при редактировании ячейки БД в правой ее части...
25. Как программно создать компонент и навесить на него обработчик события ?
26. Можно ли в процессе выполнения программы узнать какой разделитель...
27. Как установить курсор мыши в определенную позицию экрана ?
28. Хочу при запуске программы сделать кнопку активной, но постоянно выдается ошибка...
29. Как из моей программы некоторый файл сделать скрытым ?
30. Как показать контекстное меню в точке нажатия кнопки мышью ?
Вопрос № 1: Как сохранить положение и размеры формы, а потом их восстановить ?
Ответ: Для этого нужно использовать файл инициализации (.ini). При выходе из программы в
событие закрытия или уничтожения формы onCloseQuery (или onDestroy) нужно сохранить положение и
размеры формы в файл инициализации, а при ее создании их восстановить:
// Сохранение свойств формы
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
Var iniFile: TiniFile;
begin
Try
// Создаем или перезаписываем файл инициализации в текущей директории
iniFile:=TIniFile.Create(ExtractFilePath(Application.ExeName)+'File.ini');
// Сохраняем свойства формы
iniFile.WriteString('Pos', 'Top', IntToStr(Top));
iniFile.WriteString('Pos', 'Left', IntToStr(Left));
iniFile.WriteString('Pos', 'Height', IntToStr(Height));
iniFile.WriteString('Pos', 'Width', IntToStr(Width));
Finally
iniFile.Free;
End;
end;
|
// Восстанавливаем свойства формы первым способом
procedure TForm1.FormCreate(Sender: TObject);
begin
Try
// Открываем файл инициализации из текущей директории
iniFile:=TIniFile.Create(ExtractFilePath(Application.ExeName)+'File.ini');
// Проверяем, нет ли пустых значений
If (iniFile.ReadString('Pos', 'Top', IntToStr(Top)) = '')
OR (iniFile.ReadString('Pos', 'Left', IntToStr(Left)) = '')
OR (iniFile.ReadString('Pos', 'Height', IntToStr(Height)) = '')
OR (iniFile.ReadString('Pos', 'Width', IntToStr(Width)) = '')
// Если пустые значения найдены, то стандартный вывод формы
Then WindowState:=wsNormal Else
// Если пустые значения не найдены, то восстанавливаем свойства формы
Begin
Top:=StrToInt(iniFile.ReadString('Pos', 'Top', IntToStr(Top)));
Left:=StrToInt(iniFile.ReadString('Pos', 'Left', IntToStr(Left)));
Height:=StrToInt(iniFile.ReadString('Pos', 'Height', IntToStr(Height)));
Width:=StrToInt(iniFile.ReadString('Pos', 'Width', IntToStr(Width)));
End;
Finally
iniFile.Free;
End;
end;
|
// Восстанавливаем свойства формы вторым способом
procedure TForm1.FormCreate(Sender: TObject);
Const NoFind = -1000;
Var iniFile : TIniFile;
Not_Left, Not_Top : Integer;
Not_Height, Not_Width : Integer;
begin
iniFile:=TIniFile.Create(ExtractFilePath(Application.Exename) + 'IniFile.ini');
// Проверяем нет ли пустых значений.
Not_Left:=iniFile.ReadInteger('Position', 'Left', NoFind);
Not_Top:=iniFile.ReadInteger('Position', 'Top', NoFind);
Not_Height:=iniFile.ReadInteger('Position', 'Height', NoFind);
Not_Width:=iniFile.ReadInteger('Position', 'Width', NoFind);
// Если пустые значения найдены, то стандартный центрируем форму
If (Not_Left = NoFind) OR (Not_Top = NoFind)
OR (Not_Height = NoFind) OR (Not_Width = NoFind)
Then Form1.Position:=poScreenCenter
// Если пустые значения не найдены, то восстанавливаем свойства формы
Else
Begin
Left:=iniFile.ReadInteger('Position', 'Left', Left);
Top:=iniFile.ReadInteger('Position', 'Top', Top);
Height:=iniFile.ReadInteger('Position', 'Height', Height);
Width:=iniFile.ReadInteger('Position', 'Width', Width);
End;
iniFile.Free;
end;
|
// Восстанавливаем свойства формы третьим способом, при помощи реестра
...
Var Reestr: TRegistry;
...
procedure TForm1.FormCreate(Sender: TObject);
begin
Reestr:=TRegistry.Create;
Reestr.RootKey:=HKEY_CURRENT_USER;
If Reestr.OpenKey('\SoftWare\MyProg\', False) Then
Begin
Form1.Top:=Reestr.ReadInteger('Top');
Form1.Left:=Reestr.ReadInteger('Left');
Form1.Height:=Reestr.ReadInteger('Height');
Form1.Width:=Reestr.ReadInteger('Width');
Reestr.CloseKey;
End;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
Reestr.RootKey:=HKEY_CURRENT_USER;
If Reestr.OpenKey('\SoftWare\MyProg\', False) Then
Begin
Reestr.WriteInteger('Top', Form1.Top);
Reestr.WriteInteger('Left', Form1.Left);
Reestr.WriteInteger('Height', Form1.Height);
Reestr.WriteInteger('Width', Form1.Width);
Reestr.CloseKey;
End;
Reestr.Free;
end;
|
Вопрос № 2: Почему при выходе из программы не сохраняются данные в Базе Данных ?
Ответ: Это одна из самых распространненых ошибок, проблема решается следующим образом:
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
If Table1.Modified Then Table1.Post;
If Query1.Modified Then Query1.Post;
end;
|
Аналогичный код, также лучше вставить куда-нибудь в пункт меню "Сохранить":
procedure TForm1.mnuSave(Sender: TObject);
begin
If Table1.Modified Then Table1.Post;
If Query1.Modified Then Query1.Post;
end;
|
Вопрос № 3: Как можно обработать нажатия кнопок различных диалогов ?
Ответ: Здесь все достаточно просто. См. пример:
// Пример с диалогом MessageBox
procedure TForm1.Button1Click(Sender: TObject);
Var ModalResult: TModalResult;
begin
ModalResult:=MessageBox(0, 'Сообщение', 'Заголовок', MB_YESNOCANCEL);
If ModalResult = idYES Then ShowMessage('Нажата кнопка Да')
Else
If ModalResult = idNO Then ShowMessage('Нажата кнопка Нет')
Else
If ModalResult = idCANCEL Then ShowMessage('Нажата кнопка Отмена');
end;
|
// Пример с диалогом MessageDlg
procedure TForm1.Button2Click(Sender: TObject);
Var ModalResult: TModalResult;
begin
ModalResult:=MessageDlg('Сообщение', mtInformation, mbYesNoCancel, 0);
If ModalResult = mrYES Then ShowMessage('Нажата кнопка YES')
Else
If ModalResult = mrNO Then ShowMessage('Нажата кнопка No')
Else
If ModalResult = mrCANCEL Then ShowMessage('Нажата кнопка Cancel');
end;
|
Вопрос № 4: Как отображать подсказки (Hint) в строке состояния StatusBar ?
Ответ: Для этого нужно использовать событие приложениея onHint:
// В событие OnHint объекта приложения Application назначаем обработчик
procedure TForm1.FormCreate(Sender: TObject);
begin
Application.OnHint:=StatusHint;
end;
// Сам обработчик заносит текст подсказки в панель строки состояния
procedure TForm1.StatusHint(Sender: TObject);
Begin
StatusBar1.Panels[1].Text:=Application.Hint;
End;
|
Вопрос № 5: Как можно занести в Базу Данных информацию из текстового файла ?
Ответ: Допустим, в Базе Данных имеются два поля - Code и Fam. Нужно
отметить, что в первом примере вся информация из файла будет занесена только в одно поле Базы
Данных. Для того чтобы информация из файла заносилась сразу в несколько полей нужно использовать, либо
типизированные файлы и работать с типом данных Запись (Record), либо использовать файлы
инициализации (см. Примеры).
// Пример № 1 - Непосредственное внесение данных в БД
procedure TForm1.Button1Click(Sender: TObject);
Var F : System.Text;
I : Integer;
X : String;
begin
I:=0; // Переходим в конец набора данных и запоминаем максимальный номер записи
Table1.Last;
I:=Table1.FieldByName('Code').AsInteger;
AssignFile(F,'File.txt'); // Открываем файл для чтения
Reset(F);
Repeat
Inc(I); // Увеличиваем номер записи
Readln(F, X); // Считываем строку из файла
Table1.Append; // Добавляем в конец Базы Данных прочитаную строку
Table1.FieldByName('Code').AsString:=IntToStr(I);
Table1.FieldByName('Fam').AsString:=X;
Table1.Next;
Until Eof(F);
CloseFile(F);
end;
|
// Пример № 2 - Использование Записей (Record)
...
Type Base = Record
Code : String;
Fam : String;
End;
Var
Form1 : TForm1;
Rec : Base;
F : System.Text;
...
procedure TForm1.Button1Click(Sender: TObject);
begin
AssignFile(F, 'File.txt');
Append(F);
// Вносим в поля записи значения редакторов
Rec.Code:=Edit1.Text;
Rec.Fam:=Edit2.Text;
// Сохраняем значения записи
Writeln(F, Rec.Code);
Writeln(F, Rec.Fam);
CloseFile(F);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
AssignFile(F, 'File.txt');
Reset(F);
Table1.First;
Repeat
// Считываем значения записи
Readln(F, Rec.Code);
Readln(F, Rec.Fam);
// Заносим значения записи в БД
Table1.Append;
Table1.FieldByName('Field1').AsString:=Rec.Code;
Table1.FieldByName('Field2').AsString:=Rec.Fam;
Table1.Next;
Until Eof(F);
CloseFile(F);
end;
|
// Пример № 3 - Использование файла инициализации
...
var
Form1 : TForm1;
IniFile : TIniFile;
Code : Integer;
...
procedure TForm1.Button1Click(Sender: TObject);
begin
Inc(Code);
// Сохраняем данные в файл инициализации
IniFile:=TIniFile.Create(ExtractFilePath(Application.ExeName) + 'IniFile.ini');
IniFile.WriteInteger('Main', 'Code', Code);
IniFile.WriteString('Step' + IntToStr(Code), 'Str1', Edit1.Text);
IniFile.WriteString('Step' + IntToStr(Code), 'Str2', Edit2.Text);
IniFile.WriteString('Step' + IntToStr(Code), 'Str3', Edit3.Text);
IniFile.Free;
end;
procedure TForm1.Button2Click(Sender: TObject);
Var I : Integer;
Str1 : String;
Str2 : String;
Str3 : String;
begin
IniFile:=TIniFile.Create(ExtractFilePath(Application.ExeName) + 'IniFile.ini');
Code:=IniFile.ReadInteger('Main', 'Code', Code);
For I:=1 To Code Do
Begin
Table1.Append;
// Считываем данные из файла инициализации и вносим их в БД
Str1:=IniFile.ReadString('Step' + IntToStr(I), 'Str1', Edit1.Text);
Str2:=IniFile.ReadString('Step' + IntToStr(I), 'Str2', Edit2.Text);
Str3:=IniFile.ReadString('Step' + IntToStr(I), 'Str3', Edit3.Text);
Table1.FieldByName('Field1').AsString:=Str1;
Table1.FieldByName('Field2').AsString:=Str2;
Table1.FieldByName('Field3').AsString:=Str3;
Table1.Next;
End;
IniFile.Free;
end;
|
Вопрос № 6: Как создать загрузочный компакт-диск ?
Ответ: Для это на диске необходимо создать файлы:
1. Autorun.exe - Исполняемая программа;
2. Autorun.inf - Файл информации для исполняемой программы;
3. Autorun.ico - Иконка.
Файл Autorun.inf можно записать различными способами:
// Стандартный автозапуск
а) [Autorun]
Icon = Autorun.ico
Open = Autorun.exe
// Автозапуск HTML-страницы
б) [Autorun]
Icon = Autorun.ico
Open = Start Autorun.htm
// Автозапуск с извлечением иконки из исполняемой программы:
в) [Autorun]
Icon = Autorun.exe, 0
Open = Autorun.exe
|
А вот еще один интересный пример, который я увидел на одном компакт-диске:
[Autorun]
Open = AutoRun.exe
Icon = AutoRun.ico
Shell\Play = Установить драйвер DivX Mpeg4
Shell\Play\Command = DivX\RunInf.exe DivX.inf
Shell\Play1 = Установить драйвер Microsoft Mpeg4
Shell\Play1\Command = Mpeg4\RunInf.exe Mpeg4fix.inf
Shell\Play2 = Установить Windows Media Player
Shell\Play2\Command = Media\mpie4ful.exe
Shell\Video = Начать просмотр фильма
Shell\Video\Command = FlyVCD.exe VideoCD.mls
|
Вопрос № 7: Почему в отчете QuickReport отображается только текущая запись ?
Ответ: Это одна из самых распространенных ошибок. Нужно указать свойство DataSet для самого компонента QuickReport.
Иначе компоненты TQRDBText как бы принудительно будут отображать содержимое текущей Базы Данных.
Вопрос № 8: Как сделать чтобы программа закрывалась при нажатии клавиши Esc ?
Ответ: Для этого нужно свойство формы KeyPreview установить в True. А в обработчик
события нажатия клавиш внести следующий код:
procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
If Key = #27 Then Close;
end;
|
Вопрос № 9: При вызове файла справки выдается ошибка, что данного раздела не существует. Причем так же не происходит переход в самом файле справки. Как это исправить ?
Ответ: 1) Если у Вас не получается запустить файл справки из Вашей программы, то Вы
скорее всего забыли указать свойство HelpContext у формы или у определенного компонента на форме.
2) Если не происходит перехода по ссылкам внутри самого файла справки, то тут скорее всего
нужно посмотреть сам файл проекта справки. Единственное что приходит в голову, так это, что
возможно Вы при создании текстового файла в формате *.rtf между видимой строкой и контекстом
случайно поставили пробел. Ни каких пробелов между строкой и контекстом быть не должно. Может
Вы неправильно указываете имя раздела, либо такого раздела действительно не существует.
Вопрос № 10: Как найти нужное место в документе Word ?
Ответ: Для начала нужно создать документ Word и вставить в него так называемые метки, то
есть те места в документе на которые будет производиться переход. Эти метки вставляются при
помощи пункта меню "Вставка" - "Закладка..." текстового редактора Word. Затем нужно положить на
форму компоненты TWordApplication и TWordDocument со страницы Servers
Палитры Компонентов.
uses Word2000, OleServer, COMobj;
...
procedure TForm1.Button1Click(Sender: TObject);
Var FileName, NewName : OleVariant;
A1, A2 : OleVariant;
begin
// Задаем имя открываемого документа (шаблона)
FileName:='C:\Мои документы\Шаблон.doc';
// Задаем имя сохраняемого документа
NewName:='C:\Копия Шаблона.doc';
// Соединяемся с Word
WordApplication1.Connect;
// Задаем имена меток
A1:='Num1';
A2:='Num2';
// Открываем файл (шаблон)
WordApplication1.Documents.Open(FileName,
EmptyParam, EmptyParam, EmptyParam,
EmptyParam, EmptyParam, EmptyParam,
EmptyParam, EmptyParam, EmptyParam,
EmptyParam, EmptyParam);
// Находим первую метку
WordApplication1.ActiveDocument.Bookmarks.Item(A1).Select;
WordApplication1.Selection.Text:='Текст_1';
// Находим вторую метку
WordApplication1.ActiveDocument.Bookmarks.Item(A2).Select;
WordApplication1.Selection.Text:='Текст_2';
// Переход на начало документа
WordApplication1.Selection.SetRange(0,0);
WordDocument1.ConnectTo(WordApplication1.ActiveDocument);
// Сохраняем файл шаблона с изменениями
WordDocument1.SaveAs(NewName);
// "Показываем" Word
WordApplication1.Visible:=True;
// Разъединяемся с Word
WordApplication1.Disconnect;
end;
|
Вопрос № 11: Как время вида 1:02:45 вывести словами 1ч. 02мин. 45сек. ?
Ответ: Для разложения даты и времени нужно воспользоваться функцией для декодирования времени:
procedure TForm1.Button1Click(Sender: TObject);
Var Hour, Min, Sec, MSec : Word;
D, M, Y : Word;
begin
DecodeTime(Time, Hour, Min, Sec, MSec);
ShowMessage(IntToStr(Hour) + 'ч.' + IntToStr(Min) + 'мин.' + IntToStr(Sec) + 'сек.');
DecodeDate(Date, Year, Month, Day);
ShowMessage(IntToStr(D) + 'число' + IntToStr(M) + 'месяца' + IntToStr(Y) + 'года');
end;
|
Вопрос № 12: Как из Базы Данных удалить записи помеченные на удаление ?
Ответ: См. пример:
procedure TForm1.FormCreate(Sender: TObject);
begin
// Создаем возможность выделения нескольких строк
DBGrid1.Options:=DBGrid1.Options + [dgMultiSelect];
end;
procedure TForm1.ButtonDeleteClick(Sender: TObject);
begin
// Проверяем действительно ли выбрано несколько записей БД
If DBGrid1.SelectedRows.Count <> 0 Then
Begin
// Перед удалением выводим запрос
If MessageDlg('Удалить помеченные записи БД ?', mtWarning,
[mbYes, mbNo], 0) = mrYes
Then DBGrid1.SelectedRows.Delete;
End
Else
Begin
// Если выбрана всего одна запись, то удаляем только ее одну
If MessageDlg('Удалить текущую запись БД ?', mtWarning,
[mbYes, mbNo], 0) = mrYes
Then Table1.Delete;
End;
end;
|
Вопрос № 13: Как программно скопировать файл ?
Ответ: Для этого нужно воспользоваться функцией CopyFile:
procedure TForm1.Button1Click(Sender: TObject);
begin
If OpenDialog1.Execute Then Edit1.Text:=OpenDialog1.FileName;
If OpenDialog2.Execute Then Edit2.Text:=OpenDialog2.FileName;
CopyFile(PChar(Edit1.Text), PChar(Edit2.Text), True);
end;
|
Вопрос № 14: Как можно анимировать нажатие кнопки ?
Ответ: Для анимации кнопки стандартная кнопка TButton не очень подойдет, поэтому удобней
будет использовать кнопку быстрого доступа TSpeedButton или кнопку TBitBtn. В обработчик события
нажатия на кнопку меняем свойства Font, а затем эти свойства восстанавливаем:
procedure TForm1.SpeedButton1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
SpeedButton1.Font.Color:=clRed;
SpeedButton1.Font.Size:=10;
SpeedButton1.Font.Style:=[fsBold]
end;
procedure TForm1.SpeedButton1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
SpeedButton1.Font.Color:=clBlack;
SpeedButton1.Font.Size:=8;
SpeedButton1.Font.Style:=[]
end;
|
Вопрос № 15: Как из своей программы перейти на сайт или на e-mail ?
Ответ: Для этого нужно воспользоваться API-функцией ShellExecute:
procedure TForm1.LabelMailClick(Sender: TObject);
begin
ShellExecute(Handle,'Open','mailto: satanzone@yandex.ru', NIL, NIL, SW_SHOWNORMAL);
end;
procedure TForm1.LabelURLClick(Sender: TObject);
begin
ShellExecute(HWND(NIL), NIL, 'IExplore', 'http://icops.narod.ru', NIL, SW_SHOWNORMAL);
end;
procedure TForm1.LabelMailMouseMove(Sender: TObject; Shift: TShiftState;
X, Y: Integer);
begin
LabelMail.Font.Style:=LabelMail.Font.Style - [fsUnderLine];
end;
procedure TForm1.LabelMailMouseLeave(Sender: TObject);
begin
LabelMail.Font.Style:=LabelMail.Font.Style + [fsUnderLine];
end;
procedure TForm1.LabelURLMouseLeave(Sender: TObject);
begin
LabelURL.Font.Style:=LabelURL.Font.Style + [fsUnderLine];
end;
procedure TForm1.LabelURLMouseMove(Sender: TObject; Shift: TShiftState;
X, Y: Integer);
begin
LabelURL.Font.Style:=LabelURL.Font.Style - [fsUnderLine];
end;
|
Вопрос № 16: В нескольких программах видел, что при нажатии на пункт меню он становился выделенным
галочкой, а при повторном нажатии это выделение пропадало. Как мне это сделать в своей
программе ?
Ответ: Для этого нужно использовать свойство Check:
procedure TForm1.mnuFileClick(Sender: TObject);
begin
If mnuFile.Checked = False Then
Begin
mnuFile.Checked:=True;
ShowMessage('Пункт меню отмечен !!!');
End
Else
If mnuFile.Checked = True Then
Begin
mnuFile.Checked:=False;
ShowMessage('Пункт меню не отмечен !!!');
End;
end;
|
Вопрос № 17: Как вывести текст поверх картинки загруженной в Image ?
Ответ: См. пример:
procedure TForm1.FormCreate(Sender: TObject);
Var BMP : TBitmap;
begin
BMP:=TBitmap.Create;
BMP.LoadFromFile('MyPicture.bmp');
Image1.Picture.Assign(BMP);
Image1.Canvas.Brush.Color:=clBlue;
Image1.Canvas.Font.Name:='Arial';
Image1.Canvas.Font.Size:=10;
Image1.Canvas.TextOut(10, 10, 'Некоторый текст !!!');
end;
|
Вопрос № 18: При выполнении большого цикла мое приложение как бы замирает. Как это исправить ?
Ответ:: Для этого нужно в тело цикла вставить конструкцию Application.ProcessMessages. При этом можно
будет нажимать на различные кнопки, пользоваться меню, но нельзя будет закрыть приложение :(.
procedure TForm1.Button1Click(Sender: TObject);
Var I: Integer;
begin
For I:=1 To 100000 Do
Begin
Label1.Caption:=IntToStr(I);
Application.ProcessMessages;
End;
end;
|
Вопрос № 19: При удалении записи в БД выдается запрос на английском языке, хотя вся моя программа построена
на русском языке. Можно ли как-нибудь сделать этот запрос русским ?
Ответ: Я тоже столкнулся с такой неприятной мелочью. Лично мне пришла в голову одна очень простая мысль:
я сделал отдельный пункт меню "Удалить запись", в котором я написал свой обработчик удаления записи
из набора данных с русским диалоговым запросом. Далее я задал свойству пункта меню ShortCut (быстрый
доступ "горячей клавишей") значение Ctrl+Del. Еще можно просто запретить вывод запроса на удаление
путем установки значения False подсвойству dgComfirmDelete свойства сетки DBGrig, но это не очень
хорошо, потому что можно и не заметить как запись будет удалена. Вот небольшой и понятный пример:
procedure TForm1.mnuDBDelClick(Sender: TObject);
begin
If Application.MessageBox('Удалить запись ?', 'Удаление:', MB_YESNO) = idYES
Then Table1.Delete;
end;
|
Вопрос № 20: Как написать свой ScreenSaver ?
Ответ: Честно говоря, я даже никогда об этом не задумывался :). По сути ScreenSaver - это
обычная программа переименованная в расширение .scr. Даже если Вы любую программу переименуете из
.exe в .scr, и поместите в каталог Windows или Windows\System, то через установленный промежуток
времени переименованная программа сработает как ScreenSaver. Значит нужно написать свою собственную
программу и в обработчики нажатия клавиш onKeyPress, onKeyDown и onKeyUp записать код закрытия
программы. Аналогичным образом нужно "оформить" обработчики движения мыши. А еще надо проверять,
чтобы программа запускалась в одном экземпляре, иначе таких хранителей экрана будет одновременно
запущено сразу несколько :).
Вопрос № 21: Во многих программах выдаются диалоги для ввода некоторых значений, например, пароля.
А как это делается, неужели создается отдельная форма ?
Ответ: Для этого, безусловно, можно создать отдельную форму, но проще будет воспользоваться функциями
InputBox или InputQuery. В своих программах с БД я частенько использую такой прием для перехода к определенной записи. Вот небольшой
и понятный пример:
procedure TForm1.mnuDBGotoClick(Sender: TObject);
Var Go: String;
begin
Go:='1';
InputQuery('Переход к записи', 'Перейти к записи с номером:', Go);
Try
If NOT Table1.Locate('Code', Go, []) Then
MessageDlg('Запись с номером' + Go + 'не найдена', mtWarning, [mbOK], 0);
Except
MessageDlg('Значение' + Go + 'не допустимо', mtWarning, [mbOK], 0);
End;
end;
|
Вопрос № 22: При вводе текста в Memo и достижении правого края контрола текст автоматически переносится
на новую строку. Как с этим бороться ?
Ответ: Для этого можно поступить двумя способами:
1) Установить свойству WordWrap значение False.
2) Установить свойству ScrollBars значение ssHorizontal - для появления горизонтальной полосы
прокрутки, или ssBoth - для появления обоих полос прокрутки.
Вопрос № 23: Как можно программно управлять открытием и закрытием компонента ComboBox и узнать его
состояние в текущий момент ?
Ответ:См. пример:
procedure TForm1.Button1Click(Sender: TObject);
begin
// Открываем список
ComboBox1.DroppedDown:=True;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
// Закрываем список
ComboBox1.DroppedDown:=False;
end;
procedure TForm1.Bla-Bla-Bla(Sender: TObject);
begin
If ComboBox1.DroppedDown = True Then ShowMessage('Список открыт')
Else ShowMessage('Список закрыт')
end;
|
Вопрос № 24: В программе 1С я заметил, что при редактировании ячейки БД в правой ее части появляется
кнопка с тремя точками. Если нажать эту кнопку, то появляется отдельная форма для выбора товара.
А можно ли такое сделать в Делфи ?
Ответ: Конечно можно, для этого нужно воспользоваться т.н. статическими полями (о них я рассказывал в
одной из статей о БД). Для определенного статического поля нужно установить свойство
ButtonStyle в значение cbsEllipsis. А затем обрабатывать событие onEditButtonClick сетки DBDrid.
procedure TForm1.DBGrid1EditButtonClick(Sender: TObject);
begin
FormAdd2.ShowModal;
end;
|
Вопрос № 25: Как программно создать компонент и навесить на него какой-нибудь обработчик события ?
Ответ: См. пример:
uses ..., StdCtrls;
...
procedure TForm1.FormCreate(Sender: TObject);
Var Memo1 : TMemo;
begin
Memo1:=TMemo.Create(Self);
Memo1.Parent:=Form1;
Memo1.Top:=10;
Memo1.Left:=10;
Memo1.Height:=90;
Memo1.Width:=150;
Memo1.OnKeyPress:=MyMemoKeyPress;
end;
procedure TForm1.MyMemoKeyPress(Sender: TObject; var Key: Char);
begin
If NOT(Key In ['0'..'9', Chr(8), Chr(32)]) Then Key:=Chr(0);
end;
|
Вопрос № 26: Можно ли в процессе выполнения программы узнать какой разделитель целой и дробной
части установлен в системе в данный момент ?
Ответ: Разделитель в своей программе можно задать свой. А так для этого служит DecimalSeparator.
procedure TForm1Main.FormCreate(Sender: TObject);
begin
DecimalSeparator:='.';
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage('Текущий разделитель: ' + DecimalSeparator);
Edit1.Text:='10' + DecimalSeparator + '5';
end;
|
Вопрос № 27: Как установить курсор мыши в определенную позицию экрана ?
Ответ:См. пример:
procedure TForm1.Button1Click(Sender: TObject);
Var P: TPoint;
begin
GetCursorPos(P); // Сохраняем позицию курсора
...
// Что-то делаем
...
SetCursorPos(P.X, P.Y); // Восстанавливаем позицию курсора
end;
|
Вопрос № 28: Хочу при запуске программы сделать кнопку активной, но постоянно выдается ошибка.
Как лечить ?
Ответ:Если уже Вы решили сделать кнопку активной в обработчике события создания формы, то нужно просто
вставить обработчик исключительной ситуации, которая как раз и генерируется. Но при компиляции
проекта это исключение все равно будет возникать, что очень не удобно. Более простым и удобным
способом будет использовать событие формы onShow. Тогда уж точно никаких ошибок не возникнет.
procedure TForm1.FormCreate(Sender: TObject);
begin
Try
If Button1.CanFocus Then Button1.SetFocus;
Except
End;
end;
procedure TForm1.FormShow(Sender: TObject);
begin
If Button1.CanFocus Then Button1.SetFocus;
end;
|
Вопрос № 29: Как из моей программы некоторый файл сделать скрытым ?
Ответ:Для этого ему нужно задать атрибут как "скрытый".
procedure TForm1.FormCreate(Sender: TObject);
begin
SetFileAttributes('File.txt', FILE_ATTRIBUTE_HIDDEN);
end;
|
Вопрос № 30: Как показать контекстное меню в точке нажатия кнопки мышью ?
Ответ:См. пример:
procedure TForm1.Button1Click(Sender: TObject);
begin
PopupMenu1.Popup(Mouse.CursorPos.X, Mouse.CursorPos.Y);
end;
|
Вернуться в оглавление
Вернуться на главную страницу
|