СообЧа > База Знаний > Программирование > Delphi

Вопрос

Delphi 2 и 3 не отображают русские TTF под Windows NT WorkStation ServicePack3. Что делать?

Ответ

Попробуйте изменить в реестре в ключе:
[HKLM\ Software\ Microsoft\ Windows NT\ CurrentVersion\ FontMapper]
параметр DEFAULT=0xcc вместо DEFAULT=0x00. Именно DEFAULT, а не Default.

Из конференции Delphi

Вопрос

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

Ответ

Application.ProcessMessages.

Если вы хотите отдавать timeslices в нитях, пользуйтесь Sleep(0); это отдаст остаток слайса системе.

(Win16) Если вы хотите разрешить отработку сообщений другим программам, но не вашей, то лучше пользоваться Yield().

Из конференции Delphi

Вопрос

Q-21 Как русифицировать сообщения Delphi?

Ответ

Ответ зависит от версии Delphi. Ежели кому интересно то на
http://members.xoom.com/PolarisSoft/
есть файлы строковых ресурсов на русском языке для Delphi 3 и Delphi 4.

Из конференции Delphi

Вопрос

Подскажите, как в неактивное окно послать нажатие на клавишу [Enter]. Пробовал sendmessage(wnd,wm_char,13,0), дескриптор окна я нахожу заранее, но ничего не получается.

Ответ

Попробуй вот так:
sendmessage(wnd,wm_keydown,vk_return,0)
sendmessage(wnd,wm_keyup,vk_return,0)
просто нажатие состоит из того чтобы нажать кнопку и отпустить.

МРАК

Вопрос

Подскажите, пожалуйста, как я могу запустить свою dll-ку с помощью rundll или rundll32

Ответ

Можно, если прототипы вызываемых функций будут следующими:

function (ahWnd: HWND;
hInstance: HINST;
CmdLine: PChar;
dummy: LongInt): LongInt;
StdCall;

Алексей

Вопрос

А как в своем приложении узнать, что была нажата "горячая" клавиша?

Ответ

Отлавливай событие WM_HOTKEY

Novikov Dmitry

Вопрос

А как поместить свою иконку на taskbar, там где часы и переключатель клавиатуры?

Ответ

В библиотеке RxLib есть компонент TrxTrayIcon, его и сипользуйте. Заметьте, что для корректного завершения работы операционной системе вам потребуется обрабатывать сообщение WM_QUERYENDSESSION.

Из конференции Delphi

Вопрос

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

Ответ

О, еще сколько. Методом таблицы модельных распределений:

type
   TCodePage = (cpWin1251, cp866, cpKOI8R);
   PMap = ^TMap;
   TMap = array [#$80..#$FF] of Char;

function GetMap(CP: TCodePage): PMap;
{ должна возвращать указатель на таблицу
перекодировки из CP в Windows1251
   (nil для CP = cpWin1251) }
begin
   GetMap:=nil;
end;

function DetermineRussian(Buf: PChar; Count: Integer): TCodePage;
const
   ModelBigrams: array [0..33, 0..33] of Byte = ({АБВГДЕЖЗИЙКЛМHОПРСТУФХЦЧШЩЪЫЬЭЮЯ_Е}
{А}(0,20,44,12,22,23,16,60,4,9,63,93,47,110,
0,16,35,61,81,1,5,13,24,17,12,4,0,0,0,0,14,31,205,1),
{Б}(19,0,0,0,4,19,0,0,8,0,2,15,1,4,41,0,15,5,
0,15,0,2,1,0,0,6,16,37,0,0,0,4,3,0),
{В}(97,0,1,0,2,57,0,5,40,0,4,25,2,23,78,2,8,28,
4,12,0,1,0,0,8,1,0,40,1,0,0,5,106,3),
{Г}(13,0,0,0,9,5,0,0,15,0,1,17,1,2,96,0,24,0,0,
7,0,0,0,0,0,0,0,0,0,0,0,0,8,0),
{Д}(63,0,9,1,2,71,1,0,35,0,3,16,2,22,50,2,19,9,
2,25,0,2,1,0,1,0,1,9,4,0,1,5,17,4),
{Е}(4,14,15,34,56,22,13,14,2,34,39,77,73,150,6,
9,101,64,81,1,0,15,5,12,10,6,0,0,0,0,3,4,235,1),
{Ж}(13,0,0,0,12,47,0,0,16,0,1,0,0,23,0,0,0,0,0,3,
0,0,0,0,0,0,0,0,0,0,0,0,2,2),
{З}(76,2,11,3,11,4,1,0,7,0,2,4,11,24,17,0,6,1,0,8,
0,0,0,0,0,0,0,16,6,0,1,4,17,0),
{И}(7,9,32,5,18,60,4,42,31,27,28,46,55,49,12,7,26,
60,53,0,5,25,14,28,4,1,0,0,0,0,9,56,255,0),
{Й}(0,0,0,0,2,0,0,0,0,0,1,3,0,3,0,0,0,10,3,0,0,0,0,
1,1,0,0,0,0,0,0,0,122,0),
{К}(92,0,3,0,0,7,2,1,39,0,0,27,0,14,110,0,18,5,35,
18,0,0,11,0,0,0,0,0,0,0,0,0,5,5,0),
{Л}(85,1,0,2,1,70,6,0,85,0,5,3,0,9,67,1,0,9,0,15,0,
0,0,2,0,0,0,9,66,0,15,43,57,4),
{М}(44,0,0,0,0,65,0,0,47,0,1,1,10,15,57,7,0,2,0,24,
0,0,0,0,0,0,0,28,0,0,0,8,109,3),
{}(139,0,0,1,11,108,0,4,152,0,7,0,1,69,161,0,0,8,25,
24,5,1,5,2,0,1,0,83,10,0,1,29,38,5),
{О}(0,72,139,76,74,32,32,19,12,52,21,93,68,72,7,34,
93,102,98,1,2,6,6,19,15,2,0,0,0,1,4,9,252,2),
{П}(17,0,0,0,0,43,0,0,14,0,1,9,0,1,125,3,120,1,2,8,
0,0,0,0,0,0,0,3,6,0,0,3,2,2),
{Р}(151,1,6,4,3,103,7,0,76,0,4,0,11,10,117,1,0,5,9,
39,2,5,0,1,3,0,0,24,7,0,1,10,22,5),
{С}(24,1,21,0,3,39,0,0,33,0,56,41,11,15,58,30,5,30,
183,16,0,4,1,4,1,0,0,8,25,0,1,50,41,2),
{Т}(83,0,43,0,3,87,0,0,71,0,9,3,2,26,180,0,55,33,1,
23,1,0,1,4,0,0,0,20,78,0,0,5,82,4),
{У}(3,6,7,14,19,8,13,6,0,1,13,15,10,7,0,12,17,16,19,
0,1,3,0,12,5,8,0,0,0,0,22,1,65,0),
{Ф}(4,0,0,0,0,4,0,0,11,0,0,1,0,0,9,0,3,0,0,4,1,0,0,0,
0,0,0,0,0,0,0,0,2,0),
{Х}(9,0,2,0,0,2,0,0,5,0,0,1,0,5,26,0,4,1,0,1,0,0,0,0,
0,0,0,0,0,0,0,0,76,0),
{Ц}(5,0,0,0,0,16,0,0,48,0,1,0,0,0,4,0,0,0,0,3,0,0,0,
0,0,0,0,2,0,0,0,0,3,0),
{Ч}(30,0,0,0,0,52,0,0,23,0,3,1,0,14,1,0,0,0,36,5,0,0,
0,0,1,0,0,0,1,0,0,0,2,2),
{Ш}(13,0,0,0,0,28,0,0,17,0,4,4,0,4,3,0,0,0,1,3,0,0,0,
0,0,0,0,0,3,0,0,0,1,1),
{Щ}(6,0,0,0,0,23,0,0,16,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,
0,0,0,0,1,0,0,0,0,1),
{Ъ}(0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,1,1,0,0),
{Ы}(0,5,14,1,3,28,0,2,0,22,6,19,21,2,0,5,4,7,10,0,0,37,
0,3,4,0,0,0,0,0,0,1,84,0),
{Ь}(0,1,0,0,0,9,0,10,1,0,13,0,2,26,0,0,0,10,3,0,0,0,1,
0,6,0,0,0,0,0,6,4,117,0),
{Э}(0,0,0,0,0,0,0,0,0,0,3,3,0,0,0,0,0,0,31,0,1,0,0,0,0,
0,0,0,0,0,0,0,0,0),
{Ю}(0,5,0,0,3,0,0,0,0,0,0,1,0,0,0,0,0,1,15,0,0,0,1,4,1,
15,0,0,0,0,0,0,38,0),
{Я}(0,0,9,2,7,10,3,19,0,0,1,6,7,8,0,0,2,6,19,0,0,3,5,1,
0,3,0,0,0,0,5,2,177,0),
{_}(42,80,193,43,109,41,18,53,159,0,144,27,83,176,187,
229,70,231,99,47,15,13,6,58,7,0,0,0,0,38,0,22,0,2),
{Е}(0,0,0,0,3,0,0,0,0,0,2,4,4,8,0,0,5,3,4,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0));
{ "рейтинг" буквы Е условно
принимается равным 1/20 от "рейтинга" буквы E,
   если сочетание с участием Е корректно, иначе — 0
}

type
   TVariation = array [0..33, 0..33] of Integer;
var
    I, J, iC, iPredC, Max: Integer;
    C: Char;
    CP: TCodePage;
    D, MinD, Factor: Double;
   AMap: PMap;
    PV: ^TVariation;
   Vars: array [TCodePage] of TVariation;
begin
  DetermineRussian:=cpWin1251; { по yмолчанию }
    { вычисление распределений биграмм }
    FillChar(Vars, SizeOf(Vars), 0);
  for CP:=Low(Vars) to High(Vars) do begin
      AMap:=GetMap(CP);
      PV:=@Vars[CP];
      iPredC:=32;
      for I:=0 to Count — 1 do begin
        C:=Buf[I];
        iC:=32;
   if C >= #128 then begin
   if AMap <> nil then C:=AMap^[C];
     if not (C in ['Е', 'е']) then begin
  C:=Chr(Ord© and not 32); { 'a'..'я' -> 'А'..'Я' }
 if C in ['А'..'Я'] then iC:=Ord© — Ord('А');
   end
      else
      iC:=33;
   end;
    Inc(PV^[iPredC, iC]);
    iPredC:=iC;
    end;
    end;
{ вычисление метрики и определение наиболее
правдоподобной кодировки }
    MinD:=0;
 for CP:=Low(Vars) to High(Vars) do begin
   PV:=@Vars[CP];
  PV^[32, 32]:=0;
    Max:=1;
   for I:=0 to 33 do
   for J:=0 to 33 do
 if PV^[I, J] > Max then Max:=PV^[I, J];
  Factor:=255 / Max; { ноpмализация }
   D:=0;
  for I:=0 to 33 do
     for J:=0 to 33 do
    D:=D + Abs(PV^[I, J] * Factor — ModelBigrams[I, J]);
  if (MinD = 0) or (D < MinD) then begin
     MinD:=D;
   DetermineRussian:=CP;
   end;
    end;
end;

begin
{ тест: слово 'Пример' в разных кодировках
(веpоятность ошибок на таких
коpотких текстах высока — в данном слyчае
пpосто повезло!) }
writeln(DetermineRussian(#$CF#$F0#$E8#$EC#$E5#$F0, 6) = cpWin1251);
writeln(DetermineRussian(#$8F#$E0#$A8#$AC#$A5#$E0, 6) = cp866);
writeln(DetermineRussian(#$F0#$D2#$C9#$CD#$C5#$D2, 6) = cpKOI8R);
 readln;
end.


Stas Malinovski

Вопрос

В Delphi есть операторы AS и IS. Как ими пользоваться?

Ответ

Операторы as и is служат для выполнения операций с типами.
Оператор is используется в выражении:
Объект is Класс
и проверяет, принадлежит ли объект указанному классу или одному из его потомков. Если да, то выражение имеет значение True, что указывает на совместимость типов. В противном случае выражение имеет значение False.

Оператор as предназначен для приведения одного типа к другому и используется в выражениях вида:
Объект as Класс
В этом выражении объект приводится к типу класса. Такое приведение типа является НЕЯВНЫМ.

Пример:

procedure TForm1.Button1Click(Sender: TObject);
begin
if (Sender is TButton) then
(Sender as TButton).Enabled := False;
end;


Димыч

Вопрос

В Edit1 вставлено полное имя файла. Как в окно Edit2 вставить только название файла без пути к нему?

Ответ

Edit2.Text := ExtractFileName(Edit1.Text);

T'Mon

Вопрос

Существует ли расширение кроме *.dbf куда можно записать таблицу из базы данных, чтобы потом ее можно было прочитать?

Ответ

Расширение dbf используется для файлов, содержащих таблицы в формате DBase, FoxPro. Кроме формата dbf в Delphi (точнее в BDE) еще поддерживается формат PARADOX (Расширение у этих файлов *.DB/*.MB), а также ASCII файлы — расширение *.txt

Информацию записать можно в файл любого типа — .bin, .txt, ..doc и т.д. Для этого возьмите таблицу из .dbf\' а например в TClientDataSet. Затем прогоните курсор по аполненному TClientDataSet, по пути преобразуя значения к требуемому типу и сливая в файл.

Вопрос

В чем pазличия ShellExecute и CreateProcess?

Ответ

ShellExecute может запустить приложение, ассоциированное с расширением файла, например:

ShellExecute(Handle, 'open', 'mydoc.doc', nil, nil, SW_SHOW);

запустит Word (или другое приложение, зарегистрованное для *.doc) и откроет файл mydoc.
CreateProcess не обращает внимание на расширения, но возможности этой функции гораздо больше. Одна из главных — получение handles нового процесса и его первичного потока, с помощью которых можно запрашивать информацию о ходе дочернего процесса.
Hадо заметить, что хендл дочернего процесса может вернуть функция ShellExecuteEx, которая занимает, скажем, промежуточное положение.

Из конференции Delphi

Вопрос

В чем отличие, если объявлять переменные в разделе: "private", "public" или после "var Form1: TForm1;" ?

Ответ

private и public — это типы полей объекта.
Если объявить переменную в private, то она будет доступна только из данного модуля, если в public — из всех модулей (если в uses вызывающего модуля дописать имя данного модуля). Причем такие переменные называются полями объекта. Поля вызываются, например, так:

Form1.SomeField…

Если описать переменную после "var Form1: TForm1;", то это будет глобальная переменная, которая будет также доступна из всех модулей (есть если в uses вызывающего модуля дописать имя данного модуля). Вызывается просто по имени, например, SomeVar := …
Хороший стиль программирования не рекомендует обращаться к полям на прямую (например, a := Form1.SomeField). Для этого нужно написать функцию (в объектно-ориентированном программировании — метод объекта), которая будет возвращать результат какого-то поля
объекта, например,

a := Form1.GetSomeFieldValue, где
function TForm1.GetSomeFieldValue: sometype;
begin
Result := Form1.SomeField;
end;

Этот стиль обеспечивает более высокую надежность и понятность, а также совместимость с другими модулями (например, более ранних версий).

Из конференции Expert_FAQ

Вопрос

В чем отличие цикла (for), повтора (repeat) и while?

Ответ

Цикл For — конечный, Repeat и While — циклы с постусловием и предусловием соответственно.

Цикл
while (condition) do
begin

end;

выполняется до тех пор, пока condition равно true.

Цикл
repeat

until (condition)

выполняется до тех пор, пока condition НЕ равно true.

Главная разница между этими циклами (кроме противоположности условий) в том, что если условие цикла while не выполняется, операторы между begin/end не будут выполнены ни разу. Что касается repeat, операторы между repeat/until выполнятся как минимум однажды, независимо от значения condition.
Проще говоря (и это видно из самих циклов), while выполняет проверку ДО выполнения цикла, а repeat — ПОСЛЕ. С помощью операторов GOTO и IF это можно отобразить так:

-repeat-

label_start_cycle:

if not(condition) then
goto label_start_cycle;


-while-

goto label_check_condition;
label_cycle:

label_check_condition:
if (condition) then
goto label_cycle;


Что же касается FOR, это цикл со счетчиком.
Т.е. при выполнении такого участка программы

for i:=1 to 5 do
writeln(i);


на экране отобразятся числа от 1 до 5. Этот цикл можно заменить эквивалентом с использованием while:

i:=1;
while i<=5 do
begin
writeln(i);
i:=i+1;
end;


Очевидно, что при использовании for программа выглядит короче и понятнее :)

Вопрос

Для команд FloodFill и т.п. можно в Brush загрузить растровый рисунок. А возможно в Brush загрузить векторный рисунок? Или может быть существует другой способ сделать заливку любого объекта векторным рисунком?

Ответ

В Windows GDI этого сделать нельзя.

Из конференции Expert_FAQ

Вопрос

Возможно ли в консольных приложениях выводить текст разными цветами? Видел такие приложения. Но может быть они не на делфи сделаны…

Ответ

См. SetConsoleTextAttribute

Из конференции Expert_FAQ

Вопрос

1. Всегда ли при вызове метода фрмы Show у нее возникает событие OnShow?(Пишу прогу, которая сидит в трее и што-то делает, а по DoubleClick-у вызывается метод Show, который выводит форму с настройками. Так вот после старта первый DoubleClick все делает нормально, а после Закрытия формы

begin

Action := caNone;

ShowWindow (Handle, sw_Hide);

end;

и повторного DoubleClick-а события OnShow не происходит ( У меня там обновление отображаемых данных) и в результате все Label-ы, Edit-ы, ListBox-ы и ComboBox-ы получаются чиствми-пречистыми. По моему что-то тут не в порядке. Это я конечно вылечил — перед Show я вызываю свою процедуру, в которой все, что было в OnShow, но это наверное не совсем правильно. Подскажите, в чем тут дело?

Ответ

На новой форме написал такую штуку

procedure TForm1.FormClick(Sender: TObject); begin ShowWindow(Handle, SW_HIDE); ShowMessage('Visible: '+BoolToStr(Visible)); end;

Так вот она выдает, что Visible=true. Поэтому и не генерится OnShow — форма-то думает, что она видима! Решение простое:

Используйте либо только ShowWindow, либо только пару Show/Hide. Например, вместо ShowWindow(Handle, SW_HIDE) вызывайте Hide. Или вместо Show вызывайте ShowWindow(Handle, SW_SHOW). Использование Show/Hide, по-моему, предпочтительнее, т.к. будут вызываться OnShow/OnHide, да и Visible будет иметь правильное значение. Иначе придется использовать IsWindowVisible…

Из конференции Expert_FAQ

Вопрос

Никто не знает, где Delphi5 хранит курсоры, которые он автоматически запихивает в ЕХЕ? Уж больно хочется их отредактировать.

Ответ

Вообще-то курсоры эти хранит Винда. Для примера — смените текущие настройки — ВСЕ курсоры изменятся. Так что их не отредактируешь. Но изменить можно.
Old:=Application.Cursors[crDefault];
Application.Cursors[crDefault]:=LoadCursorFromFile('name');
crDefault — идентификатор изменяемого курсора. При завершении работы необходимо сделать «как было»:
DestroyCursor(Application.Cursors[crDefault]);
Application.Cursors[crDefault]:=Old;

Бузуверов Михаил

Они устанавливаются с дельфи и хранятся в comon files\borland sharps\..

yoof

Вопрос

В Tools / Editor Options / Code Insight можно создавать свои сокращения для наиболее употребляемых выражений. Все это хорошо, но при переустановке системы и, соответственно, Delphi приходиться все набирать заново. Вопрос: в каком фале Delphi храняться эти сокращения, чтобы этот файл можно было сохранить, а после переустановки Delphi скопировать в рабочий каталог и получить все, что было раньше?

Ответ

%Delphi%\Bin\DELPHI32.DCI где: %Delphi%, это полный путь к директории, в которую установлен Delphi.

Вопрос

Не подскажете сайты в зоне *.ru, где есть информация для начинающих?

Ответ

Попробуйте, во-первых, подписаться на соответствующую рассылку Гор.Кота:
http://subscribe.ru
Во-вторых, не покупайте книг типа «для Чайников», «за 21 день» и т.п.
Лучше всего купить книги издательства Питер или BSV (серии Мастер) для профессиональных программистов — там вы найдете все ответы с объяснениями, а не просто «сделайте так».
Можно посмотреть здесь:
www.rusdoc.ru
www.citforum.ru
http://www.delphi.mastak.ru
Но все-таки рекомендую купить хорошую бумажную книгу (типа Маркова и Дарахвелидзе).

http://www.helloworld.ru

Макс

http://www.adelavida.com/Forums/?Delphi

******

www.cydsoft.com/vr-online онлайн журнал о Delphi
http://www.delphimaster.ru/links/ куча линков.

fenix

Вопрос

Где в опциях Delphi задается имя и расширение ехе-файла?

Ответ

Имя файла совпадает с именем файла проекта .dpr
Расширение выходного файла задается в Project — Options — Application. Target file extension

Вопрос

Где можно взять компоненты RXLib для Delphi 7?

Ответ

Проект RxLib перестал развиваться и включен в библиотеку JEDI
http://delphi-jedi.org/Jedi:CODELIBJCL

Viktor Kharchenko

Вопрос

Где взять пример работы с сокетами на WinAPI?

Ответ

Загляни сюда:
http://tothpaul.free.fr/
Очень простое и красивое решение (работа ведется через файловые дескрипторы). Можешь использовать как образец для дальнейшей работы, или использовать как библиотеку. Даже есть пример с UDP. uses windows, winsock;
есть еще очень толковая статья
http://www.vcl.ru/html/cb/socket/ch5.html
но для C++ Builder'a, но основы в ней хорошо изложены.

Plazmer

Вопрос

Где взять справочник по работе в Delphiс ADO в общем, и с БД MS Access в частности.

Ответ

В составе MS Office есть справка по JET это наиболее компетентный источника по работе с Акцессом.

Anatoly Podgoretsky

Вопрос

Где достать процедуру типа "сумма прописью"?

Ответ

http://www.tsinet.ru/~vg. Здесь лежит библиотека vgLib, содержащая еще массу полезных вещей.

Vladimir Gaitanoff

Вопрос

Где можно найти документацию по созданию прог работающими с локальными сетями?

Ответ

Странный вопрос, в интернете конечно:

www.delphimaster.ru
www.infocity.com.ua
www.codenet.ru
delphiplus.org
www.delphi.h5.ru
www.programmist.info
tdelphi.spb.ru
delphi.mtu-net.ru
www.sources.ru
Вот основной набор ссылок, который поможет вам быть в курсе основных событий, а так же поможет узнать и скачать много интересного.

Из конференции Expert_FAQ

www.delphi.vov.ru

ovsyannikov

http://www.realcoding.net

admin realcoding.net

Вопрос

Для чего у TForm в Дельфи 5, в закладке Свойства (Properties) нужна опция WindowMenu ???

Ответ

Help — Index — TForm — Property — WindowMenu.
Это свойство нужно при разработке приложений типа MDI и используется в родительской форме (FormStyle property is set to fsMDIForm). Оно позволяет управлять выбором размещения дочерних форм (Cascade, Arrange Icons, Tile, and so on).

Shadow.

Вопрос

У меня такой вот вопрос, связанный с MSScriptControl: я разрабатываю MDI-приложение, мне нужно при помощи JavaScript создавать дочерние окна. Окна создаются, но есть одно «но»: если в обработчике события FormClose дочерней формы стоит Action := caFree; то при закрытии этой формы возникает исключение: Acces Volidation at address 00000000.

Read of address 00000000. Форма при этом исчезает с экрана, но не уничтожается. Пробовал я еще убрать эту строку(Action := caFree), тогда при попытке закрытия формы она просто сворачивается. Как мне с этим бороться?

Ответ

Скорей всего, ты обращаешься после закрытия к нулевому указателю.

Степанов Эдуард

Попробуй перед Action := caFree установить указатель формы в NIL, и перед вызовом формы его проверять.

Вопрос

Есть 10 Button'ов. Надо всем им сделать Enabled:=False.

Ответ

with Form1 do
   for i:=0 to ControlCount-1 do
     if Controls[i] is TButton then
    (Controls[i] as TButton).Enabled:=false;

Viktor Kharchenko

Вопрос

Зачем в DELPHI нужно выделение памяти? указатели? Неужели это все для старых компов? Дайте ссылку на доку по этой информации?

Ответ

Указатели — это далеко не для старых машин!

Указатели используются для работы с динамической памятью. Например, создание массива, размер которого заранее не известен. Работа с динамически загружаемыми библиотеками (dll) осуществляется через указатели. Через указатели можно получить доступ к конкретному физическому адресу.

Выделение памяти происходит каждый раз при всего таких объектов, как формы, кнопки… В область памяти помещается экземпляр того или иного объекта. После завершения работы с экземпляром, память необходимо освобождать (обычно это делается в деструкторе автоматически, но есть такие методы как free и destroy). При работе с динамическими библиотеками (dll) это надо делать обязательно.

Самое интересное, что когда вы пишете процедуру типа procedure a(var b: integer) и вызываете ее a(some_var), то в нее передается адрес переменной some_var. Именно по этому адресу процедура изменяет значение some_var;

Про указатели можно прочитать в любом учебнике Turbo Pascal (если я не ошибаюсь, указатели появились, начиная с 5й версии Turbo Pascal'a). В Delphi — все аналогично.

Простенький пример:

procedure TForm1.Button1Click(Sender: TObject);
var
a: ^Integer;
begin
New(a); //Выделение памяти
a^ := 5;
Form1.Caption := IntToStr(a^);
Dispose(a); //Освобождение памяти
end;

Из конференции Expert_FAQ

Вопрос

Кaк yзнaть кaкиe фyнкции нaхoдятcя в DLL и кaк их иcпoльзoвaть?

Ответ

Запустить одну из следующих программ:

delphi%\bin\tdump.exe
MS Quick View

Если без документации, вслепую — не получится. Еще надо знать параметры и возвращаемый результат. Если заголовок есть, он описывается в разделе implementation как external. Обычно библиотеки используют соглашение stdcall. (реже cdecl, дельфийские — register).

Леонид Трояновский

Вопрос

Кaк искать oкнo по части eгo нaзвaния?

Ответ

function FindNextWnd(StartHWND: HWND; AString : String): HWND;
var
    Buffer : array [0..255] of char;
begin
    Result := StartHWND;
    repeat
  Result := FindWindowEx(0, Result, nil, nil);
  GetWindowText(Result, Buffer, SizeOf(Buffer));
if StrPos(StrUpper(Buffer), PChar(UpperCase(AString))) <> nil
        then Break;
    until (Result = 0);
end;

Из конференции Delphi

Вопрос

Как Delphi-программе присвоить 2 иконки размером 16х16 и 32х32? Т.е. если файлы в проводнике Windows представлены списком, то ехе'шник имеет иконку 16х16, а если крупными значками — то 32х32.

Ответ

А в чем, собственно, проблема? Открываешь Delphi, нажимаешь Shift+Ctrl+F11, выбираешь закладку Application. Там щелкаешь Load Icon и указываешь иконку, содержащую и 16х16, и 32х32 одновременно. Чтоб такую сделать, скачай любой редактор иконок (я пользуюсь Aha-soft ArtIcons Pro 3.01: http://www.aha-soft.com).

Олег

Вопрос

Q-25 Как мне вывести какое-нибудь окошко с картинкой (Splash-Screen), пока программа грузится?

Ответ

Смотрите пример в X:\DELPHI\DEMOS\DB\MASTAPP\mastapp.dpr (Х — это ваш CD-ROM с дистрибутивом Delphi).
Удобно использовать функцию ShowSplashWindow из библиотеки RxLib.

Из конференции Delphi

Вопрос

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

Ответ

Отвечаю:

procedure Test(); var i: integer; begin for i:= 0 to 100 do begin ListBox1.Items.Add(format('Line number %d successfully inserted and scrolled down.', [i])); sleep(100); ListBox1.Perform(WM_VSCROLL, 1, 0); {^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^} {Это и есть ответ на заданый вопрос} end; end;

Из конференции Expert_FAQ

Вопрос

Как yзнать текущую (Ru/En) pаскладкy клавиатypы?

Ответ

GetKeyboardLayoutName(buffer{:array [0..KL_NAMELENGTH] of Char});
case ((StrToInt('$'+ Buffer)) and $03FF) of
    LANG_ENGLISH: Caption := 'Eng';
    LANG_RUSSIAN: Caption := 'Rus';
end;

procedure TForm1.Button1Click(Sender: TObject);
var
    AklName: array [0..2] of Char;
begin
    GetLocaleInfo( LoWord(GetKeyboardLayout(0)),
     LOCALE_SABBREVLANGNAME,
   AklName,
  SizeOf(AklName));
    Caption := AklName;
end;

Leonid Troyanovsky

Вопрос

Такая ситуация — есть таблица(dbf 4),выгруженная с 1С:Предприятия, содержит поля с русскими буквами, при попытке открыть из проги (BDE) вместо русского — всякая дребедень, но если открыть таблицу в Еxcel, и потом просто пересохранить ее под другим именем в том же dbf, то все нормально, при попытке открыть таблицу до Еxcel в фаре по F3/F4 вижу русские буквы, в чем причина и как заставить BDE открывать начальную таблицу нормально?

Ответ

Возможно, не настроен BDE.
Зайдите в BDE Administrator. На вкладке Configuration — Drivers — Native должны быть следующие настройки параметра LANGDRIVER:
PARADOX — Pdox ANSI Cyrillic
DBASE — dBASE RUS cp866
FOXPRO — dBASE RUS cp866
У 1С кодовая страница по умолчанию 1251

Yuriy Poltorak

Следует использовать метод объекта XBase
КодоваяСтраница()
КодоваяСтраница(<Режим>)
Назначение: установить режим кодировки для чтения и записи строковых значений в файл.
Возвращает: текущее числовое значение режима кодировки (на момент до исполнения метода).
Параметры:
Режим: 0 — windows-кодировка, 1 — DOS-кодировка

Якушев Антон Юрьевич

Вопрос

Как работать с ComboBox чтобы она брала из БД столбец и отображала его для выбора?

Ответ

Используй компонент TDBLookupComboBox.
Свойства ListSource, ListField задают соответственно источник данных и поле источника, данные из которого будут перечисляться в выпадающем списке.
Свойства DataSource, DataField соответственно источник данных и поле(текущей записи) источника данных, куда будет записано значение, выбранное пользователем. Два последних свойства можно не задавать, тогда выбор пользователя приведет к изменению текущей записи в ListSource.DataSet. Все это описывается в хелпе к Дельфям.

Viktor Kharchenko

Вопрос

При нажатии на иконку в заголовке окна видим меню (свернуть, переместить, закрыть, ..). Как внести туда свои строчки?

Ответ

Отвечаю как можно подробнее и понятнее.

Для изменения этого меню мы должны использовать API-функцию InsertMenu. Также нам пригодится API-функция GetSystemMenu — она возвращает указатель на системное меню. Вот конкретный пример кода:


menu:=GetSystemMenu(Handle, False);
InsertMenu(menu, 5, MF_ByPosition, 1000, 'About');


Этот код надо поместить, например, в обработчик нажатия кнопки (при нажатии на которую и будет добавлятся в системное меню новый пункт). Разумеется, переменная menu типа HMENU должна быть до этого определена:


var
menu: HMENU;


Параметры у функции InsertMenu следующии: первый — это указатель на системное меню. Его мы получили через API-функцию GetSystemMenu. Второй — это номер позиции, на которую наш новый пункт меню вставится (нумерация идет с нуля!). Значение третьего параметра (MF_ByPosition) говорит о том, что второй параметр интерпретируется именно как номер позиции для нового пункта меню. Четвертый — это идентификатор меню (мы задали для него значение 1000). И, наконец, пятый — это заголовок нового пункта меню.

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

Сейчас при выборе этого пункта ничего не происходит. Давайте добавим обработчик. Для этого вносим объявление нового обработчика в соответствующее место кода нашей формы:

type … procedure SystemMenu(var Msg:TMessage); Message WM_SysCommand; …

Далее пишем сам обработчик:

… procedure TForm1.SystemMenu(var Msg:TMessage); begin if Msg.wParam=1000 Then //если выбрали меню с идентификатором 1000 ShowMessage('О программе …'); inherited; end; …

Теперь при выборе нашего пункта меню, естественно, появится messagebox «О программе …».

Садыков Алексей Николаевич

Вопрос

Как сделать так, чтобы пока курсор мыши находится над объектом (Panel1), он изменял свой цвет?

Ответ

Сделать это можно так:

var Flip:Boolean;
//На форме должно быть: Timer1 и Panel1
//у Формы в событии OnMouseMove пишем
Procedure TForm1.FormMouseMove(…)
begin
if X > Panel1.Left && X < Panel1.Left + Panel1.Width && Y
>Panel1.Top && Y < Panel1.Top + Panel1.Width then
Timer1.Enabled:= true;
else
Timer1.Enabled:= false;
end;
//Выставляем у таймера нужное время и пишем в его событии OnTimer
//такой код
procedure TForm1.Timer1Timer(Sender:TObject)
begin
Flip = not Flip;
if Flip = true then
Panel1.Color:= clRed;
else
Panel1.Color:= clGreen;
end;


Вот и все. Ну, а дальше уже вариации на эту тему.

Sergey

Вопрос

Можно ли на объект (и на какой) положить иконку, взятую из ехе-файла? Подобно тому, как это делает ярлык к файлу.

Ответ

А в чем проблема? Можно ее (иконку) отрисовать хоть на форме (точнее — на любом объекте с canvas'ом).
Следующий код рисует 5-ую иконку из файла moricons.dll (в Win9x валяется в папке windows).

procedure TForm1.Button1Click(Sender: TObject);
var iHwnd : LongInt;
begin
img.picture:=nil;
iHwnd:=extracticon(Form1.Handle, 'moricons.dll', 5);
if ihwnd=0 then
application.messagebox('Error','Иконка не обнаруженна',MB_ICONINFORMATION);
drawicon(Image1.Canvas.Handle ,0,0,ihwnd);
Image1.Refresh ;
Image1.repaint;
destroyicon(ihwnd);
end;


Олег

Вопрос

Как сделать, чтобы Delphi-программа отслеживала запускаемые программы в Windows (98SE)? Допустим, чтобы при запуске игры «Сапер» (при запуске Проводника или открытии Word) запускалась Delphi-программа (выдавалось сообщение или производились другие возможные действия).

Ответ

Можно написать программку, которая будет периодически проверять, не появилось ли окно с нужным заголовком.
Для этого моно на форму положить таймер и написать в обработчике OnTimer что-нибудь вроде

uses Windows, Messages;

procedure TForm1.Timer1Timer(Sender: TObject);
var
wnd: hWnd;
begin
wnd:=FindWindow(nil, 'Сапер');
if wnd<>0 then //Есть такое окно!
begin
//Здесь делаем, что нам нужно, например, закрываем нафиг это окно
SendMessage(wnd, WM_CLOSE, 0, 0);
end;
end;

Вопрос

Как показать сообщение (showmessage или подобное) на короткий промежуток времени? Или как его закрыть спустя какое-то время?

Ответ

Ну, например, создать свою форму, которая будет выполнять функции MessageBox'а. На форму положить таймер. При срабатывании OnCreate — включить таймер. При срабатывании OnTimer вызывать Self.Close;

Вопрос

Как в Delphi 6 можно работать с Com1 портом.

Подскажите пожалуйста какие для этого нужны команды

Ответ

Работай как с обычным файлом, но имя ему «COM1».

Из конференции Expert_FAQ

Вопрос

Как в Delphi exe'шнику присвоить иконку?

Ответ

По идее, изменить иконку по умолчанию можно вызвав Project — Options (Ctrl + Shift + F11) — Application — Icon и нажать на кнопку «Load Icon…».

А может, вы хотите изменять в Run-Time (т.е. во время работы приложения)? Тогда надо изменять свойство Icon объекта Application, т.е. application.icon. Например,
Application.Icon.LoadFromFile(FileName : String);
Здесь уже можете делать все, что вам нужно.

Если хотите, чтобы exe-шник содержал больше одной иконки, отредактируйте с помощью ImageEditor'а файл ресурсов projectname.res (projectname — имя проекта).

Герун Данил, Михаил Подгурский

Также можно отредоктировать exe-шник в программе Resource Workshop, поместив в папку Resource Workshop\BIN этот exe-шник.

sh_script

Вопрос

Можно ли вычислить в компоненте MonthCalendar рабочие дни, т.е. кол-во дней в месяце кроме суббот и воскресений? Существуют ли компоненты, которые могут делать такие вычисления?

Ответ

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

function QuatityOfWorkDays(Month, Year: Integer): Integer;
var DT: TDateTime;
I, SD, ED: Integer;
begin
SD := Round(EncodeDate(Year, Month, 1)); // Первый день месяца
ED := Round(IncMonth(SD, 1)) — 1; // Последний день месяца
Result := 0;
for I := SD to ED do // Перебираем все дни
if DayOfWeek(I) in [2..6] then Inc(Result);
// Увеличиваем счетчик, если не 1 — воскресенье и 7 — суббота
end;


T'Mon

Вопрос

Вот часть кода, который при запуске выводит надпись «Текст», но на белом фоне, а как сделать, чтобы фон был прозрачным? что еще надо добавить к моему коду:
Image1.Canvas.Font.Name:='Courier';
Image1.Canvas.Font.Size:=35;
Image1.Canvas.Font.Style:=[fsBold];
Image1.Canvas.Font.Color:=clRed;
Image1.Canvas.TextOut(475,150, 'Текст');

Ответ

Image1.Canvas.Brush.Style:=bsClear;

Novikov Dmitry.

Вопрос

Как в delphi вычислить значение выражения, введенного с клавиатуры, типа a + b*2 — 7, где a — Arr[0], b — Arr[1], Arr — массив real.

Ответ

В Библиотеке RX http://www.torry.net/vcl/packs/huge/etrx275d6.zip
есть Unit Parsing Description. Класс TRxMathParser представляет анализатор арифметических выражений, предоставляемых в виде строки. Строка передается для анализа как параметр AFormula метода Exec. В случае ошибки вычисления возникает исключительная ситуация типа ERxParserError. Допустимые операторы: + , — , * , / , ^ В выражении могут быть использованы следующие функции: Cos, Sin, Tan, ArcTan, ArcSin, ArcCos, Abs, Exp, Ln,
Log, Sqrt, Sqr, Int, Fraq, Trunc, Round, Sign, Not.

Вопрос

Как завершить выполнение другой программы, зная имя экзешника?

Ответ

Используй EnumWindows для перечисления процессов, а в EnumWindowsProc вызывай GetModuleFileName для каждого модуля. Если это он, то посылаешь ему сообщение WM_CLOSE.

Azanov

Вопрос

Как в окно Edit'а не допустить ввод букв? Т.е. игнорировать нажатие буквенных клавиш и реагировать только на цифровые.

Ответ

Для того, чтобы не допустить ввод букв в Edit, можно в событии OnKeyPress прописать примерно следующее:

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
Case key of
'0'..'9': ;
chr(8) : ;
else key:=chr(0);
end;
end;

То есть, если производится ввод цифр (0-9), то они вводятся, также и клавиша BackSpace (chr(8)). Иначе же ничего не вводим (chr(0)). Можно вывести сообщение.

Sergey K.

procedure TInputForm.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
if not(Key in ['0'..'9',#8]) then Key := #0;
end;
mr_eduard

Вопрос

Как заставить программу спрятаться в TRAY (там, где часики)?

Ответ

Ни в Delphi, ни где-либо еще нельзя «свернуть» или «спрятать» приложение в трей. На самом деле происходит следующее: программа добавляет иконку в трей, а сама становится невидимой.

1. Способ, основанный на использовании компонента TRxTrayIcon из RxLib:
Со страницы Rx Tools берешь RxTrayIcon. Выбираешь иконку для статического отображения или для анимированной картинки. Пишешь код примерно такой:

interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, RXShell;
type
TForm1 = class(TForm)
RxTrayIcon1: TRxTrayIcon;
procedure FormCreate(Sender : TObject);
procedure RxTrayIcon1DblClick(Sender: TObject);
procedure FormShow(Sender: TObject);
private
procedure ApplicationMinimize(Sender : TObject);
procedure ApplicationRestore(Sender : TObject);
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
RXTrayIcon1.Icon:=Application.Icon; //Присваиваем икону от приложения
Application.OnMinimize := ApplicationMinimize; // Описываем обработчики
Application.OnRestore := ApplicationRestore; // событий
end;

procedure TForm1.ApplicationMinimize(Sender : TObject);
begin
ShowWindow(Application.Handle, SW_HIDE); // Скрываем прямоугольник в Task Bar
end;

procedure TForm1.ApplicationRestore(Sender : TObject);
begin
ShowWindow(Application.Handle, SW_HIDE); // Скрываем прямоугольник в Task Bar
end;

procedure TForm1.RxTrayIcon1DblClick(Sender: TObject);
begin
Application.Restore; // Восстанавливаем
Application.BringToFront; // Выносим вперед
end;

procedure TForm1.FormShow(Sender: TObject);
begin
ShowWindow(Application.Handle, SW_HIDE); // Скрываем прямоугольник в Task Bar
end;


2. Для добавления иконки нужно пользоваться ф-ией Shell_NotifyIcon. Она очень простая:

WINSHELLAPI BOOL WINAPI Shell_NotifyIcon(
DWORD dwMessage, // message identifier
PNOTIFYICONDATA pnid // pointer to structure
);
dwMessage может принимать сл. значения:
NIM_ADD Добавить иконку в трей
NIM_DELETE Удалить иконку из трея
NIM_MODIFY Изменить свойства иконки в трее
Второй параметр pnid содержит тип NOTIFYICONDATA:
typedef struct _NOTIFYICONDATA { // nid
DWORD cbSize; // на практике это SizeOf(IconData)
HWND hWnd; // хэндл главного окна твоего приложения
UINT uID; // на практике — $DEDB
UINT uFlags; // ставь NIF_MESSAGE or NIF_ICON or NIF_TIP
UINT uCallbackMessage; // идентификатор сообщения, которое
// будет получать твое приложение при «колдовании»
// пользователя над иконкой в трее. Забей как константу,
// например, WM_MyIcon = WM_USER + 1
HICON hIcon; // хэндл иконки, например,
// application.Icon.Handle
char szTip[64]; // текст всплывающей подсказки
} NOTIFYICONDATA, *PNOTIFYICONDATA;


Все. Осталось только ловить сообщения.

Олег Анатольевич

www.listplayer.narod.ru
Там и статья, как это сделать, и компонент есть.

fse

Вопрос

Как заставить форму находиться позади всех окон в системе, даже если на ней происходят какие-либо события (нажатие кнопки, ввод текста, etc.)?

Ответ

Цитата из MSDN:
An application cannot activate an inactive window without also bringing it to the top of the Z order. Applications can change an activated window's position in the Z order without restrictions, or it can activate a window and then move it to the top of the topmost or non-topmost windows.
Поэтому при любой активации окна нужно будет вручную изменять Z-order.
Для этого достаточно висеть на WM_ACTIVATE и при активации окна помещать последнее вниз Z-order'а:

SetWindowPos(
Handle, // здесь указать хэндл окна формы
HWND_BOTTOM,
0, 0, 0, 0,
SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE or SWP_NOREDRAW);


Novikov Dmitry

Вопрос

Требуется при помощи SQL-запроса выбрать из таблицы записи, в которых значение поля grupp равно значению переменной S типа String.
Пишу:

var S:String;

QDk.Close;
QDk.SQL.Clear;
QDk.SQL.Add('select * from dk where grupp='+S);
QDk.Open;


А программа при обработке события выдает «Type mismatch in expression». Почему?

Ответ

Если это поле имеет строковый тип, то абсолютно правильно, исключение вылетает на этой строчке:

QDk.SQL.Add('select * from dk where grupp='+S);

Кстати, ты не указал, что именно ругается — твоя прога или SQL-сервер. И если тип поля все-таки строковый, то записывать это надо так:

QDk.SQL.Add('select * from dk where grupp="'+S +'"');

чтобы символьное выражение оказалось в кавычках. Да и параметры запросов никто не отменял. во время разработки записываешь в QDk.SQL:

select * from dk where grupp=:GroupName

Выражения, начинающиеся с двоеточия, воспринимаются, как параметры, и с ними можно работать через свойство TQuery.Params. Т.е, чтобы выполнить очередной запрос, тебе надо будет сделать:

QDk.Active:= false;
QDk.Params.ParamByName('GroupName').asString:= '…';
или
QDk.Params[0].asString:= '…';
QDk.Active:= true;


Azanov

Вопрос

Как изменить вид кнопки? Например, сделать ее круглой, а не квадратной.

Ответ

Я думаю, что вам будет лучше скачать компонент, который специально предназначен для создания красивых кнопок. Таких компонентов полно на всяких серверах, типа http://www.torry.net, http://delphi.mastak.ru

Дело в том, что самостоятельное создание этого компонента отнимет много времени; но если вы вдруг захотите разобраться, как это делается, то копать следует в направлении Регионов и таких функций, как CreateRectRgn и всей группы этих функций (группа — это значит вызываете справку по этой функции и нажимаете на кнопочку Group). В общем, проблем много — надо будет создавать обработчики сообщений, функции отображения, обновления, реакции на события, конструкторы, …

Герун Данил

Лучше нарисовать в Potoshop круглю кнопку и вставить ее, как рисунок. После компиляции будет не ясно, что это за объект — кнопка или рисунок или вообще что. Так что все будет путем.

Dart Wader

Не знаю, насколько это правильно с точки зрения понятия кнопки, но я рисовала рисунки в PhotoShop'е, вставляла их (было три рисунка: фоновый, при движении и нажатии) и доваляла действия типа OnMouseMove, Click, Down. В результате получилось очень даже красиво…

moorka

Вопрос

Как перевести данные из таблицы в Exсel в мою программу?

Ответ

Воспользуйся компонентами с вкладки Servers из Delphi 5/6 (там находятся компоненты по работе с Microsoft Office 97/2000). После того, как с помощью методов нужных компонентов откроешь нужный лист, просто переноси данные из него в свою программу переходя в цикле из ячейки в ячейку. Многие методы компонентов схожи с методами VBA из MS Office.

Вопрос

На форме 4 (или более) кнопок. Каждая из них свое название и запускаемую программу берет из ini-файла, используя команды TiniFile.Create, ReadString и ShellExecute. Как упростить, чтобы по возможности исключить повторяющиеся процедуры (TForm1.Button1-4.Click) и команды?

Ответ

// Обработчик у всех кнопок одинаковый
procedure btnMyButtonClick(Sender: TObject);
begin
// Создание компонента
with TIniFile.Create(…) do
try
// Проверка того, какая кнопка. Можно сделать любое другое условие,
// но через Tag делать — красивее и быстрее всего. Tag не используется
// Delphi, поэтому можно без боязни его использовать
if TButton(Sender).Tag = 1 then
begin

end;
finally
Free;
end;
end;


Можно и явно указать «отправителя события»
if sender=btn123 then…

vmd

Вопрос

Где надо написать присвоения, чтобы они использовались во всех процедурах? Например, для (var) inif : TiniFile; присвоение (begin) inif := tinifile.create('c:\work\enter.ini'); надо прописывать для каждой процедуры, что не очень удобно.

Ответ

unit TestUnit;
interface
procedure Test(var Param);
implementation
uses … // — прописать то, что надо
var IniFile: TIniFile;
procedure Test(var Param);
begin
IniFile.ТырыПыры;
end;
procedure Test2;
begin
IniFile.ТралиВали;
end;
initialization
IniFile:=TIniFile.Create('c:\work\enter.ini');
// …
finalization
// …
IniFile.Free;
end


Novikov Dmitry

Вопрос

Как программно заставить Винду перерисовать обои на рабочем столе? Смысл затеи: нужно 1 раз в минуту менять WallPapper на DeskTop т.к. на нем всякая полезная информация типа информации о новостях в организации.

Ответ

Вот вам пример с сайта http://delphi.mastak.ru :

program wallpapr;
uses Registry, WinProcs;
procedure SetWallpaper(sWallpaperBMPPath : String; bTile : boolean );
var
reg : TRegIniFile;
begin
// Изменяем ключи реестра
// HKEY_CURRENT_USER
// Control Panel\Desktop
// TileWallpaper (REG_SZ)
// Wallpaper (REG_SZ)

reg := TRegIniFile.Create('Control Panel\Desktop' );
with reg do begin
WriteString( '', 'Wallpaper',
sWallpaperBMPPath );
if( bTile )then
begin
WriteString('', 'TileWallpaper', '1' );
end else begin
WriteString('', 'TileWallpaper', '0' );
end;
end;
reg.Free;
// Оповещаем всех о том, что мы
// изменили системные настройки
SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, Nil, SPIF_SENDWININICHANGE);
end;
begin
// пример установки WallPaper по центру рабочего стола
SetWallpaper('c:\winnt\winnt.bmp', False );
end.


От себя добавлю: если вы изменяете один графический файл с обоями, то нет нужды писать в реестр: можете выполнить только процедуру SystemParametersInfo(…), т.к. она оповещает Windows просто перегрузить текущие обои (на мой взгляд). В любом случае, можете поэкспериментировать и найти для себя подходящее решение.

Также можете попробовать другой вариант:

str1:='D:\GRAPHICS\PICTURE\logo.bmp';
SystemParametersInfo(SPI_SETDESKWALLPAPER,0,PChar(str1),SPIF_UPDATEINIFILE);
SystemParametersInfo(SPI_SETDESKWALLPAPER,0,PChar(str1),SPIF_SENDWININICHANGE);
UpdateWindow(FindWindow('Progman', nil));


И вот еще проще (по идее, то же самое): как заставить винды, например, «заметить» изменения в *.BMP файле-заставке рабочего стола.

SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, PChar(FileName), SPIF_UPDATEINIFILE);

Герун Данил

Вопрос

Как в Delphi назначить горячие клавиши?

Ответ

С сайта http://delphi.mastak.ru:
Как назначить горячие клавиши (shortcuts), чтобы они были доступны даже если сейчас активна другая программа (как это делает аська). Попробуй этот код:

type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
protected
procedure hotykey(var msg:TMessage); message WM_HOTKEY;
end;

var
Form1: TForm1;
id,id2:Integer;

implementation

{$R *.DFM}

procedure TForm1.hotykey(var msg:TMessage);
begin
if (msg.LParamLo=MOD_CONTROL) and (msg.LParamHi=81) then
begin
ShowMessage('Ctrl + Q wurde gedrьckt !');
end;

if (msg.LParamLo=MOD_CONTROL) and (msg.LParamHi=82) then
begin
ShowMessage('Ctrl + R wurde gedrьckt !');
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
id:=GlobalAddAtom('hotkey');
RegisterHotKey(handle,id,mod_control,81);

id2:=GlobalAddAtom('hotkey2');
RegisterHotKey(handle,id2,mod_control,82);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
UnRegisterHotKey(handle,id);
UnRegisterHotKey(handle,id2);
end;


Комментарий от Евгения Гаечкина: при смене стиля окна с fsStayOnTop на fsNormal и обратно(предполагаю, что так происходит при смене стиля на любой), у него меняется handle, и соответственно сообщения WM_HOTKEY перестают поступать. Метод реанимации, в принципе прост:

UnRegisterHotKey со старым handle
смена стиля окна
RegisterHotKey — с новым handle

Метод не единственный, но поможет.

Вопрос

Как реализовать обработку информации одновременно несколькими потоками? Нужно как можно более подробно.

Ответ

Запускайте Delphi. Итак, наша программа будет представлять из себя форму с двумя edit'ами и кнопкой. Добавьте их на форму.

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

Добавьте в программу еще один модуль (меню File, New, Unit).

Внесите в окно кода нового модуля следующий код:

unit Unit2;
interface
uses
Classes;
type
TMyThread = class(TThread) //Новый класс
private
answer:Integer;
protected
procedure ShowResult;
procedure Execute; override;
end;
implementation
uses
SysUtils, Unit1;
//Процедура для вывода информации из потока
procedure TMyThread.ShowResult;
begin
Form1.Edit1.Text:=IntToStr(answer);
end;
//Длинная процедура
procedure TMyThread.Execute;
var
i:Integer;
begin
for i:=1 to 10000 do
begin
answer:=answer+1;
Synchronize(ShowResult);
end;
end;
end.


Немного комментария по коду. В нашем модуле мы вводим новый класс TMyThread как «потомок» TThread. В экземпляре нашего класса и будет выполнятся отдельный поток программы. В классе есть процедура ShowResult для вывода информации из работающего потока в основной поток (форму) нашей программы. Кроме того, в классе есть наша версия метода Execute из родительского класса TThread. Обратите внимание, что в нашей реализации Execute мы пишем


Synchronize(ShowResult);


Тем самым наш поток что-то отправляет в основной поток программы (в данном случае, значение переменной answer). Делаем мы это посредством вызова Synchronize, в котором в качестве параметра указываем имя нужной процедуры.

Теперь переходим к нашему основному модулю Unit1. Во-первых, добавьте в секцию uses ссылку на Unit2:


uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Unit2;


Во-вторых, напишите обработчик для нажатия кнопки:

procedure TForm1.Button1Click(Sender: TObject);
var
MyThread: TMyThread;
begin
MyThread:=TMyThread.Create(False);
end;


Тут мы создаем второй поток для нашего приложения. Параметр False означает, что метод Execute для нашего потока вызовется немедленно.

Запускайте программу. Нажимайте на кнопку. В первом edit'е замелькают промежуточные результаты работы второго потока. Во время его работы вы можете вводить информацию во второй edit — т.е. работа одного потока не мешает работе другого.

Садыков Алексей Николаевич

Вопрос

Как открыть ссылку на документ в интернете в браузере, установленном по умолчанию? Например, для обработчика события Click кнопки HomePage.

Ответ

Возможен такой вариант

Procedure TForm1.XClick(Sender: TObject);
Var
St: Array[0..255] of Char;
Begin
ShellExecute(Application.Handle, 'open', StrPCopy(St,'http://' + Label1.Caption),
nil, nil, SW_SHOW);
End;


Вместо LAbel1.Caption можно вставить понятно что.

Sergey

Вопрос

Как сделать, чтобы окно программы перемещалось мышью, если держать его не только за заголовок, но и в любой точке внутри окна?

Ответ

Для перетаскивания формы не только за ее заголовок, можно использовать следующий обработчик события OnMouseDown формы:

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
ReleaseCapture;
Form1.Perform(WM_SYSCOMMAND, $F012, 0);
end;


Димыч

Вопрос

Если я на форму кину кнопку, можно сделать так, чтобы при нажатии на кнопку запускался файл *.exe, находящийся в этой же папке?

Ответ

Пишем событие кнопки onClick

Begin
winexec('file.exe',1);
End;


Денис

Вопрос

Как сделать чтобы при нажатии на надпись создавалось новое сообщение почтовой программой? И может ли такое быть, если текст написан в окне Memo?

Ответ

Очень просто. Допустим, что текст у вас на писан в Label1, тогда:

uses ShellAPI;
procedure TForm1.Label1Click(Sender: TObject);
begin
ShellExecute(Application.Handle, nil,'mailto:name@domain.ru',nil, nil, SW_SHOWNORMAL);
end;


Любому написанному адресу будет создаваться сообщение для отправки письма. А если ты хочешь, чтобы пользователь писал в Memo адрес и письмо отправлялось, тогда это можно сделать. Тут всего несколько процедур:

uses ShellAPI;
var
Form1: TForm1;
s:String;
procedure TForm1.Button1Click(Sender: TObject);
begin
s:=Memo1.Lines.Text;
Label1.Caption:=s;
ShellExecute(Application.Handle, nil,'mailto:name@domain.ru',nil, nil,
SW_SHOWNORMAL);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Label1.Visible:=False;
end;
end.


Это все.

graywolfik

Вопрос

Как программно присвоить картинку (bmp, jpg, ico) объекту Image1 или BitBtn1? Т.е., чтобы изображение появилось на Форме или Кнопке, например, после нажатия другой кнопки — Button1?

Ответ

Image1.Picture.LoadFromFile('c:\picture.bmp');
BitBtn1.Glyph.LoadFromFile('c:\picture.bmp');

Вопрос

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

Ответ

Создаешь новое приложение, потом идешь в Project-View Source и вписываешь туда это:

program Proc2;

uses
Windows,ShellApi,
Forms,
Unit1 in 'Unit1.pas' {Form1};

{$R *.RES}

const
semName='{268726AA-0250-4241-BD3E-B3A68E059B07}';
terminate:Boolean=False;

Var
tid:Cardinal;
h:THandle;
th:THandle;

function ThrFunc(Parameter: Pointer): Integer;
begin
while not terminate do
begin
if WaitForSingleObject(h,100) = WAIT_OBJECT_0 then
ShellExecute(0,nil,PChar(ParamStr(0)),nil,nil,SW_NORMAL);
end;
ReleaseSemaphore(h,1,nil);
Result:=0;
end;


begin
h:=CreateSemaphore(nil,1,1,semName);
if h<>0 then
try
th:=BeginThread(nil,0,ThrFunc,nil,0,tid);
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
terminate:=True;
WaitForSingleObject(th,INFINITE);
finally
CloseHandle(h);
end;
end


PS: Через диспетчер задач это можно снять… слава богу =)

A.Z.

Вопрос

На Delphi написана программа, использует несколько связанных таблиц Paradox. Периодически (предположительно после зависаний, некорректных перезагрузок и пр.) в базе наблюдается бардак — потери данных, несоответствие… Упаковка таблиц при помощи DataBaseDesktop помогает. Как программно паковать таблицы Paradox или восстанавливать индексы?

Ответ

Вот держи пример, я сам использую в работе:
unit repair_u;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Db, DBTables, BDE, StdCtrls;
type
TForm1 = class(TForm)
tb: TTable;
te: TTable;
Button1: TButton;
Label1: TLabel;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
// Pack a Paradox or dBASE table
// The table must be opened execlusively before calling this function…
procedure PackTable(Table: TTable);
var
Props: CURProps;
hDb: hDBIDb;
TableDesc: CRTblDesc;
begin
// Make sure the table is open exclusively so we can get the db handle…
if not Table.Active then
raise EDatabaseError.Create('Table must be opened to pack');
if not Table.Exclusive then
raise EDatabaseError.Create('Table must be opened exclusively to pack');
// Get the table properties to determine table type…
Check(DbiGetCursorProps(Table.Handle, Props));
// If the table is a Paradox table, you must call DbiDoRestructure…
if (Props.szTableType = szPARADOX) then begin
// Blank out the structure…
FillChar(TableDesc, sizeof(TableDesc), 0);
// Get the database handle from the table's cursor handle…
Check(DbiGetObjFromObj(hDBIObj(Table.Handle), objDATABASE, hDBIObj(hDb)));
// Put the table name in the table descriptor…
StrPCopy(TableDesc.szTblName, Table.TableName);
// Put the table type in the table descriptor…
StrPCopy(TableDesc.szTblType, Props.szTableType);
// Set the Pack option in the table descriptor to TRUE…
TableDesc.bPack := True;
// Close the table so the restructure can complete…
Table.Close;
// Call DbiDoRestructure…
Check(DbiDoRestructure(hDb, 1, @TableDesc, nil, nil, nil, False));
end
else
// If the table is a dBASE table, simply call DbiPackTable…
if (Props.szTableType = szDBASE) then
Check(DbiPackTable(Table.DBHandle, Table.Handle, nil, szDBASE, True))
else
// Pack only works on PAradox or dBASE; nothing else…
raise EDatabaseError.Create('Table must be either of Paradox or dBASE ' +
'type to pack');
Table.Open;
end;
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
begin
tb.open; PackTable(tb); tb.close;
te.open; PackTable(te); te.close;
end;
end


Сергей А.

Вопрос

Как в Delphi работать с битами?

Ответ

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

var
    I : integer;
    N : integer; // Hомер бита в диапазоне от
0..SizeOf(TYPE)*8 — 1

  I := I or (1 shl N); // установка бита
  I := I and not (1 shl N); // сброс бита
  I := I xor (1 shl N); // инверсия бита
if (i and (1 shl N)) <> 0 then… // проверка установленного бита

Высокоуровневый подход опирается на представление числа в виде множества:

type
    TIntegerSet = set of 0..SizeOf(Integer)*8 — 1;
var
    I : Integer;
    N : Integer;

  Include(TIntegerSet(I), N); // установили N-ный бит в 1
  Exclude(TIntegerSet(I), N); // сбросили N-ный бит в 0
  if N in TIntegerSet(I) then… // проверили N-ный бит


Из конференции Delphi

Вопрос

Нужно отправить сообщение по электронной почте, с помощью компонента NMSMTP (закладка FastNet). Куда ему нужно вписать логин/пароль и требуется ли вообще на сервере авторизация?

Ответ

Для компоненты NMSMTP обязательно заполняются свойства Hosts — адрес сервера SMTP, Port -обычно 25 и UserID — зарегистрированное имя на сервере. В свойстве PostMessage записывается сообщение, но обязательными являются только два: ToAdress типа TStringList со списком адресов, по которым необходимо отправить письмо (можно только один), и FromAdres с адресом отправителя. Даже не обязательно наличие самого сообщения. Ввод пароля в компоненте не предусмотрен, поэтому отправить сообщение через сервер, требующий авторизации, например, mailru.com, невозможно. Однако большинство SMTP серверов не требуют авторизации и отправить через них можно любое письмо с любым обратным адресом.

Проще всего попробовать отправлять письмо, через SMTP сервер получателя, т.к. обычно имя пользователя совпадает с левой частью почтового адреса. Обратный адрес при этом может быть любой, типа kto-to@gde-to.com

Игорь Румянцев

Вопрос

Как текст на кнопке (или другом объекте) расположить под заданным углом?

Ответ

Как выдать текст под наклоном? Чтобы вывести под любым углом текст необходимо использовать TrueType Fonts (например «Arial»). Например:

var
LogFont : TLogFont;

GetObject(Canvas.Font.Handle, SizeOf(TLogFont), @LogFont);
{Вывести текст 1/10 градуса против часовой стрелки}
LogFont.lfEscapement := Angle*10;
Canvas.Font.Handle := CreateFontIndirect(LogFont);


A.Z.

Вопрос

Я пишу прогу на делфях и как сделать DLL(как его вообще прописать в программу и какие у него есть особенности написания)???

Ответ

library lib_name;
uses classes, sysutils; // подключаемые модули {$r *.res}
begin function b(a : string)
begin end; exports b; end.
а из программы ее можно вызывать так: function b(a : string); external 'lib_name.dll';

Вопрос

Как сделать картинку (image1) на форме поверх других объектов (button1, memo1, edit1)? «Bring to front» не работает.

Ответ

Попробуй записать это в коде:

Image1.BringToFront;

а тем, которые могут мешать:

Edit1.SendToBack

Sergey

Это невозможно, т.к. timage — потомок tgraphiccontrol (рендерится на поверхности своего parentа), а всякие teditы и tbuttonы — потомки twincontrol, они являются окнами и имеют дескрипторы (число которых в win98 сильно ограничено — не размножайте много twincontroloв).

shurik

Положить картинку на панель, а уже панель отправлять наверх.

thum-hansa

Вопрос

Как сделать генератор случайных чисел формата XXXXX-XXXXX-XXXXX-XXXXX-XXXXX, чтобы числа состояли минимум из 5-ти знаков?

Ответ

На входе: Length — длина
На выходе: строка из цифр длины Length

function GenerateRandomNumber(Length : byte) : string;
var
Cnt1 : byte;
GenStr : string;
begin
GenStr := '';
Randomize;
for Cnt1 := 1 to Length do GenStr := GenStr + IntToStr(Random(10));
Result := GenStr;
end;


Конечно, не особенно быстрый алгоритм… Как сгенерировать последовательность по нужному шаблону:


PS : перевод из строки в число StrToInt

Вопрос

Как изменить стиль формы, т.е сделать ее плоской — избавиться от 3D эффекта?

Ответ

borderstyle:= bsnone; ???

Вопрос

Как сделать, чтобы форма отображалась в центре экрана (или в какой-нибудь другой области) независимо от разрешения?

Ответ

У компонента Форма есть свойство Position, в котором вы можете указать положение формы сразу после запуска, например, по центру и как в режиме проектирования. Но это повлияет на ее положение только сразу после запуска.

Чтобы изменить положение формы во время работы, вам надо изменять ее свойства Left и Top. Например, чтобы прижать форму к правому краю, вам надо написать следующее:
form1.Left := screen.Width — form1.Width;
Здесь объект Screen предоставляет вам информацию об «экране», т.е. ширина (screen.Width), высота (screen.Height) и т.д. Соответственно, прижать форму к нижнему краю можно так:
form1.Top := screen.Height — form1.Height;

Герун Данил

Вопрос

Программа должна коннектиться на определенный порт на удаленном компе, однако неизвестно, открыт или закрыт этот порт. При попытке коннекта на закрытый порт вылезает сообщение об ошибке ConnectionFailed и прога вылетает. Как сделать, чтобы это сообщение обрабатывалось как событие OnConnectionFailed и программа продолжала работать своим естественным образом?

Ответ

try
. //операторы, вызывающие ИС
.
except
//обработка ИС
end;


В Tools — Debugger Options — Laungauge Exception снять флажок «Stop on Delpi Exception»

Вячеслав

Компоненты стандартные? Если да — вешай на событие OnError обработчик, который ничего не делает. И все. Если это событие не обрабатывается, то выводится стандартный Exception.

Алексеев

Вопрос

Как программно создать ярлык и узнать свойства уже существующего?

Ответ

uses ShlObj, ComObj, ActiveX;

procedure CreateLink(const PathObj, PathLink, Desc, Param: string);
var
IObject: IUnknown;
SLink: IShellLink;
PFile: IPersistFile;
begin
IObject := CreateComObject(CLSID_ShellLink);
SLink := IObject as IShellLink;
PFile := IObject as IPersistFile;
with SLink do begin
SetArguments(PChar(Param));
SetDescription(PChar(Desc));
SetPath(PChar(PathObj));
end;
PFile.Save(PWChar(WideString(PathLink)), FALSE);
end;

Вопрос

Как убрать штриховую рамку (положение курсора) на кнопках (button1,2,…).

Ответ

TAbstop = False
Defailt(Cancel) = True

Вопрос

Подскажите, как узнать текущие координаты курсора мыши.

Ответ

1. Procedure GetCursorPos(var P: TPoint); или GetCursorPos(cpos), где cpos:tpoint возвращает значение, считая от левого верхнего угла экрана.
2. getcursorpos(x,y);
3. Mouse.CursorPos

******

4.в обработчике событий OnMouseMove в переменных х и у содержаться координаты курсора внутри формы.

apolnikov

Вопрос

Как в Delphi5 перехватить нажатие ALT+F4 так, чтобы при этом появлялась форма с вопросом «Хотите сохранить файл?» с тремя кнопками: «да», «нет», «отмена»? Варианты такие:

  1. Если нажата кнопка «отмена», то приложение остается, форма с вопросом закрывается.
  2. Если нажата кнопка «нет», то приложение закрывается и больше никаких форм не появляется.
  3. Если нажата кнопка «да», то появляется еще одна форма — диалог сохранения файла (диалог я сам сделаю).

Ответ

Повесь на OnCloseQuery следующее:
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
Var Res: integer; begin Res:=MessageBox(Handle, 'Были произведены изменения. Сохранить?',
'Предупреждение', MB_YESNOCANCEL or MB_ICONQUESTION);
If Res=IDCANCEL then begin // Выбрана отмена, запрещаем завершение
CanClose:=False; exit; end; If Res=IDYES then begin // Здесь сохраняем изменения MessageBox(Handle, 'Изменения сохранены', '',
MB_OK or MB_ICONINFORMATION); end; // Завершение программы
end;


Novikov Dmitry.

Вопрос

Допустим, я запускаю Delphi-прогу из c:\work\proga.exe или из c:\soft\proga.exe. Как в окно Edit'а этой же программы вставить путь, откуда она была запущена?

Ответ

edit1.Text:=paramstr(0);
Paramstr(0) — это нулевой параметр командной строки, то есть полный путь для запускаемой программы

Садыков Алексей Николаевич

ExtractFileDir(Application.ExeName)

Михаил Подгурский

Вопрос

На пустую форму ставим объект «Edit» и запускаем. Получилось, что в окошке Edit'а написано и выделено «Edit1», а если сразу начать набирать что-либо с клавиатуры надпись «Edit1» затрется новыми символами. Вопрос: как поставить выделение надписи в зависимости от введенного текста. Например, если ввести в окно Edit'а текст «проба», то его выделить, а если любой другой текст, то не выделять.

Ответ

Смотри пример:

procedure TForm1.Edit1Change(Sender: TObject);
begin
If edit1.Text='проба' then
Begin edit1.SelStart:=0; edit1.SelLength:=length(edit1.text); end;
end;


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

Вопрос

Как в Memo1 определить позицию курсора? Не указателя мыши, а курсора вида I?

Ответ

Вроде бы вот так:
procedure TForm1.Button1Click(Sender: TObject);
var
xChr, xRow, xCol: LongInt;
begin
xRow := SendMessage(Memo1.Handle, EM_LINEFROMCHAR, Memo1.SelStart, 0);
xChr := SendMessage(Memo1.Handle, EM_LINEINDEX, Memo1.SelLength, 0);
xCol := Memo1.SelStart — xChr + 1;
Label1.Caption:= IntToStr(xCol);
Label2.Caption:= IntToStr(xRow);
end;


Shadow.

Вопрос

Как в mp3 файл добавить(изменить) ID3TAG(желательно текст программы выполняющий данные операции)?

Ответ

Попробуй поискать в интернете программу Marsi MP3 Tag Editor — она написана на Дельфи, посмотри ее исходники.
А на сайте http://delphi.mastak.ru в разделе Кладовка (Готовые программы) есть MP3Renamer и MP3Namer (с исходниками).

Shadow.

Вопрос

Как в RichEdit сделать скролл на конец текста?

Ответ

with RichEdit do begin
    SelLength := 0;
    SelStart := Length(Text);
    Perform(EM_SCROLLCARET,0,0);
end;

Из конференции Delphi

Вопрос

Почему после RichEdit1.Lines.SaveToFile(name) в файле, кроме моего текста, еще всякий бред написан?

Ответ

Таким образом в RTF сохраняется информация об оформлении текста. Если сохранять нужно только текст, перед сохранением в файл добавь следующую строку:

RichEdit1.PlainText := True;

Из конференции Delphi

Вопрос

Как в RichEdit установить каретку в нужное место?

Ответ

Используйте свойства SelStart, SelLength компонента TRichEdit.
SelStart — номер первой буквы выделенного текста, SelLength — его длина. Просто переместить курсор можно, задав SelLength=0.
procedure TForm1.Button1Click(Sender: TObject); begin RichEdit1.SetFocus; RichEdit1.SelStart :=25; // переходим к 25-му символу в RichEdit1.
RichEdit1.SelLength:=0; end;

Shadow.

Вопрос

Как в TListBox пеpетаскивать итемы?

Ответ

DragMode := dmAutomatic;
{OnDragOver}
procedure TForm1.ListBox1DragOver(Sender, Source: TObject; X, Y: Integer;
    State: TDragState; var Accept: Boolean);
begin
    Accept := True;
end;

{OnDragDrop}
procedure TForm1.ListBox1DragDrop(Sender, Source: TObject; X, Y: Integer);
var
    NewIndex : Integer;
begin
    with Sender as TListBox do begin
    NewIndex := ItemAtPos(Point(X,Y), True);
     Items.Move(ItemIndex, NewIndex);
        ItemIndex:= NewIndex;
    end;
end;

Из конференции Delphi

Вопрос

Как в TMemo вставить дату в позицию каретки?

Ответ

С помощью следующего кода:

Memo1.SetSelTextBuf(PChar(DateToStr(Date)));

Из конференции Delphi

Вопрос

Как в Делфи (5-м) из своей программы запустить другую? Например: нужно запустить программу goblin.exe, находится на D:\goblin.exe. Что мне нужно сделать, чтобы запустилась именно эта конкретная программа?

Ответ

Вопрос больше относится к Win API…
Нужная Вам функция -CreateProcess, описание смотрите в Windows Programmers Refference.

Пример:

var
StartInfo:TStartUpInfo;
ProcInfo:TProcessInformation;
begin
GetStartUpInfo(StartInfo);
CreateProcess('D:\goblin.exe',nil,nil,nil,False,
CREATE_DEFAULT_ERROR_MODE or NORMAL_PRIORITY_CLASS,
nil,nil,StartInfo,ProcInfo);
end;


******

Можно проще:
uses ShellAPI;
ShellExecute(Handle,'OPEN','D:\goblin.exe',nil,nil,SW_SHOWNORMAL);

Вопрос

Скажите, пожалуйста, как в Дельфи сделать следующее: мне нужно, чтобы exe файл запускался по истечении определенного времени.

Ответ

В закладке System ставим на форму компонент TTimer. В uses добавляем ShellAPI, в процедуре OnTimer пишем:
timer1.tag := timer1.tag + 1;
if timer1.tag = 5 then
begin
shellexecute(handle,'open','d:\programma.exe',nil,nil);
end;

Вопрос

Как сохранить в reg-файле определенный ключ реестра?

Ответ

Использовать метод TRegistry.SaveKey. Для загрузки ключа TRegistry.LoadKey.

Бузуверов Михаил

Вопрос

Как сделать чтобы, в зависимости от положения переключателя (checkbox1), при закрытии формы она либо закрывалась (close) либо скрывалась (hide)?

Ответ

Вот так пойдет?
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if CheckBox1.Checked then
begin
form1.Visible:=false;
Action := caNone;
end
else
Action := caFree;
end;


Олег

Вопрос

Как в компоненте StringGrid добавить запись во вновь создаваемую строку, а не в выделенную?

var n: longint;
begin
StringGrid.RowCount:=StringGrid.RowCount+1;
StringGrid.Rows[StringGrid.RowCount-1].Clear;
n:=StringGrid.Row;
StringGrid.Cells[0,n]:=Ed1.Text;
StringGrid.Cells[3,n]:=Ed2.Text;
StringGrid.Cells[4,n]:=Ed3.Text;
StringGrid.Cells[5,n]:=Ed4.Text;
StringGrid.Cells[6,n]:=Ed5.Text;
end;

Ответ

>n:=StringGrid.Row;
вот тут ошибка.
Надо n:=StringGrid.RowCount-1;
Остальное все ОК


Из конференции Expert_FAQ

Вопрос

Как в Мемо установить карет в нyжнyю позицию?

Ответ

Вот так

with Memo do SelStart := Perform(EM_LINEINDEX, LineIndex, 0) + CharIndex;

PS: карет — это специальный указатель позиции ввода следующего символа, не путать с курсором мышки.

Из конференции Delphi

Вопрос

Есть у меня обьект Ticon, как мне в него загрузить из файла ресурсов иконку?

Ответ

Попробуйте так:

procedure LoadJPEGfromEXE;
var MyJPG : TJPEGImage; // JPEG
ResStream : TResourceStream; // Resource Stream
begin
  MyJPG := TJPEGImage.Create;
  ResStream := nil;
  try
    ResStream := TResourceStream.CreateFromID(HInstance, 1, RT_RCDATA);
    MyJPG.LoadFromStream(ResStream); // ДА! Так просто :)
    Canvas.Draw(12,12,MyJPG); // Нарисуем на Canvas, чтобы убедиться, что все работает!
  finally
    MyJPG.Free;
    ResStream.Free;
  end;
end; // end procedure


Или проще в OnCreate прописываешь:

Icon.Handle:=LoadIcon(HInstance,'MAINICON');

Краснов Кирилл

Вопрос

Имеется таблица в MS SQL, в ней поля varchar длиной 100 символов. Как правило значения поля имеют меньшую длину, и остальное место соответственно заполняется пробелами. Теперь беру квантумГрид, ставлю в нем true для опции AutoHeight, и получаю многострочные ячейки длиной именно 100 символов, т.е. с пробелами на конце, что есть очень некрасиво. Как можно убрать эти пробелы?

Ответ

По умолчанию VarChar поля не имеют хвостовых пробелов, наверное у тебя были поля Char и потом ты их превратил в VarChar, естественно, пробелы остались. Обрежь лишние пробелы один раз и все.

T'Mon

Вопрос

Как ввести текст в "чужой" Edit?

Ответ

SendMessage(EditHandle, WM_SETTEXT, 0, LParam(PChar('MyText')));

Из конференции Delphi

Вопрос

Как взять скриншот экрана и сохранить его картинкой на винт?

Ответ

Есть, как минимум, два способа:

1. имитировать нажатие клавиши Print Screen:

procedure TForm1.Button1Click(Sender: TObject);
var Clpbrd: TClipboard;
Bmp1: TBitmap;
begin
Clpbrd:=TClipboard.Create;
Bmp1:=TBitmap.Create;
try
Clpbrd.Open;
keybd_event(VK_SNAPSHOT,1,0,0); // Print Screen
Bmp1.Assign(Clpbrd);
Bmp1.SaveToFile('MyScreenPicture.bmp');
finally
Clpbrd.Close;
Bmp1.Free;
Clpbrd.Free;
end;
end;


2. захватить рисунок из девайс-контекста экрана (информация есть в хелпе Win32 SDK):

procedure TForm1.Button1Click(Sender: TObject);
var hWndScreen: HWND;
DesktopDC, MemoryDC: Integer;
hBmpPrev: Integer;
Bitmap1: TBitmap;
begin
hWndScreen:=GetDesktopWindow;
DesktopDC:=GetWindowDC(hWndScreen);
MemoryDC:=CreateCompatibleDC(DesktopDC);
Bitmap1:=TBitmap.Create;
Bitmap1.Handle:=CreateCompatibleBitmap(DesktopDC,Screen.Width,Screen.Height);
hBmpPrev:=SelectObject(MemoryDC,Bitmap1.Handle);
BitBlt(MemoryDC,0,0,Screen.Width,Screen.Height,DesktopDC,0,0,SRCCOPY);
Bitmap1.Handle:=SelectObject(MemoryDC,hBmpPrev);
Bitmap1.SaveToFile('MyScreenPicture.bmp');
ReleaseDC(hWndScreen,DesktopDC);
DeleteDC(MemoryDC);
Bitmap1.Free;
end;


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

Из конференции Expert_FAQ

Вопрос

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

Case цвет_пиксела_с_координатами(x,y) of
clWhite: команда1;
clRed: команда2;
и тд.

Как это сделать?

Ответ

Надо брать значение цвета из массива "Pixels" свойства "Canvas". Ты не написал, где у тебя картинка — в битмапе или может еще где, но свойство "Canvas" есть у всех компонентов, связанных с рисованием. Оно может быть на 3-4 уровне, но оно полюбому присутствует. Вот приблизительный кусок кода:

var
bm:TBitmap;
begin
bm:=Tbitmap.Create;
bm.LoadFromFile('имя_файла_с_картинкой');
case bm.Canvas.Pixels[x,y] of
clWhite: … ;
clRed: … ;
end;


Из конференции Expert_FAQ

Вопрос

Как включить окно CPU Window?

Ответ

Вставьте в реестр строковый ключ:


HKCU\ Software\ Borland\ Delphi\ 2.0\ Debugging\ EnableCPU=1
Соответственно, для Delphi 3 — Delphi\3.0.

Вопрос

Как внедрить dll в другое приложение?

Ответ

procedure QryName(threadID: DWord; Caller: HWND); external 'lib0.dll';

procedure TForm1.WMCopydata(var msg: TMessage); // message WM_COPYDATA;
begin
    Caption := PChar(PCopyDataStruct(Pointer(msg.LParam)).lpData);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
    ahwnd: THandle;
begin
    {Ищем по заголовку}
    ahwnd := FindWindow(nil, PChar(Edit1.Text));
    if ahwnd <> 0 then
  QryName(GetWindowThreadProcessID(ahwnd, nil), Handle);
end;

— lib0.dpr —
library lib0;

uses
Messages, Windows;

function Answer( nCode: Integer; wprm: WParam; lprm: LParam): LResult; stdcall;
type
    PMsg = ^TMsg;
var
    buffer : array [0..MAX_PATH] of Char;
    cd : TCopyDataStruct;
    msg : PMsg;
    Caller : HWND;
    AHook: HHook;
begin
    Result := 0;
    msg := PMsg(lprm);
    if (msg.Message = 0) and (msg.LParam <> 0) then
        begin
      AHook := msg.lParam;
      Caller := msg.wParam;
 cd.cbData := GetModuleFileName(0, buffer, SizeOf(buffer))+1;
    cd.lpData := @buffer;
   cd.dwData := GetCurrentThreadID;
   SendMessage(Caller, WM_COPYDATA, 0, LParam(@cd));
    UnHookWindowsHookEx(AHook);
   PostThreadMessage(GetCurrentThreadID, 0, 0, 0);
        end;
end;

procedure QryName(tid: DWord; Caller: HWND);
var
      AHook : Hhook;
begin
AHook := SetWindowsHookEx(WH_GETMESSAGE, Answer, Hinstance, tid);
 if AHook <> 0 then PostThreadMessage(tid, 0, Caller, AHook);
end;

exports
    QryName;
begin
end.

Из конференции Delphi

Вопрос

Как во время выполнения программы создать так называемый "array of const" ?

Ответ

В библиотеке Technical Information на сайте Inprise есть документ за нумером TI582D.txt, посвященный этой проблеме. Вкратце, в качестве array of const можно использовать массив типа TVarRec.

Из конференции Delphi

procedure TForm1.FormActivate(Sender: TObject);
var A: array of TVarRec;
function MakeStr(const Args: array of const): string;
const
BoolChars: array[Boolean] of Char = ('F', 'T');
var
I: Integer;
begin
Result := '';
for I := 0 to High(Args) do
with Args[I] do
case VType of
vtInteger: Result := Result + IntToStr(VInteger);
vtBoolean: Result := Result + BoolChars[VBoolean];
vtChar: Result := Result + VChar;
vtExtended: Result := Result + FloatToStr(VExtended^);
vtString: Result := Result + VString^;
vtPChar: Result := Result + VPChar;
vtObject: Result := Result + VObject.ClassName;
vtClass: Result := Result + VClass.ClassName;
vtAnsiString: Result := Result + string(VAnsiString);
vtCurrency: Result := Result + CurrToStr(VCurrency^);
vtVariant: Result := Result + string(VVariant^);
vtInt64: Result := Result + IntToStr(VInt64^);
end;
end;

begin
// создаем массив из 2 элементов
SetLength(A, 2);
// отчет идет с 0-го элемента
A[0].VType := vtInteger;
// vtInteger стоит по умолчанию
A[0].VInteger := 100;
A[1].VType := vtPChar;
A[1].VPChar := PChar('Hello');
Caption :=MakeStr(A);
end;


--Dec--

Вопрос

Есть некая фигура, нарисованная в TPaintbox (к примеру, пятиконечная звезда) как ее повращать? Как изменять скорость вращения?

Ответ

Если есть координаты x и y всех вершин, то это очень просто.
По шагам.
1. Создаем массив, который содержит координаты всех точек (удобно сделать одномерный массив типа TPoint). Это будет исходный массив.
2. СоздаJм второй такой же массив и при инициализации программы записываем туда данные из исходного.
3. Теперь немного теории: для поворота на плоскости относительно центра координат на угол L надо:
записать координаты x,y в виде матрицы-строки:
( x y )
и матрично умножить их на матрицу поворота:
( cos(L) sin(L) )
( -sin(L) cos(L) ).

В итоге имеем конечные формулы: x2 = x1*cos(L) — y1*sin(L); y2 = x1*sin(L) + y*cos(L), где x2, y2 — новые координаты, x1, y1 — старые координаты, а L — угол поворота.
Зачем создавали второй массив. Дело в том, что результат умножения — вещественный, а координаты — целые. Поэтому каждый раз придется округлять результат и в конце (после длительного вращения) получатся очень сильные искажения. Поэтому надо делать так:
Берем x,y из исходного массива (это будет x1, y1 в формулах). Делаем преобразования и результат записываем во второй массив (x2, y2).
Так пробегаем в цикле для всех точек. А потом соединяем линиями точки из второго массива.
На следующей итерации переписываем во второй массив исходный и увеличиваем угол. Делаем все тоже самое, только угол уже другой.
Т.е. получается, что мы повернули на некоторый угол, затем вернули назад, затем увеличили угол и опять повернули.
Теперь все это можно повесить на таймер.
Скорость вращения изменяется либо углом, либо интервалом таймера, хотя признаюсь, ни тот, ни другой не являются правильными — для этого существуют специальные математические преобразования, которых я не знаю.

Из конференции Expert_FAQ

Вопрос

Как вставить картинку в StatusPanel?

Ответ

Вот так:

Image1.Parent := StatusBar1;

Вопрос

Как вставить картинку в TDrawGrid?

Ответ

Вот так:

procedure TForm1.DrawGrid1DrawCell(Sender: TObject; Col, Row: Integer;
    Rect: TRect; State: TGridDrawState);
begin
    if (Sender is TDrawGrid) and
   not (gdFixed in State) then
TDrawGrid(Sender).Canvas.Draw(Rect.Left, Rect.Top,Image1.Picture.Graphic);
end;

Из конференции Delphi

Вопрос

Как вывести в edit box значение FLOAT, округленное до определенного знака после запятой? Есть 2.3914, нужно получить только один знак в дробной части (2.4)

Ответ

Существует функция FloatToStrF(n, f, k, m), где n — изображение вещественного n, f — формат (способ изображения), k — точность (ужное общее количество цифр), m — количество цифр после десятичной точки. В твоем случае на месте m ставишь «1».

Из конференции Expert_FAQ

Вопрос

Как выдвинуть дверцу CD-ROM'а?

Ответ

procedure EjectCDROM(aLetter : char);
const
AliasName = 'MyCoolCdrom';
var s : string;
begin
 s := 'open ' + aLetter + ': type cdaudio alias ' + AliasName + aLetter + ' shareable wait';
if mciSendString(PChar(s), nil, 0, 0) <> 0 then exit; // fails to open
    try
 s := 'set ' + AliasName + aLetter + ' door open wait';
      mciSendString(PChar(s), nil, 0, 0);
    finally
  s := 'close ' + AliasName + aLetter + ' wait';
      mciSendString(PChar(s), nil, 0, 0);
    end;
end;

Из конференции Delphi

Вопрос

Как вызывать из 32-битной программы 16-битные DLL?

Ответ

Hадо применять так называемые "thunks". Смотри статьи на
http://www.thedelphimagazine.com/samples/thunk/thunk95.htm

Из конференции Delphi

Вопрос

Как вызывать процедуру на событие другого контрола.

Ответ

Можно вот так:

procedure TfMain.ToolButton2Click(Sender: TObject);
begin
  Button1.Click;
end;

Но таким образом мона вызывать процедуры класса TControl…
А например для вызова этой процедуры:

Form1.Label1Click(Sender: TObject);


придется делать так:

Form1.Label1Click(Sender);

И еще, при использовании специфических процедур, таких как OnMouseMove, OnKeyPress, etc… придется передавать (желательно) дополнительные параметры типа TShiftState, X, Y — для OnMouseMove и Key — для OnKeyPress — соответственно.

Из конференции Delphi

Вопрос

Как вырубить комп с вынь2000 из своей программы? — Не понял из справки по WinAPI как получить права для этого, в 9Х получилось.

Ответ

procedure NTShutdown; var TokenHandle: Cardinal; RetLength: Cardinal; TP: TTokenPrivileges; begin OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY,
TokenHandle); if LookupPrivilegeValue(nil, 'SeShutdownPrivilege', TP.Privileges[0].Luid) then begin TP.PrivilegeCount:=1; TP.Privileges[0].Attributes:=SE_PRIVILEGE_ENABLED;
RetLength:=0; If AdjustTokenPrivileges(TokenHandle, FALSE, TP, 0, nil, RetLength) then begin If not SetProcessShutdownParameters($4FF,
SHUTDOWN_NORETRY) then begin
MessageBox(0, 'Shutdown failed', nil, MB_OK or MB_ICONSTOP); end else begin
ExitWindowsEx(EWX_FORCE or EWX_SHUTDOWN, 0); end; exit; end; end;
MessageBox(0, 'Access denied', nil, MB_OK or MB_ICONSTOP); end;

Novikov Dmitry.

Вопрос

Как выполнить команду DOS? Например,

attrib +r *.*
copy *.* a:
label a: my_disk и др.

Не заменять командами Delphi.

Ответ

WinExec('attrib +r *.*', SW_SHOW); — показать окно консоли при выполнении.

WinExec('copy *.* a:', SW_HIDE); — никаких новых окон.

WinExec('label a: my_disk', SW_MINIMIZE); — минимизировать окно консоли при выполнении.

Из конференции Expert_FAQ

Если так как написано здесь ничего не получилось, то попробуйте дописать команды так :

'command.com /C attr +r *.*'

и т.д.
Я лично возился с копированием и уменя все получилось.
Почему так: На мой взгляд, потому что WinExec предназначена для запуска програм (exe , com) файлов, а command.com с параметром /C уже для выполнения команд DOS.

Вопрос

Как делать поиск, замену и переход по строкам в TMemo?

Ответ

Поиск в ТMemo:

procedure Find(s: string);
var i: integer;
begin
for i:=0 to Memo1.Count-1 do
if pos(s,Memo1.Strings[i])>0 then
begin
Memo.Cursor.SetSelText(i, pos(s,Memo1.Strings[i]), i,
pos(s,Memo1.Strings[i])+length(s));
exit
end;
end;


Замена:
Так же, только удаляй процедурой DelSelBuff

Переход к строке x:

Memo1.Cursor.SetPosition(x,1);

Белозеров Сергей

Вопрос

Как в Delphi динамически, т.е вовремя работы программы, создать компонент? Т.е нажал, скажем копку, СОЗДАЛСЯ (не появился Visible, а создался) компонент конечно видимый, пусть Panel, но когда его создал чтобы не было надписи по середине компонента и можно было изменять программно его ширину высоту и тд.

Ответ

var P: TPanel; begin P:=TPanel.Create(self);
// self должна быть TForm P.Caption:='';
P.SetBounds(10, 10, 100, 100);
// размеры и положение P.Parent:=self;
// после этого панелька появится на форме self


Из конференции Expert_FAQ

Вопрос

Как для TPopupMenu сделать background? Т.е. чтобы у меня вместо серого фона была своя картинка, или залить серый фон другим цветом, лучше всего SkyBlue!

Ответ

Попробуй использовать библиотеку CLX(Delphi 6). Там TPopUpMenu имеет свойства Bitmap и Color.

******

Можно унаследоваться и переопределить процедуру paint (или обрабатывать сообщение wm_paint), при этом inherited лучше не использовать вообще, а компоненту поставить в конструкторе doublebuffered := true (чтобы не мелькало).

shurik

Вопрос

Как для компонента RxTrayIcon взять иконку из ImageList'a?

Ответ

ImageList1.GetIcon(0, RxTrayIcon1.Icon);

0 — индекс иконки

Из конференции Expert_FAQ править вопрос 3916

Вопрос

Допустим, у меня на форме две кнопки и PageControl c двумя вкладками (TabSheet1 и 2). Мне нужно, чтобы при нажатии на Button1 грузилась вкладка1 (TabSheet1), а при нажатии на кнопку Button2 грузилась вкладка(TabSheet2).

Ответ

Для этого в обработчике события OnClick для кнопки 01 пишем следующее:

pagecontrol1.ActivePage := tabsheet1;

Ну а для кнопки 02:

pagecontrol1.ActivePage := tabsheet2;

Герун Данил

Для этого надо просто написать:
в события onclick кнопок след:
1) tabsheet1.show;
3) tabsheet2.show;

squeeze_ms

Вопрос

Как добавить пункты в системное меню окна?

Ответ

Получить хэндл системного меню окна можно с помощью функции GetSystemMenu(). А потом добавлять вроде бы как в обыкновеное меню.

Из конференции Delphi

Вопрос

Как добавить строку в контекстное меню текстовых файлов? И как вообще с этим меню работать? Как передать имя и путь файла?

Ответ

[HKEY_CLASSES_ROOT\.txt\shell\Bred2r\command]

@="C:\\Progra~1\\Bred2\\Bred2r.exe %1"

Из конференции Expert_FAQ

Вопрос

Как дождаться завершения программы, запущенной ShellExecute?

Ответ

Вот так:
uses
ShellAPI;

procedure TForm1.Button1Click(Sender: TObject);
var
    ProcInfo: PShellExecuteInfo;
begin
    (Sender as TControl).Enabled := False;
    GetMem(ProcInfo, SizeOf(ProcInfo^));
    with ProcInfo^ do begin
      Wnd := Handle;
      cbSize := SizeOf(ProcInfo^);
      lpFile := PChar('notepad.exe');
      lpParameters := nil;
      lpVerb := 'open';
      nShow := SW_SHOW;
  fMask := SEE_MASK_DOENVSUBST or SEE_MASK_NOCLOSEPROCESS;
    end;
    try
    Win32check(ShellExecuteEx(ProcInfo));
    while not Application.Terminated and
(WaitForSingleObject(ProcInfo.hProcess, 100)=WAIT_TIMEOUT) do
    Application.ProcessMessages;
    finally
 if ProcInfo.hProcess <> 0 then CloseHandle(ProcInfo.hProcess);
        Dispose(ProcInfo);
   (Sender as TControl).Enabled := True;
    end;
end;

Из конференции Delphi

Вопрос

Как на Delphi3 можно:

1. Сделать так, чтобы когда программа выполняет длительную операцию, пользователь не мог ничего нажать на форме? И даже после окончания этой операции, если он куда-то там во время ее выполнения кликал, ничего не произошло?

2. И как сделать, извините за глупый вопрос, чтобы во время этой длительной операции курсор принял форму песочных часов? Присвоение значения Cursor формы не дает ничего, а присваивать значение Cursor каждого компонента — …

Ответ

1. Можно сделать так:

begin
Form1.Enabled:=false;
//Здесь выполняется длительная работа…
Form1.Enabled:=true;
end;

2. Сам с этим когда-то повозился :)
Screen.Cursor:=crHourGlass;

Из конференции Expert_FAQ

Вопрос

Как загрузить из ImageList иконку приложения?

Ответ

Очень просто:

ImageList1.GetIcon(Idx, Application.Icon);

Из конференции Delphi

Вопрос

Как загрузить на форму битмап в качестве фона или background'а?

Ответ

С помощью вот такого кода:

var
    Bitmap:TBitmap;
begin
Bitmap := TBitmap.Create;
    try
  Bitmap.LoadFromFile('vgr.bmp');
  Form1.Canvas.Brush.Bitmap := Bitmap;
Form1.Canvas.FillRect(Rect(0,0,Form1.width,Form1.height));
    finally
   Form1.Canvas.Brush.Bitmap := nil;
        Bitmap.Free;
end;

Забиваешь этот код в обработчик onPaint, а в onActivate делаешь form1.refresh, и тогда даже при перекрывании формы другим окном все будет нормально.

GK

Вопрос

Мне нужно загрузить файл с расширением Wav и взять из него для начала значения сигналов в единицу времени и на их основе строить графики и по полученным данным проводить расчеты… Только вот не очень у меня получается. Для начала я нашел формат Wav

({{!> http://graphics.cs.msu.su/courses/cg02b/assigns/hw-2/help/wavfmt.htm<!}} ) только вот проблема в том, что я вообще не могу понять эту таблицу и как с ней работать, как считывать данные из файла, нужные мне данные, мне ничего не понятно кроме общих слов, «от начала на столько то» а вот на сколько, и как это сколько отступить не знаю… неполучается…

Что это ch, ah, h и как с ними работать…

… Вот, что я наделал:

var Form1: TForm1;

i, i1:integer; implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);

var f:file;

buf:char;

begin

//i:=0;

assignfile(f,'1.wav');

reset(f, 1); seek(f, i);

BlockRead(f, buf, 1);

memo1.Lines.Add(buf);

closefile(f);

i:=i+1;

end;

procedure TForm1.Button2Click(Sender: TObject);

var f:file;

buf:integer;

p:^integer;

begin

//i:=0;

assignfile(f,'1.wav');

reset(f, 1);

seek(f, i1);

BlockRead(f, buf, 1);

p:=@buf;

memo2.Lines.Add(inttostr(p^));

closefile(f);

i1:=i1+1;

end;

Данные то я прочитал, только вот проблема то в том, что я явно не то читаю, что мне нужно, когда читаю по символьно, то выводит непонятно что, а когда предпологаю чтение чисел у меня всегда идут, какие-то цифры, даже там где по идее должны быть буквы… то что там указатели есть, так это я подумал может там храняться указатели на нужные мне

значения пытался их достать, глупость конечно… но раз уж набрал так пусть остается

Буду благодарен за любую помощь, можно пример кода, можно ссылочку, только чтобы уж сдвинуться с мертвой точки…

Ответ

Если подумать…

Тема вообще очень большая и примеры тебе я сейчас состряпать не смогу, но общее направление дать могу. Использовать тебе надо WinAPI, а точнее следующие разделы справки:

Waveform Audio Reference

здесь есть следующая структура

typedef struct {

WORD wFormatTag;

WORD nChannels;

DWORD nSamplesPerSec;

DWORD nAvgBytesPerSec;

WORD nBlockAlign;

WORD wBitsPerSample;

WORD cbSize;

} WAVEFORMATEX;

Из нее можно узнать, сколько байт в секунду (nAvgBytesPerSec, wBitsPerSample), частоту дискретизации (nSamplesPerSec).

Далее надо использовать следующие функции:

HMMIO mmioOpen(

LPSTR szFilename,

LPMMIOINFO lpmmioinfo,

DWORD dwOpenFlags

); //открываем файл

LONG mmioRead(

HMMIO hmmio,

HPSTR pch,

LONG cch

); //читаем блок данных из файла

Все это есть в файле справки «Microsoft Multimedia Programmer's Reference»

Вот, это основное, дальше придется самому.

Из конференции Expert_FAQ

Вопрос

Есть код для подсчета всех файлов в директории (по маске '*.*'). Как задать маску для файлов, не имеющих расширений?

Ответ

из справки по F1:

var SearchRec:TSearchRec; Attr,Found,Count: Integer; Path:string; begin Count:=0; Atr:=faAnyFile AND (not (faDirectory OR faVolumeID)); //если каталоги не считаем path:='c:\test\*.*'; Found := FindFirst(Path, Attr, SearchRec); while Found = 0 do begin inc(count); Found := FindNext(SearchRec); end; FindClose(SearchRec); writeln('total files: ',count); end;

Файл без расширения — это файл, оканчивающийся на точку — маска '*.'.

Из конференции Expert_FAQ

Вопрос

Как закрывать программу при нажатии на клавишу Esc?

Ответ

Здесь можно придумать несколько способов:
1. Простой:
— ставите обычную кнопку или BitBtn (палитра Additional)
— назначаете ей параметр Cancel равный True
— делаете ей такой обработчик события OnClick:
Close;
— все: теперь при нажатии Escape будет выполняться код OnClick, а именно — закрытие формы.

2. Посложнее:
— у формы есть параметр KeyPreview: делаете его True.
— пишете обработчик события ДЛЯ ФОРМЫ OnKeyPress:
if (key = #27) then close;
— дело в том, что у клавиши Escape код 27, а т.к. переменная Key поступает в обработчик события типа Char, то с помощью решетки мы преобразуем число 27 в символ с кодом 27.

3. Самый сложный — будем обрабатывать сообщения (это не так уж и сложно):
— в объявлении класса вашей формы (по умолчанию TForm1) в разделе
private добавляете:
procedure ProcMess(var Msg: TWMKEYUP);
message WM_KEYUP;

этим мы определяем процедуру, которая будет реагировать на сообщение WM_KEYUP, т.е. отпущена клавиша
— в самой процедуре пишем (шаблон нам в этом случае не делают, поэтому в любом месте программы сами пишите следующее):
procedure TForm1.ProcMess(var Msg: TWMKEYUP);
begin
if (msg.CharCode = 27) then close;
end;

т.е. если код отпущенной клавиши равен 27 (Escape), то выполняем закрытие формы.

PS: Если вы не знаете, как писать обработчик события, то это значит: для компонента, для которого вы хотите описать событие, в закладке Events Инспектора Объектов ищете, например, OnClick и щелкаете 2 раза мышью на пустой (пока что) строке напротив надписи OnClick — получите шаблон процедуры, куда можете вписать свой код (или мой, который я привел здесь в качестве примеров).

Герун Данил

Вопрос

Как закрыть внешнюю программу?

Ответ

Hапример, Блокнот можно закрыть так:

procedure TForm1.Button1Click(Sender: TObject);
var
    phandle : HWND;
begin
    phandle := FindWindow('Notepad', nil);
    if phandle = 0 then
   RaiseLastWin32Error;
    SendMessage(phandle, WM_CLOSE, 0, 0);
end;

Из конференции Delphi

Вопрос

Как закрыть окно сеанса MS Dos после завершения выполнения процесса (createprocess)

Ответ

Чтобы выяснить, работает ли еще программа, используйте GetProcessTimes, параметр lpExitTime.

Для принудительного завершения процесса — TerminateProcess.

Из конференции Expert_FAQ

Вопрос

Как записать в файл несколько TImage?

Ответ

procedure TForm1.Button1Click(Sender: TObject);
begin
with TFileStream.Create(FileName,fmCreate or fmOpenWrite) do begin
    WriteComponentRes('IMAGE1', image1);
    WriteComponentRes('IMAGE2', image2);
        Free;
    end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
    Image1.Free;
    Image2.Free;
    RegisterClass(TImage);
    Image1 := TImage.Create(Self);
    Image2 := TImage.Create(Self);
  with TFileStream.Create(FileName, fmOpenRead) do begin
  ReadComponentRes(Image1);
  ReadComponentRes(Image2);
        Free;
    end;
    Image1.Parent:= Self;
    Image2.Parent:= Self;
    UnregisterClass(TImage);
end;

Из конференции Delphi

Вопрос

Как запретить автодобавление новой записи в DBGrid при нажатии клавиши вниз, когда стоишь на последней записи?

Ответ

Добавь в событие "BeforeInsert"=компонентов TTable=следущее:

procedure=TForm1.Tbable1BeforeInsert(DataSet:=TDataSet);
begin
    Abort;=={вот это}
end;

Это перехватывает нажатие клавиш и проверяет на конец данных в таблице:

procedure=TForm8.DBGrid1KeyDown(Sender:=TObject;=var=Key:=Word;=Shift:=TShiftState);
begin
  if=(Key===VK_DOWN)=then
   begin
   TTable1.DisableControls;
    TTable1Next;
     if=TTable1.EOF=then Key=:==0
       else TTable1.Prior;
        TTable1.EnableControls;
    end;
end;

Кирилл Краснов

Вопрос

Как запретить копирование конкретного файла или группы файлов?

Ответ

Можно написать прогу, которая будет постоянно сидеть в памяти и не выпускать файлы из-под своего контроля, не давая никакого доступа к ним другим программам, в том числе и копирующей. Делается это так:

var

Form1: TForm1;

fs: TFileStream; //через этот поток мы будем работать с файлом. Для нескольких файлов — несколько потоков.

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);

begin

fs:=TFileStream.Create('D:\gigi.txt', fmOpenRead, fmShareDenyNone); //вешаем ограничение. Теперь никто не будет трогать

//файл

end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);

begin

fs.Free; //Снимаем ограничение.

end;

Естественно, вместо D:\gigi.txt — твой файл.

Из конференции Expert_FAQ

Вопрос

Есть проблема:

Пытаюсь выполнить .bat файл, в результате которого данные либо садятся в Оракл без ошибок, либо создается файл с ошибками… Необходимо заголовку метки передавть состояние загрузки — либо все ок либо есть ошибки (создался файл .bad).

Как подождать пока .bat файл закончит свою работу, а уже потом проверять наличие файла ошибок? класс cmd программа не восприняла… имя заголовка может быть разным (заранее неизвестным)…И еще вопрос — можно ли самому формировать заголовок запускаемого окна командной строки (в данном случае)?

Ответ

Если я правильно понял то надо при определенных условиях выполнить один bat файл и дождаться пока он завершиться. Если так то вот процедура которая это делает:

Function FssRunWait(Const FileName,CmdLine:
String;
Show:
integer = SW_SHOWNORMAL):
Integer;
var StartupInfo : TStartupInfo;
ProcessInfo : TProcessInformation;
Res : Cardinal;
begin FillChar(StartupInfo,Sizeof(StartupInfo),#0);
StartupInfo.cb:=Sizeof(StartupInfo);
StartupInfo.dwFlags:=STARTF_USESHOWWINDOW;
StartupInfo.wShowWindow:=Show;
if (FileName = '') then Result:=FssBoolToInt(CreateProcess(nil,PChar(CmdLine),nil,nil,false,CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS,nil,nil,StartupInfo,ProcessInfo))
else Result:=FssBoolToInt(CreateProcess(nil,PChar(FileName+' '+CmdLine),nil,nil,false,CREATE_NEW_CONSOLE
or NORMAL_PRIORITY_CLASS,nil,nil,StartupInfo,ProcessInfo));
if (Result = 0) then Exit else begin CloseHandle(ProcessInfo.hThread);
WaitforSingleObject(ProcessInfo.hProcess,INFINITE);
GetExitCodeProcess(ProcessInfo.hProcess,Res);
Result:=Res;
CloseHandle(ProcessInfo.hProcess);
end;
end;


Из конференции Expert_FAQ

Вопрос

Написал некую программу (на Delphi5), которая запускает внешнюю программу (консольная, написанная не мной, которая выполняет свою задачу и закрывается сама) в скрытом режиме (SW_HIDE). Работая в Win2000 замечаю, что если в диспетчере задач «подправить» приоритет внешней программы на «высокий», она заканчивает свою работу заметно быстрее. Как мне запускать внешнюю программу сразу с высоким приоритетом?

Ответ

Предлагаю Вашему вниманию пример, который изменяет приоритет приложения. Изменение приоритета следует использовать с осторожностью, так как присвоение слишком высокого приоритета может привести к медленной работе остальных программ и системы в целом. См. Win32 help for SetThreadPriority() function.
Пример: procedure TForm1.Button1Click(Sender: TObject);
var ProcessID : DWORD;
ProcessHandle : THandle; ThreadHandle : THandle;
begin
ProcessID := GetCurrentProcessID; ProcessHandle := OpenProcess(PROCESS_SET_INFORMATION, false, ProcessID);
SetPriorityClass(ProcessHandle, REALTIME_PRIORITY_CLASS); ThreadHandle := GetCurrentThread;
SetThreadPriority(ThreadHandle, THREAD_PRIORITY_TIME_CRITICAL); end;

Shadow.

Вопрос

Хочу написать такой код: берем текст (путь к файлу) из TextEdit и запускаем указанный файл. В результате запуска программа выдает ошибку. Подозреваю, что из edit текст копируется как string, а в параметрах запуска ShellExecute требуется PChar. Помогите пожалуйста разобраться или предложите более простой выход из этой ситуации. procedure TForm1.bbRunClick(Sender: TObject); var h:hWnd; i:byte; begin ShellExecute(h,'open',edit1.text,nil,'',SW_RESTORE); end; end;

Ответ

procedure TForm1.bbRunClick(Sender: TObject);
var h:hWnd;
i:byte;
begin
ShellExecute(h,'open',PChar(edit1.text),nil,SW_RESTORE);
end;
end;
winexec('путь', SW_HIDE); Или SW_SHOW.

Вопрос

Есть роцедура. Ее надо запустить сочетанием клавиш [CTRL]+[F].

Ответ

На форму бросаешь TActionList, на нем кликаешь мышой дважды, там давишь кнопку "New Action", выбираешь создавшийся Action1, в инспекторе объектов задаешь ему нужную комбинацию клавиш в свойстве ShortCut, а затем дважды щелкаешь на Action1 и увидишь в коде пустой обработчик OnExecute — там и пиши свою процедуру, которую "надо запустить сочетанием клавиш [CTRL]+[F]".

Michael Uskoff

Вопрос

Как запустить процесс с правами другого пользователя?

Ответ

procedure TForm1.Button1Click(Sender: TObject);
var
   si: STARTUPINFOW;
   pif: PROCESS_INFORMATION;
   res: Bool;
   s: string;
begin
   //инициализация StartUpInfoW
   si.cb := SizeOf(startupinfow);
   si.dwFlags := STARTF_USESHOWWINDOW;
   si.wShowWindow := SW_SHOWDEFAULT;
   si.lpReserved := nil;
   si.lpDesktop := nil;
   si.lpTitle := 'Консоль';

// запуск CreateProcessWithLogonW…
:= CreateProcessWithLogonW('Security', 'ArViCor', 'test', LOGON_WITH_PROFILE,
  'c:\win2kas\system32\regedt32.exe', nil
 , CREATE_DEFAULT_ERROR_MODE, nil, nil, si, pif);
   if booltostr(res) = '0' then
   begin
//если возникла ошибка, то покажем ее код
//этот код можно 'перевести' с помощью 'net helpmsg <код ошибки>'
//в командной строке
  str(GetLastError, s);
ShowMessage('CreateProcessWithLogonResult: ' + booltostr(res) + #10 +
   'GetLastError: ' + s);
   end;
end;

Кирилл Краснов

Вопрос

Версия языка: Delphi 6.0

Как заставить GroupBox1 прорисовать на форме свой Caption неактивным цветом? GroupBox1.Enabled:=FALSE не помогает. Хотя если то же самое проделать с Label1 или Edit1, то все получается.

Ответ

GroupBox1.Font.color:=clInactiveCaption;

Гавриш Дмитрий

Вопрос

Как заставить MediaPlayer крутить один и тот же клип?

Ответ

procedure TForm1.WMUser1(var msg:TMessage);// message WM_USER+1;
begin
    with MediaPlayer1 do begin
        Previous;
        Notify := True;
        Play;
    end;
end;

procedure TForm1.MediaPlayer1Notify(Sender: TObject);
begin
if (Sender as TMediaPlayer).NotifyValue = nvSuccessful then PostMessage(Handle, WM_USER+1, 0, 0);
end;

Из конференции Delphi

Вопрос

Как заставить мигать кнопку приложения на AppBar?

Ответ

procedure TForm1.Timer1Timer(Sender: TObject);
begin
    FlashWindow(Application.Handle, True);
end;

Leonid Troyanovsky

Вопрос

Что нужно сделать для того, чтобы программа, написанная в DELPHI 5 и работающая с базами данных, работала на других компьютерах? Предполагаю, что нужно перекинуть кое-какие библиотеки, но какие и куда?

Ответ

Используется ли в программе BDE? В любом случае, можно:

  1. Создать инсталляционный пакет, при помощи, например InstallShield(наилучшее решение).

  2. Hе использовать его. В этом случае нет универсального решения. Оно будет варьироваться в зависимости от использования BDE в локальном или серверном режиме, для доступа к Paradox- или DBF-таблицам, использования локального SQL, версии BDE, и так далее.

    Ниже приведен пример для такого варианта: пятая версия BDE, локальные таблицы, без использования локального SQL, стандартная кодировка ANSI. Hужно добавить следующие файлы из папки BDE к вашему исполняемому модулю: blw32.dll, idapi32.dll, idr20009.dll, idpdx32.dll для Paradox-таблиц или iddbas32.dll для DBF-таблиц, bantam.dll, charset.cvb, usa.btl Доступ к таблицам надо настроить не через псевдонимы (alias'ы), а через пути в файловой системе. В идеале все таблицы храните в папке программы, тогда достаточно только указать имя таблицы без пути. Приготовленный таким образом дистрибутив должен запуститься на любой машине без необходимости инсталляции BDE, максимально устойчив и нечувствителен к смене имен папок, переинсталляции системы, порче реестра, влиянию других BDE-приложений.

    shadow

    Вопрос

    Как из Delphi4 подключиться к линуксовому серверу MySQL в локальной сети?

    Ответ

    Есть такая библиотека Zeos Access
    (http://www.zeoslib.org/).
    Позволяет работать напрямую с MySQL, IB, PostgreSql, MS SQL, Oracle8. Есть версии для D3-D6 и для kylix.

    Igor A. Rumiantcev

    Вопрос

    Как из dll узнать узнать полный путь к этой dll?

    Ответ

    function GetModuleFileNameStr(Instance: THandle): String;
    var
        buffer : array [0..MAX_PATH] of Char;
    begin
        GetModuleFileName( Instance, buffer, MAX_PATH);
        Result := buffer;
    end;

      GetModuleFileNameStr(Hinstance); // dll name
       GetModuleFileNameStr(0); // exe name

    Leonid Troyanovsky

    Вопрос

    Версия языка:7

    Имеется две стандартные процедуры нажатия клавиш 1 и 2, как мне из одной процедуры вызвать другую? Если можно, то пример пожалуйста.

    Ответ

    procedure TForm1.Button1Click(Sender:TObject);

    begin

    ShowMesage('Первая кнопень');

    end;

    procedure TForm1.Button2Click(Sender:TObject);

    begin

    Button1Click(self);

    end;

    Из конференции Expert_FAQ

    Вопрос

    Как из программы закрыть активное окно, даже если оно не является окном моего приложения?

    Ответ

    uses Windows, Messages;
    var HWinToClose: HWND;
    begin HWinToClose := FindWindow('', 'Заголовок нужного окна');
    SendMessage(HWinToClose, WM_CLOSE, 0, 0);
    end;


    Из конференции Expert_FAQ

    Вопрос

    Как из программы переключить раскладку клавиатуры?

    Ответ

    Используя функцию ActivateKeyboardLayout(). Хотя некоторые считают, что использование этой функции — плохой тон.

    Из конференции Delphi

    Вопрос

    Буду очень благодарен, если вы объясните мне как я могу из своей програмки запустить exe'шный файл.

    Ответ

    Есть два варианта.

    первый:

    ShellExecute(nil, nil, PChar(«d:\MyExe.exe»), nil,PChar(«d:\WorkingDirectory»), SW_SHOW);

    тут ты просто вызываешь на выполнение, можно и не ехешник, тогда откроется умолчательное приложение (например Word для .doc файла)

    второй:

    тут возможностей много больше, например можно дождаться завершения

    // Запуск архиватора. procedure RunExtern(ComStr: String); //ComStr — путь до ехешника var SI: TStartupInfo; PI: TProcessInformation; begin // Готовимся к запуску FillChar(SI, 0, sizeof(SI)); SI.cb := sizeof(SI); SI.dwFlags:= STARTF_USESHOWWINDOW; SI.wShowWindow:=SW_HIDE; // SW_SHOW — чтобы окно было видно на экране // SW_HIDE — чтобы окно было НЕ видно на экране // Запускаем архиватор if(CreateProcess(nil, PChar(ComStr), nil, nil, false, CREATE_DEFAULT_ERROR_MODE, nil, PChar(ComStr), // тут можно указать рабочий каталог программы SI, PI)) then begin // Если удачно запустился, сразу грохаем описатель потока… CloseHandle(PI.hThread); // ----------------------------// этот кусок для ожидания завершения программы // иначе просто нужно убрать все от сиз пор… // и ждем, до завершения или 20 секунд, чтобы изменить интервал // — смотри число ниже. Чтобы ждать бесконечно (т.е. пока не // завершится) вместо числа INFINITE. if(WaitForSingleObject(PI.hProcess, 20000) = WAIT_TIMEOUT) then //ждем begin // не дождались, будем терминировать процесс… ShowMessage('Ошибка ожидания.'); TerminateProcess(PI.hProcess, 1); end; // и до сих пор… // — CloseHandle(PI.hProcess); // Закрываем описатель потока. end else ShowMessage('Ошибка запуска…'); end;

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

    Из конференции Expert_FAQ

    Вопрос

    Можно ли из одной программы спрятать другую (визуально)? То есть чтобы убралось окно (но не закрылось) и исчезла кнопка на таскбаре?

    Ответ

    Вот пример подобной программы:

    program Project;
    {$APPTYPE CONSOLE}
    uses Windows;
    var
        Wnd: HWND;
    begin
    // Здесь заменить строкой заголовка вашего запущенного блокнота
    Wnd:=FindWindow(nil, 'Безымянный — Блокнот');
        if Wnd>0 then
        begin
      WriteLn('It is going to hide an application window');
      WriteLn('Press "Enter" to continue');
            ReadLn;
      ShowWindow(Wnd, SW_HIDE);
      WriteLn('The application window is unvisible.');
      WriteLn('Press "Enter" to continue');
      ReadLn;
      ShowWindow(Wnd, SW_SHOW);
      WriteLn('Now the application window is already visible.');
      WriteLn('Press "Enter" to finish');
            ReadLn;
        end else
        begin
    WriteLn('The application window was not found');
        end;
    end.

    Данная программа является консольным приложением.

    Novikov Dmitry

    Вопрос

    Как избежать повторного запуска моего приложения?

    Ответ

    type
      TForm1 = class(TForm)
          Memo1: TMemo;
      procedure FormCreate(Sender: TObject);
      private
      { Private declarations }
    procedure WMCopyData(var msg: TMessage); message WM_COPYDATA;
      public
          { Public declarations }
      end;

    var
        Form1: TForm1;

    implementation

    {$R *.DFM}

    uses
        checkinst;

    procedure TForm1.FormCreate(Sender: TObject);
    var
        h : HWND;
    begin
    h := SetUniqueUID(Handle, 123456); // назначаем уникальный идентификатор
        if h <> Handle then
            begin
    SendString(h, GetCommandLineStr, Handle, 0);
      ActivatePrevInstance(h);
       Halt;
            end;
    end;

    procedure TForm1.WMCopyData;
    begin
      Memo1.Lines.CommaText := PChar(PCopyDataStruct(msg.LParam).lpData);
    end;

    ----------checkinst.pas------------
    unit checkinst;

    interface

    uses
        Windows, Messages, Sysutils;

    function SetUniqueUID(ahwnd: HWND; uid: DWord): HWND;
    procedure ActivatePrevInstance(ahwnd: HWND);
    procedure SendString(ahwnd:HWND; const s: String; aWParam: WParam; dwData:DWord);
    function GetCommandLineStr: String;

    implementation

    function SetUniqueUID(ahwnd: HWND; uid: DWord): HWND;
    var
        ClassName: array [0..255] of Char;
    begin
     GetClassName(ahwnd, ClassName, SizeOf(classname));
        Result := FindWindowEx(0, 0, ClassName, nil);
        while (Result <> 0) do
       if GetProp(Result, 'UID') = uid then
           Exit
            else
      Result := FindWindowEx(0, Result, ClassName, nil);
        SetProp(ahwnd, 'UID', uid);
        Result := ahwnd;
    end;

    procedure ActivatePrevInstance(ahwnd: HWND);
    var
        h : HWND;
    begin
        h := GetWindowLong(ahwnd, GWL_HWNDPARENT);
        if IsIconic(h) then ShowWindow(h, SW_RESTORE);
        SetForegroundWindow(h);
    end;

    procedure SendString(ahwnd:HWND; const s: String; aWParam: WParam; dwData:DWord);
    var
        cds: TCopyDataStruct;
    begin
        cds.cbData := Length(s)+1;
        cds.lpData := Pointer(s);
        cds.dwData := dwData;
     SendMessage(ahwnd, WM_COPYDATA, aWParam, LParam(@cds));
    end;

    function GetCommandLineStr: String;
    var
        i : Integer;
    begin
        for i := 0 to ParamCount do
             Result:= Result + ' ' +AnsiQuotedStr(ParamStr(i), '"');
    end;

    -----------EOF checkinst.pas--------------

    Leonid Troyanovsky

    Вопрос

    Как извлечь полное содержимое канвы какого-либо обекта если его часть находится за пределами экрана?

    Ответ

    см. Unit Controls;

    procedure TWinControl.PaintTo(DC: HDC; X, Y: Integer);

    Из конференции Expert_FAQ

    Вопрос

    Как издать звук через PC Speaker?

    Ответ

    // Для WinNT вызов функции из ОС, для Win9x прямое обращение к портам

    Procedure BeepEx(Freq: Word; Duration: Integer);
    var
        Ver: TOsVersionInfo;
    begin
        Ver.dwOSVersionInfoSize := SizeOf(Ver);
        GetVersionEx(Ver);
     if Ver.dwPlatformId = VER_PLATFORM_WIN32_NT then
          Windows.Beep(Freq, Duration)
        else begin
            asm
          movzx ecx, Freq
    mov eax, 1193180 // тактовая частота
          sub edx, edx
     div ecx // преобразование частоты в делитель
          mov ecx, eax
          mov al,0b6H
    out 43H,al // управляющие слово
        mov al,cl
    out 42h,al // младший байт делителя
        mov al,ch
    out 42h,al // старший байт делителя
        in al,61H
         or al,03H
        out 61H,al // включить звук
            end;
     sleep(Duration); // пауза на время звучани
            asm
       in al,61H
       and al,0fcH
    out 61H,al // выключить звук по окончанию Duration
            end;
        end;
    end;

    Из конференции Delphi

    Вопрос

    Как изменить разрешение экрана из своей программы?

    Ответ

    Рекомендую копнуть в сторону DirectX откроешь для себя много нового. Для простоты — возьми DelphiX компоненты
    Пример:
    Установим видеорежим 640x480x8 {используем DirectX headers от JEDI}

    procedure TForm1.Button1Click(Sender: TObject);
    var
        DD : IDirectDraw;
        DD4 : IDirectDraw4;
        hr : HRESULT;
    begin
        hr := DirectDrawCreate(nil, DD, nil);
        if(hr = DD_OK) then
        begin
       DD.QueryInterface(IID_IDirectDraw4,DD4);
    DD4.SetCooperativeLevel(Self.Handle, DDSCL_EXCLUSIVE or DDSCL_FULLSCREEN);
       DD4.SetDisplayMode(640,480,8,0,0);
       //DD4.RestoreDisplayMode;
        end;
    end;

    то же используя компонент DelphiX

    procedure TForm1.Button1Click(Sender: TObject);
    begin
        DXDraw1.Display.Width := 640;
        DXDraw1.Display.Height := 480;
         DXDraw1.Display.BitCount := 8;
     DXDraw1.Options := DXDraw1.Options + [doFullScreen];
        DXDraw1.Initialize;
    end;

    Aleksey Rykov

    Вопрос

    Как изменить свойства текста (то есть жирный или курсив, выравнивание в ячейке) в ячейке TStringGrid?

    Ответ

    procedure TForm1.TotalGridDrawCell(Sender: TObject;
    Col, Row: Integer;
    Rect: TRect;
    State: TGridDrawState);
    begin //Determine appearance of individual
    cells if gdSelected in State then TotalGrid.Canvas.Brush.Color:= clHighlight
    else if gdFixed in State then TotalGrid.Canvas.Brush.Color:= clBtnFace
    else TotalGrid.CAnvas.Brush.Color:= clWindow;
    if gdFocused in State then begin TotalGrid.Canvas.Font.Color:= clWhite;
    TotalGrid.Canvas.DrawFocusRect(Rect);
    end
    else TotalGrid.Canvas.Font.Color:= clBlack;
    //Display left or right justified and/or Bold if (Row = 0)
    or (Col = 0) or (TotalGrid.Cells[Col, Row] = '')
    then begin TotalGrid.Canvas.Font.Style:= [fsBold];
    TotalGrid.Canvas.TextRect(Rect, Rect.Left, Rect.Top, TotalGrid.Cells [Col, Row]);
    end else begin TotalGrid.Canvas.Font.Style:= [];
    TotalGrid.Canvas.TextRect (Rect, Rect.Right — Canvas.TextWidth(TotalGrid.Cells[Col, Row]), Rect.Top, TotalGrid.Cells [Col, Row]);
    end;
    end;


    Из конференции Expert_FAQ

    Вопрос

    Как изменять мышкой размеры формы с borderstile bsNone?

    Ответ

    Лови сообщение WM_NCHITTEST и сам подсовывай ему нужные параметры HT*, в зависимости от координат мыши.

    Из конференции Expert_FAQ

    Вопрос

    Как использовать DirectX в своей программе?

    Ответ

    Модули для работы с DirectX находятся на Delphi Super Page, в пакете DelphiX. Также на http://www.geocities.com/SiliconValley/1142/ лежaт модули для работы с DirectSound. Информацию по программированию DirectX можно взять на MSDN и в книге Чарльза Калверта "Delphi 2: Энциклопедия пользователя".
    Самая прелесть, и забыта:
    http://www.yks.ne.jp/~hori/index-e.html — DelphiX by Hiroyuki Hori — лучший набор инструментов для работы с DirectX
    Обидно за Хироюки, вроде как первый был. Жаль Хирюки и за то что его (вернее его проекта) уже нет. Хотя можно взять более новые компоненты (вернее модули) для DirectX с сайта проекта JEDI-Graphics
    http://www.crazyentertainment.net
    Из конференции Delphi

    Вопрос

    Как использовать OpenGL в своей программе?

    Ответ

    Модули для работы с OpenGL можно взять на
    http://www.signsoft.com/opengl. Информацию — на
    http://www.opengl.org.
    Также есть книга Ю. Тихомирова "OpenGL: программирование трехмерной графики".
    Еще загляните на
    http://reality.sgi.com/mjk за примерами и http://www.scitechsoft.com за библиотекой MesaGL.

    Из конференции Delphi

    Вопрос

    Как использовать в Дельфи API фyнкции?

    Ответ

    Как это ни странно, вызывать их. предварительно заюзав (добавть в uses) модуль windows.
    Если быть совсем точным — вызвать, предварительно подключив модуль, в котором данная функция описана (это может быть windows, activex, shellapi и т.д.). Hайти модуль поможет клавиша F1 на имени функции.
    Если функция не нашлась — то попробовать сделать поиск в папке с исходными текстами Дельфи.
    Если функция не нашлась — есть шанс, что в этой версии Дельфи она не описана. В этом случае надо поискать "заголовочный файл" (API header file) в интернете. Огромная коллекция их находится на сайте
    www.delphi-jedi.org/.

    Если не помогло и это — придется взять описание функции из документации производителя данного API (обычно оно на С) и самому сделать ее обьявление, так же, как это сделано в windows.pas, только в своем модуле.

    Сергей Кабиков

    Вопрос

    Как использовать в качестве обработчика сообщения обычную процедуру, а не метод объекта?

    Ответ

    У этой процедуры должен быть еще один дополнительный параметр.
    В метод класса кpоме паpаметpов, обьявленных в заголовке, пеpедается еще паpаметp Self

    procedure MyRegularProc(ASelf, Sender: TObject);
    begin
     ShowMessage(ASelf.ClassName + ' ' + Sender.ClassName);
    end;

    procedure TForm1.Button1Click(Sender: TObject);
    var
        amethod: TMethod;
    begin
        amethod.Code := @MyRegularProc;
        amethod.Data := Self;
        Button1.OnClick := TNotifyEvent(amethod);
    end;

    Leonid Troyanovsky

    Вопрос

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

    Ответ

    Посмотрите исходники компонента TRegExpr :

    http://anso.virtualave.net/regexpr.zip- сам компонент

    http://anso.virtualave.net/regexpru.zip- русский хелп

    Из конференции Expert_FAQ

    Вопрос

    Как использовать свои курсоры в программе?

    Ответ

    {$R CURSORS.RES}

    const
        crZoomIn = 1;
        crZoomOut = 2;

    Screen.Cursors[crZoomIn] := LoadCursor(hInstance, 'CURSOR_ZOOMIN');
    Screen.Cursors[crZoomOut] := LoadCursor(hInstance, 'CURSOR_ZOOMOUT');

    С вашей программой должен быть слинкован файл ресурсов, содержащий соответствующие курсоры.

    Из конференции Delphi

    Вопрос

    Как использовать функцию ShowMessageFmt, с примером.

    Ответ

    ShowMessageFmt('This is %s.'#13'Handle: %.8x '#13'WindowProc: %p', [Caption, Handle, @WindowProc]);

    %s — вместо нее подставляется первый параметр из [], приведенный к типу String

    %.8x — подставляется целое, переведенное в 16-ричную систему, дополненное слева нулями до 8-ми цифр

    %p — подставляется указатель

    Из конференции Expert_FAQ

    Вопрос

    Как исправить проблемы с вызовом помощи при одновременно стоящих Delphi 1 и Delphi 2?

    Ответ

    В реестре убейте из секции HKLM\SOFTWARE\Microsoft\Windows\Help все, что равно "…\help".
    Изменив соответствующие пути, импортируйте в реестр следующий reg-файл:

    REGEDIT4

    [HKEY_LOCAL_MACHINE\ SOFTWARE\ Microsoft\ Windows\ CurrentVersion\ AppPaths\ delphi32.exe]
    @="C:\\DELPHI2\\BIN\\delphi32.exe"
    "Path"="C:\\DELPHI2\\HELP"

    Анатолий Подгорецкий

    Вопрос

    Как контрол может сам себя разрушить?

    Ответ

    TMyWinControl = class(TWinControl)
    private
     procedure WMuser1(var msg: TMessage); message WM_USER+1;
        …
    public
        procedure Release;
        …
    end;

    procedure TMyWinControl.WMuser1;
    begin
        Free;
    end;

    procedure TMyWinControl.Release;
    begin
        PostMessage(Handle, WM_USER+1, 0, 0);
    end;

    Из конференции Delphi

    Вопрос

    Как корректнее завершать приложение — Terminate или MainForm.Close?

    Ответ

    Terminate очень грубый метод. Если вызывать Application.Terminate, то не сработают обработчики OnCloseQuery, OnClose главной формы.

    Из конференции Delphi

    Вопрос

    Мне надо сохранить содержимое экрана ,например, в bmp-ху. Все нормально сохраняется, если на экране не идет фильм, тогда сохраняется просто черный экран. (Даже если при просмотре фильма нажать ПринтСкрин, все равно сохранится черный экран). Это из-за аппататного ускорения. Можно это как-то обойти или отключть это ускорение?

    Ответ

    Ты, поди, еще BitBlt с GetDC(GetDesktopWindow) делаешь? Тебе, естественно, копируется битмапка с цветом, близким к черному (не $xx000000). Так реализованы в DirectX Layer'ы.

    Чтобы не перерисовывать тормозной Device Context там пиксели одного и того же цвета (как раз того, который ты получил на битмапке) подменяются драйвером на пиксели Layer'а. Поэтому RTFM MSDN, Video Capture, как минимум.

    Из конференции Expert_FAQ

    Вопрос

    Какое событие надо описать, чтобы при наведении на какую-нибудь кнопку на ней менялся рисунок? Или лучше сделать это для Image?

    Ответ

    В Delphi5 — OnMouseMove // Меняет надпись на кнопке при наведении мышиного курсора на кнопку
    procedure Tf_inp.BitBtn1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
    begin
    TBitbtn(sender).caption:='***';
    end;

    ******

    Лучше унаследоваться и определить процедуры, реагирующие на сообщения CM_MOUSEENTER и CM_MOUSELEAVE,
    Например:
    procedure CMMouseEnter(var Message: TMessage);
    message CM_MOUSEENTER;
    подробности — см. в исходниках VCL

    shurik

    Вопрос

    Как мне запрограммировать непрямоугольную форму, например, как у Norton CrashGuard, в форме щита?

    Ответ

    Используйте функцию SetWindowRgn()

    Из конференции Delphi

    Вопрос

    Как мне запустить какую-нибудь программу? А как подождать, пока эта программа не отработает? Как выяснить, работает ли программа или уже завершилась? Как принудительно закрыть выполняющуюся программу?

    Ответ

    WinExec() или ShellExecute. Первая оставлена для совместимости с Win 3.1, у второй к тому же больше возможностей.

    uses
        ShellApi;

    ShellExecute(Handle,'Open','c:\path\prog.exe',nil,nil,SW_SHOWNORMAL)

    Последний параметр функции описан в Win32.hlp

    CreateProcess() в параметре process info возвращает handle запущенного процесса. Вот и делаешь
    WaitForSingleObject(pi.hProcess, INFINITE);

    (Win16) Delay можно взять из rxLib.

    handle := WinExec(…);
    if handle >= 32 then
        while GetModuleUsage(handle) > 0 do
            Delay( nn );
    else
      raise …

    Чтобы выяснить, работает ли программа, используйте GetProcessTimes(), параметр lpExitTime.
    (Win32) Для принудительного завершения процесса используйте TerminateProcess.
    (Win16) (RR): Hадо послать программе сообщение WM_QUIT:

    Handle := Winexec(App, 0);
    PostMessage(Handle, WM_QUIT, 0, 0);

    Из конференции Delphi

    Вопрос

    Как мне можно узнать путь к своей программе?

    Ответ

    Вот так:

    PathPrg:=ExtractFilePath(Application.ExeName);
    или
    PathPrg := ExtractFilePath(ParamStr(0));

    Из конференции Delphi

    Вопрос

    Как мне перекодировать строки из Win-кодировки в Dos-кодировку и наоборот?

    Ответ

    CharToOEM, OEMToChar, CharToOEMBuff, OEMToCharBuff.

    1. if S <> '' then CharToOem(PChar(S),PChar(S));
    2. CharToOem(Pointer(S),Pointer(S));

    Примечания:
    1. Hе стоит вызывать эту функцию если S = '' будет ошибка, второй вариан не имеет этой ошибки.
    2. Заметьте однако, что эти функции не умеют делать таких, вещей, как koi8-r в DOS и т. п.
    3. Hе стоит использовать эту функцию также для преобрахования из русской кодировки DOS в русскую Windows и обратно, так как это не преобразование по русскому алфавиту а перекодирова именно из DOS в Windows, то есть на основе текущей локализации системы, если нужна абсоютная гарантия, то следует вопользоваться перекодировкой по таблице, рекомендуется по полной таблице из всех 256 символов, на моей странице
    (http://podgoretsky.com) есть универсальная функция перекодировки (CharCvt) с набором некоторых основных таблиц.

    Из конференции Delphi

    Вопрос

    Как мне работать с файлами MS Word или таблицами MS Excel?

    Ответ

    Есть два пути решения этой проблемы:

    Первое — воспользоваться функцией CreateOLEObject и работать с VBA (Visual Basic for Applications) или WordBasic.
    Обратите внимание на то, как устанавливаются именованные параметры у процедур WordBasic'а, например, FileOpen(Name := 'myname.doc');
    Пример проверен только на русском Word 7.0! Может, поможет…

    unit InWord;
    interface
    uses
        … ComCtrls; // Delphi3
        … OLEAuto; // Delphi2
    [skip]
    procedure TPrintForm.MPrintClick(Sender: TObject);
    var W: Variant;
            S: String;
    begin
    S:=VarToStr(Table1['Num']); //В D3 без промежуточной записи
    // в var у меня не пошло :(
        try // А вдруг где ошибка :)
       W:=CreateOleObject('Word.Basic');
        // Создаем документ по шаблону MyWordDot
      // с указанием пути если он не в папке шаблонов Word
     W.FileNew(Template:='C:\MyPath\DB\MyWordDot',NewTemplate:=0);
     // Отключение фоновой печати (на LJ5L без этого был пустой лист)
      W.ToolsOptionsPrint(Background:=0);

        // Переходим к закладке Word'a 'Num'
        W.EditGoto('Num'); W.Insert(S);
            //Сохранение
        W.FileSaveAs('C:\MayPath\Reports\MyReport')
      W.FilePrint(NumCopies:='2'); // Печать 2-х копий
        finally
        W.ToolsOptionsPrint(Background:=1);
            W:=UnAssigned;
        end;
    end;

    Второй путь, более правильный:

    Hужно импортировать TLB библиотеку соответствующего COM-сервера (MS Word, MS Excel, AutoCAD, и т.п.) или воспользоваться готовыми компонентами из палитры Servers поставляемыми с Delphi 5 и более свежими версиями. Среда построит unit содержащий описания всех доступных интерфейсов сервера. Кроме того будут созданы классы-обертки для некоторых интерфейсов сервера. Преимущество этого метода заключается в том что компилятор может проверить правильность синтаксиса обращений к серверу, кроме того повышается скорость работы за счет меньших накладных расходов на каждое обращение.
    Пример использования TLB.

    program wordemo;

    {$APPTYPE CONSOLE}

    uses
      SysUtils, ActiveX, Word2000, OleCtrls, Variants;
    var
          W:TWordApplication;
          D:_Document;
          P:Paragraph;
          FileName:OleVariant;
    begin
      CoInitialize(NIL);
      try
     // создадим экземпляр объекта-обертки вокруг Word 2000
       W:=TWordApplication.Create(NIL);
            try
      // создадим новый документ на основе шаблона Normal

    D:=W.Application.Documents.Add(EmptyParam,EmptyParam,
    EmptyParam,EmptyParam);
          // добавим новый параграф
       P:=D.Paragraphs.Add(EmptyParam);
          // Запишем туда какой-нибудь текст
        P.Range.InsertAfter('Hello Word :-)');
          // сохраним документ
         FileName:='wordemo.doc';

    D.SaveAs(FileName,EmptyParam,EmptyParam,EmptyParam,
    EmptyParam,EmptyParam,EmptyParam,EmptyParam,
    EmptyParam,EmptyParam,EmptyParam);
            finally
           // завершим работу Word
            W.Free;
            end;
      finally
            CoUnInitialize;
      end;
    end.

    Из конференции Delphi

    function Xls_To_StringGrid(AGrid: TStringGrid; AXLSFile: string): Boolean;
    const
    xlCellTypeLastCell = $0000000B;
    var
    XLApp, Sheet: OLEVariant;
    RangeMatrix: Variant;
    x, y, k, r: Integer;
    begin
    Result := False;
    // Create Excel-OLE Object
    XLApp := CreateOleObject('Excel.Application');
    try
    // Hide Excel
    XLApp.Visible := False;
    // Open the Workbook
    XLApp.Workbooks.Open(AXLSFile);
    // Sheet := XLApp.Workbooks[1].WorkSheets[1];
    Sheet := XLApp.Workbooks[ExtractFileName(AXLSFile)].WorkSheets[1];
    Sheet.Cells.SpecialCells(xlCellTypeLastCell, EmptyParam).Activate;
    // Get the value of the last row
    x := XLApp.ActiveCell.Row;
    // Get the value of the last column
    y := XLApp.ActiveCell.Column;
    // Set Stringgrid's row &col dimensions

    AGrid.RowCount := x;
    AGrid.ColCount := y;
    // Assign the Variant associated with the WorkSheet to the Delphi Variant
    RangeMatrix := XLApp.Range['A1', XLApp.Cells.Item[X, Y]].Value;
    // Define the loop for filling in the TStringGrid
    k := 1;
    repeat
    for r := 1 to y do
    AGrid.Cells[(r — 1), (k — 1)] := RangeMatrix[K, R];
    Inc(k, 1);
    AGrid.RowCount := k + 1;
    until k > x;
    // Unassign the Delphi Variant Matrix
    RangeMatrix := Unassigned;

    finally
    // Quit Excel
    if not VarIsEmpty(XLApp) then
    begin
    // XLApp.DisplayAlerts := False;
    XLApp.Quit;
    XLAPP := Unassigned;
    Sheet := Unassigned;
    Result := True;
    end;
    end;
    end;

    procedure TForm1.BitBtn1Click(Sender: TObject);
    begin
    if Xls_To_StringGrid(StringGrid1,
    ExtractFileDir(Application.ExeName)+'\Test.xls') then
    ShowMessage('Table has been exported!');
    end;

    Вопрос

    Вопрос из области работы с Интернет. Подскажите пожалуйста, как в html-файле, обращаясь к нему по URL (например, прочитать web-документ) найти указанные строки по шаблону? И еще к этому же вопросу: как мне сделать, чтобы если найденная строка является ссылкой, то получить адрес ссылки.

    Ответ

    Если Вам нужно извлекать информацию из web-страниц, то в данном случае лучше использовать регулярные выражения. Это очень гибкий инструмент. Для Delphi компонент можно взять здесь: http://anso.virtualave.net/ там же и хелпик по основам регексп.

    По второму вопросу: тоже применить регексп, ведь формат ссылки заранее предопределен: <a href="www.serv.ru">ссылка</a>, просто требуется «наложить» :) на эту последовательность регулярное выражение.

    Из конференции Expert_FAQ

    Вопрос

    Подскажите, пожалуйста, как можно в байте информации выделить биты. Через сдвиг и умножение на соответствующую маску работает очень долго (из 8 секунд работы программы выделение битов в общей сложности занимает 6 сек.). Надо бы существенно ускорить выполнение этой операции.

    Ответ

    В Delphi используй операцию and, которая возвращает результат побитового умножения. Пример a and $10 — выделить 4-ый бит. Если результат не ноль — бит установлен.

    То же самое, но на ассемблере. Это позволяет достичь максимальной скорости выполнения.
    function GetBites(t, Mask:LongWord):LongWord; asm
    mov eax, t;
    and eax, mask;
    end;
    Эта функция возвращает t and Mask. Если необходимо выполнить сдвиг, то применяется команда shr:
    function ShiftBites(t, Mask:LongWord; shift:byte):LongWord; asm
    mov eax, t;
    mov cl, shift;
    shr eax;
    and eax, Mask;
    end;
    Эта функция возвращает (t shr shift) and Mask. Если же ассемблер не поможет, надо или переделывать алгоритм, или менять компьютер :))

    Вопрос

    Как можно вызвать процедуру по горячей клавише?

    Ответ

    Способов немало вообщем-то. Попробуй этот:

    if (key=vk_n)then // vk_n — твоя горячая кклавиша
      button1click(sender);

    Хрюк

    Вопрос

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

    Ответ

    Я так думаю, что следующим образом:

    // код для Дельфи. Для паскаля textfile=text, assignfile=assign, closefile=close
    Procedure Print;
    var f:textfile;
    begin
    assignfile(f,'LPT1'); //порт, куда подключен принтер
    rewrite(f);
    writeln(f,'---123---'); // тута можно печатать всJ, что угодно.
    writeln(f,'---456---'); // коды символов псевдографики можно найти
    writeln(f,'---789---'); // в мануале к принтеру или в приведенном ниже примере
    writeln(f,#12); // кажись так делается прогон страницы.
    closefile(f);
    end;
    // коды символов в следующем виде
    Code 129 = А
    Code 130 = Б
    Code 131 = В
    Code 132 = Г
    Procedure Codes;
    var f:textfile;
    i:byte;
    begin
    assignfile(f,'LPT1');
    rewrite(f);
    for i:=129 to 254 do begin
    if i mod 2 = 0 then write(f,' '); // это чтоб разнести коды
    // по горизонтали (иначе псевдографика слиться
    // может друг в друга…
    writeln(f,'Code ',inttostr(i),' = ',chr(i));
    end;
    writeln(f,#12);
    closefile(f);
    end;

    Из конференции Expert_FAQ

    Вопрос

    Как можно обнаружить утечки памяти и ресурсов в программе?

    Ответ

    MSDebug Макса Русова. Hаходится на
    http://www.dic.ru/users/rusov/.
    Поддерживает Delphi 3 и выше, ловит только утечки памяти, но делает это хорошо.
    http://www.numega.com можно купить BoundsChecker for Delphi. Он проверяет также и утечки ресурсов.
    Рекламировался также "MemProof", информацию о котором можно получить на
    http://www.listsoft.ru/programs/pr1520.htm

    Из конференции Delphi

    Вопрос

    Как можно перетаскивать форму не только за заголовок?

    Ответ

    Попробуйте отлавливать событие WM_NCHITTEST.

    Из конференции Delphi

    Вопрос

    Как можно программно заблокировать клавиши [BackSpace], [Ctrl], [Alt], [Esc] и их сочетания?

    Ответ

    Ставь системную ловушку на нажатие клавиш и не пропускай в ней нужные тебе клавиши.

    Алексеев И.Н.

    Вопрос

    Версия языка: 6
    Как можно программно отправить почту с почтового клиента, установленного по умолчанию?

    Т.е.: сформировать конверт, заполнить тему, тело письма и отправить его? Желательно сделать это так, что бы пользователь не смог воспрепятствовать отправке письма или даже не знал о факте его отправки.

    Ответ

    С Портала для программистов:

    КАК ОТПРАВИТЬ ПИСЬМО НА E-MAIL ТАК, ЧТОБЫ ПОЛЬЗОВАТЕЛЬ НЕ ПОДОЗРЕВАЛ ОБ ЭТОМ

    {*******************BEGIN**********************}

    unit Email;
    interface uses Windows, SusUtils, Classes;
    function SendEmail(const RecipName, RecipAddress, Subject, Attachment: string): Boolean; function IsOnline: Boolean; implementation uses Mapi;
    function SendEmail(const RecipName, RecipAddress, Subject, Attachment: string): Boolean;
    var MapiMessage: TMapiMessage;
    MapiFileDesc: TMapiFileDesc;
    MapiRecipDesc: TMapiRecipDesc;
    i: integer;
    s: string;
    begin with MapiRecipDesc do begin ulRecerved:= 0;
    ulRecipClass:= MAPI_TO;
    lpszName:= PChar(RecipName);
    lpszAddress:= PChar(RecipAddress);
    ulEIDSize:= 0;
    lpEntryID:= nil;
    end;
    with MapiFileDesc do begin ulReserved:= 0;
    flFlags:= 0;
    nPosition:= 0;
    lpszPathName:= PChar(Attachment);
    lpszFileName:= nil;
    lpFileType:= nil;
    end;
    with MapiMessage do begin ulReserved := 0; lpszSubject := nil; lpszNoteText := PChar(Subject); lpszMessageType := nil;
    lpszDateReceived := nil; lpszConversationID := nil; flFlags := 0; lpOriginator := nil;
    nRecipCount := 1;
    lpRecips := @MapiRecipDesc;
    if length(Attachment) > 0 then begin nFileCount:= 1;
    lpFiles := @MapiFileDesc;
    end else begin nFileCount:= 0;
    lpFiles:= nil;
    end;
    end;
    Result:= MapiSendMail(0, 0, MapiMessage, MAPI_DIALOG or MAPI_LOGON_UI or MAPI_NEW_SESSION, 0) = SUCCESS_SUCCESS;
    end;
    function IsOnline: Boolean;
    var RASConn: TRASConn;
    dwSize,dwCount: DWORD;
    begin RASConns.dwSize:= SizeOf(TRASConn);
    dwSize:= SizeOf(RASConns);
    Res:=RASEnumConnectionsA(@RASConns, @dwSize, @dwCount);
    Result:= (Res = 0) and (dwCount > 0);
    end;
    end.


    {******************END**********************}

    Из конференции Expert_FAQ

    Вопрос

    Как в Делфи можно проиграть набор нот (имеется инфа о ноте: тон, частота, амплитуда, длительность и тд.), если этот набор формируется в ходе выполнения программы и не записан ни в какой файл. Желательно, чтобы звук проигрывался через звуковую карту, так как ч/з динамик плохое качество, что совсем не желательно.

    Ответ

    Воспроизвести звук на звуковую карту можно при помощи следующей функции:

    BOOL PlaySound(
    LPCSTR pszSound,
    HMODULE hmod,0000
    DWORD fdwSound000
    );

    При помощи этой функции можно воспроизводить WAVфайлы (любые, как с винта так и записанные в ресурсы). Можно также сгенерировать WAVфайл в памяти процесса и воспроизвести его. Функция описана в модуле 0MMSystem

    Из конференции Expert_FAQ

    Вопрос

    Как можно работать с терминалом (допустим напрямую с smtp сервером)?

    Ответ

    Запустите telnet.exe из каталога Windows
    Меню «Подключение» — «Удаленная система»
    Главный компьютер — pop.mail.ru
    Порт — 25
    кнопка «Подключить»
    mail>220 pop.mail.ru
    your>HELO localhost
    mail>250 pop.mail.ru Hello localhost [999.999.999.999]
    your>MAIL FROM:expert2497@mail.ru
    mail>250 <expert2497@mail.ru> Sender ok
    your>RCPT TO: user@mail.ru
    mail>250 <user@mail.ru> Recipient ok
    your>DATA
    your>From: «Пуп Васькин» <expert2497@mail.ru>
    your>To: «Вася Пупкин» <user@mail.ru>
    your>Subject: Test
    your>Date: Tue, 18 Mar 2003 07:25:40 +0300
    your>
    your>Subj!
    your>.
    mail>250 Mail accepted
    your>QUIT

    your — это то, что Вы должны послать
    mail — код ответа + примечания — то, что Вы получаете и должны проанализировать.

    Команды HELO, MAIL FROM, RCPT TO, DATA, QUIT и некоторые другие, а также ответы — часть протокола SMTP. Детали можно уточнить, запросив RFC0010, RFC1869, RFC1870, отослав в теле письма команду

    ---отрезать-------

    Retrieve: RFC
    Doc-ID: RFCномер

    ---отрезать-------

    по адресу mailto:rfc-info@isi.edu
    Если Вы хотите программно реализовать приведенный Выше диалог, то Вам нужно читать и писать из/в _сокет_ приведенные выше строки. Сокет — фактически это запись, состоящая из 3 полей — IP-адреса, протокола (TCP, UDP и т.п), и номера порта — аналог хэндла для файла.

    Из конференции Expert_FAQ

    Вопрос

    Как можно распечатать на принтере какой-нибудь объект с формы с заданными размерами? В частности, меня интересует ListView.

    Ответ

    Посмотрите как работает PaintTo
    Т.е. создать Image1.
    ListView.paintto(image1…
    ну а с печатью изображения проблем не должно быть.

    Из конференции Expert_FAQ

    Вопрос

    Как можно создать массив CheckBox'ов во время работы программы?

    Ответ

    Опиши массив чекбоксов в разделе глобальных переменных:

    var
    Form1:TForm1;
    Cb:Array [1..10] of TCheckBox;


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

    procedure TForm1.Button1Click(Sender: TObject);
    var
    i:integer;
    begin
    for i:=1 to 10 do begin
    //Создаем сам объект
    Cb[i]:=TCheckBox.Create(form1);
    //Далее обращаемся к свойствам объекта
    with Cb[i] do begin
    //Присваиваем чекбокс форме, что б она его отображала
    Parent:=Form1;
    //Далее идут необходимые свойства чекбокса
    Caption:='CheckBox'+inttostr(i);
    Left:=200;
    top:=i*30;
    end;
    end;
    end;


    Собственно и все.

    Из конференции Expert_FAQ

    Вопрос

    Как можно создать окно с помощью WinAPI и Delphi с какими-нибудь компонентами типа кнопки?

    Ответ

    Перво-наперво создадим макет диалогового окошка с двумя кнопочками… Ваще-то есть в природе специальные программы для энтого, ну да ладно, мы — люди не гордые и руки у нас прямые. Так вот. Создадим-ка мы файл, который назовем demo.rc:

    DLG_DEMO DIALOG 0, 0, 135, 25 STYLE WS_VISIBLE
    | WS_CAPTION
    | WS_SYSMENU
    | WS_GROUP
    | DS_FIXEDSYS
    | DS_SETFONT
    | 0x200 EXSTYLE WS_EX_TOPMOST CAPTION
    "Our demo dialog"
    CLASS "DDEMO" LANGUAGE LANG_RUSSIAN,
    0x1 FONT 8,
    "MS Sans Serif"
    {
    CONTROL "Й-еееее…", 124, BUTTON, BS_PUSHBUTTON
    | WS_CHILD
    | WS_VISIBLE, 5, 5, 60, 14 CONTROL "Ффууууу…", 123, BUTTON, BS_PUSHBUTTON
    | WS_CHILD
    | WS_VISIBLE, 70, 5, 60, 14
    }


    Создали. Таперь его скомпилировать надо. А то линковщик не прожует. Для энтого у нас есть утилитка специальная хитрая, которая в {$DELPHI}\Bin лежит. «brcc32.exe» прозывается. Вот ее-то мы и натравим на наш «demo.rc» посредством командной строки.

    И о, чудо, появился «demo.res». А таперь, собссно, самое главное.
    Создадим файл «demo.dpr»:

    program demo;
    uses Windows, Messages;
    {$R DEMO.RES} Var Dialog: hWnd; Msg: TMsg; WindowClass: TWndClass;
    function DlgCallBack(HdlDlg: hWnd;
    Msg: Cardinal;
    WParam, LParam: LongInt): LongInt;
    stdcall;
    begin Result:=0;
    case Msg of WM_INITDIALOG: begin Dialog:=HdlDlg;
    end;
    WM_COMMAND: Case LoWord(WParam) of 124: begin MessageBox(Dialog, 'Стопудово! :)',
    'Ага',
    MB_OK or MB_ICONINFORMATION);
    end;
    123: begin MessageBox(Dialog, 'Ну и ладно. :(', nil, MB_OK or MB_ICONWARNING);
    PostMessage(Dialog, WM_CLOSE, 0, 0);
    end;
    End;
    WM_CLOSE: begin PostQuitMessage(0);
    end;
    end; end;
    Var Err: LongWord;
    begin With WindowClass do begin Style:=cs_HRedraw or cs_VRedraw;
    lpfnWndProc:=@DefDlgProc;
    cbClsExtra:=0;
    cbWndExtra:=DLGWINDOWEXTRA;
    hIcon:=LoadIcon(0, idi_Application);
    hCursor:=LoadCursor (0, idc_Arrow);
    hbrBackground:=GetStockObject(White_Brush);
    lpszMenuName:=NIL;
    lpszClassName:='DDEMO';
    end;
    WindowClass.hInstance:=hInstance;
    If RegisterClass(WindowClass)=0 then Halt (255);
    If DialogBox(hInstance, 'DLG_DEMO', 0, @DlgCallBack)=-1 then MessageBox(0, 'Dialog creation failed', 'Error', MB_OK or MB_ICONSTOP);
    end.


    И его скомпилируем.
    Усе. :) Можно запускать.

    Из конференции Expert_FAQ

    Вопрос

    Как можно удалить с формы все имеющиеся на ней компоненты TShape. Имена компонентам TShape не присвоены.

    Ответ

    procedure TForm1.Button1Click(Sender: TObject);
    var
    i: Byte;
    begin
    i := 0;
    while i < Form1.ComponentCount do
    if Form1.Components[i] is TShape
    then Form1.Components[i].Free
    else Inc(i);
    end;

    Из конференции Expert_FAQ

    Вопрос

    Как на форме запустить анимацию GIF файла?

    Ответ

    Простейший вариант: кладем на форму компонент 0WebBrowser, который находится на вкладке Internet, подбираем его размер, по размерам GIF-а, затем на любое событие пишем: WebBrowser1.Navigate('Pricol027.gif'), если gif находится в папке с проектом, или полный путь к этому гифу — WebBrowser1.Navigate('F:\Path\Pricol027.gif'),.

    Из конференции Expert_FAQ

    Вопрос

    На форме два ListBox'а, в первом выделено несколько строк. Как нажатием кнопки (Button1) на форме перенести эти выделенные строки в другой ListBox?

    Ответ

    ListBox1 — откуда переносить

    ListBox2 — куда переносить

    Процедура указана для кнопки.

    procedure TForm1.Button1Click(Sender: TObject); var i, i1: integer; begin for i:=0 to listbox1.Items.Count-1 do begin if ListBox1.Selected[i] then begin ListBox2.Items.Add(ListBox1.Items.Strings[i]); end; end; i:=ListBox1.Items.Count-1; i1:=0; while i1<=i do begin if ListBox1.Selected[i1] then begin ListBox1.Items.Delete(i1); i:=listBox1.Items.Count-1; i1:=0; continue; end; inc(i1); end; end;

    Из конференции Expert_FAQ

    Вопрос

    Как нажать [Ctrl]+[Del] программным путем?

    Ответ

    keybd_event(vk_control, 0, 0, 0);
    keybd_event(vk_delete, 0, 0, 0);
    keybd_event(vk_delete, 0, KEYEVENTF_KEYUP, 0);
    keybd_event(vk_control, 0, KEYEVENTF_KEYUP, 0);

    keybd_event(vk_control, MapVirtualKey(vk_control, 0), 0, 0);
    keybd_event(vk_delete, MapVirtualKey(vk_control, 0), 0, 0);
    keybd_event(vk_delete, MapVirtualKey(vk_control, 0), KEYEVENTF_KEYUP, 0);
    keybd_event(vk_control, MapVirtualKey(vk_control, 0), KEYEVENTF_KEYUP, 0);

    Leonid Troyanovsky

    Вопрос

    Как назначить процедуру собственному пункту системного меню?

    Ответ

    const
        cm_mycommand = $00A0;

    procedure TForm1.FormCreate(Sender: TObject);
        var HSysMenu: HMENU;
    begin
        HSysMenu:=GetSystemMenu(Handle,FALSE);
        InsertMenu( HSysMenu, 0, MF_BYPOSITION or MF_STRING,cm_mycommand, 'MyString');
    end;

    procedure TForm1.WMSysCommand (var Message:TWMSysCommand); // message WM_SYSCOMMAND;
    begin
        case Message.CmdType of
       cm_mycommand: ShowMessage('My Command');
        else
            inherited;
        end;
    end;

    Leonid Troyanovsky

    Вопрос

    Как найти самую свежую дату в массиве дат?

    Ответ

    Вот так:

    var D: TDateTime; // Для поиска последней даты
        i,index: Integer;
    begin
        D := LOW(M); // твой массив
        for i := LOW(M)+1 to HIGH(M) do
       if M[i] > D then begin
          D := M[i]; // Твоя последняя дата
          index := i; // индекс в массиве
            end;
    end;

    Soldatov Sergey Viktorovich

    Вопрос

    Как нарисовать градиентную заливку на канве заданными цветами?

    Ответ

    {
    Следующий код дает Вам возможность заполнить канву градиентной заливкой с заданным количеством цветов (минимум 2). Для рисования на канве формы, вызовите процедуру DrawGradient() в событиях OnPaint и OnResize.
    }

    procedure DrawGradient(ACanvas: TCanvas; Rect: TRect;
       Horicontal: Boolean; Colors: array of TColor);
    type
       RGBArray = array[0..2] of Byte;
    var
    x, y, z, stelle, mx, bis, faColorsh, mass: Integer;
       Faktor: double;
       A: RGBArray;
       B: array of RGBArray;
       merkw: integer;
       merks: TPenStyle;
       merkp: TColor;
    begin
       mx := High(Colors);
       if mx > 0 then
       begin
         if Horicontal then
    mass := Rect.Right — Rect.Left
         else
    mass := Rect.Bottom — Rect.Top;
         SetLength(b, mx + 1);
         for x := 0 to mx do
         begin
    Colors[x] := ColorToRGB(Colors[x]);
    b[x][0] := GetRValue(Colors[x]);
    b[x][1] := GetGValue(Colors[x]);
    b[x][2] := GetBValue(Colors[x]);
         end;
         merkw := ACanvas.Pen.Width;
         merks := ACanvas.Pen.Style;
         merkp := ACanvas.Pen.Color;
         ACanvas.Pen.Width := 1;
         ACanvas.Pen.Style := psSolid;
         faColorsh := Round(mass / mx);
         for y := 0 to mx — 1 do
         begin
    if y = mx — 1 then
    bis := mass — y * faColorsh — 1
           else
    bis := faColorsh;
       for x := 0 to bis do
           begin
    Stelle := x + y * faColorsh;
    faktor := x / bis;
    for z := 0 to 3 do
    a[z] := Trunc(b[y][z] + ((b[y + 1][z] — b[y][z]) * Faktor));
    ACanvas.Pen.Color := RGB(a[0], a[1], a[2]);
    if Horicontal then
    begin
    ACanvas.MoveTo(Rect.Left + Stelle, Rect.Top);
    ACanvas.LineTo(Rect.Left + Stelle, Rect.Bottom);
      end
       else
        begin
    ACanvas.MoveTo(Rect.Left, Rect.Top + Stelle);
    ACanvas.LineTo(Rect.Right, Rect.Top + Stelle);
      end;
           end;
         end;
         b := nil;
    ACanvas.Pen.Width := merkw;
      ACanvas.Pen.Style := merks;
       ACanvas.Pen.Color := merkp;
       end
       else
    // Пожалуйста, укажите минимум два цвета
    raise EMathError.Create('Пожалуйста, укажите минимум два цвета.');
    end;

    // Примеры вызовов:

    DrawGradient(Image1.Canvas, Rect(0, 0, 100, 200), False, [clRed, $00FFA9B4]);

    DrawGradient(Canvas, GetClientRect, True, [121351, clBtnFace, clBlack, clWhite]);

    Кирилл Краснов

    Вопрос

    Как не допусть повторного вызова обработчика до заверщения его работы?

    Ответ

    В обработчике сбросить обработчик .
    А потом, последней строкой, вернуть как было…

    procedure TForm1.Button1OnClick(…)
    begin
    Button1.OnClick := nil;
    //Тут идет страшный код
    Button1.OnClick := Button1Click;
    end;

    Примерно так.

    Из конференции Expert_FAQ

    Вопрос

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

    Ответ

    S:='K';//то по какой ищем

    listbox1.itemIndex := Perform(LB_SELECTSTRING, listbox1.itemIndex, LongInt(S));

    Из конференции Expert_FAQ

    Вопрос

    Как обнаружить активность пользователя?

    Ответ

    Application.OnMessage := DoMessageEvent;

    procedure TForm1.DoMessageEvent ( var Msg: TMsg; var Handled: Boolean);
    begin
      case Msg.message of
     WM_KEYFIRST..WM_KEYLAST,WM_MOUSEFIRST..WM_MOUSELAST:
        {Произошли события клавиатуры и мыши};
              ..
      end;
    end;

    Leonid Troyanovsky

    Вопрос

    Как обратиться к определенному адресу физической памяти? А как прочитать значение из порта? Где мой любимый массив Port[]?

    Ответ

    Прочитайте какую-нибудь книжку про программирование под Win32. Вкратце — забудьте про все эти глупости (массив Port[] и т.п.).

    Из конференции Delphi

    Вопрос

    Как обратиться к свойству по его имени?

    Ответ

    type
      TForm1 = class(TForm)
          Button1: TButton;
    procedure Button1Click(Sender: TObject);
      private
     f1 : Integer; // Это приватное поле хранит значение
      published
     {К свойству p1 мы будем обращаться по его имени}
     property p1 : Integer read f1 write f1;
      end;

    var
        Form1: TForm1;

    implementation

    {$R *.DFM}

    uses
        TypInfo;

    procedure TForm1.Button1Click(Sender: TObject);
    var
        PInfo : PPropInfo;
    begin
    p1 := GetTickCount; // Здесь свойству что-то присвоили
    PInfo:= GetPropInfo(TForm1.ClassInfo, 'p1'); // Получаем описание свойства
    // из описания класса
        if PInfo = nil then
       raise Exception.Create('Property not exist');
    Caption := IntToStr(GetOrdProp(Form1, PInfo)); // Получаем значение свойства
    end;

    uses
        TypInfo;

    function ObjPropInfo(AObject: TObject; const PropName: String): PPropInfo;
    begin
     Result := GetPropInfo(AObject.ClassInfo, PropName);
        if Result = nil then
      raise Exception.Create('Property not exist');
    end;

    procedure SetOrdProperty( AObject: TObject; const PropName:String; const Value: Longint);
    begin
     SetOrdProp(AObject, ObjPropInfo(AObject, PropName), Value);
    end;

    function GetOrdProperty(AObject: TObject; const PropName:String):Longint;
    {см. также TypInfo: GetStrProp, GetFloatProp, GetEnumValue etc.}
    begin
     Result:= GetOrdProp(AObject, ObjPropInfo(AObject, PropName));
    end;

    procedure SetStrProperty( AObject: TObject; const PropName:String; const Value: String);
    begin
     SetStrProp(AObject, ObjPropInfo(AObject, PropName), Value);
    end;

    procedure SetFloatProperty( AObject: TObject; const PropName:String; const Value: Extended);
    begin
     SetFloatProp(AObject, ObjPropInfo(AObject, PropName), Value);
    end;

    procedure SetVariantProperty( AObject: TObject; const PropName:String; const Value: Variant);
    begin
    SetVariantProp(AObject, ObjPropInfo(AObject, PropName), Value);
    end;

    procedure SetMethodProperty( AObject: TObject; const PropName:String; const Value: Pointer);
    var
        AMethod: TMethod;
    begin
        AMethod.Code := Value;
        AMethod.Data := AObject;
     SetMethodProp(AObject, ObjPropInfo(AObject, PropName), AMethod);
    end;

    procedure TForm1.Button1Click(Sender: TObject);
    var
        AFont: TFont;
    begin
     SetOrdProperty(Button1, 'Width', 100); // целое
        AFont := TFont.Create;
        AFont.Style := [fsBold];
     SetOrdProperty(Button1, 'Font', Longint(AFont)); // объект
        AFont.Free;
    SetMethodProperty(Button1, 'OnClick', @TForm1.Button2Click); // метод
    end;

    procedure TForm1.Button2Click(Sender: TObject);
    begin
        ShowMessage((Sender as TButton).Caption);
    end;

    Leonid Troyanovsky

    Вопрос

    Как объявлять переменные, что бы они были видны в других модулях проекта?

    Ответ

    Лучше всего создать отдельный модуль для таких переменных, назвать его скажем ComVars.pas и подключать его в остальных модулях.

    unit ComVars;

    interface

    var
     MyVar : Integer

    implementation
    end.

    Кроме этого модуля полезно создать еще два
    ComConst — для общих констант
    ComUtils — для общих процедур

    Из конференции Delphi

    Вопрос

    Как ограничить перемещение курсора мыши какой-либо областью экрана?

    Ответ

    Используя функцию ClipCursor(). Хотя некоторые считают, что использование этой функции — плохой тон.

    Из конференции Delphi

    Вопрос

    Как определить время изменения (создания) файла?

    Ответ

    datetostr(FileDateToDateTime(fileage('autoexec.bat')))
      
    где вместо "autoexec.bat" подставляем имя нужного файла.

    Evilious

    Вопрос

    Как определить дублирущиеся записи в запроче с помощью SQL?

    Ответ

    При помощи вот такой конструкции:

    SELECT Field FROM Table GROUP BY Field Having Count(*)> 1

    Field — имя поля таблицы, а Table — соответственно имя самой таблицы.

    T'Mon

    Вопрос

    Как определить координаты окна чужого приложения (известен класс окна и Caption) ?

    Ответ

    procedure TForm1.Button1Click(Sender: TObject);
    var
    R: TRect;
    P: TPoint;
    begin
    GetWindowRect(FindWindow(SomeClass, SomeCaption), R);
    P.X := R.Left;
    P.Y := R.Top;
    ShowMessage('x: ' + IntToStr(P.X) + ' y: ' + IntToStr(P.Y));
    end;


    Из конференции Expert_FAQ

    Вопрос

    У меня такая проблема. Необходимо в программе сделать так, чтобы когда переносишь, например ярлык с рабочего стола или любой файл на текстовое поле, то в нем появлялся путь к этому файлу, например c:\program files\the bat!\thebat.exe. Как это можно реализовать?

    Ответ

    На эту форму можно бросить файл (например из проводника) и он будет открыт.

    unit Unit1;
    interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ShellAPI {обязательно!};
    type TForm1 = class(TForm) Memo1: TMemo; FileNameLabel: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    protected
    {Это и есть самая главная процедура}
    procedure WMDropFiles(var Msg: TMessage);
    message wm_DropFiles;
    end;
    var Form1: TForm1;
    implementation {$R *.DFM} procedure TForm1.WMDropFiles(var Msg: TMessage);
    var Filename: array[0 .. 256] of Char;
    Count : integer;
    begin
    { Получаем количество файлов (просто пример) }
    nCount := DragQueryFile( msg.WParam, $FFFFFFFF, acFileName, cnMaxFileNameLen);
    { Получаем имя первого файла }
    DragQueryFile( THandle(Msg.WParam), 0,
    { это номер файла }
    Filename,SizeOf(Filename) ) ;
    { Открываем его }
    with FileNameLabel do begin Caption := LowerCase(StrPas(FileName));
    Memo1.Lines.LoadfromFile(Caption);
    end;
    { Отдаем сообщение о завершении процесса }
    DragFinish(THandle(Msg.WParam));
    end;
    procedure TForm1.FormCreate(Sender: TObject);
    begin
    { Говорим Windows, что на нас можно бросать файлы }
    DragAcceptFiles(Handle, True);
    end;
    procedure TForm1.FormDestroy(Sender: TObject);
    begin
    { Закрываем за собой дверь золотым ключиком}
    DragAcceptFiles(Handle, False);
    end;
    end.


    Из конференции Expert_FAQ

    Вопрос

    Как определить серийный номер винчестера? Scandisk его распознает как S2df-gh3h или что-то в этом роде.

    Ответ

    Должно помочь.

    function disknumber(disk: string):string;
    // Серийный номер диска var VolumeName, FileSystemName : array [0..MAX_PATH-1] of Char;
    VolumeSerialNo : DWord;
    MaxComponentLength, FileSystemFlags : Cardinal;
    begin disk := copy(disk, 1, 1) + ':\';
    GetVolumeInformation(pchar(disk),VolumeName,MAX_PATH,@VolumeSerialNo, MaxComponentLength,FileSystemFlags, FileSystemName,MAX_PATH);
    result := IntToStr(VolumeSerialNo);
    end;


    Из конференции Expert_FAQ

    Это не серийный номер винчестера! Это серийный номер тома, а это разные вещи!

    Вопрос

    Как определить что программа запущена в эмуляторе в Virtual PC?

    Ответ

    Эта функция может быть использована для определения, что ваша программа запущена в Connectrix's Virtual PC

    function running_inside_vpc: boolean; assembler;
    asm
        push ebp

        mov ecx, offset @@exception_handler
        mov ebp, esp

        push ebx
        push ecx
        push dword ptr fs:[0]
        mov dword ptr fs:[0], esp

        mov ebx, 0 // флаг
        mov eax, 1 // номер функции VPC

        // call VPC
        db 00Fh, 03Fh, 007h, 00Bh

        mov eax, dword ptr ss:[esp]
        mov dword ptr fs:[0], eax
        add esp, 8

        test ebx, ebx
        setz al
        lea esp, dword ptr ss:[ebp-4]
        mov ebx, dword ptr ss:[esp]
        mov ebp, dword ptr ss:[esp+4]
        add esp, 8
        jmp @@ret
        @@exception_handler:
        mov ecx, [esp+0Ch]
    mov dword ptr [ecx+0A4h], -1 // EBX = -1 -> не запущен, ebx = 0 -> запущен
        add dword ptr [ecx+0B8h], 4
        xor eax, eax
        ret
        @@ret:
    end;

    Из конференции Delphi

    Вопрос

    Как в Delphi 6 организовать вывод определенных полей базы данных. Слышал, что надо делать через компонет QUERY, а как?

    Ответ

    Двойной щелчок по компоненту TQuery (который размещен на форме.) Откроется окошко редактора полей. Щелкайте в белом поле правой кнопкой мыши. В появившемся меню первые три команды относятся к добавлению полей.

    Add all fields — добавит все поля.

    Add fields… — вывалит список полей, из которого можно выбрать нужные.

    New field — позволяет добавлять вычисляемые и lookup-поля.

    Добавленные поля создаются как отдельные объекты TxxxField. Где xxx определяет тип значения поля. И к ним можно обращаться как к отдельным объектам.

    Если выбрать какое-то поле в редакторе полей, то набор его свойств появится в Инспекторе объектов — здесь можно управлять видимостью поля, задать заголовок колонки, который будет отображаться в DBGrid-е, настроить ширину колонки (так как на самомо деле поле может быть, например, в 100 символов и на экране такая колонка без особой надобности будет очень широкой — ее можно уменьшить.)

    Из конференции Expert_FAQ

    Вопрос

    Подскажите, как организовать опережающее описание типов в Делфи. Должна получится такая структура:

    type TMyType = array of TMyArrayType;
    TMyArrayType = record
    X: byte;
    Y: TMyType;
    end;

    Ответ

    До объявления в Паскале можно использовать указатели. Правда, тогда и с выделением/освобождением памяти придется повозиться…

    В Вашем случае:

    type
    PMyType = ^TMyType;
    TMyType = array of TMyArrayType;
    TMyArrayType = record
    X: byte;
    Y: PMyType;
    end;

    Из конференции Expert_FAQ

    Вопрос

    В Windows Commander есть просмотрщик текстовых файлов. По нажатии F3 открывается окно, как в Блокноте, текст в котором недоступен для редактирования (нельзя даже поставить курсор редактирования). Пробовал сделать что-то подобное на Delphi, сделав поле RichEdit неактивным (Enabled=false). Но при этом пропадает возможность прокрутки текста (исчезают scroll bars). Каким образом можно сделать так, чтобы в окне редактора текста отсутствовал курсор и возможность выделения текста, но оставались линии прокрутки?

    Ответ

    В принципе можешь использовать и RichEdit (с Enabled := False), только придется обрабатывать скроллинг ручками. Для этого берется компонент TScrollBar и обрабатываются его события. Например:

    procedure TForm1.ScrollBar1Scroll(Sender: TObject; ScrollCode: TScrollCode; var ScrollPos: Integer); begin case ScrollCode of scLineUp: Memo1.Perform(EM_LINESCROLL, 1, -1); scLineDown: Memo1.Perform(EM_LINESCROLL, 1, 1); scPageUp: Memo1.Perform(EM_LINESCROLL, 1, -10); scPageDown: Memo1.Perform(EM_LINESCROLL, 1, 10); // Здесь можно дописать обработчик и для других ScrollCode :) end; end;

    Это только часть событий. Если хочешь обработать все, читай справку по WinApi и по TScrollBar.

    Из конференции Expert_FAQ

    Вопрос

    Как осуществить поиск по неиндексированному полю в TTable?

    Ответ

    {Следущая функция может быть добавлена в Ваш модуль и названа, например:}

    Locate(Table1,=Table1LName,='Строка поиска');

    {Table1=это ваш компонент таблицы,=Table1LName=это имя TField,=в котором будет производиться поиск и 'Строка поиска'=это то, что надо найти.}

    {Locate=будет искать=SValue=в неиндексированной таблице}
    function=Locate(const=oTable:=TTable;=const=oField:=TField;
        const=sValue:=string):=Boolean;
    var
        bmPos:=TBookMark;
        bFound:=Boolean;
    begin
        Locate=:==False;
        bFound=:==False;
        if=not=oTable.Active=then=Exit;
        if=oTable.FieldDefs.IndexOf(oField.FieldName)=<=0=then=Exit;
        bmPos=:==oTable.GetBookMark;
        with=oTable=do
        begin
            DisableControls;
            First;
            while=not=EOF=do
          if=oField.AsString===sValue=then
         begin
        Locate=:==True;
          bFound=:==True;
            Break;
           end
            else
             Next;
      end;
      if=(not=bFound)=then   oTable.GotoBookMark(bmPos);
        oTable.FreeBookMark(bmPos);
        oTable.EnableControls;
    end;

    Кирилл Краснов

    Вопрос

    Как осуществить экспорт данных из ADO tables в различные форматы?

    Ответ

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

    1. Excel
    2. Html
    3. Paradox
    4. Dbase
    5. Text

    Все поддерживаемые форматы Вы можете просмотреть в реестре:

    HKEY_LOCAL_MACHINE\ Software\ Microsoft\ Jet\ 4.0\ ISAM=formats

    Полный листинг компонента:

    unit=ExportADOTable;
    interface
    uses
    ==Windows,=Messages,=SysUtils,=Classes,=Graphics,=Controls,
    =Forms,=Dialogs, Db,=ADODB;

    type
    ==TExportADOTable===class(TADOTable)
    ==private
    ===={=Private=declarations=}
    //TADOCommand=component=used=to=execute=the=SQL
    =exporting=commands
    ====FADOCommand:=TADOCommand;
    ==protected
    ===={=Protected=declarations=}
    ==public
    ===={=Public=declarations=}
    ====constructor=Create(AOwner:=TComponent);=override;

    //Экспортируемые процедуры
    //"FiledNames" строка с названиями полей, разделенные
    запятыми, для экспорта
    //"FileName" полный путь на файл, в который будут
    импортироваться данные
    //если база отфильтрована(Filtered===true=and=Filter=<>=''), добавлена=
    //строка фильтра в sql=command в директиву "where&;quot;
    //если база отсортирована (Sort=<>='') добавлена строка в sql=command в
    //директиве "order=by"

    procedure=ExportToExcel(FieldNames:=string;=FileName:=string;
    SheetName:=string;=IsamFormat:=string);
    procedure=ExportToHtml(FieldNames:=string;=FileName:=string);
    procedure=ExportToParadox(FieldNames:=string;=FileName:=string;
    =IsamFormat:=string);
    procedure=ExportToDbase(FieldNames:=string;=FileName:=string;
    =IsamFormat:=string);
    procedure=ExportToTxt(FieldNames:=string;=FileName:=string);

    ==published
    ===={=Published=declarations=}
    ==end;

    procedure=Register;

    implementation

    procedure=Register;
    begin
    ==RegisterComponents('ADO',=[TExportADOTable]);
    end;

    constructor=TExportADOTable.Create(AOwner:=TComponent);
    begin
    ==inherited;
    ==FADOCommand=:==TADOCommand.Create(Self);
    end;

    procedure=TExportADOTable.ExportToExcel(FieldNames:=string;
    =FileName:=string; SheetName:=string;=IsamFormat:=string);
    begin
    ={IsamFormat=values
    ==Excel=3.0
    ==Excel=4.0
    ==Excel=5.0
    ==Excel=8.0
    =}

    ==if=not=Active=then =Exit;
    ==FADOCommand.Connection==:==Connection;==
    ==FADOCommand.CommandText=:=='Select='=+=FieldNames=+='
    =INTO='=+='['=+
    ====SheetName=+=']'=+='=IN='=+='"'=+=FileName=+='"'=+='
    ['=+=IsamFormat=+
    ====';]'=+='=From='=+=TableName;
    ==if=Filtered=and=(Filter=<>='')=then
    ====FADOCommand.CommandText=:==FADOCommand.CommandText=+='
    =where='=+=Filter;
    ==if=(Sort=<>='')=then
    ====FADOCommand.CommandText=:==FADOCommand.CommandText=+='
    =order=by='=+=Sort;
    ==FADOCommand.Execute;
    end;

    procedure=TExportADOTable.ExportToHtml(FieldNames:=string;
    =FileName:=string);
    var
    ==IsamFormat:=string;
    begin
    ==if=not=Active=then Exit;
    ==IsamFormat=:=='HTML=Export';
    ==FADOCommand.Connection==:==Connection;
    ==FADOCommand.CommandText=:=='Select='=+=FieldNames=+='
    =INTO='=+='['=+
    ====ExtractFileName(FileName)=+=']'=+=
    ===='=IN='=+='"'=+=ExtractFilePath(FileName)=+='"'=+='
    ['=+=IsamFormat=+
    ====';]'=+='=From='=+=TableName;
    ==if=Filtered=and=(Filter=<>='')=then
    ====FADOCommand.CommandText=:==FADOCommand.CommandText=+='
    =where='=+=Filter;
    ==if=(Sort=<>='')=then
    ====FADOCommand.CommandText=:==FADOCommand.CommandText=+='
    =order=by='=+=Sort;
    ==FADOCommand.Execute;
    end;

    procedure=TExportADOTable.ExportToParadox(FieldNames:=string;
    ==FileName:=string;=IsamFormat:=string);
    begin
    ={IsamFormat=values
    =Paradox=3.X
    =Paradox=4.X
    =Paradox=5.X
    =Paradox=7.X
    =}
      =if=not=Active=then Exit;
    ==FADOCommand.Connection==:==Connection;
    ==FADOCommand.CommandText=:=='Select='=+=FieldNames=+='
    =INTO='=+='['=+
    ====ExtractFileName(FileName)=+=']'=+=
    ===='=IN='=+='"'=+=ExtractFilePath(FileName)=+='"'=+='
    ['=+=IsamFormat=+
    ====';]'=+='=From='=+=TableName;
    ==if=Filtered=and=(Filter=<>='')=then
    =FADOCommand.CommandText=:==FADOCommand.CommandText=+='
    =where='=+=Filter;
    ==if=(Sort=<>='')=then
    =FADOCommand.CommandText=:==FADOCommand.CommandText=+='
    =order=by='=+=Sort;
    ==FADOCommand.Execute;
    end;

    procedure=TExportADOTable.ExportToDbase(FieldNames:=string;
    =FileName:=string;
    ==IsamFormat:=string);
    begin
    ={IsamFormat=values
    =dBase=III
    =dBase=IV
    =dBase=5.0
    =}
    ==if=not=Active=then Exit;
    ==FADOCommand.Connection==:==Connection;
    ==FADOCommand.CommandText=:=='Select='=+=FieldNames=+='
    =INTO='=+='['=+
    ====ExtractFileName(FileName)=+=']'=+=
    ===='=IN='=+='"'=+=ExtractFilePath(FileName)=+='"'=+='
    ['=+=IsamFormat=+
    ====';]'=+='=From='=+=TableName;
    ==if=Filtered=and=(Filter=<>='')=then
    ====FADOCommand.CommandText=:==FADOCommand.CommandText=+='
    =where='=+=Filter;
    ==if=(Sort=<>='')=then
    ====FADOCommand.CommandText=:==FADOCommand.CommandText=+='
    =order=by='=+=Sort;
    ==FADOCommand.Execute;
    end;

    procedure=TExportADOTable.ExportToTxt(FieldNames:=string;
    =FileName:=string);
    var
    ==IsamFormat:=string;
    begin
    ==if=not=Active=then Exit;
    ==IsamFormat=:=='Text';
    ==FADOCommand.Connection==:==Connection;
    ==FADOCommand.CommandText=:=='Select='=+=FieldNames=+='
    =INTO='=+='['=+
    ====ExtractFileName(FileName)=+=']'=+=
    ===='=IN='=+='"'=+=ExtractFilePath(FileName)=+='"'=+='
    ['=+=IsamFormat=+
    ====';]'=+='=From='=+=TableName;
    ==if=Filtered=and=(Filter=<>='')=then
    ====FADOCommand.CommandText=:==FADOCommand.CommandText
    =+='=where='=+=Filter;
    ==if=(Sort=<>='')=then
    ====FADOCommand.CommandText=:==FADOCommand.CommandText
    =+='=order=by='=+=Sort;
    ==FADOCommand.Execute;
    end;
    end


    Пример использования:

    var ADOTable: TADOTable;
    ExpADOTable: TExportADOTable;
    begin

       ExpADOTable:=TExportADOTable.Create(Self{если есть форма});
       ExpADOTable.Assign(ADOTable);
    ExpADOTable.ExportToExcel('name,birthday','c:\test.xls',
    'Test','Excel=8.0');

    end;


    Кирилл Краснов

    Вопрос

    Delphi 6. Окно моей программы при работе не получает фокуса. Как отловить и обработать в ней событие нажатия комбинации клавиш на клавиатуре (например Ctrl+Q). Если можно пример.

    Ответ

    Это далеко не лучший пример, но все же:

    if GetAsyncKeyState(VK_CONTROL) <> 0 then

    if GetAsyncKeyState(13) <> 0 then

    ShowMessage('Вы нажали Ctrl-Enter');

    Это все надо повесить на Timer

    Из конференции Expert_FAQ

    Вопрос

    Как отловить нажатие Enter в TEdit?

    Ответ

    Чтобы сделать в духе Windows, то добавь к Edit один TButton, с свойством default := True, обработчик OnClick которой будет делать нужную работу.

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

    1. OnClick кнопки default
    2. OnClick формы, если у нее KeyPreview := True;
    3. OnKeyDown/KeyPress/KeyUp контрола имеющего фокус ввода.

    Это особенность роли, которую этой клавише обычно назначают в win приложениях. Обрати также внимание на свойство TButton Cancel — оно заставляет срабатывать кнопку при нажатии Esc

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

    procedure TForm1.Button1Click(Sender: TObject);
    begin
        //Button1.Default := True;
        ShowMessage('Key1');
    end;

    procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
    begin
        //KeyPreview := True;
        if Key = #13 then
            begin
         ShowMessage('Key2');
          Key := #0;
            end;
    end;

    procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
    begin
      if key = #13 then
            ShowMessage('Key3');
    end;

    Из конференции Delphi

    Вопрос

    Как отловить нажатие клавиш F1..F10?

    Ответ

    procedure TForm1.AppMessage(var Msg:TMsg; var Handled: Boolean);
    begin
      case msg.wParam of
          VK_F1..VK_F10 :
         case Msg.message of
         WM_KEYUP: ShowMessage('Key up');
       WM_KEYDOWN: ShowMessage('Key down');
              end;
      end;
    end;

    procedure TForm1.FormCreate(Sender: TObject);
    begin
        Application.OnMessage := AppMessage;
    end;

    Из конференции Delphi

    Вопрос

    Как отловить системную ошибку при операциях с файлами?

    Ответ

    Для Паскаль функций, например, BlockWrite, можно использовать такую конструкцию:

    try
    BlockWrite(f, buf, count); //См.также хелп: параметр AmtTransferred
        ..
    except
        on E:EInOutError do
          begin
    ShowMessage('Произошла ошибка записи ' + E.Message);
       ..// пытаемся что-то поправить
       if {не удалось} then
    raise; //Повторно возбуждаем исключение, чтобы не удалить файл
          end;
    end;

    ..
    CloseFile(..);
    DeleteFile(..);

    Из конференции Delphi

    Вопрос

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

    Ответ

    В rxLib есть TrxFolderMonitor.
    (Win16) FileCDR, но она плохо документирована.

    Из конференции Delphi

    Вопрос

    Как сделать так, чтобы форма отображалась, но на таскбаре не было для этой формы кнопки?

    Ответ

    ShowWindow(application.handle,SW_MINIMIZE); }  спрятали
    ShowWindow(application.handle,SW_HIDE);

    ShowWindow(application.handle,SW_RESTORE); }  показали
    ShowWindow(application.handle,SW_SHOW);

    Dima S.

    Вопрос

    Делаю что-то вроде браузера, как как сделать, чтобы при нажатии в TEdit в TWebBrowser отображалась страница, которая введена в TEdit. И еще: если в TEdit введен не локальный путь, то должно вызываться подключение к интернету, а если локальный, то нет. Но если на локальной странице есть рисунки, для просмотра которых требуется подключение, то, соответственно, нужно вызвать это самое подключение к интернету.

    Ответ

    Я тоже использую TwebBrowser и вот функция, которая открывает нужный URL:

    procedure Tf_multih.open(url:string); var v:Olevariant;
    begin v:=navNoReadFromCache+navNoWriteToCache; WebBr.navigate(url,v);
    end;


    Webbr — обьект типа TwebBrowser. Он использует Internet Explorer версии не ниже 4 как OLE сервер.
    Что касается автодозвона — это нужно настраивать Internet explorer, чтобы он сам инициировал звонилку при открытии URL, когда это необходимо.

    Svap

    Вопрос

    Как отправлять почту, используя Delphi 6?

    Ответ

    Можно, используя компоненту закладки fastnet nmsmtp. Можно, используя компоненты Indy clients — стандартная поставка делфей.

    seacat, Soldat

    Можно зайти на сайт www.sources.ru и там далее щелкнуть по ссылке Delphi, а дальше все увидишь сам, кроме этого там есть еще много чего полезного.

    yuris

    Вопрос

    Как отследить "уход" курсора мыши с компоненты?

    Ответ

    Hадо обрабатывать события CM_MOUSEENTER/CM_MOUSELEAVE.

    Из конференции Delphi

    Вопрос

    Как отследить переход фокуса в приложении?

    Ответ

    procedure TForm1.AppControlChange(Sender: TObject);
    begin
      if Sender is TScreen then
     Caption := TScreen(Sender).ActiveForm.ActiveControl.Name;
    end;

    procedure TForm1.FormCreate(Sender: TObject);
    begin
     Screen.OnActiveControlChange := AppControlChange;
    end;

    Leonid Troyanovsky

    Вопрос

    Как панель перемещать по форме в режиме работы программы?

    Ответ

    Из советов Валентина Озерова:

    {Так можно таскать мышкой TPanel по форме в run-time'е. Поместите на форму TPanel и напишите обработчик события OnMauseDown, запустите программу и задвинте эту панель подальше.
    }

    procedure TForm1.Panel1MouseDown(Sender: TObject;
    Button: TMouseButton;
    Shift: TShiftState;
    X, Y: Integer);
    const SC_DRAGMOVE = $F012;
    begin ReleaseCapture;
    Panel1{а если сюда написать Form1, то можно таскать форму по экрану}.Perform(WM_SYSCOMMAND, SC_DRAGMOVE, 0);
    end;


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

    Из конференции Expert_FAQ

    Вопрос

    Как передать строку другому приложению?

    Ответ

    Используйте следующий код:

    В приложении-получателье:

    procedure ReceiveMessage (var Msg: TMessage); message WM_COPYDATA;
    ..
    procedure TFormReceive.ReceiveMessage;
    var
        pcd : PCopyDataStruct;
    begin
        pcd := PCopyDataStruct(Msg.LParam);
        Caption := PChar(pcd.lpData);
    end;

    в приложении-отправителе:

    procedure TFormXXX.Button1Click(Sender: TObject);
    var
      cd : TCopyDataStruct;
    begin
      cd.cbData := Length(Edit1.Text)+1;
      cd.lpData := PChar(Edit1.Text);
    SendMessage ( FindWindow('TFormReceive', nil),WM_COPYDATA,0,LParam(@cd));
    end;

    Leonid Troyanovsky

    Вопрос

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

    Ответ

    Пишешь еще одну прогу, которая будет заниматься удалением. И программно запускаешь. Она делает попытки удаления то тех пор, пока у нее это не получится. Понятно, что для того, чтобы получилось, нужно будет основную прогу завершить. EXE'шник проги для удаления можно таскать в ресурсах основной проги. Хотя это довольно-таки замороченный способ.

    Novikov Dmitry

    Вопрос

    У меня есть форма(form2), у которой не ни верхней полосы с кнопками, ни границ. Как мне сделать чтобы по нажатию и удерживанию левой кнопки мыши форма цеплялась и перемешалась с мышкой.

    Ответ

    Это делается просто. Обьясняю саму идею: сначала обьявляем некую глобальную переменную, которой мы будем присваивать true если окно тащат, и false если нет, и еще две глобальных переменных, где будем хранить старые координаты окна.
    В OnMouseDown мы будем давать булевой переменной — true, OnMouseUp — false, а в OnMouseMove — мы будем перемещать окно. Вот и все. А теперь в коде.

    private
    { Private declarations }
    Dragging : Boolean;
    OldLeft, OldTop: Integer;
    procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
    Shift: TShiftState; X, Y: Integer);
    begin
    if button=mbLeft then
    begin
    Dragging := True;
    OldLeft := X;
    OldTop := Y;
    end;
    end;
    procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
    Y: Integer);
    begin
    if Dragging then
    begin
    Left := Left+X-OldLeft;
    Top := Top+Y-OldTop;
    end;
    end;
    procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
    Shift: TShiftState; X, Y: Integer);
    begin
    Dragging:=false;
    end;


    Из конференции Expert_FAQ

    Вопрос

    Есть форма (Form1), компонент TListView (List1), 2 кнопки (B1, B2, 1-я "Вверх", 2-я "Вниз"). Как мне сделать так, чтобы при нажатии кнопки "Вверх" выбранная мною строка переместилась вверх тем самым верхнюю строчку опустить вниз. И обратное действие при нажатии на кнопку "Вниз"?

    Ответ

    Перемещение вниз:

    Procedure DownClick;
    var s:string;
    begin
    if List1.items.Count=0 then exit; // если список пуст — выходим
    if List1.ItemIndex=List1.items.count-1 then exit; //если выделен последний элемент
    //списка — вниз двигать некуда — выходим
    s:=list1.Items[List.ItemIndex]; // \
    list1.Items[List.ItemIndex]:=list1.Items[List.ItemIndex+1]; // } меняем местами записи
    list1.Items[List.ItemIndex+1]:=s; // /
    list1.ItemIndex:=List1.ItemIndex+1; // перемещаем выделение на строку ниже.
    end;

    Перемещение вверх делается аналогично :

    Procedure UpClick;
    var s:string;
    begin
    if List1.items.Count=0 then exit; // если список пуст — выходим
    if List1.ItemIndex=0 then exit; //если выделен первый элемент
    //списка — вверх двигать некуда — выходим
    s:=list1.Items[List.ItemIndex]; // \
    list1.Items[List.ItemIndex]:=list1.Items[List.ItemIndex-1]; // } меняем местами записи
    list1.Items[List.ItemIndex-1]:=s; // /
    list1.ItemIndex:=List1.ItemIndex-1; // перемещаем выделение на строку выше.
    end;

    Из конференции Expert_FAQ

    Вопрос

    Как перетащить файлы из проводника в мою программу?

    Ответ

    TMainForm = class(TForm)
        …
    private
        procedure WMDROPFILES(var Message: TWMDROPFILES); message WM_DROPFILES;
        procedure ProcessFile(Filename: string);
    end;

    procedure TMainForm.FormCreate(Sender: TObject);
    begin
        DragAcceptFiles(MainForm.Handle, TRUE); // enable drag&drop
    end;

    procedure TMainForm.ProcessFile(Filename: string);
    begin
    // any actions
    end;

    procedure TMainForm.WMDROPFILES(var Message: TWMDROPFILES);
    var
        Files : Longint;
        I : Longint;
        Buffer : array[0..MAX_PATH] of Char;
    begin
        Files := DragQueryFile(Message.Drop,$FFFFFFFF,nil,0); // Get count of files
        for I := 0 to Files — 1 do begin
            DragQueryFile(Message.Drop,I,@Buffer,SizeOf(Buffer)); // Get N file
            ProcessFile(Buffer); // do something with the file
        end;
        DragFinish(Message.Drop); // end drag loop
    end;


    Anatoly Podgoretsky

    Вопрос

    Как плавно изменить цвет панели от черного к красному?

    Ответ

    Кинь на форму TPanel (это будет Panel1) и батон (Button1). У панели поменяй цвет на "clBlack" (RGB — #000000). Далее в обработчике onClick батона напиши следующее:

    procedure TForm1.Button1Click(Sender: TObject);
    var
    i:integer;
    begin
    //Изменять будем только красную компоненту цвета,
    //ее возможные значения — 0..255 (byte)
    For I:=1 to 255 do begin
    //Установим цвет функцией RGB — она
    //возвращает цвет по его составляющим
    Panel1.Color:=RGB(i,0,0);
    //Сделаем задержку
    sleep(10);
    //Обработаем системные сообщения
    Application.processmessages
    end;
    end;


    Небольшое пояснение к комментариям. Задержку выставляй какую тебе надо — это не существенно, просто со значением 10 у меня выглядело лучше всего.
    Системные сообщения обработать НЕОБХОДИМО! Среди них есть мессага WM_PAINT, после получения которой прга перерисует свое окно. Если этого не делать, то цвет измениться резко — как закончиться процедура так тут же и произойдет изменение цвета, а нам надо изменять цвет в цикле, с задержкой.
    ЗЫ: таким же способом можно изменять цвет шрифта, например что б плавно появилась надпись на панели.

    Из конференции Expert_FAQ

    Вопрос

    Иногда происходит такой глюк — CodeExplorer (это который по умолчанию слева сверху) перестает реагировать на мышь и клавиши. Помогает только перезапуск дельфей.
    Как это можно побороть?

    Ответ

    Когда зависло, выбираешь меню File — Close All (желательно чтобы у вас было включено автосохранение среды?). Потом File — Reopen и открываешь последний проект. Все-таки это шустрее чем перегруз всей Delphi. Хотя в некоторых случаях может зависнуть сама среда разработки.

    A.Z.

    Вопрос

    Как справку в файле *.chm правильно подключить к моему приложению, чтобы была возможность вызывать отдельные темы справки?

    Ответ

    На сайте http://www.helpandmanual.com (на английском языке) есть все, что надо для прикручивания и создания chm-справки.

    Краснов Кирилл

    Вопрос

    Как показать Hint для MenuItem?

    Ответ

    Hint, назначенный Item, можно показать в Statusbar:

    procedure TForm1.AppHint(Sender: TObject);
    begin
        StatusBar1.SimpleText := Application.Hint;
    end;

    procedure TForm1.FormCreate(Sender: TObject);
    begin
        Application.OnHint := AppHint;
    end;

    Из конференции Delphi

    Вопрос

    Как показать диалог выбора директории?

    Ответ

    из модуля FileCtrl.

    1. function SelectDirectory(const Caption: string; const Root: WideString; out Directory: string): Boolean; overload;
    2. function SelectDirectory(var Directory: string; Options: TSelectDirOpts; HelpCtx: Longint): Boolean; overload;

    из RxLib
    TDirectoryEdit

    function GetDirectory(nFolder: Longint): String;
    var
        Bi : TBrowseInfo;
        lpName: array [0..MAX_PATH] of Char;
        ppidl, aItemLst : PItemIDList;
    begin
     SHGetSpecialFolderLocation(Application.Handle, nFolder, pppidl);
        FillChar(Bi, SizeOf(bi), 0);
        Bi.hwndOwner := Application.Handle;
        Bi.pidlRoot := ppidl;
        Bi.pszDisplayName := lpName;
        Bi.lpszTitle := 'Open directory';
        aItemLst := SHBrowseForFolder(Bi);
        CoTaskMemFree(ppidl);
        SHGetPathFromIDList(aItemLst, lpName);
        CoTaskMemFree(aItemLst);
        Result := lpName;
    end;

    Пример использования (иначе не поймут, что такое nFolder)

    // значения nFolder можно найти в описании
    // к SHGetSpecialFolderLocation
    // из Win32 Programmer's Reference (win32.hlp)
    procedure TForm1.Button1Click(Sender: TObject);
    begin
        Caption := GetDirectory(CSIDL_DRIVES);
    end;

    Из конференции Delphi

    Вопрос

    Как показать картинку в моей программе из ресурса DLL библиотеки, т.е. компилируется res файл DLL и она прикладывается к проге, а сами ресурсы используются в программе, вызывающей DLL?

    Ответ

    1 Посмотри демо пример в Delphi ..\Delphi\Demos\Resxplor\ — там и ответ на твои вопросы.

    2 Написать что-то типа этого (сорри, не запускал и не отлаживал, возможны ошибки)

    uses …,Sysutils;
    procedure TfrmMain.CheckForAddFlow;
    var SearchRec: TSearchRec; LibHandle: Cardinal;
    ResStream: TResourceStream;
    begin if FindFirst('your-lib.dll', faAnyFile, SearchRec) <> 0 then begin {Загружаем библиотеку} LibHandle := LoadLibrary('your-lib.dll');
    if Handle <> 0 then {Загружаем ресурс} ResStream := TResourceStream.Create(LibHandle, PChar('res_name'), RT_BITMAP);
    try ImageViewer.Picture.Graphic.LoadFromStream(ResStream);
    finally ResStream.Free();
    end;
    end;
    end;
    //ShowMessage(IntToStr(AllocMemCount) + ':' + IntToStr(AllocMemSize));
    end;


    Из конференции Expert_FAQ

    Вопрос

    Как показать текстовый файл в TLabel?

    Ответ

    procedure TForm1.Button1Click(Sender: TObject);
    var
        fs : TFileStream;
        s : String;
    begin
    fs := TFileStream.Create('unit1.pas', fmOpenRead or fmShareDenyNone );
        SetLength(s, fs.Size);
        fs.Read(s[1], Length(s));
        fs.Free;
        Label1.Caption := s;
    end;

    Из конференции Delphi

    Вопрос

    Как показывать хинты для частично видимых элементов ListBox?

    Ответ

    Hаписать для OnMouseMove следующий код:

    procedure TForm1.ListBox1MouseMove(Sender: TObject; Shift: TShiftState; X,Y: Integer);
    const
        oldidx : Longint = -1;
    var
        idx : Longint;
    begin
        with Sender as TListBox do begin
       idx := ItemAtPos(Point(x,y),True);
       if (idx < 0) or (idx = oldidx) then Exit;
       Application.ProcessMessages;
       Application.CancelHint;
            oldidx := idx;
            Hint := '';
    if Canvas.TextWidth(Items[idx]) > Width — 4 then Hint:=Items[idx];
        end;
    end;

    Из конференции Delphi

    Вопрос

    Как получить выделенный текст из окна Internet Explorer?

    Ответ

    Вот так:

    uses SHDocVw_TLB;
    // если у Вас нет этого модуля, то Вам сюда:
    http://www.euromind.com/iedelphi/

    function GetSelectedIEtext: string;
    var
        x: Integer;
        Sw: IShellWindows;
        IE: HWND;
    begin
        IE := FindWindow('IEFrame', nil);
        sw := CoShellWindows.Create;
        for x := SW.Count — 1 downto 0 do
       if (Sw.Item(x) as IWebbrowser2).hwnd = IE then begin
    Result := variant(Sw.Item(x)).Document.Selection.createRange.Text;
            break;
        end;
    end;

    Из конференции Delphi

    Вопрос

    Как в программе получить данные и ключи, переданные в командной строке?

    Ответ

    Функция ParamStr(I:Integer) возвращает I-тый параметр командной строки. 0-вой параметр — полный путь к файлу и имя файла запуска. 1,2,3,4 и т.д — соответственно, параметры по порядку.

    if (LowerCase(ParamStr(1)) = 'exit' then Application.Terminate;

    Вопрос

    Подскажите, как получить данные о компьютере, как-то: тип процессора, модель материнки, тип винчестера, количество и тип памяти и т.п.

    Ответ

    Установите компонент MiTeC System Information Component (MSystemInfo).

    Ищите на www.torry.net или www.vclcomponents.ru

    Весит он почти 7 Мб. В нем содержится ряд подпрограмм для извлечения информации о компьютере — смотрите исходники.

    Из конференции Expert_FAQ

    Есть очень хорошая программа по сбору информации о компьютере AIDA32 — Personal System Information

    shah

    Вопрос

    Как получить имена всех ресурсов существующих в приложении?

    Ответ

    type
       TForm1 = class(TForm)
         Button1: TButton;
         Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
       private
       end;

    var
       Form1: TForm1;

    implementation

    {$R *.dfm}

    function enumResNamesProc(module: HMODULE; restype, resname: PChar;
       list: TStrings): Integer; stdcall;
    begin
       if HiWord(Cardinal(resname)) <> 0 then
         list.Add(' ' + resname)
       else
    list.Add(Format(' #%d', [loword(Cardinal(resname))]));
       Result := 1;
    end;

    Function StockResourceType(restype: PChar): string;
    const
    Array [1..22] of String =
    ( 'RT_CURSOR', // = MakeIntResource(1);
    'RT_BITMAP', // = MakeIntResource(2);
    'RT_ICON', // = MakeIntResource(3);
    'RT_MENU', // = MakeIntResource(4);
    'RT_DIALOG', // = MakeIntResource(5);
    'RT_STRING', // = MakeIntResource(6);
    'RT_FONTDIR',// = MakeIntResource(7);
    'RT_FONT', // = MakeIntResource(8);
    'RT_ACCELERATOR',// = MakeIntResource(9);
    'RT_RCDATA', // = MakeIntResource(10);
    'RT_MESSAGETABLE',// = MakeIntResource(11);
    // DIFFERENCE = 11;
    'RT_GROUP_CURSOR',// = MakeIntResource(DWORD(RT_CURSOR +7DIFFERENCE));
    'UNKNOWN', // 13 not used
    'RT_GROUP_ICON', // = MakeIntResource(DWORD(RT_ICON +DIFFERENCE));
    'UNKNOWN', // 15 not used
    'RT_VERSION', // = MakeIntResource(16);
    'RT_DLGINCLUDE', // = MakeIntResource(17);
    'UNKNOWN',
    'RT_PLUGPLAY', // = MakeIntResource(19);
    'RT_VXD', // = MakeIntResource(20);
    'RT_ANICURSOR', // = MakeIntResource(21);
    'RT_ANIICON' // = MakeIntResource(22);
         );
    var
       resid: Cardinal absolute restype;
    begin
    if resid in [1..22] then Result := restypenames[resid]
    else Result := 'UNKNOWN';
    end;

    function enumResTypesProc(module: HMODULE; restype: PChar; list: TStrings):
    Integer; stdcall;
    begin
    if HiWord(Cardinal(restype)) <> 0 then list.Add(restype)
         else
    list.Add(Format('Stock type %d: %s', [LoWord(Cardinal(restype)),
    StockResourcetype(restype)]));
    EnumResourceNames(module, restype, @enumResNamesProc, Integer(list));
       Result := 1;
    end;

    procedure TForm1.Button1Click(Sender: TObject);
    begin
       memo1.Clear;
    if not EnumResourceTypes(hinstance, @enumResTypesProc, Integer(memo1.Lines)) then
    memo1.Lines.Add(Format('GetLastError= %8.8x', [GetLastError]))
       else
       memo1.Lines.Add('Выполнено');
    end;
    end

    Кирилл Краснов

    Вопрос

    Как получить короткий путь файла если имеется длинный?

    Ответ

    Использйте функцию GetShortPathName()

    Из конференции Delphi

    Вопрос

    Как получить набранный в Блокноте текст в свою пpогpаммку?

    Ответ

    function GetWindText(AHandle: THandle): String;
    var
        cb : DWord;
    begin
     cb := SendMessage(AHandle, WM_GETTEXTLENGTH, 0, 0);
        SetLength(Result, cb);
        if cb > 0 then
     SendMessage(AHandle, WM_GETTEXT, cb+1, LParam(@Result[1]));
    end;

    procedure TForm1.Button1Click(Sender: TObject);
    var
        AHandle: THandle;
    begin
        AHandle := FindWindow('Notepad', nil);
        Win32Check(AHandle <> 0);
     AHandle := FindWindowEx(AHandle, 0, 'Edit', nil);
        Win32Check(AHandle <> 0);
        Memo1.Text := GetWindText(AHandle);
    end;

    Из конференции Delphi

    Вопрос

    Как получить путь к временному каталогу windows или назначенному в Autoexec.bat?

    Ответ

    unction GetTempPath(nBufferLength: DWORD; lpBuffer: PChar): DWORD;
    nBufferLength
    Размер буфера для приема строки
    lpBuffer
    Указатель на буфер, в который будет помещен путь к temp-директории.

    Если произошла ошибка, функция вернет 0.
    Путь берется в следующем порядке:

    1. Указанный в переменной TMP
    2. Указанный в переменной TEMP, если TMP не задан.
    3. Текущий путь, если ни TMP, ни TEMP не заданы.

    Из конференции Expert_FAQ

    Вопрос

    Как получить список всех таблиц базы данных с помощью ADO?

    Ответ

    unit dbTables;
    interface
    uses ADODb;

    type
    TTableType = (ttTable, ttView, ttSynonym, ttSystemTable, ttAccessTable);

    type
      TTableTypes = set of TTableType;

    type
      TTableItem = record
          ItemName: string;
          ItemType: string;
      end;

    type
      TTableItems = array of TTableItem;

    function addFilter(string1, string2: string): string;
    function ADODbTables(ADOConnection: TADOConnection; types: TTableTypes): TTableItems;

    implementation

    function addFilter(string1, string2: string): string;
    begin
      if string1 <> '' then Result := string1 + ' or ' + string2
    else Result := string2;
    end;

    function ADODbTables(ADOConnection: TADOConnection; types: TTableTypes): TTableItems;
    var
      ADODataSet: TADODataSet;
      i: integer;
    begin
    ADODataSet := TADODataSet.Create(nil);
    ADODataSet.Connection := ADOConnection;
    ADOConnection.OpenSchema(siTables, EmptyParam, EmptyParam, ADODataSet);
      if (ttTable in types) then
    ADODataSet.Filter := addFilter(ADODataSet.Filter, '(TABLE_TYPE = ''TABLE'')');

      if (ttView in types) then
    ADODataSet.Filter := addFilter(ADODataSet.Filter, '(TABLE_TYPE = ''VIEW'')');

      if (ttSynonym in types) then
    ADODataSet.Filter := addFilter(ADODataSet.Filter, '(TABLE_TYPE = ''SYNONYM'')');

      if (ttSystemTable in types) then
    ADODataSet.Filter := addFilter(ADODataSet.Filter, '(TABLE_TYPE = ''SYSTEM TABLE'')');

      if (ttAccessTable in types) then
    ADODataSet.Filter := addFilter(ADODataSet.Filter, '(TABLE_TYPE = ''ACCESS TABLE'')');

      ADODataSet.Filtered := True;
      SetLength(Result, ADODataSet.RecordCount);
      i := 0;
      with ADODataSet do
      begin
    First;
     while not EOF do
       begin
    with Result[i] do
      begin
    ItemName := FieldByName('TABLE_NAME').AsString;
    ItemType := FieldByName('TABLE_TYPE').AsString;
     end;
      Inc(i);
       Next;
          end;
      end;
      ADODataSet.Free;
    end;
    end.

    {
    Пример: Создайте новый проект и добавьте TADOConnection (ADOConnection1),
    TButton (Button1) и TMemo (Memo1); присвойте ConnectionString к
    TADOConnection и установить "ADOConnection1.Active := True"
    }

    procedure TForm1.Button1Click(Sender: TObject);
    var
      output: ttableitems;
      i: integer;
    begin
    output := ADODbTables(ADOConnection1, [ttTable, ttView, ttSynonym]);
    // output := ADODbTables(ADOConnection1, [ttSystemTable, ttAccessTable]);
      for i := Low(output) to High(output) do
      begin
    Memo1.Lines.Add(output[i].ItemName + '---' + output[i].ItemType);
      end;
      output := nil;
    end;

    Из конференции Delphi

    Вопрос

    Как получить список файлов со всеми подкаталогами

    Ответ

    procedure ScanDir(StartDir: string; Mask:string; List:TStrings);
    var
    SearchRec : TSearchRec;
    begin
        if Mask = '' then Mask := '*.*';
    if StartDir[Length(StartDir)] <> '\' then StartDir := StartDir + '\';
     if FindFirst(StartDir+Mask, faAnyFile, SearchRec) = 0 then
        begin
            repeat
           Application.ProcessMessages;
    if (SearchRec.Attr and faDirectory) <> faDirectory then List.Add(StartDir + SearchRec.Name)
    else if (SearchRec.Name <> '..') and (SearchRec.Name <> '.') then begin
     List.Add(StartDir + SearchRec.Name + '\');
    ScanDir(StartDir + SearchRec.Name + '\',Mask,List);
        end;
    until FindNext(SearchRec) <><> 0;
            FindClose(SearchRec);
        end;
    end;

    Пример вызова. параметры

    1. имя папки
    2. маска, по умолчанию *.*
    3. хранилище для резульатат, любой наследник от TString, например TStringList

    procedure TForm1.Button1Click(Sender: TObject);
    begin
        ListBox1.Items.Clear;
        ScanDir('c:','',ListBox1.Items);
    Label1.Caption := IntToStr(ListBox1.Items.Count);
    end;

    Анатолий Подгорецкий

    Вопрос

    Как получить список файлов со всеми подкаталогами?

    Ответ

    Вот так:

    procedure ScanDir(StartDir: string; Mask:string; List:TStrings);
    var
    SearchRec : TSearchRec;
    begin
        if Mask = '' then Mask := '*.*';
        if StartDir[Length(StartDir)] <> '\' then StartDir := StartDir + '\';
        if FindFirst(StartDir+Mask, faAnyFile, SearchRec) = 0 then
        begin
            repeat
                Application.ProcessMessages;
                if (SearchRec.Attr and faDirectory) <> faDirectory then List.Add(StartDir + SearchRec.Name)
                else if (SearchRec.Name <> '..') and (SearchRec.Name <> '.') then begin
                    List.Add(StartDir + SearchRec.Name + '\');
                    ScanDir(StartDir + SearchRec.Name + '\',Mask,List);
                end;
            until FindNext(SearchRec) <> 0;
            FindClose(SearchRec);
        end;
    end;


    Пример вызова. параметры
    1. имя папки
    2. маска, по умолчанию *.*
    3. хранилище для резульатат, любой наследник от TString, например TStringList

    procedure TForm1.Button1Click(Sender: TObject);
    begin
        ListBox1.Items.Clear;
        ScanDir('c:','',ListBox1.Items);
        Label1.Caption := IntToStr(ListBox1.Items.Count);
    end;


    Анатолий Подгорецкий

    Вопрос

    Как получить уникальный идентификационный номер винчестера?

    Ответ

    Не совсем то, что вам надо, но все же:

    Из советов Валентина Озерова:

    Как получить серийный номер тома жесткого диска?

    procedure TForm1.Button1Click(Sender: TObject);
    var VolumeName, FileSystemName : array [0..MAX_PATH-1] of Char;
    VolumeSerialNo : DWord;
    MaxComponentLength, FileSystemFlags : Integer;
    begin GetVolumeInformation('C:\',VolumeName,MAX_PATH,@VolumeSerialNo, MaxComponentLength,FileSystemFlags, FileSystemName,MAX_PATH);
    Memo1.Lines.Add('VName = '+VolumeName);
    Memo1.Lines.Add('SerialNo = $'+IntToHex(VolumeSerialNo,8));
    Memo1.Lines.Add('CompLen = '+IntToStr(MaxComponentLength));
    Memo1.Lines.Add('Flags = $'+IntToHex(FileSystemFlags,4));
    Memo1.Lines.Add('FSName = '+FileSystemName);
    end;


    Замечание: у меня в XP Delphi 7 выдавала ошибку,
    «Types of actual and formal var parameters must be identical».
    Я заменил
    MaxComponentLength, FileSystemFlags : Integer; на MaxComponentLength, FileSystemFlags : Cardinal и все заработало.

    Из конференции Expert_FAQ

    Серийный номер винчестера и серийный номер тома (логич. диск) винчестера — это разные вещи.

    psv-savage

    Вопрос

    Уже несколько лет работаю на дельфи, но так до сей поры не понял что за Code Insight и с чем его едят ну конечно я не совсем тормоз чтобы не понять что это нужно для ускорения ввода текста программы… но как ей пользоваться например в tools|Editor options| Code Insight Есть сокращение tryf как сделать так, чтоб после того как я ввел tryf в едиторе появился код: try | finally end; или тут есть какая то заморочка… или я действительно конченный тормоз Заранее благодарен за ответ С уважением Не Подтвержденный Тормоз

    Ответ

    Для этого есть комбинация клавиш Ctrl+j. Тут есть два варианта. Если ты уже ввел название шаблона, то сразу вставляется шаблон. Если ты ничего не вводил, то появится список всех шаблонов.

    Виталий.

    Вопрос

    Как поменять Items в ListView?

    Ответ

    var LI: TListItem; begin ListView1.Items.BeginUpdate; LI:=TListItem.Create(ListView1.Items); try LI.Assign(ListView1.Items[0]); ListView1.Items[0].Assign(ListView1.Items[1]); ListView1.Items[1].Assign(LI); finally LI.Free; ListView1.Items.EndUpdate; end; end;

    Из конференции Expert_FAQ

    Вопрос

    Как поменять иконку и стpокy в заголовке консольного окна?

    Ответ

    procedure TForm1.Button1Click(Sender: TObject);
    var
        h : HWND;
        AIcon : TIcon;
    begin
        AllocConsole;
        SetConsoleTitle(PChar('Console Title'));
        Sleep(0);
        h := FindWindow(nil, PChar('Console Title'));
        AIcon := TIcon.Create;
        ImageList1.GetIcon(0, AIcon);
        SendMessage(h, WM_SETICON, 1, AIcon.Handle);
        AIcon.Free;
    end;

    Leonid Troyanovsky

    Вопрос

    Как поместить иконку приложения в Sуstem Tray?

    Ответ

    Там где нужно создать иконку — ставишь код из FormCreate, там где удалить — из FormDestroy. Для изменения иконки нужно:

    pnid.hIcon присвоить новое значение иконки

    вызвать Shell_NotifyIcon(NIM_MODIFY, Addr(pnid))

    unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, shellapi, ExtCtrls; type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); end; const WM_NOTIFYTRAYICON = (WM_USER+1); // сообщения от иконки. // нужно только если будет обработка событий от иконки var Form1: TForm1; pnid: NOTIFYICONDATA; // указатель на структуру описывающую иконку implementation {$R *.DFM} procedure TForm1.FormCreate(Sender: TObject); begin pnid.cbSize := sizeof(NOTIFYICONDATA); // размер структуры pnid.Wnd := Form1.Handle; // HWND окна, которое будет обрабатывать сообщения от иконки pnid.uID := 0; // номер иконки pnid.uFlags := NIF_ICON + NIF_TIP; // иконка видна + у нее есть хинт pnid.hIcon := CopyIcon(Application.Icon.Handle); pnid.szTip := 'Пример иконки'; // хинт { pnid.uCallbackMessage := WM_NOTIFYTRAYICON; // сообщение которое будет посылать иконка, при действиях с ней // будет работать, если добавить NIF_MESSAGE в pnid.uFlags } Shell_NotifyIcon(NIM_ADD, Addr(pnid)); // добавляем иконку в трей end; procedure TForm1.FormDestroy(Sender: TObject); begin Shell_NotifyIcon(NIM_DELETE, Addr(pnid)); // убираем иконку их трея, иначе будеи там сидеть до тех пор, пока не проведеш мышью над треем end; end.

    Из конференции Expert_FAQ

    Вопрос

    Как помигать Scroll Lock'ом?

    Ответ

    procedure TForm1.Timer1Timer(Sender: TObject);
    begin
        keybd_event(VK_SCROLL, 0, 0, 0);
        keybd_event(VK_SCROLL, 0, vk_up, 0);
    end;

    procedure TForm1.Timer1Timer(Sender: TObject);
    begin
     keybd_event(VK_SCROLL, MapVirtualKey(VK_SCROLL, 0) , 0, 0);
     keybd_event(VK_SCROLL, MapVirtualKey(VK_SCROLL, 0), vk_up, 0);
    end;

    Leonid Troyanovsky

    Вопрос

    Как помигать лампочками на клавиатуре?

    Ответ

    var
        KeyState : TKeyboardState;
    begin
        GetKeyboardState(KeyState);
        KeyState[VK_NUMLOCK] := KeyState[VK_NUMLOCK] xor 1;
        SetKeyboardState(KeyState);
    end;


    Изменяет состояние индикаторов на обратное…
    См. также справочную информацию по VK_NUMLOCK, VK_CAPITAL

    WinNT:
            {
            keybd_event( VK_SCROLL, 0x46, KEYEVENTF_EXTENDEDKEY | 0, 0 );
            keybd_event( VK_SCROLL, 0x46, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP,0);
            }


    Stas Malinovski

    Вопрос

    Как правильно завершить поток и освободить занимаемую им память — в примере, описанном ниже, если код MyThrd.Terminate; MyThrd.Free; после выхода из потока вешает компьютер. При отработке кода до конца (без принудительного останова) никаких проблем не возникает. Пример:
    Procedure TMyThread.Execute;
    Begin

    Recurs(:.);

    End;
    Procedure TMyThread.Recurs(:..);
    Begin

    Recurs(:.);

    End;

    Ответ

    Проблема в том, что вызов Terminate не означает немедленного завершения потока. Terminate просто устанавливает в true поле Terminated, так что во время вызова MyThread.Free поток еще выполняется, откуда и проблемы! Чтобы избавиться от них, можно в начале Recurs поставить проверку Terminated:

    procedure TMyThread.Recurs; begin if Terminated then exit; … Recurs(…); if Terminated then exit; … end;

    После вызова Terminate надо еще вызвать TMyThread.WaitFor, чтобы дождаться, пока поток действительно завершится.

    Еще небольшое примечание: у TThread есть свойство FreeOnTerminate. Если оно равно true, то Free можно не вызывать — поток сам освободит занимаемую память при завершении.

    Вопрос

    Как правильно закрыть и удалить форму? Почему моя MDI Child форма при закрывании просто минимизируется?

    Ответ

    Обрабатывайте событие OnClose для формы и выставляйте в нем параметр Action в caFree. Дело в том, что его значение по умолчанию для MDI Child форм caMinimize. Кстати, если сделать Action := caNone, то форму нельзя будет закрыть.

    Из конференции Delphi

    Вопрос

    Как правильно конвертировать текстовую строку (буквы+цифры+спец_символы) в 16-ричный вид?

    Ответ

    Вот функция, она преобразовывает значение типа "byte" в строку, состоящую из двух символов (как в HEX-виверах). Перебери все символы и отправь их коды поочереди в эту функцию — получишь набор шестнадцатиричных кодов. Минус — она рассчитана на ASCII таблицу символов. Если будет выдавать неправильный код символа — подправь значения в строках (1) и (2) — у меня они равны 55. Это разница между цифрой (0..9) и буквами (A..F) из таблицы символов.

    function TForm1.IntToHex(a:byte):string;
    var
    s:string;
    t1,t2:byte;
    begin
    s:='';
    t1:=a div 16;
    t2:=a mod 16;
    if t1<10 then s:=s+inttostr(t1)
    else s:=s+chr(t1+55); //(1)
    if t2<10 then s:=s+inttostr(t2)
    else s:=s+chr(t2+55); //(2)
    IntToHex:=s;
    end;


    Из конференции Expert_FAQ

    Вопрос

    Версия языка:6
    Как правильно (удобно и удачно) работать с датами?

    Например в типе TDateTime даты записываются как dd.mm.yy, а хотелось бы dd.mm.yyyy, т.к. путаница получается. Дайте plz совет по этому поводу.

    И еще одно: есть строка с датой. Если ли стандартные функции для проверки правильности синтаксиса введенной даты? А то если дата неправильная прога просто вылетает с ошибкой :( Что посоветуете?

    Ответ

    1. formatdatetime('dd' + dateseparator + 'mm' + dateseparator + 'yyyy', date);
    2.На OnKeyPress повесить
    if (key = '.') or (key = ',') or (key = '/') then key := dateseparator;

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

    var d: tdatetime;
    try
    d := strtodate(edit1.text);
    except
    d := date;
    // материмся чем-нибудь красным
    // по поводу неверного ввода и предупреждаем,
    // что по умолчанию воткнули текущую дату
    end;
    edit1.text := datetostr(d);
    faormatdatetime — (F1)
    strtodate — (F1)
    datetostr — (F1)

    Из конференции Expert_FAQ

    Вопрос

    Как правильно создавать компоненты в run-time? Что задавать в качестве параметра Owner при создании компоненты? Как обрабатывать события от созданных компонент, типа нажатий на кнопки?

    Ответ

    Hачнем с создания.
    Сущность свойства Owner в том, что владелец перед смертью уничтожает (через Free) принадлежащие ему объекты. Таким образом, все зависит от того, кому вы хотите доверить уничтожение созданных форм/компонентов. В частности, если вы сами будете этим заниматься, то AOwner может быть, например, nil.
    Для того, чтобы созданный компонент появился на экране, надо указать его родителя, заполнив свойство Parent, например,

    NewButton.Parent := Form1;

    Пример кода, обрабатывающего события от свежесозданных компонентов:

    type
      TForm1 = class(TForm)
      { … }
      private
      { эта процедура будет вызываться при нажатии на кнопку }
      procedure ButtonClicked(Sender : TObject);

      public
      { в этой процедуре происходит создание кнопки }
          procedure CreateButton;

      end;

    { … }

    procedure TForm1.CreateButton;
    var
        btn : TButton;
    begin
     btn := TButton.Create(Self); // Уничтожать кнопку будет форма
     btn.Parent := Self; // Родителем кнопки будет форма
     btn.OnClick := ButtonClicked; // Процедура, которая будет исполняться при
     btn.Visible := true; // нажатии на кнопку
    end;

    Из конференции Delphi

    Вопрос

    Как правильно указать путь к файлу, лежащему в текущей папке?

    Ответ

    Вот так:

    x:= ExtractFilePath(ParamStr(0))+'info\index.html';

    x — это переменная, в которую вы загоняете путь к файлу для дальнейшего использования в вашей программе.

    Из конференции Delphi

    Вопрос

    Как запретить автодобавление новой записи в DBGrid при нажатии клавиши вниз, когда стоишь на последней записи?

    Ответ

    Добавь в событие "BeforeInsert" компонентов TTable следущие строки:

    procedure TForm1.Tbable1BeforeInsert(DataSet: TDataSet);
    begin
          Abort;
    end;

    А вот такая процедура перехватывает нажатие клавиш и проверяет достигнут ли конец данных в таблице

    procedure TForm8.DBGrid1KeyDown(Sender: TObject; var Key: Word;
        Shift: TShiftState);
    begin
        if (Key = VK_DOWN) then
        begin
            TTable1.DisableControls;
            TTable1Next;
            if TTable1.EOF then
                 Key := 0
            else
                 TTable1.Prior;
            TTable1.EnableControls;
        end;
    end;

    Из конференции Delphi

    Вопрос

    Исходные данные:

    Есть главная форма, которая вызывает доченюю, скажем Form2.Show;

    В дочерней форме на событии OnShow висит обработчик, который в процессе каких-то вычислений может выяснить, что показ формы не имеет смысла.

    Вопрос, значит такой: Как прекратить загрузку дочернего окна из него же?

    Просто Form2.Close; не работает.

    Предвижу ответ: «Сначала проверяй, потом вызывай Show»

    Обработчик занимает более 2000 строк и выяснится, что грузиться не надо может в любом месте обработчика, а переносить код из дочерней формы в главную — таких дочерних форм 43 штуки, на 2000 умножить? :) Как быть?

    Ответ

    А как ты создаешь дочерние окна???

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

    В модуле для дочернего окна:

    type TFrmChild = class(TForm) procedure FormClose(Sender: TObject; var Action: TCloseAction); private { Private declarations } public { Public declarations } end; procedure ActivateFrmChild; var FrmChild: TFrmChild; implementation {$R *.dfm} … procedure ActivateFrmChild; begin FrmChild := TFrmChild.Create(Application); end; … procedure TFrmChild.FormClose(Sender: TObject; var Action: TCloseAction); begin Action:=caFree; // Это уничтожит дочернее окно end; end.

    В главной форме где надо вызываешь ActivateFrmChild. Т.е. там, где твой огромный обработчик это разрешит. Также необходимо убрать дочерние окна из списка автосоздаваемых форм. Это значительно экономит ресурсы…

    Из конференции Expert_FAQ

    Вопрос

    Как преобразовать String в PChar и обратно

    Ответ

    Для этого достаточно приведения

    StringVar := String(PCharVar);
    PCharVar := PChar(StringVar);

    Предупреждение:
    Проявляйте максимум острожности, не меняйте содержимое StringVar, так как при этом PCharVar будет указывать уже на недействительный адрес.

    Из конференции Delphi

    Вопрос

    Как преобразовать unix time в TDateTime

    Ответ

    unix timestamp представляет собой число секунд начиная с 1.01.1970

    const
        SecPerDay = 86400;
        Offset1970 = 25569;

    function UnixTimeToDateTime(UnixTime : LongInt): TDate;
    begin
     Result := DateTimeToStr(UnixTime / SecPerDay + Offset1970);
    end;

    function DateTimeToUnixTime(DelphiDate : TDate) : LongInt;
    begin
     Result := Trunc((DelphiDate — Offset1970) * SecPerDay);
    end;

    Если необходима корректировка зимнего/летнего времени, то ее следует сделать самостоятельно.

    Из конференции Delphi

    Вопрос

    Как преобразовать unix time в TDateTime?

    Ответ

    unix timestamp представляет собой число секунд начиная с 1.01.1970

    const
        SecPerDay = 86400;
        Offset1970 = 25569;

    function UnixTimeToDateTime(UnixTime : LongInt): TDate;
    begin
        Result := DateTimeToStr(UnixTime / SecPerDay + Offset1970);
    end;

    function DateTimeToUnixTime(DelphiDate : TDate) : LongInt;
    begin
        Result := Trunc((DelphiDate — Offset1970) * SecPerDay);
    end;


    Если необходима корректировка зимнего/летнего времени, то ее следует сделать самостоятельно.

    Из конференции Delphi

    Вопрос

    Как сделать, чтобы при запуске формы проигрывался музыкальный файл (автоматически)?

    Ответ

    Если файл Wav, то можно так:
    PlaySound('td.wav', 0,SND_SYNC);
    Да, и не забываем uses mmsystem

    Sergey

    Вопрос

    Как из программы (или при инсталляции программы) зарегистрировать за программой определJнный тип файла, т.е. щелкаешь по файлу и открывается программа с открытым этим файлом.

    Ответ

    Надо в реестре создать в ветке "HKEY_CLASSES_ROOT" — подключ ".нужное_разширение" ( есесно без кавычек ), там записать значение дефолтовое какое-нть, например "my_file". Затем создаешь еще один подключ "my_file" в этой же ветке реестра "HKEY_CLASSES_ROOT" . В нем создаешь подключ "shell" — в нем подключ "open" — в нем подключ "command" — там дефолтовое значение — "нужная_прога %1", т.е. теперь нужной_прогой будут открываться файлы с расширением ".нужное_расширение".

    Чтоб закрепить за данным типом файлов икошку — создай в ключе "my_file" — подключ "DefaultIcon", а там дефолтовое значение — икошка, которой будут отображаться файлы данного типа.

    Из конференции Expert_FAQ

    Вопрос

    Я на форме поместил браузер, в него загружаю html страницу. Щелкая по ссылкам (на exe файлы) на этой странице вылетает окошко с запросом открытия или сохранения. Как можно избавиться от него, чтобы при клике по ссылке сразу запускался exe файл, без запроса на сохранение?

    Ответ

    Поставить галочку всегда выполнять это действие для файлов с таким расширением (в настройках винды). Это приблуда IE и никак это не обойти. Попробуй написать свой движок :).

    Кирилл Краснов

    Вопрос

    Как при наведении курсора на кнопку менять ее цвет?

    Ответ

    type
      TForm1 = class(TForm)
          BitBtn1: TBitBtn;
      procedure FormCreate(Sender: TObject);
      private
    procedure NewBtnWindowProc(var Msg:TMessage); // Это новый обработчик
      end;

    var
        Form1: TForm1;

    implementation

    {$R *.DFM}

    var
        OldBtnWindowProc : TWndMethod;

    procedure TForm1.NewBtnWindowProc;
    begin
        case msg.Msg of
       CM_MOUSELEAVE: BitBtn1.Font.Color := clGray;
        CM_MOUSEENTER: BitBtn1.Font.Color := clBlack;
        end;
        OldBtnWindowProc(Msg);
    end;

    procedure TForm1.FormCreate(Sender: TObject);
    begin
        OldBtnWindowProc := BitBtn1.WindowProc;
        BitBtn1.WindowProc := NewBtnWindowProc;
    BitBtn1.Perform(CM_MOUSELEAVE,0,0); // Изначально серый
    end;

    Из конференции Delphi

    Вопрос

    Как применить изменение в реестре без перезагрузки компьютера?

    Ответ

    Многие программы могут откликнуться на:

    SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, ..) в Win9х
    SendMessage(HWND_BROADCAST, WM_WININICHANGE, 0, ..) в NT-подобных системах

    Из конференции Delphi

    Вопрос

    Помогите прояснить ситуацию с компонентом tserversocket. Как принять информацию с помощью socket.receivebuf? И как кинуть принятую информацию в untyped файл?

    Ответ

    Проясняю ситуация с компонентом TServerSocket — исходники лежат в файле %DELPHI%\Source\INTERNET\scktcomp.pas его свойство .socket имеет тип TServerWinSocket, исходники которого также лежат в этом файле. Метод ReceiveBuf принадлежит предку — TServerSocket, которому Вы должны передать буфер и размер этого буфера, например так

    var buf:array[1..100] of byte; Num:integer; … Num:=YourServerSocket.Socket.ReceiveBuf(buf[1],100); writeln('получено ',num,' байт:'); if num > 0 then for ind:=1 to num do write(buf[ind]);

    > И как кинуть принятую информацию в untyped файл?

    Не стоит использовать этот тип файла — все гораздо проще

    var ff:file of byte;

    numWritenBiytes:Integer;



    BlockWrite(ff,buf[1],num,numWritenBiytes);

    Честно говоря, мне еще не попадался компонент, с которым было бы удобнее работать, чем напрямую с функциями из модуля WinSock %DELPHI%\Source\RTL\WIN\winsock.pas

    Из конференции Expert_FAQ

    Вопрос

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

    Слышал есть такие компоненты, подскажите как они называються и где их можно найти, и желательно как использовать.

    Ответ

    Пусть главная таблица называется GLAV, подчиненная — PODCH, поле, по которому между ними осуществляется связб один ко многим, — KOD. Тогда для выполнения удаления всех записей в подчиненной таблице, для которых нет кода в главной, выполни следующий запро

    с:

    DELETE FROM podch WHERE kod NOT IN (SELECT kod FROM glav)

    00000000000 Для выполнения запроса положи на форму компонент TQuery, назвав его Query1, например, пропиши в свойстве SQL указанный выше запрос и запусти выполнение, воспользовавшись следующей конструкцией:



    Query1.ExecSQL;



    Из конференции Expert_FAQ

    Вопрос

    Как проверить условие: если колесико мыши крутится вниз, то…

    Ответ

    Для Delphi 5+ посмотри события TForm.OnMouseWheelDown, OnMouseWheelUp В другом случае попробуй так:

    TForm1 = class(TForm) //… private procedure WMMouseWheel(var Msg: TWMMouseWheel); message WM_MOUSEWHEEL; end; procedure TForm1.WMMouseWheel(var Msg: TWMMouseWheel); begin if Msg.WheelDelta>0 then Windows.Beep(500, 100) else Windows.Beep(1500, 100); end;

    Из конференции Expert_FAQ

    Вопрос

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

    Ответ

    «КАК ПРОВЕРИТЬ СОЕДИНЕНИЕ С ИНТЕРНЕТОМ И УЗНАТЬ ТИП СОЕДИНЕНИЯ»

    {*******************BEGIN*************************}

    По нажатию на кнопку в появляется сообщение. Если не 0 — есть соединения с Интернетом. А в заголовке формы показывается тип соединения.

    unit Unit1;
    interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Registry, WinSock, WinInet, StdCtrls;
    type TConnectionType = (ctNone, ctProxy, ctDialup);
    function ConnectedToInternet : TConnectionType;
    function RasConnectionCount : Integer;
    type TForm1 = class(TForm) Button1: TButton;
    procedure Button1Click(Sender: TObject);
    private { Private declarations } public { Public declarations } end;
    var Form1: TForm1;
    implementation {$R *.DFM} //For RasConnectionCount ======================= const cERROR_BUFFER_TOO_SMALL = 603;
    cRAS_MaxEntryName = 256;
    cRAS_MaxDeviceName = 128;
    cRAS_MaxDeviceType = 16;
    type ERasError = class(Exception);
    HRASConn = DWord; PRASConn = ^TRASConn;
    TRASConn = record dwSize: DWORD; rasConn: HRASConn;
    szEntryName: Array[0..cRAS_MaxEntryName] Of Char;
    szDeviceType : Array[0..cRAS_MaxDeviceType] Of Char;
    szDeviceName : Array [0..cRAS_MaxDeviceName] of char;
    end;
    TRasEnumConnections = function (RASConn: PrasConn; { buffer to receive Connections data } var BufSize: DWord; { size in bytes of buffer } var Connections: DWord { number of Connections written to buffer } ): LongInt; stdcall;
    //End RasConnectionCount ======================= function ConnectedToInternet: TConnectionType; var Reg : TRegistry; bUseProxy : Boolean; UseProxy : LongWord;
    begin Result := ctNone;
    Reg := TRegistry.Create; with REG do try try RootKey := HKEY_CURRENT_USER;
    if OpenKey('\Software\Microsoft\Windows\CurrentVersion\Internet settings',False) then begin //I just try to read it, and trap an exception if GetDataType('ProxyEnable') = rdBinary then ReadBinaryData('ProxyEnable', UseProxy, SizeOf(LongWord) ) else begin bUseProxy := ReadBool('ProxyEnable');
    if bUseProxy then UseProxy := 1 else UseProxy := 0;
    end;
    if (UseProxy <> 0) and ( ReadString('ProxyServer') <> '' ) then Result := ctProxy;
    end;
    except //Obviously not connected through a proxy end; finally Free;
    end;
    //We can check RasConnectionCount even if dialup networking is not installed //simply because it will return 0 if the DLL is not found. if Result = ctNone then begin if RasConnectionCount > 0 then Result := ctDialup;
    end;
    end;
    function RasConnectionCount : Integer;
    var RasDLL : HInst; Conns : Array[1..4] of TRasConn; RasEnums : TRasEnumConnections; BufSize : DWord;
    NumConns : DWord;
    RasResult : Longint;
    begin Result := 0;
    //Load the RAS DLL RasDLL := LoadLibrary('rasapi32.dll');
    if RasDLL = 0 then exit;
    try RasEnums := GetProcAddress(RasDLL,'RasEnumConnectionsA');
    if @RasEnums = nil then raise ERasError.Create('RasEnumConnectionsA not found in rasapi32.dll');
    Conns[1].dwSize := Sizeof (Conns[1]);
    BufSize := SizeOf(Conns);
    RasResult := RasEnums(@Conns, BufSize, NumConns);
    If (RasResult = 0) or (Result = cERROR_BUFFER_TOO_SMALL) then Result := NumConns;
    finally FreeLibrary(RasDLL);
    end;
    end;
    procedure TForm1.Button1Click(Sender: TObject);
    begin ShowMessage(IntToStr(RasConnectionCount));
    if ConnectedToInternet=ctNone then Form1.Caption:='ctNone';
    if ConnectedToInternet=ctProxy then Form1.Caption:='ctProxy';
    if ConnectedToInternet=ctDialup then Form1.Caption:='ctDialup';
    end;
    end.


    {********************END***********************}

    Из конференции Expert_FAQ

    Вопрос

    Как программно осуществить заполнение полей формы MS Word?

    Ответ

    При помощи следующего кода:

    uses
        ComObj;

    procedure TForm1.Button1Click(Sender: TObject);
    var
        WordApp: OLEvariant;
    begin
        Screen.Cursor := crHourglass;
        try
       // Create Word Instance
       WordApp := CreateOleObject('Word.Application');
        except
       ShowMessage('Не могу запустить MS Word.');
       Screen.Cursor := crDefault;
            Exit;
        end;

        try
       // Открыть документ Word'а
       WordApp.Documents.Add(Template := 'C:\TestDoc.doc');
            // Показать Word
       WordApp.Visible := True;
    // Проверка на существование FormField и связаность с текстом
    if WordApp.ActiveDocument.Bookmarks.Exists('YourFormFieldName') then
    WordApp.ActiveDocument.FormFields.Item('YourFormFieldName').Result := 'Ваш текст';
        finally
            WordApp := Unassigned;
       Screen.Cursor := crDefault;
        end;
    end;

    Из конференции Delphi

    Вопрос

    Как программно извлечь файлы из cab архива?

    Ответ

    Функция WinaPI SetupIterateCabinet. Смотри описание в помощи Suncerelly yours, IGP Systems

    Из конференции Expert_FAQ

    Вопрос

    Возможно ли программно определить сколько прошло времени с момента включения компьютера?

    Ответ

    SystemUpTime:=GetTickCount/1000;

    Получишь время в секундах с момента старта Windows

    Svik, Dima S., Дружинец А.В

    Вопрос

    Как программно переключить раскладку клавиатуры с русского на английский и наоборот?

    Ответ

    LoadKeyboardLayout('00000409', KLF_ACTIVATE); // английский
    LoadKeyboardLayout('00000419', KLF_ACTIVATE); // русский

    Это для установки конкретного языка.
    Для переключения между имеющимися:

    ActivateKeyBoardLayout(HKL_NEXT, 0) — следующая раскладка
    ActivateKeyBoardLayout(HKL_PREV, 0) — предыдущая.

    Более подробно см. win32.hlp — справочная система по Win32 API и SDK.

    Вопрос

    Пользователи работают с программой написанной в FoxPro (Dos версия). На машинах стоит Windows 98 (другую ОС ставить не желательно, двойная загрузка ОС также не желательна). Для работы они сначала запускают Norton Commander 5.0 и затем из меню свою программу.

    Часто из-за длительного отсутствия активности окно их программы сбрасывается на панель задач. И они снова открывают Norton Commander и запускают программу второй раз. Часто это приводит к сбою в работе программы. Можно ли как-то программно предупредить второй запуск программы?

    Ответ

    Я понимаю, что переписать прогу на ФоксПРО не предоставляется возможным. Для решения вашей проблемы нужно написать программку на делфи из которой будет запускаться программа на Фоксе. При этом будет производится проверка, работает ли предыдущий экземпляр, или нет. Если работает мы должны его активировать, а если нет то запустить. Вот пример для блокнота, со своим приложением разберешься:

    program Pro;
    uses Windows, Forms;
    var Handle1 : LongInt; Handle2 : LongInt;
    {$R *.RES} begin Application.Initialize;
    Handle1 := FindWindow('Notepad',nil);
    // Указать заголовок окна Или его часть if handle1 = 0 then begin WinExec('Notepad.exe', SW_SHOWNORMAL)
    // Запускаем программу end else begin Handle2 := GetWindow(Handle1,GW_OWNER);
    file:
    //Чтоб заметили :) ShowWindow(Handle2,SW_HIDE);
    ShowWindow(Handle2,SW_RESTORE);
    SetForegroundWindow(Handle1);
    // Активизируем предыдущую копию ShowWindow(Handle1, SW_SHOWNORMAL) end;
    end.


    Из конференции Expert_FAQ

    Вопрос

    Как программно создать гиперсылку на какой-нибудь файл(например хранящийся в базе данных) в RichEdit-е? Пользователь выбирает любое слово в тексте и привязывает к нему файл. Все это должно происходить в Run-Time

    Ответ

    Если исходить из Вашей задачи, то, во-первых, Вам нужно продумать два момента:
    а) структура связывающая текст и имена файлов
    б) как Вы эту структуру будете хранить на диске

    Здесь у Вас два пути — поискать среди существующих компонент

    у Торри www.torry.ru на Delphi Super Page delphi.icm.edu.pl просто на Delphi Pages www.delphipages.com или www.delphisource.com либо разделить котлеты и мухи, т.е. сущность отдельно, изображение для юзера отдельно и делать это самому/самой.

    Если Вы хотите выбрать первый путь — компонент TRichEdit Вам не помощник. У него нет методов сохранения rich-текста куда-либо. Значит Вам надо их писать самостоятельно процедуры LoadFromFile и SaveToFile, и само собой хранить в отдельной структуре данные какие слова с какими файлами связаны — а это второй путь.

    Из конференции Expert_FAQ

    Вопрос

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

    Ответ

    Для этой цели применима функция WinApi:

    BOOL EnumJobs(
    HANDLE hPrinter, // handle to printer object
    DWORD FirstJob, // location of first job in print queue to enumerate
    DWORD NoJobs, // number of jobs to enumerate
    DWORD Level, // structure level
    LPBYTE pJob, // pointer to structure array
    DWORD cbBuf, // size of array, in bytes
    LPDWORD pcbNeeded, // addr. of variable with no. of bytes copied (or required)
    LPDWORD pcReturned // addr. of variable with no. of job info. structures copied
    );

    А если знаешь английский, то прочитай справочку по WinApi программированию, которая поставляется вместе с Delphi. Там все хорошо написано.

    Из конференции Expert_FAQ

    Вопрос

    Как програмно в Image1 вставить иконку текущей программы?

    Ответ

    Image1.Picture.Icon.Assign(Application.Icon);

    Из конференции Expert_FAQ

    Вопрос

    Как проиграть midi файл?

    Ответ

    uses
        MPlayer;
    var
        mp : TMediaPlayer;

    procedure TForm1.Button1Click(Sender: TObject);

    begin
        with Sender as TButton do
            case Tag of
              0 :
          begin
          Tag := 1;
      mp := TMediaPlayer.CreateParented(Handle);
       mp.DeviceType := dtSequencer;
       mp.FileName := 'c:\winnt\media\Canyon.mid';
      mp.Wait:= True;
         mp.Open;
        mp.Play;
           end;
              1 :
           begin
         Tag := 0;
         mp.Wait := True;
         mp.Stop;
         mp.Free;
           end;
            end;
    end;

    Из конференции Delphi

    Вопрос

    Как происходит выделение памяти под локальные переменные процедур и функций (procedure and function)? Память выделяется при обращении к процедуре и освобождается по завершении процедуры? Если это так, то в кратковременных процедурах нет смысла использовать динамическое распределение памяти.

    Ответ

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

    Из конференции Expert_FAQ

    Вопрос

    Допустим, на фоме есть Image1 размером 200х160. Как нажатием кнопки Button1 пропорцианально уменьшить Image1 до размеров 150х120, т.е. сохранить отношение ширины и высоты картинкаи?

    Ответ

    свойство Stretch:=true //картинка масштабируется

    свойство Proportional := true //понятно з названия :)

    свойство Width:=xxx //ширина

    свойство Height:=xxx //высота

    Из конференции Expert_FAQ

    Вопрос

    Как сделать, чтобы при выборе файла (bmp) в FileListBox этот файл (с расширением bmp) просматривался в Image?

    Ответ

    Для этого надо обработать событие OnClick для компонента, который отображает файлы. Написать надо следующее:
    image1.Picture.LoadFromFile(filename);
    где filename — переменная типа string. Значение переменной вы получите из списка файлов, точнее из элемента, на котором щелкнули мышью.

    Герун Данил

    Вопрос

    Как прочесть BlobStream с помощью TADOQuery из БД Access?

    Ответ

    function GetBlobStream(Query: TADOQuery): TMemoryStream;
    begin
       result := TMemoryStream.Create;

    // Сначала надо подключиться к БД Access.
    // Смотрите: Query.Connection, TADOConection и Query.ConnectString

       // Отправляем SQL запрос
       Query.Active := False;
       Query.SQL.Clear;
    // data это столбец нужных данных, а email — таблица
    Query.SQL.Append('SELECT data FROM email WHERE id=1');
       Query.Active := True;

    Result.LoadFromStream(Query.CreateBlobStream(Query.FieldByName('Data'), bmRead));
    end;

    Кирилл Краснов

    Вопрос

    Как прочитать порт или записать в него.

    Ответ

    В мультизадачных ОС как правило доступ к портам запрещен идеологией системы. И это неспроста — подумайте, что будет, если одновременно с вашей программой этот же порт попробует использовать другая программа.
    Hо в Win9x существует частичная возможность обратиться напрямую с помощью ассемблерных команд. Делать это надо с определенной осторожность. Даже если вы получите доступ до порта на своей машине, то это не означает, что это будет и на другой машине, например доступ до LPT порта может быть закрыт драйвером принтера, такое редко но встречается. Доступ к наиболее важным портам прикрыты запрещен полностью соответствующими системными драйверами.
    В Win NT доступ к оборудованию со стороны пользовательской программы запрещен полностью. Для доступа на этих ОС требуется использовать kernel mode драйвера, тоже самое рекомендуется и для Win9x.
    Вот несколько полезных ссылок:

    TVicHW32 http://www.entechtaiwan.com/tools.htm
    Tinyport (NT) http://www.winsite.com/info/pc/winnt/programr/tinypo21.zip.drag
    DriverX http://www.tetradyne.com
    giveio (NT) http://www.wideman-one.com/gw/tech/Delphi/iopm/index.htm
    Ports, by Harold Howe, http://www.bcbdev.com/components.htm

    Код доступа к портам с помощью ассемблера.

    procedure WritePortByte(Port:Word; Value:Byte);
    asm
        XCHG EDX,EAX
        OUT DX,AL
    end;

    procedure WritePortWord(Port:Word; Value:Word);
    asm
        XCHG EDX,EAX
        OUT DX,AX
    end;

    function ReadPortByte(Port:Word) : Byte;
    asm
        MOV EDX,EAX
        IN AL,DX
    end;

    function ReadPortWord(Port:Word) : Word;
    asm
        MOV EDX,EAX
        IN AX,DX
    end;


    Примечание:

    Существуют устройства с подряд идущими (по адресам) _байтовыми_ портами, к которым нельзя обращаться со словными командами I/O. Hа сегодня они почти вымерли, но :
    При выборе типа процедуры (BYTE или WORD) следует ориентироваться на спецификацию устройства ввода-вывода, к которому идет обращение. Hе следует обращаться к байтовому устройству с WORD-ориентированными процедурами — экономия времени мизерная, а побочные эффекты могут быть катастрофическими."
    Hапример, некоторые адаптеры сбрасывают биты ошибок после чтения статус-регистра. Другие отображают несколько внутренних регистров на один адрес I/O, и т.п.
    Hа некоторых старых компьютерах Word процедуры могут не работать из за специфических особенностей интерфейса, правда такие компьютера практически уже не встречаются. Есть ISA Bus Specification, где эти вопросы четко формализованы. Выборка словного порта может быть разбита на два раза, даже если адрес четный, в зависимости от пожеланий устройства I/O.

    Из конференции Delphi

    Методы с помощью ассемблера не пойдут под WinXP
    Нужно пользоваться ReadFile и WriteFile

    raven

    Вопрос

    Как работать с базами данных без BDE?

    Ответ

    Это смотря с какими базами…

    Для DBF подойдет Apollo или что еще
    Для ACCESS подойдет KADao (без BDE но через DAO, а можно и через ADO)
    Для MSSQL, MySQL, IB и прочее SQL подойдет ZEOS
    Есть и свои собственные форматы типа TinyDB или DBISAM.
    Это я перечислил только с тем с чем сталкивался непосредственно.

    Как с ними работать, у каждой библиотеки свои нюансы, но в общем в той или иной степени похоже на BDE.

    Из конференции Expert_FAQ

    Делается все просто. Пишется СОМ на VFP 6.0 с функционалом по управлению. Практика показала что дельфи хавает такие объекты, как и наоборот. И рули пожалуйста хоть какими базами. Можешь и через АDO, но все же его тоже целесообразно воткнуть в DLL.

    lexmal

    Вопрос

    Как работать с битами?

    Ответ

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

    var
        I : integer;
        N : integer; // Hомер бита в диапазоне от
    0..SizeOf(TYPE)*8 — 1

        I := I or (1 shl N); // установка бита
        I := I and not (1 shl N); // сброс бита
        I := I xor (1 shl N); // инверсия бита
        if (i and (1 shl N)) <> 0 then… // проверка установленного бита


    Высокоуровневый подход опирается на представление числа в виде множества:

    type
        TIntegerSet = set of 0..SizeOf(Integer)*8 — 1;
    var
        I : Integer;
        N : Integer;

        Include(TIntegerSet(I), N); // установили N-ный бит в 1
        Exclude(TIntegerSet(I), N); // сбросили N-ный бит в 0
        if N in TIntegerSet(I) then… // проверили N-ный бит


    Из конференции Delphi

    Вопрос

    Как работать с графическими форматами, хотя бы самыми известными?

    Ответ

    http://www.imagelib.com лежит библиотека ImageLib.
    Hа компакте с Delphi 3 в каталоге EXTRAS есть библиотека JPEG. Если сказать в модуле uses jpeg; то можно работать с .jpg как с TPicture.
    Еще есть freeware-библиотека Nishita ViewLib. JPG, JFIF, GIF, BMP, DIB, RLE, TGA, PCX.
    http://einstein.ae.eng.ua.edu/nishita/index.htm.

    Из конференции Delphi

    Вопрос

    Как работать с реестром?

    Ответ

    uses TRegistry

    Begin
      with TRegistry.Create;
      try
      OpenKey('\Sotware\FirmName\ProgName\Version',True);
          WriteInteger('Count',Count);
      finally
          Free;
      end;
    end;

    Из конференции Delphi

    Вопрос

    Как работать с файлами архивов, хотя бы самыми распространенными?

    Ответ

    Воспользуйтесь библиотекой ExceedZip 3.0 -
    http://www.exceedsoft.com

    Из конференции Delphi

    Вопрос

    Как разбить строку на слова?

    Ответ

    (*
    В Delphi есть класс, называемый TParser, который IDE использует для
    парсинга исходного кода. Вы тоже можете использовать этот класс для
    парсинга строк.
    Процедура берет строку и делит ее на слова.
    *)

    procedure ParseThis(MyStr: String);
    var
       MyParser: TParser;
       MS: TMemoryStream;
    begin
       MS := TMemoryStream.Create;
       MS.Position := 0;
       MS.Write(MyStr[1], Length(MyStr));
       MS.Position := 0;
       MyParser := TParser.Create(MS);
       MyStr := MyParser.TokenString;
       ShowMessage(MyStr);
    while MyParser.Token <> toEOF do begin
    MyParser.NextToken;
    if MyParser.TokenSymbolIs(MyParser.TokenString) then begin
    MyStr := MyParser.TokenString;
      ShowMessage(MyStr);
         end;
       end;
       MyParser.Free;
       MS.Free;
    end;

    procedure TForm1.Button1Click(Sender: TObject);
    begin
       ParseThis('Сканировать эту строку');
    end;

    Кирилл Краснов

    Вопрос

    Есть ли в природе компоненты, позволяющие реализовать дерево каталогов, как в Проводнике, к примеру? Если нет, как можно реализовать это самому?

    Ответ

    Стандартных нет. Можно сделать самому, используя TTreeView и TListView. Также используется FindFirst, FindNext.

    Делаешь первый вызов FindFirst, получаешь объект, добавляешь узел в дерево. Проверяешь этот объект(DirectoryExist()), если это файл — значит, этот узел последний в ветви. Если же это директория, рекурсивно просматриваешь с помощью того же FindFirst и добавляешь узлы-потомки. Потом вызываешь FindNext и делаешь те же проверки…
    Таким образом и строишь дерево каталогов.

    Правая часть немного проще. Ставишь процедуру на выбор узла в дереве и в ней заполняешь объектами, содержащимися в этой ветви. Объяснил немного скомкано, но на самом деле тема это очень большая (как и пример, готового нет, а делать на ходу очень долго…). В принципе, существуют готовые компоненты сторонних разработчиков.

    Из конференции Expert_FAQ

    Вопрос

    Как реализовать перетаскивание файлов на ListBox и отображение в нем пути и имени файла, который перетащили?

    Ответ

    Вот пример реализации для одного файла:

    uses
      shellapi;

    protected
      procedure wmdropfiles(var msg:tmessage);message wm_dropfiles;
    end;

    procedure TForm2.FormCreate(Sender: TObject);
    begin
      dragacceptfiles(form2.handle,true);
    end;

    procedure tform2.wmdropfiles(var msg:tmessage);
    var
      filename:array[0..256] of char;
      s:string;
    begin
      dragqueryfile(thandle(msg.WParam),0,filename,sizeof(filename));
      s:=strpas(filename);
    if fileexists(s) then edit2.text:=s;
      dragfinish(thandle(msg.WParam));
    end;

    procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
    dragacceptfiles(form2.handle,false);
    end;
    end.


    Александр

    Вопрос

    Как реализовать поиск текста в RichEdit с помощью FindDialog'a?

    Ответ

    var SPos: Integer; procedure TForm1.FindDialog1Find(Sender: TObject); begin with FindDialog1 do begin if frMatchCase in Options then { Поиск с учетом регистра } RichEdit1.SelStart := Pos(FindText, Copy(RichEdit1.Lines.Text, SPos + 1, Length(RichEdit1.Lines.Text))) + SPos — 1 else { Поиск без учета регистра } RichEdit1.SelStart := Pos(AnsiLowerCase(FindText), AnsiLowerCase(Copy(RichEdit1.Lines.Text, SPos + 1, Length(RichEdit1.Lines.Text)))) + SPos — 1; if RichEdit1.SelStart >= SPos then begin RichEdit1.SelLength := Length(FindText); { Выделение найденного текста } SPos := RichEdit1.SelStart + RichEdit1.SelLength + 1; { Изменение начальной позиции поиска } end else if MessageDlg('Текст "' + FindText + '" не найден. Продолжать диалог?', mtConfirmation, mbYesNoCancel, 0) <> mrYes then CloseDialog; end; RichEdit1.SetFocus; end; procedure TForm1.Button1Click(Sender: TObject); begin SPos := RichEdit1.SelStart; { Запоминание позиции курсора } with FindDialog1 do begin FindText := RichEdit1.SelText; { Начальное значение текста поиска — текст, выделенный в RichEdit } Position := Point(Form1.Left, Form1.Top + RichEdit1.Top + RichEdit1.Height); { Позиционирование окна диалога внизу RichEdit } Options := Options + [frHideUpDown, frHideWholeWord]; { Удаление из диалога кнопок "Вверх", "Вниз", "Только слово целиком" } Execute; { Выполнение } end; end;

    В программе вводится переменная SPos, сохраняющая позицию, начиная с которой надо проводить поиск. При нажатии на кнопку появляется диалог, процедура FindDialog1Find (событие OnFind) обеспечивает поиск с учетом или без учета регистра в зависимости от флага frMatchCase. После нахождения очередного вхождения искомого текста этот текст выделяется в окне RichEdit и управление передается этому окну редактирования. Затем при нажатии пользователем в диалоговом окне кнопки «Найти далее», поиск продолжается в оставшейся части текста. Если искомый текст не найден, делается запрос пользователю о продолжении диалога. Если пользователь не ответил на этот вопрос положительно, то диалог закрывается методом CloseDialog.

    При ответе использована книга «Программирование в Delphi 5» Архангельского А.Я.

    Из конференции Expert_FAQ

    Вопрос

    Необходимо реализовать полный перебор всех вложенных папок в указанной папке (т.е. все вложенные папки должны быть представлены в виде дерева, к примеру). Как это можно сделать?

    Ответ

    Простейший сканнер

    Вот пример, который ищет мп3 файлы на жестком диске…

    unit Audit1;
    interface uses windos;
    var dest:string;
    procedure dorecurse(dir:string);
    implementation {$R *.DFM} Procedure Process (dir:string; Searchrec:tsearchrec);
    begin showmessage (Searchrec.name);
    case Searchrec.attr of $10: if (searchrec.name<>'.') and (searchrec.name<>'..') then begin dorecurse (dir+'\'+searchrec.name);
    writeln (dir);
    end;
    end;
    end;
    Procedure Dorecurse(dir:string);
    var Searchrec:Tsearchrec;
    pc: array[0..79] of Char;
    begin StrPCopy(pc, dir+'\*.mp3');
    FindFirst(pc, FaAnyfile, SearchRec);
    Process (dir,SearchRec);
    while FindNext(SearchRec)<>
    -18 do begin Process (dir,SearchRec);
    end;
    end;
    Procedure startsearch;
    begin dorecurse (paramstr(1));
    end;
    begin startsearch;
    end.


    Из конференции Expert_FAQ

    Вопрос

    Как рисовать линии в PaintBox'е, чтобы не было глюков?

    Ответ

    Установи в свойствах объекта TPen, которым рисуегшь, режим рисования XORMode.

    Denis Dzyubenko

    Вопрос

    Я время от времени добавляю некую строку в мемо. Как сделать автоматический скроллинг мемо?

    Ответ

    Непонятно, что значит «автоматический» скроллинг. Если выставить свойство ScrollBars в ssVertical, то как раз при добавлении строки будет происходить и скроллинг. А про ручной скажу так:
    Memo1.SetFocus;
    Memo1.SelStart :=Length(Memo1.Text);
    Memo1.SelLength:=0;

    Вопрос

    Я пишу игру наподобие Комерсанта. И у меня возникла такая проблема.

    Мне нужно, чтобы по истечению 24 секунд в Label1.Capton записывалось например 20$, а если еще пройдет 24 секунды, то Label1.Caption уже запишется 40$ и т.д., то есть получается авто обновление Label1.Caption и складывание чисел (20$+20$=40$ и т.д.).

    Ответ

    1. Положите на форму компонент Label и установите свойство Caption в '0$'
    2. Положите на форму компонент Timer и установите свойство Interval в '24000' (24 тысячи миллисекунд), а свойство Enabled в false
    3. Положите на форму компонент Button — при нажатии на кнопку будет запускаться Timer (можно повесить на Form.OnActivate)
    4. Обработчик нажатия кнопки:

    procedure TForm1.Button1Click(Sender: TObject);
    begin
    Timer1.Enabled := true;
    end;

    5. Обработчик таймера:

    procedure TForm1.Timer1Timer(Sender: TObject);
    var
    st: string;
    begin
    st := copy(Label1.Caption, 1, pos('$', Label1.Caption) — 1); //Копируем строку с начала до символа перед долларом
    st := IntToStr(StrToInt(st) + 20) + '$'; //Прибавляем 20
    Label1.Caption := st; //Изменяем Label.Caption
    end;

    Все!!!

    Из конференции Expert_FAQ

    Вопрос

    Подскажите как сделать в главном меню дополнительное подменю (например как в Дельфи пункт открытия ранее открытых файлов)?

    Ответ

    Нажми на проектируемой менюшке Ctrl+Вправо.

    Из конференции Expert_FAQ

    Вопрос

    Как сделать в меню список последних открытых файлов?

    Ответ

    Пусть список файлов хранится в FileList : TStringList, a mmReopen : TMenuItem — пункт меню, содержащий ссылки на файлы, тогда при изменениии списка файлов надо сделать:

      {var NewItem: TMenuItem}

      for I := mmReopen.Count -1 downto 0 do
      begin
          mmReopen.Delete(I);
      end;

      for I := 0 to lf.Count-1 do
      begin
     NewItem := TMenuItem.Create(mmReopen);
     NewItem.Caption := '&'+IntToStr(I) + ' ' + FileList.Strings[I];
          NewItem.OnClick := FileOpenProc;
          mmReopen.Add(NewItem);
      end;
      …
      procedure FormX.FileOpenProc(Sender : TObject);
      var
          Filename : String;
      begin
    Filename := FileList.Strings[mmReopen.IndexOf(TMenuItem(Sender))];
          …
      end;

    Из конференции Delphi

    Вопрос

    Я пишу программу, к которой пользователь должен обращаться очень часто. Для этого ей нужно сделать горячую клавишу, например как в виндах вин+a — поиск файлов. Вызываться должна даже тогда, когда ни одно окно не активно (и когда программа, естественно, висит в памяти). Где-то писали, как это сделать, но оно не работало. Можно также кинуть ссылочку на компонент если таковой имеется.

    Ответ

    Для начала надо зарегистрировать горячую клавишу

    procedure TForm1.FormCreate(Sender: TObject);
    begin
    RegisterHotKey(Form1.Handle, id, 0, VK_RETURN);
    end;

    Здесь id — это константа — идентификатор клавиши (не путать с виртуальным кодом). См. его использование далее. Значение — любое от 0 до 49151. Важно, чтобы другие клавиши не имели этот же идентификаторы.

    Третий параметр может принимать значения MOD_ALT (клавиша ALT должна удерживаться), MOD_CONTROL, MOD_SHIFT.

    Четвертый параметр — виртуальный код клавиши. В данном примере — Enter.

    Далее на в форме (public или private) надо описать метод WMHotKey:

    public
    { Public declarations }
    procedure WMHotKey(var Msg : TWMHotKey); message WM_HOTKEY;
    end;

    И затем его реализацию:

    procedure TForm1.WMHotKey(var Msg : TWMHotKey);
    begin
    if Msg.HotKey = id then //Обратите внимание на id — это тот самый идентификатор
    ShowMessage('Вы нажали на Enter'); //Нужные вам действия
    end;

    При завершении работы горячую клавишу надо удалять:

    procedure TForm1.FormDestroy(Sender: TObject);
    begin
    UnregisterHotKey(Form1.Handle, id);
    end;

    Вот и все.

    Из конференции Expert_FAQ

    Вопрос

    Как сделать индикатор прогресса для длительного запроса?

    Ответ

    Так как оценить объем запроса до его выполнения сложно, то совсем непросто придумать (и сделать) что-то лучше, чем показать пользователю TAnimate.
    Однако, чтобы показывать что-либо при большом запросе придется выполнять запрос в потоке. См. пример, который назодится в каталоге delphi%\demos\db\bkquery

    Из конференции Delphi

    Вопрос

    Как сделать, чтобы программка написанная на Perl запускалась в windows-e с расширением .exe ? Что именно надо сделать, чтобы программа имела расширение .exe и запускалась ? В общем, чтобы работала не из ДОСа.

    Ответ

    Не надо никаких компонентов. Чтобы твоя прога поддерживала новый ХРшный интерфейс, в нее надо залинковать как ресурс следующий файл:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    <assemblyIdentity version="1.35.0.0" processorArchitecture="X86" name="Microsoft.Windows.Shell" type="win32" />
    <description>Windows Shell</description>
    <dependency>
    <dependentAssembly>
    <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="X86" publicKeyToken="6595b64144ccf1df" language="*" />
    </dependentAssembly>
    </dependency>
    </assembly>


    Делается это так: сохраняешь его куда-нибудь под любым именем (допустим, manifest.txt), создаешь рядом с ним файл, например, manifest.rc с одной строчкой:

    1 24 «manifest.txt»
    Потом компилируешь его прогой brcc32 из папки с Дельфой:
    brcc32 manifest.rc
    и получаешь файл manifest.res

    А уж его можешь кидать в папки со своими проектами и прописывать в файле проекта строчку

    {$R manifest.res}

    Из конференции Expert_FAQ

    В Delphi 7 есть специальный компонент.

    Alex

    Вопрос

    Я недавно поставил себе Delphi 6, смотрел настройки и случайно через Component-Configure Palette сделал один из компонентов вкладки Common Controls скрытым (кнопка Hide), но обратно видимым его сделать не получается, он просто исчез и его не видно не в Configure Palette не на панели.

    Ответ

    Там же в разделе «Pages» перечислены закладки. Последняя закладка — [all]. В ней находятся ВСЕ компоненты. Там есть столбик «Page», который показывает положение компонента. Ищите те, у которых «Hide». Нажимаете на них, становится доступной 2я кнопка «Show» — вот и все.

    Из конференции Expert_FAQ

    Вопрос

    Мне нужно, чтобы моя прога запускалась и ее не было видно по CTRL ALT DEL. Знаю, что нужно использовать функцию WinApi RegisterServiceProcess, а вот как, если можно с примером?

    Ответ

    Procedure RegisterServiceProcess(par1,par2:dword); stdcall; external 'kernel32.dll';
    RegisterServiceProcess(0,1);

    Это касается только win9x.

    shadow

    Вопрос

    Столкнулся с одной проблемой…

    Дано:

    Timer (RxTimer)

    Interval1=1000; // 1 sec. Enabled; Cycled

    Interval2=300000; // 5 min. Enabled; Cycled

    Panel1

    Найти :

    OnTimer1:

    Panel1.Caption:=//? Время оставшееся от Interval2

    Мне надо, что-бы на Panel.Caption шел обратный счетчик Interval2… т.е. каждую секунду он писал типа: 05:59…05:58…и.т.д. т.е. сколько осталось до истечения Interval2.

    Ну Вы поняли для чего это… типа на один тур дается 5 мин. Вверху есть часики, показывающие время до конца тура… Вот уже все написал, кроме этого…И не знаю как делать… Как получить данные остатка Interval2, хотябы в милисикундах…

    Ответ

    Ну а кто тебе мешает из пяти минут каждую секунду вычитать по секунде?

    И вовсе для этого никаких компонентов иметь не надо. Создай свежий проект, намажь на форму Panel1: TPanel. У формы заполни свойство OnCreate. После этого скопируй текст модуля отсюда. Запускай, наслаждайся.

    unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls; type TForm1 = class(TForm) Panel1: TPanel; procedure FormCreate(Sender: TObject); private { Private declarations } FSeconds: Cardinal; procedure WMTimer(var M: TWMTimer); message WM_TIMER; procedure StartTimer(Seconds: Cardinal); public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} const ID_TIMER: Cardinal = 10; procedure TForm1.FormCreate(Sender: TObject); begin StartTimer(300); end; procedure TForm1.StartTimer(Seconds: Cardinal); begin FSeconds:=Seconds; SetTimer(Handle, ID_TIMER, 1000, nil); end; procedure TForm1.WMTimer(var M: TWMTimer); begin if M.TimerID=ID_TIMER then begin Dec(FSeconds); if FSeconds>0 then begin Panel1.Caption:=IntToStr(FSeconds div 60)+':'+ FormatFloat('00', FSeconds mod 60); end else begin Panel1.Caption:='Game Over'; KillTimer(Handle, ID_TIMER); end; end; end; end.

    Из конференции Expert_FAQ

    Вопрос

    На моей форме более 20 Panel'ей и в каждой я обрабатываю событие MouseMove и MouseDown, у всех панелей эти события одинаковы! Получился очень большой объем исходного кода, более 300 строк одинаковой информации! Можно ли как то это изменить?

    Ответ

    Конечно.
    Например имеем обрабочик события для первой панели, тогда просто для второй и последующих:

    PanelN.onMouseMove=Обработчик первой панели;

    А в самом обработчике мы можем узнать кто именно вызвал его:

    MessageDlg('Это событие от '+TPanel(Sender).Name);

    Вот и все. Так же мы можем и любые properties панели, которая вызвала обработчик изменять. Например так:

    TPanel(Sender).Color:=clWhite;

    Из конференции Expert_FAQ

    Вопрос

    Как написать приложение, которое будет являться не обычной формой, например, произвольным bmp-файлом. И чтобы если этот файл не квадратный, то и форма была не квадратной (типа как сделаны программы со скинами). Просто хочется написать оригинальную оболочку для cd, а если просто так делать, то получается не красиво.

    Ответ

    Для начала надо кинуть на форму TImage и загрузить в него картинку, а свойство Align выставить в "alClient". Потом надо создать регион (тип HRGN) соответствующего вида и применить его к форме при помощи функции SetWindowRgn:

    var
    a:HRGN;
    begin
    a:=CreateEllipticRgn(10,10,400,600);//Эллипс, если два последних
    //параметра равны — круг
    SetWindowRgn(Form1.handle,a,true);


    Это можно делать в любом месте программы — т.е. динамически изменять форму окна. Например сделать эллипс, который сжимается и разжимается:

    //должна быть описана глобальная переменная fl:Boolean и обработчик
    //нажатия на какую либо кнопку, в котором написана строка fl:=true
    var
    rgn:HRGN;
    i:integer;
    begin
    fl:=false;
    while (not fl) do begin
    for i:=1 to 200 do begin
    rgn:=CreateEllipticRgn(10,10,400,400+i);
    SetWindowRgn(Form1.handle,rgn,true);
    end;
    application.ProcessMessages;
    for i:=200 downto 1 do begin
    rgn:=CreateEllipticRgn(10,10,400,400+i);
    SetWindowRgn(Form1.handle,rgn,true);
    end;
    end;
    end;


    Точно так же можно создавать окна любой другой формы, используя функции WinAPI для создания региона. Например
    CreatePolygonRgn(var Points; Count, PolyFillMode: Integer): HRgn;
    Создает многоугольник с вершинами в TPoints, ЛЮБОЙ формы — думаю, для создания окон он подходит больше всего, хотя… В общем смотри справочник по WinAPI — там всяких таких функций с десяток точно наберется.

    Из конференции Expert_FAQ

    Вопрос

    Как сделать плавно изменяющийся цвет заголовка окна, как в MSOffice'95?

    Ответ

    В библиотеке RxLib есть компонент TGradientCaption.

    Из конференции Delphi

    Вопрос

    Как сделать поиск в ADO?

    Делаю так:
    ADOTable1.Locate('Name', VarArrayOf(['Clients']),[loPartialKey]);

    Должна находится запись 'Clients' в поле 'Name' , но эта запись не выделяется. Курсор так же и стоит на первой записи.

    В чем тут дело?

    Ответ

    Возможно проблема в VarArrayOf(), разбираться, почему не работает не хочется, вот кусок кода который работает:

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

    procedure TfrmListEdit.SearchIn(DisplayName: String);
    var SStr: string;
    begin InputQuery('Поиск', 'поиск по столбцу [' + DisplayName + ']', SStr);
    if Length(SStr) > 0 then if not ADOTable.Locate(DisplayName, SStr, [loCaseInsensitive, loPartialKey])
    then MainData.EAccessMsg(-1, 'Ничего не найдено', 'Поиск');
    end;


    Из конференции Expert_FAQ

    Могу предложить следующий вариант может поможет.
    На форму кинте Button и два поля Edit.
    В Edit1 вводите по какому столбцу искать, а в Edit2 текст для поиска.

    procedure TForm1.Button1Click(Sender: TObject);
    var stolbec:string;
    begin
    stolbec:=Edit1.Text;
    adodataset1.close;
    AdoDataset1.CommandText:='select * from ваша_таблица where ' + stolbec + '
    like '+ QuotedStr(edit2.text);
    adodataset1.Open;
    end;


    Так же можно использовать символ "%" для поиска по шаблону (можно ставить в начале и в конце слова, по середине ставить не пробовал может и получится не знаю), в Windows обычно используется "*".

    rustik

    Вопрос

    Как сделать программу без главной формы?

    Ответ

    Вот таким образом:

    program Project1;

    uses
        Dialogs;

    begin
        ShowMessage('Is there anybody out there ?' );
    end.

    Из конференции Delphi

    Вопрос

    Как сделать прозрачным фон при выводе Canvas.TextOut?

    Ответ

    Вот так:

    Canvas.Brush.Style := bsClear;

    Из конференции Delphi

    Вопрос

    Вас не раздражает, что нет «быстрых клавиш» для «Select All»? Ужасно неудобно… Не подскажите ли, как справить этот недостаток, т.е. сделать, чтобы Select All выполнялось по Ctrl+A. Я обычно такие вещи редактором ресурсов делаю, а в Delphi как-то мудрено диалоги запрятаны — с моими мозгами не разобраться… Поможете?

    Ответ

    Ваш вопрос можно понять двояко — то ли Вам не хватает Ctrl+A в самом Дельфи, то ли в Вашем приложении. В первом случае -

    Tools — Enviroment options — вкладыш Editor — Combobox Editor SpeedSetting или что-то в этом роде — четные версии себе на ставлю.

    Если не ошибаюсь, что в 6-ой версии уже можно поднастраивать любимые сочетания.
    Если в приложении — если нет меню на форме — кидаете компонент, дважды щелкаете по нему, чтобы появилось окно редактирования меню, F11 — Вкладка свойства — свойство ShortCut.

    Что касается диалогов из ресурсов, то по умолчанию в Дельфи не используется ресурс типа диалог. Дельфи использует свой тип ресурса под названием «Форма». Хороший встроенный редактор этого типа ресурсов — IDE Delphi :) В экзешниках формы можно редактировать с помощью Restorator-а
    wasm.ru [1.3Mb]

    Из конференции Expert_FAQ

    Вопрос

    Как сделать так, чтобы запущенная программа не была видна на панели задач?

    Ответ

    Во-первых, можно по примеру Back Orifice воспользоваться функцией RegisterServiceProcess (только для Win9x).
    Во-вторых, предположим, вы пользуетесь компонентой TrxTrayIcon из rxLib, иначе непонятно, как вы будете возвращать программу обратно из минимизированного состояния.

    type
      TForm1 = class(TForm)
        Label1: TLabel;
        RxTrayIcon1: TRxTrayIcon;
        procedure FormCreate(Sender : TObject);
        procedure RxTrayIcon1DblClick(Sender: TObject);
      private
        procedure ApplicationMinimize(Sender : TObject);
        procedure ApplicationRestore(Sender : TObject);
      end;

    var
      Form1: TForm1;

    implementation

    {$R *.DFM}

    procedure TForm1.FormCreate(Sender: TObject);
    begin
        Application.OnMinimize := ApplicationMinimize;
        Application.OnRestore := ApplicationRestore;
        ShowWindow(Application.Handle, SW_HIDE);
    end;

    procedure TForm1.ApplicationMinimize(Sender : TObject);
    begin
        ShowWindow(Application.Handle, SW_HIDE);
    end;

    procedure TForm1.ApplicationRestore(Sender : TObject);
    begin
        ShowWindow(Application.Handle, SW_RESTORE);
    end;

    procedure TForm1.RxTrayIcon1DblClick(Sender: TObject);
    begin
        Application.Restore;
        Application.BringToFront;
    end;

    Только сpазу предупреждаю про некоторые проблемы — будь готов к тому, что если пpи попытке закрытия приложения в OnCloseQuery или OnClose выводится вопрос о подтверждении, то могут быть проблемы с автоматическим завершением пpогpаммы пpи shutdown — под Win95 просто зависает, под WinNT не завершается. Очевидно, что сообщение выводится, но его не видно (причем SW_RESTORE не сpабатывает). Решение — ловить WM_QUERYENDSESSION и после всяких завеpшающих действий и вызова CallTerminateProcs выдавать Halt.

    Из конференции Delphi

    Вопрос

    Версия языка: 7

    Подскажите как сделать так, чтобы иконка моей проги отображалась в трее?

    Ответ

    Там где нужно создать иконку — ставишь код из FormCreate, там где удалить — из FormDestroy. Для изменения иконки нужно:

    pnid.hIcon присвоить новое значение иконки

    вызвать Shell_NotifyIcon(NIM_MODIFY, Addr(pnid))

    //----------------------------------------------------------

    unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, shellapi, ExtCtrls; type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); end; const WM_NOTIFYTRAYICON = (WM_USER+1); // сообщения от иконки. // нужно только если будет обработка событий от иконки var Form1: TForm1; pnid: NOTIFYICONDATA; // указатель на структуру описывающую иконку implementation {$R *.DFM} procedure TForm1.FormCreate(Sender: TObject); begin pnid.cbSize := sizeof(NOTIFYICONDATA); // размер структуры pnid.Wnd := Form1.Handle; // HWND окна, которое будет обрабатывать сообщения от иконки pnid.uID := 0; // номер иконки pnid.uFlags := NIF_ICON + NIF_TIP; // иконка видна + у нее есть хинт pnid.hIcon := CopyIcon(Application.Icon.Handle); pnid.szTip := 'Пример иконки'; // хинт { pnid.uCallbackMessage := WM_NOTIFYTRAYICON; // сообщение которое будет посылать иконка, при действиях с ней // будет работать, если добавить NIF_MESSAGE в pnid.uFlags } Shell_NotifyIcon(NIM_ADD, Addr(pnid)); // добавляем иконку в трей end; procedure TForm1.FormDestroy(Sender: TObject); begin Shell_NotifyIcon(NIM_DELETE, Addr(pnid)); // убираем иконку их трея, //иначе будет там сидеть до тех пор, пока не проведешь мышью над треем end; end. //--------------------------------------------------------

    Из конференции Expert_FAQ

    Вопрос

    Как в Delphi сделать так, чтобы некоторые параметры объекта записать в INI файл а потом их считывать, изменять и дополнять в процессе работы программы?

    Ответ

    Сначала нужно привести все необходимые для сохранения параметры объекта к типу, который можно записывать в INI-файл (например, строки, целые числа, булевы), а затем записать как обычно. Например, мы хотим запомнить, где последний раз была видна кнопка и что на ней было написано. Пишем так в FormClose:

    uses …, IniFiles,…



    procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);

    var

    ini: TIniFile;

    begin

    ini:=TIniFile.Create(ExtractFilePath(Application.ExeName)+'options.ini');

    ini.WriteString('main', 'caption', button1.caption);

    ini.WriteInteger('main', 'fromleft', button1.left);

    ini.WriteBoolean('main', 'isvisible', button1.visible);

    ini.Free; //Не забываем освободить!

    end;

    А при FormShow:

    procedure TForm1.FormShow(Sender: TObject);

    var

    ini: TIniFile;

    begin

    ini:=TIniFile.Create(ExtractFilePath(Application.ExeName)+'options.ini');

    button1.caption:=ini.ReadString('main', 'caption', '<empty>');

    button1.left:=ini.readinteger('main', 'fromleft', 0);

    button1.visible:=ini.ReadBoolean('main', 'isvisible', true);

    ini.Free;

    end;

    Таким образом, изменяя параметры в options.ini мы можем влиять на внешний вид нашей кнопки. Аналогично все делается и с другими объектами.

    Из конференции Expert_FAQ

    Вопрос

    Как сделать форму(не главную,form2), абсолютно всегда, видимой по верх всех окон?

    Ответ

    setwindowpos(form.handle,hwnd_topmost,form.left,form.top,form.
    width,form.height,swp_noactivate);


    Из конференции Expert_FAQ

    Вопрос

    В общем, хочется, чтобы в Windows XP программа-резидент получала сообщения о том, что произошел Fast User Switching.

    Ответ

    Прога должна получать мессаги

    WM_WTSSESSION_CHANGE = $02b1

    wParam = 7 при выходе юзера в экран приветствия,

    wParam = 8 при входе обратно.

    Для этого надо вызвать след. ф-ю:

    function WTSRegisterSessionNotification(hWnd: HWND; dwFlags: DWORD): BOOL; stdcall; external 'wtsapi32.dll';

    hWnd ставишь главного окна проги, dwFlags ставишь 0 для текущего юзера, 1 для сообщений о всех юзерах (Вроде бы. Тогда lParam будет ID сессии, не знаю как это понимать)

    При окончании работы проги надо вызвать:

    function WTSUnRegisterSessionNotification(hWnd: HWND): BOOL; stdcall; external 'wtsapi32.dll';

    А вообще это из MSDN взято.

    Из конференции Expert_FAQ

    Вопрос

    При загрузке Дельфи появляется окошко, (в 3-их желтое с девушкой). Может кто подскажет как сделать что при запуске программы появлялось такое же окошко с произвольным рисунком. И на ней отображался ход загрузки. Чтоб появлялись надписи: Открытие таблицы месяца. и т.д. и т.п.

    Ответ

    Я думаю, надо в этом случае работать с файлом проекта *.dpr. В списке создаваемых форм надо поставить заставку первой, сделать ее видимой и потом после создания каждой формы отображать на заставке соответствующую надпись (менять прогрессбар, etc.)

    Кстати, по Русским Документам или Мастак-Дельфи проходил цикл статей для начинающих, и там как раз была такая тема. Можешь посмотреть их архивы.

    Из конференции Expert_FAQ

    Вот нашел в FAQ'е на delphi.mastak.ru:

    Сведения о программе, авторские права и т.д., лучше оформить в виде отдельной формы и показывать ее при запуске программы (как это сделано в Word).
    Сделать это не сложно:
    1. Создаете форму (например SplashForm).
    2. Объявляете ее свободной (availableForms).
    3. В Progect Source вставляете следующее (например):

    program Splashin;
    uses Forms,
    Main in 'MAIN.PAS',
    Splash in 'SPLASH.PAS' {$R *.RES} begin try SplashForm := TSplashForm.Create(Application);
    SplashForm.Show;
    SplashForm.Update;
    Application.CreateForm(TMainForm, MainForm);
    SplashForm.Hide;
    finally SplashForm.Free;
    end;
    Application.Run;
    end.


    И форма SplashForm держится на экране пока выполняется Create в главной форме. Но иногда она появляется и пропадает очень быстро, поэтому нужно сделать задержку:
    1. Добавляете на форму таймер с событием:

    procedure TSplashForm.Timer1Timer(Sender: TObject);
    begin Timer1.Enabled := False;
    end;


    2. Событие onCloseQuery для формы:

    procedure TSplashForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    begin CanClose := Not Timer1.Enabled;
    end;


    3. И перед SplashForm.Hide; ставите цикл:

    repeat Application.ProcessMessages;
    until SplashForm.CloseQuery;


    4. Все! Осталось установить на таймере период задержки 3-4 секунды.

    5. На последок, у такой формы желательно убрать Caption:

    SetWindowLong (Main.Handle,GWL_STYLE, GetWindowLong(Main.Handle, GWL_STYLE) AND NOT WS_CAPTION OR WS_SIZEBOX);

    fed_art

    Вопрос

    1. random генерирует ПСЕВДОслучайные числа, как это исправить? мне надо чтобы при каждом запуске проги генерировались разные числа;

    2. зачем нужен randomize, если и без него random все генерирует?

    Ответ

    Randomize как раз и инициализирует начальное значение генератора псевдослучайных чисел текущим системным временем, чтобы результаты функции Random отличались от запуска к запуску.

    Из конференции Expert_FAQ

    Вопрос

    Версия языка: 6

    Мне нужна такая помощь. Хочу, чтобы программа, искала на всех возможных логических дисках свою копию и если находила, то удаляла бы их и удалялась сама. Например, по истечению некоторого ограничения программа искала свои копии и удалялась вместе с ними. P.S. Кстати, об ограничениях. Как лучше организовать демо-версию программы? Куда лучше записывать счетчик-ограничитель и в каком виде? Желательно, чтобы при обнаружении некого скрытого ключа (в реестре, в файле) программа бы удалялась. Надеюсь я Вас не запутал…:)

    P.P.S. И еще про ограничения. Можно ли как-нибудь в программе, например после того как счетчик покажет определенное значение удалилось строковое значение, но так, чтобы удалилось из кода программы и больше в ней не появлялось…

    Ответ

    1. Бегаешь по дискам (GetLogicalDrives) по всем каталогам (FindFirstFile, FindNextFile, FindClose) и ищешь файл <имя_твоего_exeшника.exe>. Если находишь, проверяешь, твой ли это, и т.д.

    2. Лучше компилировать демоверсию отдельно от полной, то есть физически не включать некоторые функции (например, сохранения документа), а вместо них писать, что они доступны только в полной версии. А всякие счетчики, как правило, пишутся в реестр в мусорные имена, но всегда обходятся и ломаются. Программно определить факт обнаружения ключа практически нереально. Соответственно, если я копию вашей программы буду хранить в архиве (а так у меня хранятся все инсталляшки), то она никогда не сможет удалить свою заархивированную копию.

    3. Теоретически возможно, но практически труднореализовываемо. Намного удобнее 2.

    Из конференции Expert_FAQ

    Вопрос

    Как сделать экспорт таблицы Excel в TStringgrid?

    Ответ

    uses ComObj;

    function Xls_To_StringGrid(AGrid: TStringGrid; AXLSFile: string): Boolean;
    const
       xlCellTypeLastCell = $0000000B;
    var
       XLApp, Sheet: OLEVariant;
       RangeMatrix: Variant;
       x, y, k, r: Integer;
    begin
       Result := False;
       // Создаем объект Excel-OLE
       XLApp := CreateOleObject('Excel.Application');
       try
         // Спрятать Excel
         XLApp.Visible := False;

         // Открыть Рабочую книгу
         XLApp.Workbooks.Open(AXLSFile);

    // Лист := XLApp.Workbooks[1].WorkSheets[1];
    Sheet := XLApp.Workbooks[ExtractFileName(AXLSFile)].WorkSheets[1];

    Sheet.Cells.SpecialCells(xlCellTypeLastCell, EmptyParam).Activate;
    // Получить значение последний строки
      x := XLApp.ActiveCell.Row;
    // Получить значение последней колонки
      y := XLApp.ActiveCell.Column;

    // Установить колонку и столбец Stringgrid'а.
         AGrid.RowCount := x;
         AGrid.ColCount := y;

    // Присвоение Variant ассоциативной WorkSheet'ому значению
    RangeMatrix := XLApp.Range['A1', XLApp.Cells.Item[X, Y]].Value;

    // Установить цикл для заполнения TStringGrid
         k := 1;
         repeat
           for r := 1 to y do
    AGrid.Cells[(r — 1), (k — 1)] := RangeMatrix[K, R];
           Inc(k, 1);
           AGrid.RowCount := k + 1;
         until k > x;

    // Очистка матрицы Delphi Variant
         RangeMatrix := Unassigned;

       finally
    // Выход Excel
      if not VarIsEmpty(XLApp) then
         begin
    // XLApp.DisplayAlerts := False;
      XLApp.Quit;
       XLAPP := Unassigned;
        Sheet := Unassigned;
           Result := True;
         end;
       end;
    end;

    procedure TForm1.Button1Click(Sender: TObject);
    begin
    if Xls_To_StringGrid(StringGrid1, 'C:\Table1.xls') then
     ShowMessage('Таблица экспортирована!');
    end;

    Кирилл Краснов

    Вопрос

    У меня такая проблема. Программе необходимо сделать себе ярлыки на рабочем столе, в меню пуск, но и в программах и без них, где windows update. Например и панели быстрого запуска. Как это можно реализовать?

    Ответ

    function CreateShortcut(const CmdLine, Args, WorkDir, LinkFile: string)
    : IPersistFile; var MyObject
    : IUnknown; MySLink
    : IShellLink; MyPFile
    : IPersistFile; WideFile
    : WideString; begin MyObject
    := CreateComObject(CLSID_ShellLink); MySLink
    := MyObject as IShellLink; MyPFile
    := MyObject as IPersistFile;
    with MySLink do begin SetPath(PChar(CmdLine));
    SetArguments(PChar(Args));
    SetWorkingDirectory(PChar(WorkDir));
    end;
    WideFile
    := LinkFile;
    MyPFile.Save(PWChar(WideFile), False);
    Result := MyPFile;
    end;
    procedure CreateShortcuts;
    var Directory, ExecDir: String;
    MyReg: TRegIniFile;
    begin MyReg
    := TRegIniFile.Create( 'Software\MicroSoft\Windows\CurrentVersion\Explorer');
    ExecDir := ExtractFilePath(ParamStr(0));
    Directory := MyReg.ReadString('Shell Folders', 'Programs', '') + '\' + ProgramMenu;
    CreateDir(Directory);
    MyReg.Free; CreateShortcut(ExecDir + 'Autorun.exe', '', ExecDir, Directory + '\Demonstration.lnk');
    CreateShortcut(ExecDir + 'Readme.txt', '', ExecDir, Directory + '\Installation notes.lnk');
    CreateShortcut(ExecDir + 'WinSys\ivi_nt95.exe', '', ExecDir, Directory + '\Install Intel Video Interactive.lnk');
    end;


    Вообще правильнее в процедуре CreateShortcuts пользовать Win32API::GetSpecialFolderLocation с нужным параметром (CSIDL_PROGRAMS в случае папки «Программы», или CSIDL_DESKTOP в случае «Рабочего стола»).

    Из конференции Expert_FAQ

    Вопрос

    Версия языка:5.0

    Хотел сделать форму базы данных полностью «flat». У большинства элементов есть либо свойство BorderStyle либо Flat, но у элемента DBLookupComboBox таковых в инспекторе объектов не оказалось. Как можно их сделать плоскими?

    Ответ

    Вообще-то, в стандартных компонентах для доступа к БД стиль Flat довольно кривовато реализован. В каких-то это свойство есть, а в каких=то — нет. Советую использовать компоненты Raize (http://www.raize.com. Преимущество:

    1. Во всех(!) компонентах есть свойство FrameStyle, которое позволяет менять стиль компонента (в том числе и Flat).

    2. Есть компонент FrameController, который позволяет менять стиль сразу всех компонентов на форме одним щелчком мыши из набора (около 10) стилей.

    3. Очень много(!) дополнительных (отличающихся от стандартных) компонент для работы с БД и просто контролов, облегчающих жизнь, таких как DBNumericEdit, DBDateTimePicker, DBSpinEdit, DBProgressBar, DBCheckBox и пр. Думаю названия говорят сами за себя.

    Это не реклама, а просто совет не изобретать второй раз велосипед…

    Из конференции Expert_FAQ

    Вопрос

    Как сделать, чтобы курсор мыши при ее движении перемещался не через 1 пиксел, как обычно, а через 5 пикселов?

    Ответ

    Если в пределах формы:

    var MP: TPoint;
    MMPar: Integer;
    procedure TForm1.FormMouseMove(Sender: TObject;
    Shift: TShiftState;
    X, Y: Integer);
    var P: TPoint;
    dx, dy: Integer;
    begin if MMPar = 0 then begin MMPar := 1;
    Exit;
    end;
    MMPar := 0;
    dx := 5;
    dy := 5;
    GetCursorPos(P);
    if P.X < MP.X then dx := -dx else if P.X = MP.X then dx := 0;
    if P.Y < MP.Y then dy := -dy else if P.Y = MP.Y then dy := 0;
    P.X := P.X + dx;
    P.Y := P.Y + dy;
    SetCursorPos(P.X, P.Y);
    MP := P;
    end;
    procedure TForm1.FormActivate(Sender: TObject);
    begin GetCursorPos(MP);
    MMPar := 0;
    end;


    Если на форме есть другие компоненты, то для них тоже надо обрабатывать OnMouseMove. Если же надо перемещать таким образом курсор по всему экрану, то тут надо ставить ловушку на мышь (функция SetWindowsHookEx с параметром WH_MOUSE). Это намного труднее и, скорее всего, понадобится создавать DLL.

    Из конференции Expert_FAQ

    Вопрос

    Как сделать, чтобы при растяжении или сжатии формы ее размеры изменялись только до определенного значения?

    Ответ

    Установить

    form1.Constraints.MaxHeight:=600;

    form1.Constraints.MaxWidth:=800;

    И все…

    При этом размеры эти будут даже при попытке максимизировать окно. Есть более сложные методы с использованием обработки системных сообщений.

    Из конференции Expert_FAQ

    Вопрос

    Как сделать так, чтобы при щелчке по кнопке или по TLabel отправить письмо

    Ответ

    В разделе uses добавить:
    ShellAPI.
    В обработчике OnClick нужного объекта ввести следующий код:

    ShellExecute(Handle,'open','mailto:Delphi@soobcha.lionovsky.us',nil,nil,SW_SHOWNORMAL);

    Это запустит настроенный по умолчанию мэйлер, и будет создано письмо с адресом Delphi@soobcha.lionovsky.us.

    Кирилл Краснов

    Вопрос

    Как сделать, чтобы программа, состоящая из одного файла *.exe, сохраняла некоторую информацию (скажем настройки пользователя) не в других отдельных файлах, а в самом же экзешнике?

    Ответ

    Смотря какие настройки. Если имена пользователей хранятся в базе данных, то туда же можно поместить настройки (я так права пользователей храню в таблице dbf). Если Вы имеете в виду содержимое визуальных компонентов, то просто внесите данные перед тем, как компилировать проект.

    Из конференции Expert_FAQ

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

    filimonofserg

    Вопрос

    Как сделать так, чтобы программу можно было запустить только в одном экземпляре?

    Ответ

    Воспользуйтесь функцией ActivatePrevInstance из библиотеки rxLib. Для завершения второго экземпляра используйте метод Application.Terminate.
    Другой вариант в файле X:\DELPHI2\DEMOS\IPCDEMOS\ipcthrd.pas (Х — это ваш CD-ROM с дистрибутивом Delphi) найдите функцию IsMonitorRunning().

    Из конференции Delphi

    Вопрос

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

    Ответ

    В Delphi5 есть свойство TForm.Constraints: TSizeConstraints;
    А у него есть свойства MinWidth, MinHeight, MaxWidth, MaxHeight;

    Из конференции Expert_FAQ

    Вопрос

    Есть DLL. В ней 2 экспортируемые функции. Как сделать, чтобы с этой dll могла работать прога, написаная на С++?

    Ответ

    Твоя задача написать. А чтобы она работала с программой на C++ ничего делать не нужно. Просто тот, кто будет писать это программу должен объявить функции из библиотеки.

    Из конференции Expert_FAQ

    Во первых, надо использовать типы переменных понимаемые C++ (не все типы Delphi понимаются C++). Во вторых, тип вызова функций тоже должен быть понимаем C++, в некоторых книгах советуется stdcall.

    zoarax

    Вопрос

    Как скопировать содержимое Caption компонента Label в буфер обмена Windows?

    Ответ

    В uses добавить модуль clipbrd.

    Далее:

    clipboard.AsText:=label1.Caption;

    Из конференции Expert_FAQ

    Вопрос

    Как скопировать экран в буфер обмена?

    Ответ

    keybd_event(VK_SNAPSHOT, MapVirtualKey(VK_SNAPSHOT, 0), 0, 0);
    keybd_event(VK_SNAPSHOT, 0, 0, 0);

    Из конференции Delphi

    Вопрос

    Необходимо скрыть приложение. Так чтоб его не было на панели задач и не было видно под Ctrl+Alt+Del? Желательно пример кода или ссылки на него?

    Ответ

    function RegisterServiceProcess(dwProcessID, dwType: Integer): Integer; stdcall; external 'KERNEL32.DLL'; procedure TForm1.Button1Click(Sender: TObject); begin RegisterServiceProcess(GetCurrentProcessId, 1); //Убираем из Alt-Ctrl-Del (0 — показать) ShowWindow(Application.Handle, SW_HIDE); //Убираем из TaskBar SetWindowLong(Application.Handle, GWL_EXSTYLE, //Убираем само приложение GetWindowLong(Application.Handle, GWL_EXSTYLE) or WS_EX_TOOLWINDOW); end;

    Из конференции Expert_FAQ

    Вопрос

    Как на Паскале/Дельфи собрать несколько файлов из папки в один файл моего формата, формат такой:

    type
    TDataFile = packed record
    DirID: string[3];
    DirName: string[12];
    FileID : string[4];
    FileName: string[12];
    FileContent: ????;
    // предполагаемое содержимое файла, не знаю какой тип использовать
    end;


    И как потом сделать чтение, показ например битмапа который допустим в середине этого файла, как это делается в Quake 1,2,3 и Half-Life — *.

    Ответ

    Что же… Вопрос неплохой, но наверное четкого ответа на него написать не получится, но напишу как это пришлось реализовывать мне.

    Требуется: Записать в один файл несколько других из папки.

    1. Использовать ZIP :). Понимаю что примитивно, но в некоторых случаях очень действенно. А самое удобное в данном варианте, что все это очень просто реализуется.
    2. Использовать потоки. То есть несколько файлов последовательно пишутся в один поток. А потом дописывается заголовок.

    type TRecInfo = record sID: String[8];
    sName: String[255];
    iStart, iSize: Cardinal;
    end;
    const UC_FILEHEADER = 'FILEVER 1.0';
    {Число -> Строка} function Number2String(Number: Extended;
    iLength: integer = 0;
    FillChar: Char = ' '): string;
    var i: integer;
    Temp: String;
    begin Result := '';
    Temp := FloatToStr(Number);
    ;
    i := Pos(',', Temp);
    if i >
    0 then Temp[i] := '.';
    Result := Temp;
    if iLength > 0 then for i := Length(Temp) to iLength do Result := Result + FillChar;
    end;
    function DoSaveFile(FileName: String): Boolean;
    var uRecord: TRecInfo;
    TempStr: String[64];
    Header, Data, Temp: TMemoryStream;
    begin Result := False;
    {Создаем потоки} Data := TMemoryStream.Create;
    Temp := TMemoryStream.Create;
    Header := TMemoryStream.Create;
    try // SKIPPED // {Организовать цикл по требуемым на запись файлами} Temp.LoadFromFile({FILE_2_SAVE});
    {Сохраняем текущую позицию} uRecord.iStart := Data.Position;
    {Записываем тип и имя объекта} uRecord.sID := {OBJECT_TYPE};
    // Укажи тип файла (например по расширению) uRecord.sName := {FILE_2_SAVE};
    // Например имя файла {Пишем данные и определяем длину} Temp.SaveToStream(Data);
    uRecord.iSize := Data.Size — uRecord.iStart;
    Header.Write(uRecord, SizeOf(uRecord));
    // SKIPPED // {Формирование блоков данных завершено — объединяем в один файл}
    {Записываем начало и длину} Header.Write(uRecord, SizeOf(uRecord));
    {Пишем файловый заголовок!} TempStr := UC_FILEHEADER + Number2String(Header.Size, 64 — (SizeOf(UC_FILEHEADER)+1), ' ');
    {Очистка} Temp.Clear;
    Temp.Position := 0; Temp.Write(TempStr, 64);
    {пишем заголовок данных, потом данные} Header.SaveToStream(Temp);
    Data.SaveToStream(Temp);
    {Записываем файл} Temp.SaveToFile(FileName);
    Result := True; finally {закрываем потоки} Temp.Free();
    Data.Free();
    Header.Free();
    end;
    end;


    Но как показывает практика данные надо еще и как-то читать. Немного печально, но необходимо. Поэтому пишем нечто похожее на это

    function IsValidHeader(Header: String): Cardinal;
    var i, j, k: Integer;
    StrTemp: String;
    begin Result := 0;
    {Проверка заголовка на идентификатор} if Pos(UC_FILEHEADER, Header) = 0 then Exit;
    {Читаем длину строки} for i := SizeOf(UC_FILEHEADER)+1 to 64 do begin Val(Header[i], k, j);
    if j <> 0 then Break;
    StrTemp := StrTemp + Header[i];
    end;
    Result := StrToInt(StrTemp);
    end;
    function DoOpenFile(FileName: String): Boolean; var i, j, RecCount: Cardinal;
    uRecord: TRecInfo;
    TempList: TStrings;
    Buffer: PChar;
    TempStr: String[64];
    Knowledge, Temp: TFileStream;
    TempFile, TempDir: array[0..255] of char;
    begin Result := False;
    {Установка для временной записи} GetTempPath(255, TempDir);
    GetTempFileName(TempDir, PChar('~wt'), 0, TempFile);
    {Начинаем с чтения в память} Knowledge := TFileStream.Create(FileName, fmOpenRead);
    try {читаем файл} Knowledge.Position := 0;
    {читаем и проверяем заголовок} Knowledge.Read(TempStr, 64);
    i := IsValidHeader(TempStr);
    {если файл не наш, то его открывать не нужно!!!}
    if i = 0 then Exit;
    {читаем заголовок данных}
    Knowledge.Position := 64;
    RecCount := i div SizeOf(uRecord);
    for j := 1 to RecCount do begin {Устанавливаем позицию}
    Knowledge.Position := 64 + (j — 1) * SizeOf(uRecord);
    Knowledge.Read(uRecord, SizeOf(uRecord));
    {Читаем гипотезу}
    if Pos('jpg', uRecord.sID) > 0 then begin GetMem(Buffer, uRecord.iSize);
    {Читаем из потока}
    i := Knowledge.Position;
    Knowledge.Position := 32 + RecCount * SizeOf(uRecord) + uRecord.iStart;
    Knowledge.Read(Buffer^, uRecord.iSize);
    Knowledge.Position := i;
    {Пишем во временный файл, если нужно, если нет то можно взять напрямую из потока}
    Temp := TFileStream.Create(TempFile, fmCreate);
    Temp.Write(Buffer^, uRecord.iSize);
    Temp.Free;
    // SKIPPED // FreeMem(Buffer);
    end;
    end;
    Result := True;
    finally {удаляем файл} DeleteFile(TempFile);
    {закрываем потоки}
    Knowledge.Free();
    end;
    end;


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

    Из конференции Expert_FAQ

    Вопрос

    Создаю динамически в консольном приложениии некий невизуал компонент, к примеру ttimer.

    А как создать ему события? :) Кусок кода не помешал бы…

    Ответ

    Создаешь свой компонент и присваиваешь его событиям свои обработчики. Т.е.

    Timer:=TTimer.create(nil);

    Timer.OnTimer:=TimerHandler;

    где TimerHandler твой обработчик события от таймера. Но тут есть одна хитрость. Она в том, что TimerHandler должен быть не просто процедурой, а МЕТОДОМ класса. Если у тебя не используются классы (имеются в виду твои собственные), то не обходимо создать fake объект:

    TFakeClass = class

    public

    procedure TimerHandler(Sender:TObject);

    end;

    и тогда пишем:

    FakeClass:=TFakeClass.Create;

    Timer:=TTimer.create(nil);

    Timer.OnTimer:=FakeClass.TimerHandler;

    Из конференции Expert_FAQ

    Вопрос

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

    Ответ

    1-й вариант:
    Берем и ложим на форму imagelist и popupmenu
    в imagelist закидываем пару-тройку иконок
    далее в раздел public записываем такой код:


       public
        tr_icon:ticon;
        trayicon:tnotifyicondata;
        // popup меню при клике на значке
        procedure onmessage(var msg:tmessage);virtual;
        Procedure WMGetSysCommand(var Message : TMessage); message
    WM_SYSCOMMAND;
        { Public declarations }

    procedure TForm1.FormCreate(Sender: TObject);
    begin
    fillchar(trayicon,sizeof(trayicon),0);
    tr_icon:=ticon.create;
    imagelist1.geticon(1,tr_icon);// здесь ты выбираешь какую иконку грузить в трей
    trayicon.cbsize:=sizeof(trayicon);
    trayicon.wnd:=allocatehwnd(onmessage);
    trayicon.hicon:=tr_icon.handle;
    trayicon.uCallbackMessage:=15;//wm_Callback_Msg;// у меня не
    // получилось в те времена зарегистрировать собщение, пришлось
    // изворачиваться…
    strplcopy(trayicon.sztip,application.title,sizeof(trayicon.sztip)-1);
    // Вместо application.title можно поставить свою
    //строку, которая будет выскакивать как хинт
    trayicon.uflags:=nif_message or nif_icon or nif_tip;
    // процедура создания иконки
    shell_notifyicon(nim_add,@trayicon);
    end;

    procedure TForm1.FormDestroy(Sender: TObject);
    begin
    // удаление иконки из трея
    shell_notifyicon(nim_delete,@trayicon);
    end;

    // обработка всплывающего окна
    procedure tform1.onmessage(var msg:tmessage);
    procedure showpopup;
    var
    x,y:integer;
    begin
    x:=getsystemmetrics(sm_cxfullscreen);
    y:=getsystemmetrics(sm_cyfullscreen)+getsystemmetrics(sm_cycaption);
    popupmenu1.popup(x,y)
    end;
    begin
    case msg.msg of
    15: case msg.LParam of
    wm_lbuttondblclk :show;
    // можно сделать по другому // if form1.visible=true then form1.hide else form1.show;
    wm_rbuttondown:showpopup;
    end;
    end;
    end;

    // обработка минимизации окна
    Procedure Tform1.WMGetSysCommand(var Message : TMessage);
      Begin
        IF (Message.wParam = SC_MINIMIZE)
        Then form1.Visible:=False
        Else Inherited;
      End;


    для смены иконки если не ошибаюсь надо сделать такой код:

    imagelist1.geticon(1,tr_icon);// здесь ты выбираешь какую иконку
    trayicon.hicon:=tr_icon.handle;
    shell_notifyicon(nim_modify,@trayicon);


    Нашел на бескрайних просторах, не помню где, собрано из разных кусков, но у меня работает, (в 95 винде иконки в трее не видно, но я думаю это связано как-то imagelist…)

    2-й вариант:
    Использовать соответствующие компоненты.

    Александр

    Вопрос

    Как создать окно «О программе» как у Блокнота?

    Ответ

    В разделе uses добавить ShellAPI

    ShellAbout(0, 'Мое приложениe', 'Я', LoadIcon(0, IDI_INFORMATION));

    или

    ShellAbout(0, 'Мое приложениe', 'Я', Application.Icon.Handle);

    Из конференции Expert_FAQ

    Вопрос

    Как создать форму в runtime-mode?

    Ответ

    Вот, можно так:

    with TxxForm.Create(Self) do Show;
    with TxxForm.Create(Self) do
    try
        ShowModal;
    finally
        Free;
    end;


    Из конференции Delphi

    Вопрос

    С помощью каких компонетов можно создать чат на Дельфи?

    Ответ

    Чат является простым клиент серверым приложением. Испульзуй стандартные компоненты вкладки "Internet" на палитре компонентов. Можешь придумать свою структуру пакетов можешь просто текстом посыласть. Главное — это тебе знать адреса и порты копмпьютеров.

    Костромич

    Вопрос

    Как сохранить в ini файле настройки TFont?

    Ответ

    uses
        IniFiles;

    procedure TForm1.Button1Click(Sender: TObject);
    var
        IniFile : TIniFile;
    begin
        IniFile := TIniFile.Create('myIni.ini');
        with Edit1.Font do with IniFile do begin
    Name := ReadString ('Font','Name','MS Mans Serif');
    Charset := ReadInteger('Font','Charset',RUSSIAN_CHARSET);
    Color := ReadInteger('Font','Color', clWindowText);
    Height := ReadInteger('Font','Height',-11);
    Size := ReadInteger('Font','Size',8);
    Style := TFontStyles(Byte(ReadInteger('Font','Style',0)));
        end;
        IniFile.Free;
    end;

    procedure TForm1.Button2Click(Sender: TObject);
    var
        IniFile : TIniFile;
    begin
        IniFile := TIniFile.Create('myIni.ini');
        with Edit1.Font do with IniFile do begin;
    WriteString ('Font','Name', Name);
    WriteInteger('Font','Charset', Charset);
    WriteInteger('Font','Color', Color);
    WriteInteger('Font','Height', Height);
    WriteInteger('Font','Size', Size);
    WriteInteger('Font','Style',Byte(Style));
        end;
        IniFile.Free;
    end;

    Из конференции Delphi

    Вопрос

    Нужно отформатировать диск С:. Delphi с кучей сторонних компонентов стоит на D:. После установки Windows придется переустанавливать Delphi. Что нужно сделать, чтобы IDE осталась в прежнем виде, со старым набором компонентов?

    Ответ

    Сохранить, а затем восстановить ключи в реестре: HKEY_LOCAL_MACHINE\SOFTWARE\Borland
    HKEY_CURRENT_USER\Software\Borland

    и все *.bpl в winnt\system32 или win9x\system

    Вопрос

    Как сохранить всю форму в файл (как Delphi в *.dfm)?

    Ответ

    constructor TForm1.Create(AOwner: TComponent); // override;
    var
        fname: String;
    begin
      { Для динамически создаваемых контролов, может требоваться RegisterClasses(..); }
      fname := FormFilename;
      if FileExists( fname ) then
          begin
         CreateNew(AOwner);
         ReadComponentResFile(fname, Self);
          end
      else
          inherited Create( AOwner );
    end;

    procedure TForm1.FormCloseQuery( Sender: TObject; var CanClose: Boolean);
    begin
        WriteComponentResFile(FormFileName, Self);
    end;

    Peter Below

    Вопрос

    Как спрятать контрол, если известен его Handle?

    Ответ

    ShowWindow(ButtonHandle, SW_HIDE); // SW_SHOW

    Из конференции Delphi

    Вопрос

    Как убрать VerticalScrollBar из TListBox навсегда?

    Ответ

    procedure TListBoxForEver.CreateParams (var Params:TCreateParams); //override
    begin
        inherited CreateParams(Params);
    Params.Style := Params.Style and not WS_VSCROLL;
    end;

    Leonid Troyanovsky

    Вопрос

    Как убрать из ListView горизонтальный скролбар навсегда?

    Ответ

    type
        TNoHScrollListview = Class( TListview )
        private
    Procedure WMNCCalcSize( Var msg: TMessage ); message WM_NCCALCSIZE;
        end;

    procedure TNoHScrollListview.WMNCCalcSize(var msg: TMessage);
    var
        style: Integer;
    begin
        style := getWindowLong( handle, GWL_STYLE );
        If (style and WS_HSCROLL) <> 0 Then
    SetWindowLong( handle, GWL_STYLE, style and not WS_HSCROLL );
        inherited;
    end;

    Peter Below

    Вопрос

    При изменении Caption'a объекта TLabel — сам объект мерцает! Помогите мне убрать это мерцание!

    Ответ

    Попробуй

    GetParentForm(Label1).DoubleBuffered:=true;

    Из конференции Expert_FAQ

    Вопрос

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

    Ответ

    Для того, чтобы убрать программу из TaskBar'а и Task Manager'а (Ctrl-Alt-Del) надо использовать следующий код:

    function RegisterServiceProcess(ProcessID, Typ: Integer): Integer;
    external 'KERNEL32.DLL';
    procedure TForm1.Button1Click(Sender: TObject);
    begin RegisterServiceProcess(GetCurrentProcessId, 1);
    ShowWindow(Application.Handle, SW_HIDE);
    SetWindowLong(Application.Handle, GWL_EXSTYLE, GetWindowLong(Application.Handle, GWL_EXSTYLE) or WS_EX_TOOLWINDOW);
    end;


    Для того, чтобы скрыть главную форму:

    {*********}

    procedure TForm1.FormCreate(Sender: TObject);
    begin
    Application.ShowMainForm := false;
    end;

    {*********}

    Хотя в данном случае можно вообще без формы все сделать — заходим в Project/View Sorce, убираем там все, что связано с формой и там же пишем необходимый код (только о разделе Uses надо позаботиться).

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

    {*********}

    uses Registry;
    procedure TForm1.Button1Click(Sender: TObject);
    var
    reg: TRegistry;
    begin
    reg := TRegistry.Create;
    reg.RootKey := HKEY_LOCAL_MACHINE;
    reg.OpenKey('Software\Microsoft\Windows\CurrentVersion\Run', false);
    reg.WriteString('My App', Application.ExeName);
    reg.CloseKey;
    reg.free;
    end;

    {*********}

    В этом случае программа будет запускаться каждый раз при запуске Windows. А можно сделать еще интереснее: использовать ключ RunOnce, а не просто Run. Тогда программа запуститься при следующем запуске Windows, а ссылка на нее автоматически удалится. Программа проверит дату (в самом простом случае — это if DateToStr(Now) = 'дд.мм.гггг' — для того, чтобы посмотреть в каком формате у вас на машине представлены данные и в зависимости от этого писать условие, напишите Form1.Caption = DateToStr(Now)), и если окажется так, что нужный день еще наступил, то просто выполнит повторную запись в реестр. Если же нужный день наступил, то она выполнит свое дело и все. Для проверки времени надо использовать TimeToStr(Now), а можно DateTimeToStr(Now).

    Как удалить файл без возможности его восстановления я не знаю. Но можно перезаписать на его место какой-нибудь другой или, если удаляются exe'шники — дописать в него пару строк — тогда он не запустится. Для удаления каталога надо учесть, что он должен быть пустым. Я не буду приводить код этого дела — в Сети достаточно примеров. Назову только основные функции:

    FileExists — проверка существования файла
    DeleteFile — удаление файла
    RenameFile — переименование файла
    RemoveDir — удаление каталога
    Для поиска — FindNext и FindFirst.

    И еще одна деталь. Программы, создаваемые Delphi, получаются довольно большими (приложение с пустой формой в Delphi 7 — 359 Кб). Поэтому если вам необходимо, чтобы запуск вашей программы при старте Windows был как можно более прозрачным, используйте упаковщики exe файлов. Один из них можно взять на http://aclab2.chat.ru называется Compressor (после его применения размер файла сократился до 149 Кб). Есть еще один — UPX Shell — http://iont.virtualave.net/

    Из конференции Expert_FAQ

    Вопрос

    Как осуществить удаление границы вокруг ComboBox'а?

    Ответ

    procedure TForm1.FormCreate(Sender: TObject);
    begin
    SetWindowRgn(ComboBox1.Handle, CreateRectRgn(2,2,ComboBox1.Width — 2,
        ComboBox1.Height — 2), True)
    end;


    Из конференции Delphi

    Вопрос

    Вопрос по нетипизированным файлам. Допустим я смогу добавить что-нть в файл методом blockwrite. А вот как удалить оттуда, то что я добавил? И вообще, как сделать удаление в untyped-файлах?

    Ответ

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

    Вопрос

    Как удалить непустой каталог?

    Ответ

    Непустой каталог можно удалить следующим образом:
    Создайте на форме кнопку с именем Button1, и вставьте в обработчик события клика мыши следующий код:

    procedure TForm1.Button1Click(Sender: TObject);
    var
        lpFileOp: TSHFileOpStruct;
    begin
          FillChar(lpFileOp,SizeOf(lpFileOp),0);
          lpFileOp.Wnd := Handle;
          lpFileOp.wFunc := FO_DELETE;
          lpFileOp.pFrom := PChar(Edit1.Text);
          lpFileOp.fFlags := FOF_NOCONFIRMATION;
          SHFileOperation(lpFileOp);
    end;


    Ivan Daniloff

    Вопрос

    Как удалить непустой каталог?

    Ответ

    procedure TForm1.Button1Click(Sender: TObject);
    var
        lpFileOp: TSHFileOpStruct;
    begin
      FillChar(lpFileOp,SizeOf(lpFileOp),0);
          lpFileOp.Wnd := Handle;
          lpFileOp.wFunc := FO_DELETE;
      lpFileOp.pFrom := PChar(Edit1.Text);
      lpFileOp.fFlags := FOF_NOCONFIRMATION;
          SHFileOperation(lpFileOp);
    end;

    Ivan Daniloff

    Вопрос

    Как узнать ip и имя хоста сервера на котором запущено приложение?

    Ответ

    Решение: TClientWinSocket и свойства LocalAddress и Localhost.
    Или gethostbyaddr и gethostbyname.

    Kviz, Rusin Konstantin

    Вопрос

    Delphi 6, Win XP, подскажите пожалуйста, как узнать, что запустилось или работает приложение (например Блокнот), и завершить его из моей программы. Если можно пример. %%%Вот так :

    uses windows, messages; var wnd: HWND; begin //Ищем окно работающего приложения по его классу. //Если нужно найти окно с конкретным заголовком, //можно использовать FindWindow(nil, "Какой-то заголовок") wnd:=FindWindow("Notepad",nil); if wnd=0 then ShowMessage("Окно не найдено") //Если приложение не запущено else SendMessage(wnd, WM_CLOSE, 0,0);//Говорим окну,что пора закрываться end;

    Из конференции Expert_FAQ

    Ответ

    Вопрос

    Как узнать и поменять разрешение экрана?

    Ответ

    Поменять:

    procedure ChangeDisplayResolution(x, y : word);
    var
        dm : TDEVMODE;
    begin
        ZeroMemory(@dm, sizeof(TDEVMODE));
        dm.dmSize := sizeof(TDEVMODE);
        dm.dmPelsWidth := x;
        dm.dmPelsHeight := y;
        dm.dmFields := DM_PELSWIDTH or DM_PELSHEIGHT;
        ChangeDisplaySettings(dm, 0);
    end;

    Узнать можно также с помощью объекта Screen

    Screen.Width
    Screen.Height

    Из конференции Delphi

    Вопрос

    Как узнать какой язык выбран в системе?

    Ответ

    Возвращает числовой код — GetKeyboardLayout(0)

    Возвращает имя

    var sNameLayout:string[256];

    GetKeyboardLayoutName(sNameLayout[1]);

    Из конференции Expert_FAQ

    Вопрос

    Как узнать коды клавиш, которые не выводятся методом:

    procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
    begin
    caption:=inttostr(ord(key));

    Т.е узнать коды функциональных клавишь, Insert, Delete, PageUp…

    Ответ

    Для их отлова надо использовать события OnKeyDown/OnKeyUp.

    Они получают код любой, не только символьной клавиши.
    Эти коды можно найти в виде констант вида VK_??? в файле windows.pas.

    procedure TForm.FormKeyDown(Sender: TObject; var Key: Word;
    Shift: TShiftState);
    begin
    if Key = VK_INSERT then
    ShowMessage('"Insert" pressed');
    end;

    Из конференции Expert_FAQ

    Вопрос

    Как узнать кол-во цветов цветовой палитры?

    Ответ

    Вот так:

    function GetColorsCount : DWord;
    var
        DC : HDC;
    begin
        DC := GetDC( 0 );
        Win32Check(DC <> 0);
        Result :=1 shl (GetDeviceCaps(DC, PLANES) *
          GetDeviceCaps(DC, BITSPIXEL));
        ReleaseDC( 0, DC );
    end;

    Leonid Troyanovsky

    Вопрос

    Можно ли как-нибудь узнать сколько продразделов находится в определенном разделе реестра?

    Ответ

    Процедура procedure GetKeyNames(Strings: TStrings);

    выдает список (тип TStrings) всех подключей (subkeys) текущего ключа (key).

    Процедура procedure GetValueNames(Strings: TStrings);

    выдает список (тип TStrings) имен (names) всех значений ассоциированных с текущим ключом (key).

    Функция function HasSubKeys: Boolean;

    возвращает True если ключ имеет хотя бы один подключ.

    Т.е. проверяешь, имеет ли ключ подключи и вытаскиваешь их GetValueNames(Strings: TStrings), а иначе вытаскиваешь значения GetValueNames(Strings: TStrings).

    А дальше — свойство Tstrings.count.

    Небольшой пример. На форме ListBox1, Edit1, Label1, Label2, Button1

    Добавить в uses registry

    procedure TForm1.Button1Click(Sender: TObject); var Reg: TRegistry; Val:TStringList; begin Reg:=TRegistry.Create; try Val:=TStringList.Create; try Reg.RootKey:=HKey_Local_Machine; if not Reg.OpenKey(Edit1.Text,False) then ShowMessage('Не могу открыть ключ!') else begin Reg.GetKeyNames(Val); Listbox1.Items:=Val; label2.Caption:=inttostr(val.Count); end; finally Val.Free; end; finally Reg.Free; end; end; procedure TForm1.ListBox1DblClick(Sender: TObject); begin edit1.Text:=listbox1.Items.Strings[listbox1.itemindex] end;

    Из конференции Expert_FAQ

    Вопрос

    Как узнать состояние управляющих клавиш — [Shift], [Ctrl], [Alt]?

    Ответ

    function IsKeyDown(vk: Word):Boolean;
    begin
        Result := GetKeyState(vk) and $8000 = $8000;
    end;

    vk для Ctrl, Shift, Alt соответственно равны: vk_control, vk_shift и vk_menu

    Из конференции Delphi

    Вопрос

    Как узнать, была ли создана ли определенная форма?

    Ответ

    function IndexOfForm (const AClassName: String; const FromIndex:Word):Integer;
    var
        i : Integer;
    begin
        Result := -1;
       for i := FromIndex to Screen.FormCount-1 do
     if (CompareText(Screen.Forms[i].ClassName, AClassName) = 0) then
            begin
          Result := i;
           Break;
            end;
    end;

    Из конференции Delphi

    Вопрос

    Как я могу узнать, что файл (любого типа) открыт каким-либо приложением?

    Ответ

    Далеко не самый изящный вариант, но…

    procedure TForm1.Button1Click(Sender: TObject);
    var F: TextFile;
    begin AssignFile(F, '1.exe');
    {$I-} Append(F);
    if IOResult = 0 then begin ShowMessage('Файл свободен');
    CloseFile(F);
    end
    else ShowMessage('Файл занят');
    {$I+}
    end;


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

    Из конференции Expert_FAQ

    Вопрос

    Как уменьшить размер исполняемого файла программы?

    Ответ

    Писать на WinAPI без использования VCL. Это пригодно для и без того крохотных программ. Существуют freeware библиотеки, упрощающие программирование без VCL, например:
    KOL http://xcl.cjb.net (ВЫБОР СОСТОВИТЕЛЯ)
    ACL http://a-press.parad.ru/pc/bokovikov/delphi

    Воспользоваться пакетами (packages) из Delphi 3. Эффект появится, когда исполняемых файлов больше одного.

    Воспользоваться компрессорами исполняемых файлов, например:
    Shrinker http://www.blinkinc.com,
    WWPack32 http://kolos.uni.lodz.pl/warezak,
    NeoLite,
    Petite, http://www.icl.ndirect.co.uk/petite/.

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

    Из конференции Delphi

    Вопрос

    Защита программ… Привязка к железу… и другие методы защит…

    Как установить защиту в программе на Delphi?

    1) Привязаться к железу — винт + ОС + процессор + видеокарта? Иные варианты?

    2) Грамотно встроить защиту в программу (Не проверка типа «if Pass<>'Password' then close;»)? В какие ключевые места программы (рекомендации)?

    3) Метод получения, ввода, проверки ключа к защите?

    4) И важно чтобы все енто работало под w9x/wnt/w2k/wxp?

    Ответ

    Могу порекомендовать сходить на сайт Королевство Дельфии посмотреть. Там была статья Дмитрия Логинова о защите информации. Очень подробно описаны методы защиты и как и чем они ломаются…

    Из конференции Expert_FAQ

    Вопрос

    Как установить комбинацию клавиш для команды и процедуры?

    Ответ

    Здесь можно предложить несколько вариантов:
    1. Большинство «логически законченных» программ имеют главное меню. Итак, добавляете главное меню (палитра Standard — MainMenu) Так вот: каждый пункт главного меню имеет свойство ShortCut — это ни что иное как горячая клавиша. Если не знаете как работать с главным меню, смотрите в конце. В общем, добавляем пункт, допустим, «Закрыть Файл». Назначаем ему ShortCut «Ctrl+W». Делаем событие OnClick для этого пункта меню и пишем там код, который надо выполнить, например,
    Close;
    После этого и Ctrl+W, и Ctrl+Ц будут приводить к закрытию формы (или выполнению вашего кода).

    Но на случай, если вы не захотите делать главное меню, существует второй вариант:
    2. Обрабатываем событие OnKeyUp, т.к. оно содержит как параметр переменную Shift: TShiftState, которая даст нам информацию о нажатых системных клавишах:
    — у формы есть параметр KeyPreview: делаете его True.
    — пишете обработчик события ДЛЯ ФОРМЫ OnKeyUp:
    if (key = vkkeyscan('w')) and (shift = [ssCtrl]) then close;
    Здесь функция vkkeyscan возвращает код символа, переданного ей в качестве параметра. Нам это надо, т.к. параметр Key поступает к нам в «виде» типа Word, поэтому надо узнать код самого символа. Переменная Shift типа TShiftState является по сути множеством и может принимать значения:
    (ssShift, ssAlt, ssCtrl, ssLeft, ssRight, ssMiddle, ssDouble)
    Хоть одно значение, хоть два, хоть все вместе. Так мы и проверяем: если переменная представляет собой множество из одного элемента [ssCtrl], то значит была нажата клавиша Control. Например, если эта переменная равна [ssCtrl, ssShift], то были нажаты обе клавиши Control и Shift.
    Естественно, вместо Close; можете поставить все, что хотите: свой оператор, вызов процедуры, операторные скобки begin..end и набор операторов между ними, …

    3. Будем обрабатывать сообщения:
    — в объявлении класса вашей формы (по умолчанию TForm1) в разделе private добавляете:
    procedure ProcMess(var Msg: TWMKEYUP);
    message WM_KEYUP;

    этим мы определяем процедуру, которая будет реагировать на сообщение WM_KEYUP, т.е. отпущена клавиша
    — в самой процедуре пишем (шаблон нам в этом случае не делают, поэтому в любом месте программы сами пишите следующее):
    procedure TForm1.ProcMess(var Msg: TWMKEYUP);
    begin
    if (msg.CharCode = vkkeyscan('w')) then
    if (getkeystate(vk_control) < 0) then
    close; //или вызов вашей процедуры, или сама
    //процедура
    end;

    Здесь функция vkkeyscan возвращает код символа, переданного ей в качестве параметра. Нам это надо, т.к. msg.CharCode поступает к нам в «виде» типа Word, поэтому надо узнать код самого символа.

    Итак, если, допустим, «отжата» клавиша w, то при этом вычисляется следующее выражение:
    getkeystate(vk_control) < 0
    Здесь getkeystate — функция Windows API, которая возвращает состояние какой-либо клавиши. Нам надо состояние, например, клавиши Control, которая имеет код, содержащийся в константе vk_control. Также это может быть и Shift с кодом vk_shift. Вот на счет Alt ничего конкретного сказать не могу (ее код — vk_menu): она определяется как-то неправильно, точнее ее нажатие не всегда определяется, можете сами поэкспериментировать.

    PS Вариант с получением кода буквы w также срабатывает и с буквой ц, т.е. не надо отдельно получать код буквы ц. И еще: всегда ставьте маленькие буквы в качестве параметра.

    PPS Про меню:
    — щелкайте дважды на палитре компонентов Standard по компоненту MainMenu — он появляется на форме
    — дважды щелкайте уже по компоненту, появившемуся на форме — перед вами редактор главного меню и по умолчанию выделен первый раздел
    — идете в Object Inspector и изменяете свойство Caption на, допустим, строку «Файл» — появляется (в редакторе) раздел с именем «Файл»
    — щелкаете по этому разделу («Файл») — выпадает первый элемент, пока пустой
    — щелкаете по этому пустому пункту и опять же изменяете свойство Caption на, допустим, «Закрыть»
    — теперь если два раза щелкнуть на пунктике «Закрыть», то вы попадаете в редактор кода с готовым шаблоном для написания обработчика события OnClick для пункта «Закрыть» и пишите там все, что хотите

    Герун Данил

    ДЕЛАЕМ СЛЕДУЮЩЕЕ:

    1. Запустить WinSight;
    2. Зайти в его настройки: Меню Messages — Options …;
    3. В окне настроек ВКЛючить галочку "Interpret Values", а "HEX Values" — ВЫКЛючить. Нажать OK! ;-);
    4. Запустить программу-"пациента", которой мы хотим посылать комбинацию клавиш;
    5. Выбрать в дереве процессов WinSight эту программу-"пациента" и тот ее объект, которому надо "посылать";
    6. Включить WinSight в режим слежения: "Start!" и переключиться на программу-"пациента";
    7. Активировать (если надо) нужный объект щелчком мыши и нажать требуемую комбинацию клавиш;
    8. Должна выполниться та функция программы-"пациента", вызов которой мы хотим эмулировать программно;
    9. Закрываем программу-"пациента" (не обязательно, можно свернуть ;-);
    10. Переходим к WinSight и смотрим, какие сообщения он у нас поймал;
    11. Если ничего нет (или нет того, что нужно), значит вы выбрали не тот процесс или объект программы.

    Коли так, возвращайтесь к пункту 4 и делайте заново… Удачи…;

    12. Если вы все-таки получили "какие то" сообщения и среди них попадаются слова WM_KEYDOWN,

    значит, возможно, это то, что нужно… ;-);

    13. Выбираем (визуально) участок сообщений, в котором содержатся сообщения WM_KEYDOWN

    и/или WM_KEYUP. Например:

    000160:00000710 {Internet Ex} WM_TIMER Dispatched id 4096 lpfn 00000000
    000161:00000710 {Internet Ex} WM_NCHITTEST Sent (236,258)
    + 000162:00000710 {Internet Ex} WM_KEYDOWN Dispatched 11h 17d VK_CONTROL Scan 1Dh Down
    000163:00000710 {Internet Ex} WM_NCHITTEST Sent (236,258)
    + 000164:00000710 {Internet Ex} WM_KEYDOWN Dispatched 46h 70d VK_F Scan 21h Down
    + 000165:00000710 {Internet Ex} WM_COMMAND Sent Accelerator 0043h 67d
    + 000166:00000710 {Internet Ex} WM_KEYUP Dispatched 46h 70d VK_F Scan 21h Up
    000167:00000710 {Internet Ex} WM_TIMER Dispatched id 4096 lpfn 00000000
    000168:00000710 {Internet Ex} wm_systimer Dispatched wp=0000FFFF lp=177F12DC

    // Плюсами я мысленно пометил те сообщения, которые нужны (в моем случае) для эмуляции нажатия.

    14. Отделите (мысленно) "мусор" от "нормальных", нужных сообщений (чтобы выбрать, можно прогнать процесс отслеживания сообщений несколько раз и сравнить полученные результаты)
    15. Допустим Вы получили список "нужных" сообщений, повторяющихся всегда при нажатии комбинации:

    000162:00000710 {Internet Ex} WM_KEYDOWN Dispatched 11h 17d VK_CONTROL Scan 1Dh Down
    000164:00000710 {Internet Ex} WM_KEYDOWN Dispatched 46h 70d VK_F Scan 21h Down
    000165:00000710 {Internet Ex} WM_COMMAND Sent Accelerator 0043h 67d
    000166:00000710 {Internet Ex} WM_KEYUP Dispatched 46h 70d VK_F Scan 21h Up
    16. Далее, нужно зайти в настройки WinSight: Меню Messages — Options …
    17. В окне настроек ВЫКЛючить галочку "Interpret Values", а "HEX Values" — ВКЛючить. Нажать OK! ;-)

    Ваши сообщения преобразуются в несколько другой вид:

    000162:00000710 {Internet Ex} WM_KEYDOWN (10004X) Dispatched wp=00000011 lp=001D0001
    000164:00000710 {Internet Ex} WM_KEYDOWN (10004X) Dispatched wp=00000046 lp=00210001
    000165:00000710 {Internet Ex} WM_COMMAND (11104X) Sent wp=00010043 lp=00000000
    000166:00000710 {Internet Ex} WM_KEYUP (10104X) Dispatched wp=00000046 lp=C0210001

    18. А вот это, девочки и мальчики — уже и есть готовые команды! Надо только переписать в Дельфю!
    19. Преобразуем в нормальный Дельфевый вид:

    // Эмуляция нажатия CTRL+F. ( HWND — соответственно хендл объекта, которому будем посылать комбинацию)
    // PostMessage применяется, если сообщение Dispatched (см. выше — перехваченные сообщения)
    // SendMessage применяется, если сообщение Sent (см. выше — перехваченные сообщения)

    PostMessage(HWND, WM_KEYDOWN, $00000011, $001D0001); // Эмулирует нажатие и задержку CTRL (Код-&H11)
    PostMessage(HWND, WM_KEYDOWN, $00000046, $00210001); // Эмулирует нажатие клавиши F (Код-&H46)
    SendMessage(HWND, WM_KEYDOWN, $00010043, $00000000); // Акселератор
    PostMessage(HWND, WM_KEYUP, $00000046, $C0210001); // Эмулирует отпускание клавиши F (Код-&H46)

    20. Вот собственно и все! Компилируйте, запускайте свою прогу, запускайте программу-"пациента" и проверяйте!
    Если не работает, значит вы чего то не учли… Попробуйте еще поискать WinSight'ом… А у меня все работает!

    BioHazard

    Вопрос

    Как установить компонент от Delphi одной версии под Delphi другой версии, если имеется только файлы *.DCU?

    Ответ

    Hикак. Фирма Borland всегда поддерживала несовместимость .DCU-файлов между разными версиями. Ищите исходник или .DCU, скомпилированный для соответствующей версии Delphi.

    Вопрос

    Как устроить Pack в dbf-ной табличке?

    Ответ

    Я делаю так:

    Function Pack(Table:TTable):Integer;
    var
      fActive:Boolean;
      fExclusive:Boolean;
    begin
        fActive:=Table.Active; { сохранить среду }
        fExclusive:=Table.Exclusive;
        Table.Active:=False;
     Table.Exclusive:=True;{ упаковка в монопольном режиме };
        Table.Active:=True;
    Result:=DbiPackTable(Table.DBHandle,Table.Handle,NIL,'DBase',True);
        Table.Active:=False;
       Table.Exclusive:=fExclusive;{востановить среду}
        Table.Active:=fActive;
        If Table.Active then Table.Refresh;
    end;

    Люба

    Вопрос

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

    Ответ

    Использовать для форматирования фунцию FormatFloat('0.00',Variable) для переменных типа Float
    Для переменных типа Currency функцию CurrToStrF
    Для полей таблиц базы данных можно использовать свойство DisplayFormat
    Можно использовать переменную CurrencyDecimals := 2;
    Особенно помогает в Win95, где в установках по умолчанию обычно нет копеек (их в те времена и не было в России ;-). Это проще, чем заставлять пользователя править настройки системы или самому мучаться с FormatFloat при каждом выводе на экран.

    Олег Степанов

    Вопрос

    Как центрировать по форме модальный диалог?

    Ответ

    procedure CenterDialogPos(DlgHandle, WindowHandle: HWND);
    var
        DlgRect : TRect;
        WndRect : TRect;
        x, y, w, h : integer;
    begin
        if (DlgHandle <> 0) then begin
        GetWindowRect(DlgHandle, DlgRect);
        GetWindowRect(WindowHandle, WndRect);
        w := DlgRect.Right — DlgRect.Left;
        h := DlgRect.Bottom — DlgRect.Top;
        //center horz
        x := WndRect.Left + ((WndRect.Right — WndRect.Left — w) div 2);
        //keep on screen
       if x < 0 then x := 0
      else if x + w > Screen.Width then x := Screen.Width — w;
        //center vert
    y := WndRect.Top + ((WndRect.Bottom — WndRect.Top — h) div 2);
      //keep on screen
      if y < 0 then y := 0
    else if y + h > Screen.Height then y := Screen.Height — h;
    SetWindowPos(DlgHandle, 0, x, y, 0, 0, SWP_NOACTIVATE or SWP_NOSIZE or SWP_NOZORDER);
        end;
    end;

    procedure TForm1.WMUser1(var msg: TMessage); // message WM_USER+1;
    begin
        CenterDialogPos(GetActiveWindow, Handle);
    end;

    procedure TForm1.Button1Click(Sender: TObject);
    begin
        PostMessage(Handle, WM_USER+1, 0, 0);
        ShowMessage('Test');
    end;

    Из конференции Delphi

    Вопрос

    Как перевести данные из таблицы в Exсel в мою прогу? Спасибо.

    Ответ

    Воспользуйся компонентами с вкладки Servers из Delphi 5/6 (там находятся компоненты по работе с Microsoft Office 97/2000). После того, как с помощью методов нужных компонентов откроешь нужный лист, просто переноси данные из него в свою программу, переходя в цикле из ячейки в ячейку. Многие методы компонентов схожи с методами VBA из MS Office.

    Вопрос

    Как сделать экспортирование данных из TStringGrid в таблицу MS Word?

    Ответ

    uses ComObj;

    procedure TForm1.Button1Click(Sender: TObject);
    var
       WordApp, NewDoc, WordTable: OLEVariant;
       iRows, iCols, iGridRows, jGridCols: Integer;
    begin
       try
    // Создание ссылки на Word
    WordApp := CreateOleObject('Word.Application');
       except
         // Ошибка…
         Exit;
       end;

       // Показать Word
       WordApp.Visible := True;

       // Добавить новый документ
       NewDoc := WordApp.Documents.Add;

       // Получаем число колонок и строк
       iCols := StringGrid1.ColCount;
       iRows := StringGrid1.RowCount;

    // Добавление таблицы
    WordTable := NewDoc.Tables.Add(WordApp.Selection.Range, iCols, iRows);

    // Заполнение таблицы Word'а содержимым Stringgrid
       for iGridRows := 1 to iRows do
      for jGridCols := 1 to iCols do
    WordTable.Cell(iGridRows, jGridCols).Range.Text :=
    StringGrid1.Cells[jGridCols — 1, iGridRows — 1];

    // Здесь можно задать вопрос на сохранение документа и выхода из Word'а…

       // …
       
       // Очистка…
       WordApp := Unassigned;
       NewDoc := Unassigned;
       WordTable := Unassigned;
    end;

    Кирилл Краснов

    Вопрос

    Как можно строчки из Delphi программы посылать и отображать в Edit компоненте другой программы?

    Ответ

    Как эмулировать нажатия клавиш в другой программе:

    {***************BEGIN************}
    Этот модуль является почти полным аналогом методу SendKeys из VB.
    (Автор: Ken Henderson, email:khen@compuserve.com)

    (* SendKeys routine for 32-bit Delphi. Written by Ken Henderson Copyright © 1995 Ken Henderson email:khen@compuserve.com This unit includes two routines that simulate popular Visual Basic routines: Sendkeys and AppActivate.
    SendKeys takes a PChar as its first parameter and a boolean as its second, like so: SendKeys('KeyString', Wait);
    where KeyString is a string of key names and modifiers that you want to send to the current input focus and Wait is a boolean variable or value that indicates whether SendKeys should wait for each key message to be processed before proceeding.
    See the table below for more information.
    AppActivate also takes a PChar as its only parameter, like so: AppActivate('WindowName');
    where WindowName is the name of the window that you want to make the current input focus.
    SendKeys supports the Visual Basic SendKeys syntax, as documented below.
    Supported modifiers: + = Shift ^ = Control % = Alt Surround sequences of characters or key names with parentheses in order to modify them as a group.
    For example, '+abc' shifts only 'a', while '+(abc)' shifts all three characters.
    Supported special characters ~ = Enter ( = Begin modifier group (see above) ) = End modifier group (see above) { = Begin key name text (see below) } = End key name text (see below) Supported characters:
    Any character that can be typed is supported. Surround the modifier keys listed above with braces in order to send as normal text.
    Supported key names (surround these with braces):
    BKSP, BS, BACKSPACE BREAK CAPSLOCK CLEAR DEL DELETE DOWN END ENTER ESC ESCAPE F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 HELP HOME INS LEFT NUMLOCK PGDN PGUP PRTSC RIGHT SCROLLLOCK TAB UP Follow the keyname with a space and a number to send the specified key a given number of times (e.g., {left 6}).
    *) unit sndkey32;
    interface Uses SysUtils, Windows, Messages;
    function SendKeys(SendKeysString : PChar; Wait : Boolean) : Boolean; function AppActivate(WindowName : PChar) : boolean; {Buffer for working with PChar's} const WorkBufLen = 40; var WorkBuf : array[0..WorkBufLen] of Char;
    implementation type THKeys = array[0..pred(MaxLongInt)] of byte;
    var AllocationSize : integer;
    (* Converts a string of characters and key names to keyboard events and passes them to Windows. Example syntax: SendKeys('abc123{left}{left}{left}def{end}456{left 6}ghi{end}789', True);
    *) function SendKeys(SendKeysString : PChar; Wait : Boolean) : Boolean;
    type WBytes = array[0..pred(SizeOf(Word))] of Byte; TSendKey = record Name : ShortString;
    VKey : Byte;
    end;
    const {Array of keys that SendKeys recognizes.
    if you add to this list, you must be sure to keep it sorted alphabetically by Name because a binary search routine is used to scan it.} MaxSendKeyRecs = 41;
    SendKeyRecs : array[1..MaxSendKeyRecs] of TSendKey = ( (Name:'BKSP'; VKey:VK_BACK), (Name:'BS';
    VKey:VK_BACK), (Name:'BACKSPACE';
    VKey:VK_BACK), (Name:'BREAK';
    VKey:VK_CANCEL), (Name:'CAPSLOCK';
    VKey:VK_CAPITAL), (Name:'CLEAR';
    VKey:VK_CLEAR), (Name:'DEL';
    VKey:VK_DELETE), (Name:'DELETE';
    VKey:VK_DELETE), (Name:'DOWN';
    VKey:VK_DOWN), (Name:'END'; VKey:VK_END), (Name:'ENTER';
    VKey:VK_RETURN), (Name:'ESC';
    VKey:VK_ESCAPE), (Name:'ESCAPE';
    VKey:VK_ESCAPE), (Name:'F1';
    VKey:VK_F1), (Name:'F10';
    VKey:VK_F10), (Name:'F11';
    VKey:VK_F11), (Name:'F12';
    VKey:VK_F12), (Name:'F13'; VKey:VK_F13), (Name:'F14';
    VKey:VK_F14), (Name:'F15';
    VKey:VK_F15), (Name:'F16';
    VKey:VK_F16), (Name:'F2';
    VKey:VK_F2), (Name:'F3';
    VKey:VK_F3), (Name:'F4';
    VKey:VK_F4), (Name:'F5';
    VKey:VK_F5), (Name:'F6';
    VKey:VK_F6), (Name:'F7';
    VKey:VK_F7), (Name:'F8';
    VKey:VK_F8), (Name:'F9';
    VKey:VK_F9), (Name:'HELP';
    VKey:VK_HELP), (Name:'HOME';
    VKey:VK_HOME), (Name:'INS';
    VKey:VK_INSERT), (Name:'LEFT';
    VKey:VK_LEFT), (Name:'NUMLOCK';
    VKey:VK_NUMLOCK), (Name:'PGDN';
    VKey:VK_NEXT), (Name:'PGUP';
    VKey:VK_PRIOR), (Name:'PRTSC';
    VKey:VK_PRINT), (Name:'RIGHT';
    VKey:VK_RIGHT), (Name:'SCROLLLOCK';
    VKey:VK_SCROLL), (Name:'TAB';
    VKey:VK_TAB), (Name:'UP';
    VKey:VK_UP) );
    {Extra VK constants missing from Delphi's Windows API interface} VK_NULL=0;
    VK_SemiColon=186;
    VK_Equal=187;
    VK_Comma=188; VK_Minus=189;
    VK_Period=190;
    VK_Slash=191;
    VK_BackQuote=192;
    VK_LeftBracket=219;
    VK_BackSlash=220;
    VK_RightBracket=221;
    VK_Quote=222;
    VK_Last=VK_Quote;
    ExtendedVKeys : set of byte = [VK_Up, VK_Down, VK_Left, VK_Right, VK_Home, VK_End, VK_Prior, {PgUp} VK_Next, {PgDn} VK_Insert, VK_Delete];
    const INVALIDKEY = $FFFF;
    VKKEYSCANSHIFTON = $01;
    VKKEYSCANCTRLON = $02; VKKEYSCANALTON = $04;
    UNITNAME = 'SendKeys';
    var UsingParens, ShiftDown, ControlDown, AltDown, FoundClose : Boolean; PosSpace : Byte; I, L : Integer;
    NumTimes, MKey : Word;
    KeyString : String[20];
    procedure DisplayMessage(Message : PChar);
    begin MessageBox(0,Message,UNITNAME,0);
    end;
    function BitSet(BitTable, BitMask : Byte) : Boolean; begin Result:=ByteBool(BitTable and BitMask);
    end;
    procedure SetBit(var BitTable : Byte;
    BitMask : Byte);
    begin BitTable:=BitTable or Bitmask;
    end;
    procedure KeyboardEvent(VKey, ScanCode : Byte; Flags : Longint);
    var KeyboardMsg : TMsg;
    begin keybd_event(VKey, ScanCode, Flags,0);
    if (Wait) then While (PeekMessage(KeyboardMsg,0,WM_KEYFIRST, WM_KEYLAST, PM_REMOVE)) do begin TranslateMessage(KeyboardMsg);
    DispatchMessage(KeyboardMsg);
    end;
    end;
    procedure SendKeyDown(VKey: Byte; NumTimes : Word;
    GenUpMsg : Boolean);
    var Cnt : Word; ScanCode : Byte; NumState : Boolean; KeyBoardState : TKeyboardState;
    begin if (VKey=VK_NUMLOCK) then begin NumState:=ByteBool(GetKeyState(VK_NUMLOCK) and 1);
    GetKeyBoardState(KeyBoardState);
    if NumState then KeyBoardState[VK_NUMLOCK]:=(KeyBoardState[VK_NUMLOCK] and not 1) else KeyBoardState[VK_NUMLOCK]:=(KeyBoardState[VK_NUMLOCK] or 1);
    SetKeyBoardState(KeyBoardState);
    exit;
    end;
    ScanCode:=Lo(MapVirtualKey(VKey,0));
    For Cnt:=1 to NumTimes do if (VKey in ExtendedVKeys)then begin KeyboardEvent(VKey, ScanCode, KEYEVENTF_EXTENDEDKEY);
    if (GenUpMsg) then KeyboardEvent(VKey, ScanCode, KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP) end else begin KeyboardEvent(VKey, ScanCode, 0);
    if (GenUpMsg) then KeyboardEvent(VKey, ScanCode, KEYEVENTF_KEYUP);
    end;
    end;
    procedure SendKeyUp(VKey: Byte);
    var ScanCode : Byte;
    begin ScanCode:=Lo(MapVirtualKey(VKey,0));
    if (VKey in ExtendedVKeys)then KeyboardEvent(VKey, ScanCode, KEYEVENTF_EXTENDEDKEY and KEYEVENTF_KEYUP) else KeyboardEvent(VKey, ScanCode, KEYEVENTF_KEYUP);
    end;
    procedure SendKey(MKey: Word; NumTimes : Word;
    GenDownMsg : Boolean);
    begin if (BitSet(Hi(MKey),VKKEYSCANSHIFTON)) then SendKeyDown(VK_SHIFT,1,False);
    if (BitSet(Hi(MKey),VKKEYSCANCTRLON)) then SendKeyDown(VK_CONTROL,1,False);
    if (BitSet(Hi(MKey),VKKEYSCANALTON)) then SendKeyDown(VK_MENU,1,False);
    SendKeyDown(Lo(MKey), NumTimes, GenDownMsg);
    if (BitSet(Hi(MKey),VKKEYSCANSHIFTON)) then SendKeyUp(VK_SHIFT);
    if (BitSet(Hi(MKey),VKKEYSCANCTRLON)) then SendKeyUp(VK_CONTROL);
    if (BitSet(Hi(MKey),VKKEYSCANALTON)) then SendKeyUp(VK_MENU);
    end;
    {Implements a simple binary search to locate special key name strings} function StringToVKey(KeyString : ShortString) : Word; var Found, Collided : Boolean;
    Bottom, Top, Middle : Byte;
    begin Result:=INVALIDKEY;
    Bottom:=1;
    Top:=MaxSendKeyRecs;
    Found:=false;
    Middle:=(Bottom+Top) div 2;
    Repeat Collided:=((Bottom=Middle) or (Top=Middle));
    if (KeyString=SendKeyRecs[Middle].Name) then begin Found:=true;
    Result:=SendKeyRecs[Middle].VKey;
    end else begin if (KeyString>SendKeyRecs[Middle].Name) then Bottom:=Middle else Top:=Middle;
    Middle:=(Succ(Bottom+Top)) div 2;
    end;
    Until (Found or Collided);
    if (Result=INVALIDKEY) then DisplayMessage('Invalid Key Name');
    end;
    procedure PopUpShiftKeys;
    begin if (not UsingParens) then begin if ShiftDown then SendKeyUp(VK_SHIFT);
    if ControlDown then SendKeyUp(VK_CONTROL);
    if AltDown then SendKeyUp(VK_MENU);
    ShiftDown:=false;
    ControlDown:=false;
    AltDown:=false;
    end;
    end;
    begin AllocationSize:=MaxInt;
    Result:=false;
    UsingParens:=false;
    ShiftDown:=false;
    ControlDown:=false;
    AltDown:=false;
    I:=0; L:=StrLen(SendKeysString);
    if (L>AllocationSize) then L:=AllocationSize;
    if (L=0) then Exit;
    While (I case SendKeysString[I] of '(' : begin UsingParens:=true;
    Inc(I);
    end;
    ')' : begin UsingParens:=false;
    PopUpShiftKeys; Inc(I);
    end;
    '%' : begin AltDown:=true;
    SendKeyDown(VK_MENU,1,False);
    Inc(I);
    end;
    '+' : begin ShiftDown:=true;
    SendKeyDown(VK_SHIFT,1,False);
    Inc(I);
    end; SendKeyDown(VK_CONTROL,1,False);
    Inc(I);
    end;
    '{' : begin NumTimes:=1;
    if (SendKeysString[Succ(I)]='{') then begin MKey:=VK_LEFTBRACKET;
    SetBit(Wbytes(MKey)[1],VKKEYSCANSHIFTON);
    SendKey(MKey,1,True);
    PopUpShiftKeys; Inc(I,3);
    Continue;
    end;
    KeyString:='';
    FoundClose:=false;
    While (I<=L) do begin Inc(I);
    if (SendKeysString[I]='}') then begin FoundClose:=true;
    Inc(I);
    Break;
    end;
    KeyString:=KeyString+Upcase(SendKeysString[I]);
    end;
    if (Not FoundClose) then begin DisplayMessage('No Close');
    Exit;
    end;
    if (SendKeysString[I]='}') then begin MKey:=VK_RIGHTBRACKET;
    SetBit(Wbytes(MKey)[1],VKKEYSCANSHIFTON);
    SendKey(MKey,1,True);
    PopUpShiftKeys;
    Inc(I);
    Continue;
    end;
    PosSpace:=Pos(' ',KeyString);
    if (PosSpace<>0) then begin NumTimes:=StrToInt(Copy(KeyString,Succ(PosSpace),Length(KeyString)-PosSp ace));
    KeyString:=Copy(KeyString,1,Pred(PosSpace));
    end;
    if (Length(KeyString)=1) then MKey:=vkKeyScan(KeyString[1]) else MKey:=StringToVKey(KeyString);
    if (MKey<>INVALIDKEY) then begin SendKey(MKey,NumTimes,True);
    PopUpShiftKeys;
    Continue;
    end;
    end;
    '~' : begin SendKeyDown(VK_RETURN,1,True);
    PopUpShiftKeys;
    Inc(I);
    end;
    else begin MKey:=vkKeyScan(SendKeysString[I]);
    if (MKey<>INVALIDKEY) then begin SendKey(MKey,1,True);
    PopUpShiftKeys;
    end else DisplayMessage('Invalid KeyName');
    Inc(I);
    end;
    end;
    end;
    Result:=true;
    PopUpShiftKeys;
    end;
    {AppActivate This is used to set the current input focus to a given window using its name.
    This is especially useful for ensuring a window is active before sending it input messages using the SendKeys function.
    You can specify a window's name in its entirety, or only portion of it, beginning from the left.
    } var WindowHandle : HWND;
    function EnumWindowsProc(WHandle: HWND;
    lParam: LPARAM): BOOL; export;
    stdcall;
    const MAX_WINDOW_NAME_LEN = 80;
    var WindowName : array[0..MAX_WINDOW_NAME_LEN] of char;
    begin {Can't test GetWindowText's return value since some windows don't have a title} GetWindowText(WHandle,WindowName,MAX_WINDOW_NAME_LEN);
    Result := (StrLIComp(WindowName,PChar(lParam), StrLen(PChar(lParam))) <> 0);
    if (not Result) then WindowHandle:=WHandle;
    end;
    function AppActivate(WindowName : PChar) : boolean;
    begin try Result:=true;
    WindowHandle:=FindWindow(nil,WindowName);
    if (WindowHandle=0) then EnumWindows(@EnumWindowsProc,Intege (PChar(WindowName)));
    if (WindowHandle<>0) then begin SendMessage(WindowHandle, WM_SYSCOMMAND, SC_HOTKEY, WindowHandle);
    SendMessage(WindowHandle, WM_SYSCOMMAND, SC_RESTORE, WindowHandle);
    end else Result:=false;
    except on Exception do Result:=false;
    end;
    end;
    end.

    {****************END****************}

    Из конференции Expert_FAQ

    Вопрос

    Как «перегнать» данные из TFileStream в TMemo?

    Ответ

    Если TFileStream представляет данные текстового файла, то воспользуйтесь методом Memo.Lines.LoadFromStream.

    Если Вы хотите представить данные в шестнадцатиричном, двоичном либо каком еще в виде текста, то читайте по байтику из stream'а и конвертируйте в нужный формат. Потом эту строку и добавите в TMemo.

    Из конференции Expert_FAQ

    Вопрос

    Я недавно начал изучать Delphi и у меня есть небольшой вопросик.

    Как, зная IP-адресс компа в локальной сети, послать ему сообщение?

    Ответ

    В Win2000/XP я сделал такую феньку.

    procedure TForm1.BitBtn1Click(Sender: TObject); Var A,Cur:LongInt; begin Form1.Enabled:=False; Cur:=Screen.Cursor; Screen.Cursor:=-11; For A:=0 to ListView1.Items.Count-1 do If ListView1.Items.item[A].Checked Then Begin WinExec(Pchar('Net send '+ListView1.Items.item[A].Caption+' '+Edit1.text),SW_HIDE); AddLog('Отправлено сообщение по адресу '+ListView1.Items.item[A].Caption+' "'+Edit1.text+'"'); End; Form1.Enabled:=True; Screen.Cursor:=Cur; end;

    Т.е. вызвал админимстративную службу «net send» при помощи функции WinExec()

    Из конференции Expert_FAQ

    Вопрос

    Как, имея HANDLE некой формы, добраться через него до какого-либо CONTROLа , принадлежащего этой форме? Пример: как, имея HANDLE окна, добавить запись в EditBox, находящемуся в этом окне?

    Ответ

    function ChangeWndFirstEditText(Wnd: HWND; const Text: string): boolean; var EditWnd: HWND; begin Result:=False; EditWnd:=FindWindowEx(Wnd, 0, 'EDIT', nil); if EditWnd=0 then exit; // edit not found Result:=SendMessage(EditWnd, WM_SETTEXT, 0, Integer(PChar(Text)))<>0; end; Из конференции Expert_FAQ

    Вопрос

    Есть два компа в сети, необходимо написать программку обмена информации между ними с использованием сокетов. Все, вроде бы, нормально, но вот при дисконнекте (со стороны сервера) в клиентской части происходит следующее: выполняется событие onDisconnect — свойство Active устанавливается в False — свойство Socket.Connected показывает True. При включении серверной программы в клиентской выполняю ClientSocket1.Open, а соединения не происходит.

    Ответ

    При разрыве соединения с стороны сервера, клиент получает ошибку eeDisconnect (событие onError), при этом нужно, если
    Client.Active=True
    то выполнить
    Client.Close
    и начинать все по новой. Это самое можно сделать через таймер по схеме:
    коннетимся … получилось-ок (таймер удавили), нет — опять по новой, разорвались — опять таймера ждем.

    Nartov Alex

    Вопрос

    Подскажите, как сделать, чтобы нажимая на кнопку на одной форме, попадал на другую форму?

    Ответ

    Form1.Button1Click(Sender:TObject);
    begin
    Form2.Show

    или
    Form2.ShowModal — тогда, пока не закроешь Form2, управление не будет передаваться Form1
    end;
    Если надо создать форму в run-time, то
    Application.CreateForm(TForm2,Form2);
    Form2.ShowModal;

    Вопрос

    Есть ли в Delphi функция, чтобы:
    отсекать последний знак у строки;
    удалять остаток строки с n-го знака;
    вести поиск подстроки в строке.

    Ответ

    Есть:
    var s,s2:string;

    1. delete(s,length(s)-1,1)
    или delete(str,length(str)-1,1);

    Если ты имеешь в виду управляющие символы конца строки, то можно использовать trimright и trimleft.

    2. delete(s,n,length(s)-n+1)
    или delete(str,n,length(str));

    3. k:=pos(s,s2);
    или i:=pos('a',str);


    MSknyaz, A.Z., Seacat

    Вопрос

    Какие есть способы заставить компонент (например Shape) самому двигаться по форме ?

    Ответ

    У компонента Shape нет методов, позволяющих ему самому двигаться по форме, зато у него есть свойства Left и Top, определяющие координаты его левого угла на форме. Их можно изменять. Лучше всего это делать через Timer (вкладка System). Установите свойство Interval таймера в 1 и Shape «поедет»:

    procedure TForm1.Timer1Timer(Sender: TObject);

    begin

    Shape1.Left := Shape1.Left + 1;

    Shape1.Top := Shape1.Top + 1;

    end;



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

    procedure TForm1.Timer1Timer(Sender: TObject); const dx: integer = 1; dy: integer = 1; begin with Shape1 do begin Left := Left + dx; Top := Top + dy; if (Left <= 0) or (Left + Width >= Form1.Width — 10) then dx := -dx; if (Top <= 0) or (Top + Height >= Form1.Height — 35) then dy := -dy; end; end;

    Из конференции Expert_FAQ

    Вопрос

    Подскажите, пожалуйста, какие программы существуют для подготовки .hlp-файлов справки (желательно free- & shareware), где их можно найти и какие из них предпочтительнее с практической точки зрения? Где можно найти компилятор для подготовленных файлов? Какой стандарт файла предпочтительнее (win98 или XP)?

    Ответ

    Используйте Microsoft Help Workshop. Он расположен в папке Delphi\Help\Tools и позволяет создавать hlp файлы.

    Но лично мне больше нравится Microsoft HTML Help Compiler (можно взять с сайта Microsoft) — она позволяет создавать chm файлы.

    Большими возможностями обладает программа Help & Manual www.ec-software.com.

    Из конференции Expert_FAQ

    Вопрос

    Каким именно релизом Delphi вообще стоит пользоваться для каждой конкретной версии?

    Ответ

    Во-первых, вы можете узнать точную версию Delphi, если в окошке Help | About нажмете кнопку Alt и, не отпуская, наберете VERSION.
    Delphi 1 следует апгрейдить до версии 1.02 с помощью патчей.
    Delphi 2 следует апгрейдить до версии 2.01. Это полноценный дистрибутив. Эту версию можно, в частности, узнать по странице «Internet» в палитре компонентов. Ее точная версия 2.0.76.0.

    Delphi 3 следует взять версии 3.02. Это полноценный дистрибутив 3.01 и патчи до 3.02.

    Delphi 4 же должна быть обновлена вторым, а затем третьим Service Pack'ами, которые можно взять на сайте Inprise. Версии Delphi 4.3 и 4.5 являются обманными версиями. В действительности это ранние беты Delphi 4.0.
    Delphi 5 же должна быть обновлена первым и вторым (обновление справочной системы) Service Pack'ами, которые можно взять на сайте Inprise. Версия Delphi 5.5 также является обманной версией.

    Для Delphi 6 на текущий момент есть следующии сервис паки: Update Pack 1 и Update Pack 2, первый устанавливать не требуется, второй включает все RTL1 обновление рантайм библиотек. Появились также еще два сервис-пака: RTL1 и обновление справочной системы.

    Первые три брать с
    здесь, а Update Help — брать с сайта, раздел Documentation

    Вопрос

    Каким редактором можно пользоваться для создания/редактирования полноцветных иконок. «Дельфийский» ImageEditor полноцветные иконки даже отображать не хочет. Желательно ссылку на такой редактор.

    Ответ

    AWicons
    www.awicons.com Просто супер, мало того, что бесплатная (для жителей бывшего СССР), так еще и русский язык есть. Возможности очень богатые — вплоть до антиалиасинга (безусловно, она может извлекать иконки из dll). Вот, что написано в русском help'е по поводу регистрации:

    "Граждане стран бывшего СССР имеют право использовать данную версию AWicons бесплатно. Для бесплатной регистрации указанной категорией лиц в диалоге О программе нужно ввести в качестве имени пользователя xUSSR регистрация, при этом в качестве регистрационного кода должен быть введен маленькими русскими буквами текущий день недели."

    Из конференции Expert_FAQ

    Вопрос

    Какое событие происходит при минимизации окна?

    Ответ

    Вот эти:
    OnResize
    Для MainForm : Application.OnMinimize

    Из конференции Delphi

    Вопрос

    Какое событие происходит при переносе формы за ее заголовок?
    Можно ли при этом выполнять заданные действия?

    Ответ

    WM_MOVING

    Из конференции Expert_FAQ

    Вопрос

    Какое сообщение надо отлавливать в Application.OnMessage для отслеживания клавиши Alt (vk_menu)

    Ответ

    WM_SYSKEYDOWN/WM_SYSKEYUP

    Из конференции Delphi

    Вопрос

    Какой класс окна у консоли?

    Ответ

    'tty' for 9x
    'ConsoleWindowClass' for NT

    Из конференции Delphi

    Вопрос

    Куда из Delphi 3 делся модуль для работы с ReportSmith?

    Ответ

    Они лежат в X:\DELPHI3\LIB\DELPHI2. В данном случае Х — это ваш CD-ROM с дистрибутивом Delphi 3.

    Из конференции Delphi

    Вопрос

    Купил и поставил себе Delphi 7 Enterprise Studio на 2 дисках, но не обнаружил там компонентов QReport, почему? и вообще какие бывают разновидности Delphi, чем отличаются, их особенности?

    Ответ

    Смотри каталог (delphi7)\Demos\Quickrpt\readme.txt

    Там, сказано что делать.

    Запускаешь Delphi выбираешь Component->Install Package и добавляешь

    (Delphi7)\bin\clqrt70.bpl

    (примечание при этом все проекты должны быть закрыты и поставь галочку Default,

    чтобы можно было использовать во всех проектах по умолчанию)

    Из конференции Expert_FAQ

    Вопрос

    Можно ли exe'шники Delphi сделать поменьше без всяких дополнительных пакетов?

    Ответ

    Пиши на WinAPI. Иначе никак. На самом деле, можно просто упаковать exe'шник прогой типа ASPack, правда, размер не будет таким же маленьким, как в случае использования WinAPI

    Alexander

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

    ******

    Можно поотключать кучу не нужных DLL-ок в настройках проекта (размер с 400kb до 20kb), но тогда могут возникнуть проблемы с запуском программы на другом компе (на счет последнего не уверен).

    Casper

    Существует еще одна программа для упаковки exe-файлов — UPX. Вот ее адрес:
    upx.sourceforge.net
    www.oberhumer.com

    mysterio2000

    Вопрос

    Можно ли встроить flash-ролик в свои программу непосредственно в exe-файл? Если да, то как? Если можмо пример.

    Ответ

    Все более чем элементарно.

    Запустите Дельфи и выберите пункт меню Component->Import ActiveX Control…

    Перед вами откроется диалоговое окно с заголовком Import ActiveX Control. В разделе Registered Controls выберите Shockwave Flash. В разделе Pallete Page… Выберите страницу в палитре компонентов, на которой будет располагаться установленный компонент (по умолчанию это ActiveX). В разделе Unit Dir Name… путь к папке куда будет установлен компонент Нажмите на кнопку Install. Перед вами появится окно, в котором вам нужно будет выбрать в какой пакет будет установлен компонент (вы можете установить как в уже существующий, так и в новый пакет). Затем перед вами появится окно редактирования выбранного пакета и Дельфи вас спросит: "…Package will be rebuilt. Continue?». Ответьте Yes. Все готово теперь можно использовать флэш в ваших приложениях!

    Ну а дельшье мучаем TShockWaveFlash:

    У него есть такие свойства как Movie: TFileName; Play, Stop (это методы), GotoFrame(Frame: Integer); CurrentFrame (возвращает текущий кадр) и т.д.

    Из конференции Expert_FAQ

    Вопрос

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

    Ответ

    Можно ли сделать так, чтобы в исполняемом файле программы находился какой-нибудь звук в формате .wav, и можно было бы проиграть этот звук?
    В файл MyWave.rc пишешь:

    MyWave RCDATA LOADONCALL MyWave.wav
    brcc32.exe MyWave.rc, получаешь MyWave.res.

    В своей программе пишешь:

    {$R MyWave.res}

    Все!

    Предупреждая следующий твой вопрос "а как прочитать wave-файл из исполняемого файла?"

    procedure RetrieveMyWave;
    var
        hResource: THandle;
        pData: Pointer;
    begin
    hResource:=LoadResource( hInstance, FindResource(hInstance, 'MyWave',RT_RCDATA));
        try
     pData := LockResource(hResource);
       if pData = nil then
      raise Exception.Create('Cannot read MyWave');
       // Здесь pData указывает на MyWave
       // Теперь можно, например, проиграть его (Win32):
        PlaySound(pData, 0, SND_MEMORY);
        finally
         FreeResource(hResource);
        end;
    end;

    PlaySound('RESNAME', 0, SND_MEMORY or SND_RESOURCE);

    Для этого надо создать файл описания ресурса, например Waves, в который поместить следующие строки:

    SOUND1 WAVE WMyWave1.wav
    SOUND2 WAVE WMyWave2.wav

    Затем запустить ресурс на компилияцию brcc32.exe Waves.rc, в результате получится файл ресурса Waves.res.
    В своей программе подключаем ресурс (в любом модуле):

    {$R Waves.res}

    Для проигрывания звука можно использольвать функцию PlaySound

    PlaySound('SOUND1', 0, SND_ASYNC or SND_RESOURCE);

    Anatoly Podgoretsky

    Вопрос

    У меня такой вопрос: Delphi 5, QuickReport — При первой печати он печатает нормально, если не выходя из программы выйти из QuickReport, а потом еще раз зайти то получается к прошлым отпечатаным страницам добавил еще такие же. То есть на отпечатаном отчете верхняя рамка нормальная я сам текст повторяется? Как от этого избавиться или можно ли как то после печати в ручную очистить буфер печати?

    Ответ

    Я обычно создаю отчеты динамически, т.е.

    Rep1:=TRep1.Create(self);

    Rep1.Preview;

    Rep1.Free;

    Тогда при повторном обращении ошибок не возникает.

    Из конференции Expert_FAQ

    Вопрос

    Такой вопрос можно ли модели нарисованные в 3DStudioMax использовать в разрабатываемых при помощи Дельфи играх, если да то как?

    Ответ

    В составе DirectX SDK есть утилитка для конвертирования .3ds файлов в формат .x, который понимает DirectX.

    A.Z.

    Вопрос

    Можно ли программно нажать кнопку у чужой программы? Известен заголовок программы и надпись на кнопке.

    Ответ


    var
    MyFormHandle, BtnHandle: HWND;
    begin
    //ищем нужное окно
    MyFormHandle := FindWindow(nil, 'Заголовок');
    //ищем кнопку
    BtnHandle := FindWindowEx(MyFormHandle, 0, nil, 'Текст на кнопке');
    //нажимаем кнопку
    SendMessage(MyFormHandle, WM_COMMAND, BN_CLICKED shl 16, BtnHandle);
    end;

    Из конференции Expert_FAQ

    Вопрос

    Можно ли программно поставить одинаковое количество дней во всех месяцах компонента MonthCalendar.

    Ответ

    Определенно НЕТ.

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

    Вопрос

    Можно ли скомпилировать на Delphi 2/3/4 программу, работающую под Windows 3.1?

    Ответ

    Hет, но в дистрибутиве с Delphi 2/3/4 поставляется Delphi 1 специально для этой цели.

    Из конференции Delphi

    Вопрос

    Можно ли форму хранить в dll и использовать в основной программе?

    Ответ

    Для модальной формы:

    function ShowMyDialog(Msg: PChar): Boolean; stdcall;


    exports ShowMyDialog;

    function ShowMyDialog(Msg: PChar): Boolean;
    begin
    // Создаем экземпляр Form1 формы TForm1
    Form1 := TForm1.Create(Application);
    // Возвращаем True только если нажата OK (ModalResult = mrOk)
    Result := (Form1.ShowModal = mrOk);
    // Освобождаем память}
    Form1.Free;
    end;


    Если же нужно разместить в DLL немодальную форму, то необходимо сделать две функции — открытия и закрытия формы. При этом нужно заставить DLL запомнить дескриптор этой формы.

    Serov Pavel

    Вопрос

    Как такое может быть: на форме кнопки нет, но процедура по обработке ее нажатия есть? И если Delphi такое допускает, то как избавиться от этих процедур, просто удалить из текста программы? Кнопки раньше на форме были, но потом удалены через Del.

    Ответ

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

    Бузуверов Михаил

    Вопрос

    Не получается вызвать браузер с сайтом программы по щелчке на Label. Я пробовал код (в низу), но не знаю, что вставлять вместо "…». И как отправить письмо? Какие нужны аргументы?

    uses ShellApi;

    ShellExecute('http://www.company.com',…);

    ShellExecute('mailto:author@somewhere.net',…);

    Ответ

    ShellExecute(nil, nil, PChar('http://www.company.com'), nil, PChar(''), SW_SHOW);

    Из конференции Expert_FAQ

    Вопрос

    Необходимо ли освобождать память в процедурах для локальных переменных типа динамический массив (array of ..)

    Ответ

    При выходе из процедуры такие массивы уничтожаются автоматически, если вы не возвращаете их "наружу"

    Из конференции Expert_FAQ

    Вопрос

    Как сделать программу, которая отключала бы все работающие приложения у юзера на компе? Например AVP монитор или SpIDer Guard.

    Ответ

    Вот мой вариант. Не будет работать в Windows NT 4.0 и ниже. В 95 и выше работает, в 2000, XP и так далее — работает. Часть идей из советов В.Озерова. Собственно, я записываю процессы и их ID в листбокс для своих целей, то есть именно на это можно не обращать внимание

    procedure TfmMain.btProcessInfoClick(Sender: TObject);
    var handler:thandle; data:TProcessEntry32;
    s : String; function return_name : String;
    var i : byte; names : String; begin names := ''; i := 0;
    while data.szExeFile[i] <> '' do begin names := names + data.szExeFile[i];
    inc(i); end;
    Result := names; end;
    begin ListBox1.Items.Clear();
    handler:=CreateToolhelp32Snapshot(TH32CS_SNAPALL,0);
    if Process32First(handler,data) then begin ListBox1.Items.AddObject(return_name,TObject(data.th32ProcessID));
    while Process32Next(handler,data) do begin s := return_name();
    ListBox1.Items.AddObject(s,TObject(data.th32ProcessID)); end;
    end else showmessage('Информацию не получили!');
    end;


    TerminateProcess(); F1… параметры из ЛистБокса + код выхода..

    Из конференции Expert_FAQ

    Вопрос

    У меня возникли кое-какие вопросы, если сможете, ответьте…

    1) DirectoryListBox1, как сделать что бы в нем были видны скрытые папки.

    2) DriveComboBox1,что бы при отсутствии дискеты во флопе или cd в cdrom'е выдавалось сообщение об этом.

    3) FilterComboBox1, как указать в одном FilterName несколько фильтров, например: [Pictures] [*.jpg ?,? *.bmp], через какой символ?

    4) FileListBox1, как сделать , что бы при 2м нажатии запускался файл?

    5) FileListBox1, пример я выделил файл, как его скопировать, вставить?

    6) И последнее: например в Edit я пишу [c:\] и нажимаю Button, а в DirectoryListBox1 открывался диск c:\

    Я конечно понимаю, что завалил вопросами, но просто мне не откуда это узнать. Купил 2 книги, а там не написано про это.

    Ответ

    По поводу твоих вопросов: итак приступим.

    1.По моему никак нельзя простыми методами, потому что когда я просмотрел unit FileCtrl и содержащийся в нем код этого компонента, то заметил, что процедура TDirectoryListbox.ReadDirectoryNames, которая ищет и принимает к сведению информацию об имеющихся каталогах делает это таким образом:

    — Ищет по FindFirst / FindNext.

    — Проверяет, директория ли это: if ( атрибут faDirectory=1010 bin) and (логическое умножение) (SearchRec.Attr — атрибуты найденного оюъекта в искомом (родительском)

    каталоге (может быть папка, файл, <.>, <..>)=faDirectory then тогда считается, что это подходящая папка и ее можно показывать, : если папка обычная, то SearchRec.Attr будут равны faAnyFile=111111 и умножение даст faDirectory, а если папка скрытая то в ее атрибуте гаситься четвертый разряд (faHidden=0010) и умножение даст faHidden, и <умный> обработчик такую папку отбросит. Выйти из этого положения думаю не так и сложно: создать свой личный компонент в котором эта процедура будет исправлена, а остальные содрать один к одному.

    2.Я надыбал только один подходящий обработчик OnChange. На него надобно считать из свойства Drive букву диска, добавить ':\' и вызвать процедуру FindFirst(та буква что считалась+':\',faAnyFile,Search). После чего вызывай функцию GetLastError и если она вернет значение ERROR_NOT_READY = 21, то это говорит о том, что диска в данное устройство не готово( нет диска, что-то он ообрабатывает (такое случается, когда всовываешь CD и он пару секунд мигает-позиционируется, читает всякие там метки и т.д., но это сейчас не важно,) так вот в это время тоже он не готов. Выводить сообщение: я так люблю: MessageDlg('В устройство '+DriveComboBox1.Drive+ ' не плохо было бы вставить что нибудь, (если некуда, так и в дисковод можно!',mtError,[mbOK],0), но учти, что при флопах будет выскакивать стандартное некрасивое системное окно(как в проводнике) и не забудь вызывать SearchClose(Search) в конце, а то мозги утекать начнут по чути-чути:-), не твои-компа;

    3.Через вертикальную палку |-разные фильтры. ;- однотопные фильтры. пример: FilterComboBox1.Filter:='Pictures|*.bmp;*.jpg|All files|*.*';

    4.Нужно обрабатывать событие DblClick-двойной щелчок и на него: пример, не могу на русском-проще па делфи.

    procedure TForm1.FileListBox1DblClick(Sender: TObject); var count:integer; selected:integer; begin selected:=-1; for count:=0 to FileListBox1.Count do if FileListBox1.Selected[count] then begin selected:=count; break; end; if selected<0 then exit; caption:=FileListBox1.Items[selected]; {шоб было видно на этапе отладки} ShellExecute(hWnd(0),'open',PChar(caption),'',PChar(FileListBox1.Directo ry),SW_SHOWNORMAL) end;

    5).Что-то ты для начинающего слишком много хочешь. =;-)). Я толком то и сам еще не знаю. Не было необходимости разбираться. Но по моему это нужно работать с потоками. А зачем, позволь спросить. Пишешь свой Windows Commander 6.99 ? -8-)). Я всегда делал по деревенски: открывал для чтения, создавал другой файл, перегонял блоком данные из одного в другой. И дело с концом. А ты, я смотрю решил что-то крутое отгрохать. Хоть поглядеть дашь, когда напишешь? :-)., а узнать, какой выделенный файл, так это в четвертом вопросе было.

    6).Все понятно, но зачем писать квадратные скобки? Их же в ручную чистить надо будет для получение той заветной буквы. Ну да ладно. По порядку.1. По Edit.Text передвигаешся for i:=0 to Length(Edit.Text) и читаешь i-е символы из него. Когда находишь букву, то проверяешь, есть ли такой диск (глянь API Windows GetLogicalDrives, она простая — кард0й бит-0то диск: бит-0-установлен — диск «а» в наличии, бит-1-сброшен — диск «b» в шкафу на полочке и тд. )- это если надо проверять корректность введенных данных, а если нет, то валяй напрямую. Дальше присвой свойству DirectoryListBox1.Drive эту буквочку. И все это дело на БоттонКлиск делаешь.

    Из конференции Expert_FAQ

    Вопрос

    Нужен примерчик функции запуска проги с параметрами. Конкретнее: получаю строчку, в которой прописан полный путь к файлу и параметры. Надо запустить это. С помощью ShellExecute не получается, а писать процедуру разделения пути и параметров нет времени, да и лень.

    Ответ

    procedure RunProgram(FileName:string);
    var
    PI:TProcessInformation;
    SI:TStartupInfo;
    const
    dwFlags:dword=CREATE_NEW_PROCESS_GROUP or CREATE_DEFAULT_ERROR_MODE;
    begin
    FillChar(si,sizeof(si),0);
    fillchar(pi,sizeof(pi),0);
    with si do
    begin
    cb:=sizeof(si);
    dwFlags:=STARTF_USESHOWWINDOW;
    wShowWindow:=SW_SHOWDEFAULT;
    end;
    CreateProcess(nil,PChar(FileName),nil,nil,false,
    dwFlags,nil,nil,SI,PI);
    closehandle(pi.hThread);
    closehandle(pi.hProcess);
    end;


    procedure TForm1.Button1Click(Sender: TObject);
    begin
    RunProgram('notepad.exe c:\boot.ini');
    end;


    A.Z.

    Вопрос

    Подскажет где в Инете есть что-то типа обучающих уроков по Delphi, чтоб последовательно занятся изучением языка?

    Ответ

    http://www.ksc.ru/cdo/metod/programmer'scourse/language/- это по Object Pascal

    http://plib.bip.ru/library/delphi/2/

    http://www.vcl.ru/html/delphi/ucheb/index.html

    http://www.vcl.ru/html/delphi/nach/index.htm

    Из конференции Expert_FAQ

    Вопрос

    От чего зависит скорость открытия форм, если расчеты не принимать во внимание? От количества компонентов на форме?

    Ответ

    Безусловно от количества компонентов + от того, какие именно это компоненты. Например большое количество TLabel не оказывают существенного влияния на скорость загрузки формы, в то время как все элементы имеющие собственное окно (в терминах виндов, например TEdit, TPanel), при большом количестве сильно тормозят открытие окна. + если имеется на форме некоторое количество TButton, и к ним динамически грузятся из ресурсов картинки, то это тоже может существенно тормозить форму.

    В моей практике был случай, когда замена картинки, загружавшейся из ресурсов, на кнопках на надпись привела к увеличению скорости загрузку где-то в три раза (правда сразу оговорюсь — кнопок исчислялось десятками + на форме было уж очень много панелей накидано…)

    Из конференции Expert_FAQ

    Вопрос

    Как избежать или отловить ошибку недоступности диска в DriveComboBox'е?

    Ответ

    Данный пример работает точно в WinХР и 98. Вместо 'W' можешь подставить строковую переменную (имя диска) в любом регистре. Я специально взял 'W' в качестве имени диска, т.к. его у меня точно нет, а там в комбо сам мудри на какую букву привязать (вставляй в событие OnChange).

    var
        DrvNum: byte;
        EMode: Word;
        result: Bool;
    begin
        result := false;
        DrvNum := ord('W');
        If DrvNum >= ord('w')
        Then dec(DrvNum,$20);
        EMode := SetErrorMode(SEM_FAILCRITICALERRORS);

        try
        If DiskSize(DrvNum-$40) <> -1
         Then result := true
         else messagebeep(0);
        finally
        SetErrorMode(EMode);
        end;

        If result = True
      Then Label1.Caption := 'Диск готов'
      Else Label1.Caption := 'Диск не готов';
    end;

    Soldatov Sergey Viktorovich

    Вопрос

    Из всех файлов, лежащих в директории, читается текст вида '25-02-03' (тип String), а затем добавляется в поле записи базы данных. В разных файлах могут содержаться одинаковые даты, соответственно и разные записи могут содержать одинаковые значения этого поля. Каким образом можно упорядочить записи по датам? Может быть, есть возможность перевести текст '25-02-03' в формат даты (TDateTime)?

    Ответ

    В Вашем вопросе везде указаны только две цифры года — что не есть гуд. В ответе будет предполагаться текущий век — в противном случае нужно добавить правило — какие 2 цифры из прошлого века, какие из нынешнего. Перевод строки формата DD-MM-ГГ в формат даты (TDateTime) легко делается ручками:

    var dt:TDateTime; … dt:=EncodeDate(2000+(ord(s[7])-ord('0'))*10+(ord(s[8])-ord('0')), (ord(s[4])-ord('0'))*10+(ord(s[5])-ord('0')), (ord(s[1])-ord('0'))*10+(ord(s[2])-ord('0')));

    Но можно повозиться с установлением глобальных переменных DateSeparator и ShortDateFormat и использовать функцию StrToDate. Вопрос про уникальность дат и сортировку не совсем понятен. Если в каждом файле нет одинаковых дат — то для уникальности записи Вы можете в записи хранить и имя файла. При сортировке с датой в качестве первого ключа — используйте в качестве второго ключа любое другое поле, если уж Вам нужна определенность при сортировке. Если вопрос был о том, что строки сортируются обычно (но не всегда) в алфавитном порядке, и дата записанные в формате dd-мм-гг будут отсортированы не в порядке возрастная дат — то тут у Вас два пути — либо хранить дату в формате ггггммдд, либо определить собственную процедуру сортировки, которой был бы известен внутренний формат данных, хранимых как строка.

    Из конференции Expert_FAQ

    Вопрос

    Подскажите, как в sql объединить два строковых значения в одно? Например есть переменные :p1 и :p2. :p1='aaa', :p2='bbb'. Хочу получить :p3= 'aaabbb', но вот такая вещь :p3=:p1+:p2 не прокатывает. Как быть?

    Ответ

    Надо написать так :p1||:p2, и получится одна строка из двух.

    Алексей

    Вопрос

    Можно ли сделать подсказку для элемента интерфеса в 2 строки?

    Ответ

    Да, вот так:

    Button1.Hint := 'Line_1'#13#10'Line_2';

    Андрей Кононенко

    Вопрос

    В каком порядке происходят события при создании и показе окна?

    Ответ

    Вот так:

    OnCreate, OnShow, OnPaint, OnActivate, OnResize и снова OnPaint.

    Из конференции Delphi

    Вопрос

    Delphi 4 виснут при запуске, на машине с видеокартой S3 Virge. Как это исправить?

    Ответ

    В реестре найдите слкдующий ключ:
    [HKEY_CURRENT_CONFIG\ Display\ Settings]
    и сделайте там следующий ключ:
    "BusThrottle"="on"
    Если не помогает, то попробуйте добавить в файл system.ini следующие строки:
    [Display]
    "BusThrottle"="On"
    Можно также попробовать снизить аппратное ускорение или поиграться количеством цветов, но наиболее кардинальное решение — сменить видеокарту.

    Из конференции Delphi

    Вопрос

    Версия Delphi: 6

    У меня такой вопрос: я создаю программу для отслеживания мыши. Использую функцию API

    SetWindowsHookEx с первым параметром JournalEdit (если использовать WMouse). Так вот все функции у меня в DLL. А DLL я вызвваю из программы. Так вот если ставить на вызов функции breakpoint, то Delphi виснет. А так все нормально. В чем тут проблемма?

    Ответ

    Здесь надо использовать Module Load Breakpoint

    Есть два пути:

    1) Run|Add Breakpoint|Module Load Breakpoint и выбираешь нужный тебе модуль

    2) View|Debug Windows|Modules, потом правый клик в любом месте верхне-левого квадрата и выбрать модуль.

    Из конференции Expert_FAQ

    Вопрос

    Почему Delphi5 так долго — примерно 60 секунд — грузится на P-III 550MH/ 128MB RAM?

    Ответ

    Единственное, что приходит в голову — замусоренность ОЗУ всякими удобняшками, улучшателями и прочими программами, которые призваны облегчить жизнь пользователю, забивая при этом память. Также может свою роль сыграть и количество установленных системных шрифтов, наличие установленных дополнительных компонент для Delphi.

    Shadow.

    Вопрос

    Почему Delphi7 не хочет компилить проект, сделанный в Delphi6? Пишет ошибку типа "e;не найден MyModule.dcu"e;, где MyModule — мой собственный модуль, сохранял я его файле MyModule.pas

    Ответ

    dcu — это откомпилированый код модуля. exe файл собирается из них. Чобы ошибки не было пропиши в Project — Options — Directories — Search path путь к каталогу с MyModule.pas
    D7 и D6 имеют разный формат файлов DCU удали все DCU и перекомпили соответствующие PAS файлы ну и пути к PAS файлам должны быть прописаны, конечно же.

    Из конференции Delphi

    Вопрос

    Почему в консольных приложениях неправильно отображаются русские буквы?

    Ответ

    Потому что кодировка шрифтов, используемых в редакторе Delphi — 1251 (ANSI), а в консольных приложениях — 866 (OEM). Чтобы добиться правильного отображения нужно использовать функцию CharToOEM (но при этом возрастет размер кода), либо сразу писать проект в каком-либо консольном текстовом редакторе (Dos Navigator, Far)

    CharToOem('Привет',TmpStr);
    Writeln(TmpStr);

    Denis Filonov

    Вопрос

    Почему, когда вношу в ячейку TStringGrid символ перехода на новую строку (то есть chr(13)) отображается какая то вертикальная черточка ( типа | ), а не переход?

    Ответ

    Перехода не происходит потому, что ты просто устанавливаешь текст ячейки. TStringGrid к этому тексту имеет отношение только в том плане, чтобы его отобразить. А все символы с кодом chr(13) отображаются именно такой вертикальной черточкой (ну, иногда еще пустым квадратиком :) Для перехода на следующую строку используй свойство Row:
    StringGrid1.Row := StringGrid1.Row + 1;

    Из конференции Expert_FAQ

    Вопрос

    При выполнении программы в строке 'Table1.IndexName:='indD';' возникает ошибка 'Index is out of date. Index indD'. В чем тут дело?

    Та же ошибка возникает при попытке установить значение свойства IndexName объекта Table1.

    Ответ

    Тут возможны два варианта:

    1) проверьте правильно ли Вы написали имя индекса — включая регистр букв

    2) была добавлена запись, а индекс не был создан. Ситуация частая во время отладки. Выгружаете проект. И запускаете любую утилиту администрирования базы данных — что Вам больше нравится. Удаляет там индекс и создаете его заново.

    Хорошим тоном будет — отлавливать такую ситуацию в программе и использовать методы DeleteIndex, AddIndex компонента TTable. Также посмотрите свойство IndexDefs и объект TIndexDefs

    Из конференции Expert_FAQ

    Вопрос

    Почему не работает передача данных по OLE в русский Excel?

    Ответ

    Дело в том что в VCL твои команды OLE2 передаются Excel'у в русском контексте. Для исправления необходимо найти в файле OLEAUTO.pas в функции GetIDsOfNames строчку:

    if Dispatch.GetIDsOfNames(GUID_NULL, @NameRefs, NameCount, LOCALE_SYSTEM_DEFAULT, DispIDs) <> 0 then

    и заменить ее на

    if Dispatch.GetIDsOfNames(GUID_NULL, @NameRefs, NameCount,((LANG_ENGLISH+SUBLANG_DEFAULT*1024)+SORT_DEFAULT* 65536 ), DispIDs) <> 0 then

    После этого Excel должен понимать нормальные английские команды. Hеобходимая комбинация для установки английского языка взята из C-шных хедеров (h-файлов).

    Из конференции Delphi

    Вопрос

    Помогите устранить ошибки:

    На форме 2 кнопки. Обрабртчики такие:
    procedure TForm1.Button1Click(Sender: TObject); begin if OpenDialog1.Execute then Edit1.Text := OpenDialog1.FileName; end; procedure TForm1.Button2Click(Sender: TObject); var inif : tinifile; begin inif := tinifile.Create('.\option.ini'); inif.Writestring('sect','ident','val'); end;
    Проблема: если сразу после запуска программы нажать 2ю кнопку, то ini-файл создается и в него заносится значение ident = val, но если сначала нажать 1ю кнопку, выбрать файл, а затем 2ю кнопку, то ini-файл не создается.

    Почему? Как исправить?

    Ответ

    Нада делать так:

    var inf:tinifile; begin inf := tinifile.create(ExtractFilePath(Application.ExeName)+'option.ini'); inf.writestring('sect','id','val'); inf.free; end; Из конференции Expert_FAQ

    Вопрос

    Я написал приложение на Дельфи типа клиент-сервер, работающее через сервер. Проверил в обной локальной сети(топология звезда, если это важно), там все работает. А в другой локальной сети — обмен данных через MailSlot'ы не происходит. Из-за чего это может быть?

    Ответ

    Проверь, функционирует ли локальная сеть по протоколу TCP/IP? А если да, то правильно ли этот протокол настроен на сервере и клиенте? Проходит ли <пинг> между сервером и клиентом по IP-адресу, по NetBIOS-имени компьютера (короткое имя) и по DNS-имени компьютера (длинное имя, вместе с доменным хвостом)? На сервере, естественно, должна <крутиться> ОС Microsoft Windows NT или 2000 Server. За объяснениями по настройке протокола лучше обратиться к администратору той сети.

    Из конференции Expert_FAQ

    Вопрос

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

    Например строку в STATUSBAR "Открытие формы" и "песочные часы", а после отображения формы всJ вернуть на место. Но где прописать этот код?

    Предположил, что нужно использовать процедуры Constructor/Destructor, но не могу правильно их объявить. При прописывании в секции Public
    constructor Create(Owner: TComponent); override;
    destructor Destroy; override;
    получаю ошибку типа "ранее эта процедура описывалась по-другому".

    Так как правильно сделать обявление этих процедур?

    Ответ

       constructor Create(AOwner: TComponent); override;
    >     ^- буква "A" пропущена была
    А вобще нужно смотреть как функции описаны у предка.

    Из конференции Expert_FAQ

    Вопрос

    Почему при вызове ф-и SetParent из WinApi происходит конфликт с борландовской ф-ией SetParent?
    Мне надо сменить родителя зная хендл окна!

    Ответ

    Нужно обращаться к "родной" функции как к
    Windows.SetParent

    Anatoly Podgoretsky

    Вопрос

    В DLL пишу функцию которая возвращает STRING, при вызове этой функции возникает ошибка на какой-то блок памяти, если функция возращает integer то все ок! В чем проблема?

    Ответ

    Из справки по Делфи:

    Если DLL использует longstring или dinamic arrays как параметр или результат функций необходимо использовать в dll и самом приложении использовать юнит ShareMem, это также верно, если приложении или dll занимает память при помощи New или GetMem с освождением этой памяти в другом модуле с помощью вызова Dispose или FreeMem. ShareMem всегда должен быть первым модулем в списке uses. ShareMem — интерфейсный модуль для менеджера памяти BORLANDMM.DLL. BORLANDMM.DLL должен распростроняться с приложением, которое использует ShareMem. То есть либо так, либо мспользовать shortstring при помощи директивы компилятора {$H-}, либо использовать типы PChar. Последнее предпочтительней для совместимости с программами на других языках (например С/C++ и прочее).

    Из конференции Expert_FAQ

    Вопрос

    Почему при циклической обработке записей типа Record происходит утечка памяти? У меня стоит Delphi6 Вот мой пример:

    Type
    TR = record
    Name : String;
    Ext : String;
    end;

    Function GetFileName(Const FileName: String): TR;
    Begin
    fillchar(Result,sizeof(Result),0);
    Result.Name:=copy(FileName,1,pos('.',FileName)-1);
    Result.Ext:=copy(FileName,pos('.',FileName)+1,Length(FileName));
    end;

    Procedure Go;
    Var
    FD : TSearchRec;
    MyRec : TR;
    Str : TStrings;
    Begin
    Str:=TStringList.create;
    try
    Str.clear;
    if (findfirst('C:\*.*',faanyfile,FD) = 0) then
    repeat
    if (FD.Name = '.') or (FD.Name = '..') then Continue;
    if ((FD.Attr and faDirectory) > 0) then Continue;
    MyRec:=GetfileName(FD.NAME); // Утечка происходит вот тут
    Str.add(MyRec.Name+'='+MyRec.Ext);
    Until FindNext(FD) <> 0;
    FindClose(FD);
    Str.savetofile('C:\res.txt');
    finally
    Str.free;
    end;
    end;


    Можно конечно обойтись и без Рекорда, но это только только пример, а в программе у меня все гораздо сложнее, да и в принципе не могу понять что я делаю не так?

    Ответ

    Эта проблема всех Дельфей и связана с изменением способа хранения строк (по сравнению с Паскалем) — строки хранятся динамически

    Решение:

    MyRec:=GetfileName(FD.NAME); // Утечка происходит вот тут
    Str.add(MyRec.Name+'='+MyRec.Ext);
    Finalize(MyRec); // Uninitializes a dynamically allocated variable.
    Until FindNext(FD) <> 0;

    Из конференции Expert_FAQ

    Вопрос

    Почему у меня record a : word; b : longint end; имеет размер восемь байт вместо шести?

    Ответ

    Если не использовать ключевое слово packed, то Дельфи производит выравнивание структуры на определенную границу. В разных версиях Дельфи по разному.
    Для того что избежать этого, надо описать структуру следующим образом:

    aRec = packed record
       a : Word;
       b : LongInt;
    end;

    Также не стоит использовать фундаментальные типы, так как их размерность зависит от версии Дельфи.

    Из конференции Delphi

    Вопрос

    От слов к делу…
    var
    HookHandle: hHook;

    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_MOUSEMOVE: Caption := IntToStr(msg.ParamL) + #32 + IntToStr(msg.ParamH);
    WM_LBUTTONDOWN: CheckBox1.Checked := true;
    WM_LBUTTONUP: CheckBox1.Checked := false;
    WM_RBUTTONDOWN: CheckBox2.Checked := true;
    WM_RBUTTONUP: CheckBox2.Checked := false;
    WM_KEYUP: CheckBox3.Checked := false;
    WM_KEYDOWN: CheckBox3.Checked := true;
    end; end else
    result := CallNextHookEx(HookHandle, code, WParam, LParam);
    end;

    procedure TForm1.FormCreate(Sender: TObject);
    begin
    Form1.FormStyle := fsStayOnTop;
    CheckBox1.Enabled := false;
    CheckBox1.Caption := 'left button';
    CheckBox2.Enabled := false;
    CheckBox2.Caption := 'right button';
    CheckBox3.Enabled := false;
    CheckBox3.Caption := 'keyboard';
    HookHandle := SetWindowsHookEx(WH_JOURNALRECORD, @HookProc, HInstance, 0);
    end;

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

    При нажатии на клавишу win все перестает работать. В чем проблема?

    Ответ

    if Code >= 0 then begin result := 0; msg := Pointer(LParam); with Form1 do case msg.message of WM_MOUSEMOVE: Caption := IntToStr(msg.ParamL) + #32 + IntToStr(msg.ParamH); WM_LBUTTONDOWN: CheckBox1.Checked := true; WM_LBUTTONUP: CheckBox1.Checked := false; WM_RBUTTONDOWN: CheckBox2.Checked := true; WM_RBUTTONUP: CheckBox2.Checked := false; WM_KEYUP: CheckBox3.Checked := false; WM_KEYDOWN: CheckBox3.Checked := true; //Вот это дописать попробуйте — else result := CallNextHookEx(HookHandle, code, WParam, LParam); //До сюда — end; end else result := CallNextHookEx(HookHandle, code, WParam, LParam);

    A.Z.

    Вопрос

    Каким образом можно привязать написанное на Delphi приложение к определенному типу файлов (к примеру, чтобы при двойном клике на текстовый файл он открывался не в Блокноте, а в моей программе)?

    Ответ

    Вот статейка на эту тему.

    Ассоциации файлов

    В основном вам необходимо добавить два ключа в улей регистра HKEY_CLASSES_ROOT. Зарегистрируете в корне ваше расширение типа ".ext» (создаете ключ с именем расширения):
    HKEY_CLASSES_ROOT\.ext\
    и запишите в строке «default» созданного ключа «внутреннее имя» вашего типа файлов — например, MyApp.Document:
    HKEY_CLASSES_ROOT\.ext\Default = «MyApp.Document»

    Затем создайте другой ключ с этим именем:
    HKEY_CLASSES_ROOT\MyApp.Document\

    Создайте подключ с именем «shell», в нем другой подключ с именем «open» и в «open», в свою очередь, еще один подключ с именем «command». Значение по умолчанию (default) — путь и имя вашего приложению с ключом "%1», представляющим параметр «имя файла», позволяя системе подставлять подставлять вызванный файл:
    HKEY_CLASSES_ROOT\MyApp.Document\shell\ open\command\Default = "C:\myapp\myapp.exe %1"

    Все манипуляции в коде производятся с помощью объекта TRegistry или при использовании InstallShield, который сделает это за вас автоматически. Я должен посоветовать вам использовать оба пути, поскольку пользователь может внести в регистры всякий мусор.

    Вот еще один совет:

    Самый простой путь достижения цели — модифицировать секцию Extensions в win.ini-файле, расположенном с директории Windows. Это также работает под Win 95, автоматически обновляя регистры при перезапуске системы. Взгляните на секцию Extensions win.ini-файл, а для определения формата записи. Поместите IniFiles в секцию используемых модулей и создайте код подобно этому:

    var INIFile: TIniFile;
    begin try
    INIFile := TInifile.Create('WIN.INI');
    INIFile.WriteString('Extensions','txt','c:\windows\notepad.exe ↑.txt');
    finally
    INIFile.Free;
    end;
    end;


    Это ассоциирует файлы с расширением *.txt с Записной Книжкой (Notepad) Windows. Например, для ассоциации вашего приложения MyApp с каталогом расположения c:\MyApps с файлами, имеющими расширение *.MAP, необходимо выполнить следующее:

    var INIFile: TIniFile;
    begin
    try
    INIFile := TInifile.Create('WIN.INI');
    INIFile.WriteString('Extensions','map','c:\myapps\myapp.exe ↑.map');
    finally
    INIFile.Free;
    end;
    end;


    Это будет работать как в Win 3.11, так и в Win 95 и избавит вас от работы с регистрами в Win 95. Не уверен насчет Win NT (или Win98), поскольку у меня нет возможности протестировать это дома. Имейте в виду, что все вышеописанное — только часть проблемы, т.к. приложение после всех вышеуказанных манипуляций еще должно этот файл открыть. Для этого вы должны прочесть ParamStr(1), содержащий полный путь к файлу, выбранному пользователем, и должным образом загрузить его в свое приложение.

    Дополнение

    Михаил Шпанер продолжает эту тему:

    Чтобы описание типа файлов появилось в списке «Типы файлов» Windows 98, укажите в параметре «default» ключа
    'HKEY_CLASSES_ROOT\MyApp.Document\' краткое описание типа файлов (файл My App).
    Чтобы ассоциированные файлы имели соответствующую приложению иконку, нужно в параметре «default» ключа
    'HKEY_CLASSES_ROOT\ MyApp.Document\DefaultIcon\' указать путь к иконке. Иконки соответствующих файлов обновятся после перезагрузки Windows. Windows 98 делает это без перезагрузки системы, но как это сделать я не знаю, может быть кто-то подскажет.

    Пример кода (проверено в Delphi5, Windows98):

    Добавьте 'Registry' в строку Uses.

    Объявите переменную 'RegFile':
    var RegFile : TRegIniFile;
    begin
    RegFile:=TRegIniFile.Create;
    RegFile.RootKey:=HKEY_CLASSES_ROOT; //устанавливаем текущий ключ
    RegFile.WriteString('.ext','','MyApp.Document'); // определяем расширение
    RegFile.WriteString('MyApp.Document','','Описание файлов');//Описание ассоциированных файлов (для списка «Типы файлов» Windows 98).
    RegFile.WriteString('MyApp.Document \DefaultIcon','','Путь к иконе для файлов'); //устанавливаем икону для ассоциированных файлов
    //Исполняемый файл (полный путь)
    RegFile.WriteString(' MyApp.Document \Shell\Open\Command','','исполняемый файл "%1» ');
    RegFile.CloseKey;
    RegFile.Free;
    End;


    Из конференции Expert_FAQ

    Вопрос

    Дайте примерчик построения синусойды, косинусойды, тангенса, катангенса, на форме!

    Ответ

    Вот так на канве формы строят синус:

    procedure TForm1.Button1Click(Sender: TObject); var x: integer; begin Form1.Canvas.Pen.Color := clBlue; // Рисуем голубым цветом Form1.Canvas.MoveTo(0, 100); // Устанавливаем точку начала рисования for x := 0 to Form1.ClientWidth do // От левого края до конца формы begin Form1.Canvas.LineTo(x, trunc(10*sin(x + 10)) + 100); // Собственно, рисуем график end; end;

    trunc(10*sin(x + 10)) + 100) — это хитрое выражение необходимо для того, чтобы график не был бы таким суженым :)

    С тангенсом и пр. я думаю сам разберешься…

    Еще надо учитывать, что на форме координата Y берет начало от левого ВЕРХНЕГО угла.

    Чтобы твой график был похож на тот, который дети в школе рисуют, необходимо пересчитать координаты…

    Из конференции Expert_FAQ

    Вопрос

    Версия языка:Delphi5.0

    Нужен пример работы с компонентой TWebBrowser метод Navigate2: отправка Post-запроса, создание заголовка с заданием по всем полям своих значение.

    Ответ

    Два примера из Фака www.slo.ru и пример от Анатолия Тенцера www.listsoft.ru
    Вопрос: Как получить POST данные?

    Ответ: Если данные передаются в формате 'animal=cat&color=brown' и т.д., то попробуйте использовать следующий код:

    procedure TMyNechto.Navigate(stURL, stPostData: String;
    var wbWebBrowser: TWebBrowser);
    {Автор: Craig Foley} var vWebAddr, vPostData, vFlags, vFrame, vHeaders: OleVariant;
    iLoop: Integer;
    begin {Are we posting data to this Url?} if Length(stPostData)> 0 then begin {Require this header information if there is stPostData.} vHeaders:= 'Content-Type: application/x-www-form-urlencoded'+ #10#13#0;
    {Set the variant type for the vPostData.} vPostData:= VarArrayCreate([0, Length(stPostData)], varByte);
    for iLoop := 0 to Length(stPostData)- 1 do // Iterate begin vPostData[iLoop]:= Ord(stPostData[iLoop+ 1]);
    end;
    // for {Final terminating Character.} vPostData[Length(stPostData)]:= 0;
    {Set the type of Variant, cast} TVarData(vPostData).vType:= varArray;
    end;
    {And the other stuff.} vWebAddr:= stURL;
    {Make the call Rex.} wbWebBrowser.Navigate2(vWebAddr, vFlags, vFrame, vPostData, vHeaders);
    end;
    {End of Navigate procedure.}


    — * --

    Ответ: А это другой способ:

    procedure TForm1.SubmitPostForm;
    {Автор: Hans Gulo.} { <!-- submit this html form: --> <form method="post" action="http://127.0.0.1/cgi-bin/register.pl">
    <input type="text" name="FIRSTNAME"
    value="Hans">
    <input type="text" name="LASTNAME" value="Gulo">
    <input type="text" name="NOTE" value="thats it">
    <input type="submit">
    </form> } var strPostData: string; Data: Pointer; URL, Flags, TargetFrameName, PostData, Headers: OleVariant; begin strPostData := 'FIRSTNAME=Hans&LASTNAME=Gulo&NOTE=thats+it';
    PostData := VarArrayCreate([0, Length(strPostData) — 1], varByte);
    Data := VarArrayLock(PostData);
    try Move(strPostData[1], Data^, Length(strPostData));
    finally VarArrayUnlock(PostData);
    end;
    URL := 'http://127.0.0.1/cgi-bin/register.pl';
    Flags := EmptyParam; TargetFrameName := EmptyParam; Headers := EmptyParam;
    // TWebBrowser автоматически заполнять // эти заголовки соответствующими значениями WebBrowser1.Navigate2(URL, Flags, TargetFrameName, PostData, Headers);
    end;


    — * --

    var LoginDialog: TLoginDialog;
    Flags, TargetFrameName, PostData, Headers: OleVariant;
    S: String;
    … with TLoginDialog.Create(Application) do try if ShowModal = mrOk then begin S := Format('UserName=%s&Password=%s', _ [Edit1.Text, Edit2.Text]);
    PostData := VarArrayCreate([1, _ Length(S) + 1], varByte);
    System.Move(S[1], VarArrayLock(PostData)^, _ Length(S) + 1);
    VarArrayUnlock(PostData);
    Headers := 'Content-Type: application/x-www-form-urlencoded'#10#13;
    WebBrowser1.Navigate('http://intranetserver/secretpage', Flags, TargetFrameName, PostData, Headers);
    end;
    finally Free;
    end;


    Из конференции Expert_FAQ

    Вопрос

    Как сделать, чтобы программа создавала (сохраняла) ini-файл в каталог, откуда была запущена эта программа, а не по умолчанию в c:\windows\?

    Ответ

    begin
    inifile:=TIniFile.Create('.\myapp.ini')
    end;

    Якушев Антон Юрьевич

    aIni := TIniFile.Create(ChangeFileExt(ParamStr(0),'.ini'));

    // ini-файл одноименный ехе-шнику — безопасно при переименованиях

    Вопрос

    Как зная IP адрес компа отослать на него сообщение и показать его там например с помощью процедуры ShowMessage. На обеих компах стоит Windows NT 4

    Ответ

    Для того чтобы на другом компьютере появилось сообщение — необходимо, чтобы там был установлен клиент. Только что в листе Delphi@soobcha.lionovsky.us пролетел пример как сделать чат для локалки на базе компонента из библиотеки Indy, отлично объясняющий принцип таких приложений. Вам нужно только заменить добавление строки в TMemo на Ваше ShowMessage, а широковещательное сообщение на сообщение для конкретного IP.

    -----------------начало цитирования---------------

    Если я не один такой идиот, то держите помощь от хрю:

    Чат для локалки собственными руками.
    Внимание!!! Пример, написанный в Kylix, прекрасно работает в Delphi
    Horrific aka Фленов Михаил
    http://www.cydsoft.com/vr-online/

    Так уж получается в последнее время, что на Delphi я пишу проги-приколы, а с помощью Kylix я рассказываю про сетевой кодинг. Сегодня я не буду нарушать эту традицию, и в этой статье тебя ожидает рассказ про UDP протокол. По рубрике Hack-FAQ я понял, что не все еще профиксили, что это за зверь.

    ТЕОРИЯ ПРОТОКОЛА

    На данный момент существует два основных и самых распространенных протокола — TCP и UDP.

    Раньше был еще очень распространен IPX, который использовала фирма Novell. Но на данный момент он отходит, и уже редко увидишь такого зверя. Только на старых системах можно увидеть IPX. Большинство остальных протоколов, которые ты знаешь (FTP, HTTP, POP3, SMTP и дальше в том же духе), работают поверх TCP или UDP.

    Что это значит — «поверх другого протокола»? В TCP реализованы основные функции для работы с сетью. Он умеет устанавливать соединение с удаленным компом, передавать и принимать данные и проверять правильность получения серваком отправленных пакетов. Теперь мы хотим создать протокол для передачи файлов (FTP). Для этого берем TCP, наделяем его нужными нам возможностями и — получите-распишитесь. Вот и получается, что FTP работает через (поверх) протокола TCP. Если бы мы захотели создать FTP с чистого листа, то нам пришлось бы заново реализовывать функции установки соединения и передачи данных. А так нам нужно только подготовить данные в спецформате (протокола FTP) и отдать их протоколу TCP, и он сам уже установит соединение и отдаст эти данные куда надо.

    Ели ты помнишь самую первую мою статью в рубрике «кодинг», где я рассматривал основы, то уже заметил аналогию с объектно-ориентированным программированием. Именно по такому принципу работает сеть. Все это дело стандартизировано, и если хочешь узнать подробнее, то почитай какую-нибудь доку про модель OSI (Open Systems Interconnection) и ее семь уровней (тут опять могу отослать на свой сайт, где я уже все подробно описал). Эта тема довольно интересна, и в любом случае желательно знать устройство протоколов.

    ПРОТОКОЛ UDP

    Протокол UDP очень похож на TCP. В нем также реализованы возможности передачи данных, но он не устанавливает соединения и не поддерживает целостности передаваемых данных. Протокол просто открывает порт, выплевывает туда порцию данных и даже не волнуется о том, дошли они к получателю или нет. Поэтому UDP работает намного быстрей. Если ты захочешь работать с этим протоколом, то проверку правильности получения данных придется реализовывать самому. Так что для передачи файлов или другой инфы большого размера ты должен выбрать TCP. Ну а для чата, который мы сегодня напишем, более удобным вариантом будет UDP. Он очень быстрый и при маленьких сообщениях очень эффективен.

    В Delphi для работы с UDP протоколом хорошо подходит библиотека Indy. Мы ее уже использовали, когда писали пример утилиты WhoIs. Сегодня снова возвращаемся к ней.

    БУДЬ ГОТОВ!

    С теорией покончено, давай переходить к написанию чата. На этот раз я написал его в Delphi и потом протестировал в Kylix. В обеих средах чат откомпилировался без проблем. Так что не имеет значения, что будешь использовать ты.

    Разомни пальцы, мышку, клаву и запусти Delphi. Сейчас мы приступим к моему любимому занятию… Да нет, не к сексу. Я его тоже люблю, но сегодня мы займемся кодингом, а секс оставим на ночь :).

    На форме мне понадобятся:

    1. Компонент TMemo. Его можно растянуть почти по всей форме.
    2. Компонент TEdit, в который мы будем писать отправляемое сообщение.
    3. Кнопка TButton, по нажатию которой сообщение будет отсылаться.

    Для работы с портами нам нужны компоненты idUDPClient с закладки «Indy Clients» и idUDPServer с закладки «Indy Servers». Брось по одному такому компоненту на форму.

    Теперь нужно настроить протокол UDP. Первое что сделаем — выберем любой порт от 1 до 65 тысяч, через который будет происходить связь. Я решил выбрать 11245 (ты можешь выбрать любое другое). Установи это значение у свойства Port компонента idUDPClient и у свойства DefaultPort компонента idUDPServer. Это заставит клиента и сервера работать на одном и том же порту, а значит может осуществиться связь.

    ЗАПОМНИ!!! Порты протокола UDP не пересекаются с портами TCP. Это значит, что TCP порт 80 не равен UDP порту 80.

    Теперь у клиента (idUDPClient) нужно указать свойство Host. Сюда записывается IP адрес компа, которому будут отправляться сообщения. Но у нас чат и сообщения должны получать все пользователи в сетке, запустившие прогу. Поэтому, чтобы не было проблем, желательно установить у обоих компонентов свойство BroadcastEnabled в true. А вместо конкретного IP адреса использовать широковещательный (такой адрес, который получают все). Если у тебя в сетке используются адреса типа 192.168.100.х, то для тебя широковещательный адрес будет 192.168.100.255 (последний октет меняем на 255). Приготовления окончены, можно кодить.

    ШКОДИНГ

    Создай обработчик события OnClick для кнопки и напиши там следующий код:

    procedure TForm1.Button1Click(Sender: TObject);
    begin
    IdUDPClient1.Send(Edit1.Text);
    end;

    Здесь всего одна строчка, которая отправляет с помощью UDP клиента содержимое строки ввода (компонента Edit1).

    Теперь нужно научить UDP сервер получать эту инфу. Для этого создай обработчик события OnUDPRead для компонента IdUDPServer. В нем напиши содержимое листинга 1, а я попытаюсь доходчиво описать происходящее. У процедуры-обработчика события есть три параметра. Первый присутствует во всех обработчиках и ничего интересного для нас сегодня в себе не несет. Второй — это данные, которые получены из сети. Третий — тут хранится информация о том, откуда пришли данные.

    Итак, полученные данные хранятся во втором параметре. Они приходят к нам как простой неформатированный поток TStream. Чтобы удобней было работать с данными, их лучше перегнать в строковый поток TStringStream. Ты думаешь, это неудобно? Неудобно на потолке сексом заниматься, одеяло падает. А также когда соседские дети на тебя похожи. А тут все удобно. А вдруг ты передаешь не текст, а картинку, и компонент форматнет ее в текст? Вот это уже будет не неудобно, а Смотри, как легко все превращается в текст. В обработчике я объявил одну переменную StringFormatedStream типа TStringStream (строковый поток). Первой строкой кода я его инициализирую. Во второй строчке я копирую в строковый поток данные из простого неформатированного потока. Все!!! Теперь переданный мне текст находится в свойстве DataString строкового потока StringFormatedStream.

    Я смело могу выводить этот результат в компонент Memo.

    Но мы же пишем чат, и желательно еще и выводить информацию о том, кто сказал этот текст. Для примера я вывожу IP адрес отправителя данных, который находится в свойстве PeerIP третьего параметра ABinding. Но это только для примера и в реальной ситуации это некрасиво. Поэтому ты можешь добавлять имя отправителя сразу в текст отправки. Это значит, что по нажатию кнопки отправки сообщения нужно изменить код следующим образом:

    IdUDPClient1.Send('Сюда помести имя отправителя'+Edit1.Text);

    Можно дать возможность юзверю вводить имя в отдельной строке ввода Edit2. В этом случае код будет таким:

    IdUDPClient1.Send(Edit2.Text+' '+Edit1.Text);

    Все!!! Кодинг окончен.

    COMPLETE!

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

    Если у тебя возникли проблемы с компиляцией, то Delphi (как и у меня) забыл добавить к проекту модуль idSocketHandle. Допиши его в раздел uses, и проблемы уйдут.

    Дополнительную инфу, как всегда, можно найти на моем сайте http://www.cydsoft.com/vr-online Там же можно найти и исходники чата, написанные мной.

    ЛИСТИНГ 1

    procedure TForm1.IdUDPServer1UDPRead(Sender: TObject;
    AData: TStream; ABinding: TIdSocketHandle);
    var StringFormatedStream: TStringStream;
    s: String;
    begin //Инициализация StringFormatedStream := TStringStream.Create('');
    //Копирование из простого потока в строковый. StringFormatedStream.CopyFrom(AData, AData.Size);
    //Вывод полученного сообщения Memo1.Lines.Add(ABinding.PeerIP+' '+StringFormatedStream.DataString);
    //Перенаправление сообщения дальше ABinding.SendTo(ABinding.PeerIP, ABinding.PeerPort, s[1], Length(s));
    //Освобождение строкового потока. StringFormatedStream.Free;
    end;


    — конец цитирования----------------

    Из конференции Expert_FAQ

    Вопрос

    Посоветуйте какой-нибудь компонент для построения графиков. Нужны обычные графики на плоскости.

    Ответ

    TChart со страницы additional (6.0) Eще есть MathImage, был недавно тут:
    http://www.snc.ru:8100/~torry/vcl/graphics/other/mathimge.zip

    Alex

    Вопрос

    Как просканированить строки с помощью TParser?

    Ответ

    В Delphi есть класс, называемый TParser, который IDE использует для парсинга исходного кода. Вы тоже можете использовать этот класс для парсинга строк. Функция берет строку и делит ее на слова.

    procedure ParseThis(MyStr: String);
    var
        MyParser: TParser;
        MS: TMemoryStream;
    begin
        MS := TMemoryStream.Create;
        MS.Position := 0;
        MS.Write(MyStr[1], Length(MyStr));
        MS.Position := 0;
        MyParser := TParser.Create(MS);
        MyStr := MyParser.TokenString;
        ShowMessage(MyStr);
        while MyParser.Token <> toEOF do begin
        MyParser.NextToken;
    if MyParser.TokenSymbolIs(MyParser.TokenString) then begin
       MyStr := MyParser.TokenString;
            ShowMessage(MyStr);
        end;
        end;
        MyParser.Free;
        MS.Free;
    end;

    procedure TForm1.Button1Click(Sender: TObject);
    begin
        ParseThis('Сканировать эту строку');
    end;

    Из конференции Delphi

    Вопрос

    При работе программ на Delphi1 под Win95 на иконках TBitBtn'ов обнаруживаются странные артефакты. Как их убрать?

    Ответ

    Попробуй залить фон битмапа синим цветом.

    Из конференции Delphi

    Вопрос

    Hужно определить с какой из заданных строк совпадает некая строковая переменная и в зависимости от этого перейти к соответсвующей процедуре. Как это выполнить без использования многочисленных if — then?

    Ответ

    Вот способ, легко приспосабливаемый для загрузки списка из строки, файла или ресурса:

    const
        vlist = 'первый, второй, третий';
    var
        Values: TStringList;
    procedure SetValues(VL : TStringList; S: String);
    var
        I : Integer;
    begin
        Values.CommaText := S;
        for I := 0 to CL.Count-1 do
       Values.Objects[I] := Pointer(I);
        Values.Sorted := True;
    end;

    function GetValueIndex(VL : TStringList; Match: String): Integer;
    begin
        Result := Values.IndexOf(Match);
        if Result >= 0 then
       Result := Integer(Values.Objects[Result]);
    end;

    procedure TForm1.Button1Click(Sender: TObject);
    begin
       case GetValueIndex(Values, Edit1.Text) of
          -1: {не найден} ;
           0: Caption := '0';
           1: Caption := '1';
           2: Caption := '2';
        end;
    end;

    initialization
        Values := TStringList.Create;
        SetValues(Values, vlist);

    finalization
        Values.Free;

    Из конференции Delphi

    Вопрос

    Существует ли в Delphi перегрузка операций?

    Ответ

    Перегрузки операций в Delphi, насколько я знаю нет. Функции(процедуры) могут быть перегруженными, для этого используется запись вида

    function a(q: integer); string; overload;

    Из конференции Expert_FAQ

    Вопрос

    Существует ли в природе сравнение библиотек MFC и VCL? Или сопоставление их классов?

    Ответ

    Придется Вас огорчить, но хорошего и не голословного сравнения классов библиотек MFC и VCL, вероятно нет.
    Кое-что можно подчерпнуть из флейма

    www.delphikingdom.com

    Из конференции Expert_FAQ

    По сути bpl — это и есть аналог mfc*.dll. А вот, если на Делфи маленькие программы хотите получать, то kol.mastak.ru

    delphikol

    Вопрос

    Мне нужно заниматься разбором математических выражений, например, строить график функции, заданной пользователем во время работы программы. Подскажите, есть ли для этого VCL-компоненты?

    Ответ

    В библиотеке rxLib есть компонент TrxMathParser, достаточно мощный для большого количества применений.

    Из конференции Delphi

    Вопрос

    Столкнулся с такой проблемой: требуется программно установить фильтр в Query: Пишу:
    Query.Close;
    Query.Filter:='(Colums='bla-bla-bla')';
    Query.Open;

    А Delphi выдает «missing operator or semicolon» в 'bla-bla-bla'. Если же прописать сразу в ИСР, то все OK. Все перепробывал — ничего не выходит. В чем же ошибка?

    Ответ

    Проблема в том, что Delphi считает апостроф перед bla-bla-bla закрывающим и воспринимает ваше bla-bla-bla как команду. Чтобы избежать этого апострофы внутри строк должны удваиваться:
    Query.Filter:='(Colums=''bla-bla-bla'')';

    Бузуверов Михаил

    Вопрос

    У меня проблемы с массивами в 5-ом Делфи. В одной процедуре у меня подчитываются x и y. В другой создается одномерный массив командой MyArray:array[x..y] of TPoint. На этой строчке компилятор сообщает, что ему нужны константы. Как это решается?

    Ответ

    Доброе время суток. Во-первых, динамические массивы, которые вы собираетесь создавать в Delphi, всегда начинаются с 0, то есть, в вашем примере, x=0. А сам процесс такой:
    Type
    TPoints=array of TPoint;
    var
    Points:TPoints;
    i:integer;
    begin
    SetLength(Points,y); // вот ключевая фраза
    for i:=Low(Points) to High(Points) do
    with Points do
    begin
    x:=i;
    y:=i;
    end;

    end;

    Вопрос

    Удаление файлов из временного каталога, безопасно ли?

    Ответ

    При получении имени папки предназначенной для хранения временных файлов могут возникнуть некоторые проблемы.
    Прекрасно это выглядит, когда в качестве каталога временных файлов назначен например C:\Windows :0(
    Особенно пикантно это выглядит, в свете того, что
    Remarks
    Windows 95/98/Me: The GetTempPath function gets the temporary file path as follows:

    The path specified by the TMP environment variable. The path specified by the TEMP environment variable, if TMP is not defined or if TMP specifies a directory that does not exist. The current directory, if both TMP and TEMP are not defined or specify nonexistent directories.

    Этак переименовываешь C:\TEMP — и программа чистит текущий каталог :-)

    Windows NT/2000 or later:

    The GetTempPath function does not verify that the directory specified by the TMP or TEMP environment variables exists.

    The function gets the temporary file path as follows:

    The path specified by the TMP environment variable. The path specified by the TEMP environment variable, if TMP is not defined. The Windows directory, if both TMP and TEMP are not defined.

    Этак удаляешь переменные окружения — и программа "деинсталлирует" Windows
    Из этого вытекает следующее, удаление файлов из л юбого каталога, особенно из временного чрезвычайно поасная операция, не ты создал — не трогай. Удалять только ручками, глядя на файлы и принимая решения индивидуально по каждому файлу.

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

    Из конференции Delphi

    Вопрос

    После снесения через родной uninstall Interbase Server 5.0 для Windows и попытки поставить 5.1.1 вылетает ошибка: IBCheck. Что делать?

    Ответ

    Надо запустить regedit, и открыть ключ

    HKEY_LOCAL_MACHINE\Environment

    Там есть строка PATH. Так вот, иногда она почему-то становится не строкой, а еще чем-то. Ее надо убить, и пересоздать как строку, прописав туда прежнее содержимое (в виде строки).

    Вопрос

    Как зная HANDLE объекта Edit в чужой прорамме, установить позицию курсора в конец строки в этом объекте?

    Ответ

    Вот так:

    procedure Set2End(hWnd:THandle);
    var
        l:integer;
    begin
        l:=GetWindowTextLength(hwnd);
        SendMessage(hwnd,EM_SETSEL,l,l);
    end;

    A.Z.

    Вопрос

    Есть проблемма. Пишу код:

    memo.lines.clear;
    memo.lines.add('Очень длинный текст');

    Элемент memo у меня не шибко большой и фокус в нем сразу убегает на конец фразы 'Очень длинный текст'. А мне нужно чтобы изначально показывалось начало фразы и пользователь memo прокручивал если захочет.
    Подскажите, как это сделать?

    Ответ

    Вот так:

    memo.SelStart := 1;

    И еще нужно установить ненулевое значение SelLength (длина выделения).

    Из конференции Delphi

    Вопрос

    Есть ли какие-либо утилиты для отслеживания утечки памяти для Delphi программ?

    Ответ

    MemorySleuth. Самая полезная. Ей можно отследить кусок кода, производящий утечки. Ищи в Инете. Нормальная версия стоит денег. Она того стоит.

    Из конференции Expert_FAQ

    Вопрос

    Как в Дельфи сделать так, чтобы текст, например, в Label, появлялся, растворяясь, и через некоторое время исчезал, растворяясь.

    Ответ

    Интересная идея! Наверное, это можно сделать, используя палитры, но такое «лобовое» решение тоже работает:

    procedure TForm1.Timer1Timer(Sender: TObject);
    var
    c: TColor;
    r, g, b: byte;
    begin
    c:=ColorToRGB(Label1.Font.Color);
    if c=RGB(0,0,0) then
    Timer1.Enabled:=false;
    r:=GetRValue©;
    g:=GetGValue©;
    b:=GetBValue©;
    r:=r-byte(r>0);
    g:=g-byte(g>0);
    b:=b-byte(b>0);
    Label1.Font.Color:=RGB(r,g,b);
    end;
    procedure TForm1.FormCreate(Sender: TObject);
    begin
    Label1.Font.Color:=Label1.Color;
    end;

    Вопрос

    Чем можно скомпилировать программу на Pascal(win32) кроме Delphi?

    Ответ

    Вот, выбирайте из известных нам:

    FreePascal
    http://www.freepacal.org
    FREEWARE
    Самый развитый из бесплатных.

    Virtual Pascal
    http://www.vpascal.com
    FREEWARE

    TMT Pascal compiler
    http://www.tmt.com
    SHAREWARE

    Irie Pascal
    http://www.irietools.com/iriepascal/
    SHAREWARE

    Кирилл Краснов, Сергей Паюк

    Вопрос

    Чем отличаются TLabel и TStaticText?

    Ответ

    TLabel is TGraphicControl
    TStaticText is TWinControl

    То есть у последнего есть окно, это дает возможность управлять этим контролом с помощью сообщений Windows.

    Из конференции Delphi

    Вопрос

    Можно ли как-нибудь почистить exe-шник после его создания? А то получается больно великоватый для размещения в сети. Почистить именно после его создания. Можно, конечно, использовать КОЛ, но для меня это не подходит.

    Ответ

    Можно попробовать сжать его при помощи специальных программ. Вот одна из них — Compressor (http://aclab2.chat.ru

    Есть еще одна — UPX Shell (http://iont.virtualave.net/ — поставляется вместе с исходниками на Delphi.

    Из конференции Expert_FAQ

    И еще один упаковщик AsPack можно скачать с www.aspack.com TiR@el

    Virus83

    Вопрос

    Чтение BlobStream с помощью TADOQuery из БД Access

    Ответ

    function GetBlobStream(Query: TADOQuery): TMemoryStream;
    begin
        result := TMemoryStream.Create;
        // Сначала надо подключиться к БД Access
     // Смотрите: Query.Connection, TADOConection и Query.ConnectString
        // Отправляем SQL запрос
        Query.Active := False;
        Query.SQL.Clear;
     // data это столбец нужных данных, а email — таблица
     Query.SQL.Append('SELECT data FROM email WHERE id=1');
        Query.Active := True;
    Result.LoadFromStream(Query.CreateBlobStream(Query.FieldByName('Data'), bmRead));
    end;

    Из конференции Delphi

    Вопрос

    Я хочу научиться програмировать на DELPHI . Расскажите пожалуйста, что это за язык и с чем его употребляют.

    Ответ

    Delphi — это не язык, а система программирования. Т.н. RAD (Rapid Application Development), т.е. система быстрой разработки программ. В качестве языка программирования в ней используется Pascal (точнее, Object Pascal). При разработке программ используется визуальный принцип (точнее сказать при разработке пользовательского интерфейса).

    Это скрывает от разработчика все «прелести» программирования под Windows, и если с использованием чистого API ваша программа заняла бы примерно 100 строк, то на Delphi это всего лишь 10 строк. Что, правда, сказывается на размерах EXE файла (10 кб против 200), но для современных компьютеров это не принципиально, хотя на Delphi также можно программировать с использованием «чистого» API. Следует отметить также наличие BDE (Borland Database Engine), который очень сильно облегчает работу с базами данных. Правда, при распространении Ваших программ придется его включать в дистрибутив. Очевидно, что использование «визуального» подхода не освобождает Вас от программирования, хотя и делает этот процесс более простым, позволяя сосредоточиться на программировании как таковом, а не на укрощении Windows.

    Goltsov Dmitry

    Во-первых ~500, а не 200. А во-вторых дело не в «лишних кодах», а в ненужных библиотеках. При правильном программировании можно всю визуалку уложить килобайт в 30 + наваянный код. Итого в среднем не более 50. По поводу RAD — это конечно так + паскалевский код довольно фигово компилируется (как по скорости, так и по объему). Учите ребята С — без него никуда не деться. Java, Sharp, PHP, Perl и многие другие за основу держат С. Выучите С — остальное будет проще. А Delphi, как была, так и останется песочницей. Под MSVC можно все гораздо круче делать и не намного медленней, только квалификация, конечно, явно выше.

    Вопрос

    Что такое ActionList, для чего он нужен? Как им пользоваться?

    Ответ

    Это замечательная вещь:
    Вы создаете свое "действие" Action.
    Заполняете поля: имя, подсказка, процедура, вызываемая при обращении к этому действию, горячая клавиша, изображение.
    Обратите внимание, что у пунктов меню, кнопок есть свойство Action — вот туда-то и прописывайте это свое действие.
    Для чего нужно? — пункты меню и кнопки дублируют часто друг друга — а тут будет однообразие и вида и названия и поведения

    Из конференции Expert_FAQ

    Вопрос

    Что такое Handle окна, и как его полyчить?

    Ответ

    Handle — это число — уникальный идентификатор окна (в данном случае) в системе.
    Получить его можно, например, так:

    hwnd := FindWindow (nil, 'Form1'); //ищем окнo с заголовком "Form1"
    if hwnd <> 0 then {нашлось};

    Из конференции Delphi

    Вопрос

    Объясните, плиз, что такое MailSlots?

    Ответ

    Mailslots — это механизм передачи коротких сообщений, встроенный в Windows 9x/ME/NT/2k/XP и т.д., поэтому ничего скачивать не надо.
    Смотри справку по функции CreateMailSlot.

    Novikov Dmitry

    Вопрос

    Plz, объясните чайнику что такое области видимости

    private, protected, public, published, или automated.

    Ответ

    Private — свойства и методы не видны вне объекта, а также не видны его потомкам

    Protected — свойства и методы . не видны вне объекта, но видны его потомкам

    Public — свойства и методы видны вне объекта и конечно видны потомкам

    Published — то же что Public плюс свойства доступны в ObjectInspector и их имена сохраняются в EXE-файле

    Automated — тоже что Public, но для написания OLE серверов или клиентов. В настоящее время не используется и оставлен только ради совместимости с предыдущими версиями Delphi

    Из конференции Expert_FAQ

    Вопрос

    Я создал объект TStrings, но при попытке обращения к нему выдается ошибка.

    Ответ

    TStrings — это базовый класс. Вам нужен TStringList.

    Из конференции Delphi