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

Интернет для Delphi-программиста


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

Интернет для Delphi программиста.

Выпуск : № 28


Здравствуйте уважаемые подписчики рассылки "Интернет для Delphi программиста". Данная рассылка предназначена для всех кого интересует Delphi, здесь будут выкладываться ссылки на различные ресурсы интернета так или иначе связанные с Delphi: книги, исходники, программы... Изучайте Delphi один из лучших языков программирования!!!


ЗАДАТЬ ВОПРОС :

Правила рассылки: 
1. Не присылайте ответов на вопросы типа "да, нет".  
2. Если отвечаешь на вопрос - то отвечай подробно с примерами (желательно с исходником примера).
3. Тема вопросов - программирование на Delphi.
Внимание авторам: - Я не указываю ваши адреса из-за спама, но кто хочет, чтобы его email был - пишите, иначе только имя(ник).
Отправить вопрос


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


Вопрос № 58 задаёт: dmn Ответить
Как программно перехватить имя файла, если запускаешь его в меню "Открыть с помощью", или задать ассоциацию так, чтобы файл при двойном щелчке открывался именно твоей программой?
Вопрос № 59 задаёт: Митек  Ответить
Как работать с COM портами в Windows XP. Уже всё испробовал , ну не как кто-нибудь сталкивался с этим ? Вроде под 95 всё работает!Надо считать данные с порта и уст. кое-какие сигналы в 1. Спасибо!
Вопрос № 60 задаёт: Dead Lord  Ответить
такая проблема: как транслировать следующие сишные типы в делфи?
LPINT, LPVOID, LPDWORD, PINT, PTSTR, DWORD. И вообче, что это за приставка такая LP? В MSDNе она встречается довольно часто...

Ещё вопрос: может кто- нибудь подсказать, где можно найти запросы- ответы, которыми обмениваются HTTP-, POP3-, SMTP- серверы и клиенты в процессе соединения и работы???

Вопрос № 61 задаёт: Стас  Ответить
Здравствуйте! Как программно разорвать DialUp соединение установленное какой либо другой программой.

Ответы.

Вопрос № 54 задаёт: Михаил Ответить 
Написал программу, которая работает с базами данных Access (ADO).
Возникла необходимость использовать ее с такими же базами, но защищенными паролем. Ввожу логин и пароль базы данных при создании строки подключения - появляется сообщение об ошибке.
Подскажите в чем дело.
Отвечает: #One® 
А что за сообщение? И какая защита: сами базы запаролены или на уровне пользователей? В последнем случае необходимо подключить файл рабочих групп (имеет расширение mdw).
Отвечает: Артём
Да действительно есть такая галиматья при работе с базами в ADO

вот смотри пример постройки соединения

Поставщик данных: Microsoft Jet 4.0 OLE DB Provider
Подключение :
База данных - указываешь свою БД
Пользователь - Имя пользователя
Пароль - ставь пустой пароль
Открываешь закладку ВСЕ:
и здесь в поле
Jet OLEDB: DatabasePassword - Указываешь свой пароль для доступа к БД

Или вот такая запись соединения
Provider=Microsoft.Jet.OLEDB.4.0;Data Source={Путь и имя твоей
БД};Persist Security Info=False;Jet OLEDB:Database Password={Пароль
подключения к БД (Пользователь-Admin)}

Вопрос № 55 задаёт: Ирина Ответить 
Здравствуйте! Подскажите чайнику, как при щелчке на записи(или кнопки, неважно) в одной DBGrid перенести эту запись в другую DBGrid(чистую)?
Отвечает: Архангельский Андрей
Важно понимать, что при работе с БД записи не переносятся из одного
грида в другой или еще какой-то элемент управления.
Любой действие на клиентской стороне приводит к созданию запроса, в
данном случае такого

Insert into Table1(Field1,Field2)
select Fld1, Fld2 from Table2
where Fld2=xxxx;

который выполняется на стороне сервера, после чего нужно обновить DBGrid.

Отвечает: dmitriy  _dmi3_@excite.com
В примере была использована DBDEMOS, таблица country.db, фирмы
Borland.

На форме у нас два DataSourse:
DBGrid1 -DataSourse1
DBGrid2 -DataSourse2

Table1 и Query1:
DataSourse1.DataSet - Table1
DataSourse2.DataSet - Query1

В свойстве Query1 SQl пишем:
select * from country.db where Name = :Selected
(Name - это имя поля по которому происходит сортировка в базе данных,
или является обязательным для заполнения в country.db, :Selected - это
параметр, который будет меняется в процессе работы, ему можно присвоить
любое имя, просто в запросе поставить ":" перед именем)

Обрабатываем событие DataSource1.OnChange. То есть, если меняется
текущая запись, например выбор другой в DBGrid. А так оно все связано
то используем Table1.FieldByName (используем то поле, значение
которого будем подставлять вместо параметра Selected):
procedure TForm1.DataSource1DataChange(Sender: TObject; Field: TField);
begin

Query1.Close; // Закрываем любой предыдущий запрос
Query1.ParamByName('Selected').AsString :=
Table1.FieldByName('Name').AsString;
\\ изменяем параметр
Query1.Open;
end;

P.S. : Чайник мужского рода :) .

Отвечает: Трифонов Владимир 
DBgrid- это компонент отображения данных из БД.

Вам надо скопировать запись из таблицы на который ссылается заполненный DBGRID в таблицу на которую ссылается пустой DBGRID .
т.е. вам надо выполнить просто INSERT.
Отвечает: vadim 
TDBGrid является компонентом для отображения данных, находящихся в наборе данных, например, компонентов TTable или TQuery. Поэтому TDBGrid не бывает чистым или нечистым, а вот набор данных - может быть пустым или непустым!
Что касается переноса данных, TDBGrid не фигурирует как источник данных в процедурах переноса данных между таблицами, так как таковым не является, но позволяет ту или иную запись набора данных сделать текущей.
Привожу пример.
Предположим у нас есть две таблицы: Days и WorkWeek, каждая из которых содержит одинаковое поле DaysField, которое является строковым и описывает сущность "День недели". Содержимое соответствующего компонента TTable Table1_Days через компонент типа TDataSource, например DSTable1_Days, отображается в TDBGrid, например DBGr_Days, так:

Понедельник
Вторник
Среда
Четверг
Пятница
Суббота
Воскресенье

Второй компонент TTable соответственно Table2_WorkWeek подключён для отображения данных через TDataSource, например DSTable2_WorkWeek, к TDBGrid, например DBGr_WorkWeek.
Допустим, что таблица Table2_WorkWeek пока ещё пуста и мы хотим предоставить пользователю возможность копировать из первой таблицы во вторую те дни, которые являются для него рабочими. Реализовывать вставку записи во вторую таблицу будем по двойному щелчку на строке DBGr_Days с предварительной проверкой на случай повторной вставки одинаковой записи:

procedure TForm1.DBGr_DaysDblClick(Sender: TObject);
begin
  if not Table2_WorkWeek.Locate('DaysField',Table1_Days.FieldByName('DaysField').AsString,[loCaseInsensitive])
     then begin
            Table2_WorkWeek.InsertRecord(Table1_Days.FieldByName('DaysField').AsString);
            Table2_WorkWeek.Refresh;
          end;
end;

или с использованием дополнительного компонента TQuery, например Query1:

procedure TForm1.DBGr_DaysDblClick(Sender: TObject);
begin
  with Query1
    do begin
         Close;
         SQL.Clear;
         SQL.Add('Select DaysField from WorkWeek Where DaysField='+Chr(39)+
                 Table1_Days.FieldByName('DaysField').AsString+Chr(39)+
                 ' Order by DaysField');
         Open;
       end;
  if Query1.FieldByName('DaysField').AsString=''
     then begin
            with Query1
              do begin
                   Close;
                   SQL.Clear;
                   SQL.Add('INSERT INTO WorkWeek (DaysField) Values('+Chr(39)+
                   Table1_Days.FieldByName('DaysField').AsString+Chr(39)+
                   ')');
                   ExecSQL;
                 end;
            Table2_WorkWeek.Refresh;
          end;
end; 
Причём, если в процедурах используется метод таблицы Locate, необходимо чтобы предварительно был установлен индекс этой таблицы, соответствующий имени поля, по которому будет выполняться поиск.
Это можно сделать сразу на этапе разработки или программно, например

Table2_WorkWeek.IndexFieldNames:='DaysField';

в процедуре перед самим поиском Locate.
А также необходимо убедиться, что в подключениях Uses добавлен юнит DB, или добавить его вручную, иначе на методе Locate при компиляции будет выпадать соответствующее сообщение об ошибке.

P.S.:
В перспективе, должен заметить важный момент, что на практике редко используется копирование строк из одной таблицы в другую, см. теорию БД понятия "избыточность" и "ссылочная целостность".
Например "избыточность", как следствие дублирования длинных строк в таблицах влечёт к нерациональному "утяжелению" размеров БД при большом объёме записей, строки которых дублируются.
Поэтому при разработке серьёзных программ для работы с большими БД используют в таблицах сущностей автоинкрементирующиеся поля ID типа Integer(4 байта) для того, чтобы в таблицах с повторяющимися строками(каждый символ = 1байт) использовать не сами строки, а их идентификаторы ID.

Вопрос № 56 задаёт: Крези.ru Ответить 
Здравствуйте всем !!! Давал советы, но вот и самому понадобился совет.
А вопрос такой: есть функция работы с компонентом TEdit.
Вот она:
procedure TComBox.EditCom1KeyPress(Sender: TObject; var Key: Char);
begin
pole1 := editcom1.text;  //в поле1 помещаем символ введенный в editcom1.text
if pole1 = '' then          // проверяем на пустую стоку, нет символа в
переменной Pole1
begin
 MessageBox(handle,PChar(' Поле ввода пустое, попытайтесь ещё раз
!!!'),PChar('  Сообщение !!!'),0);  //оповещаем об этом
 EditCom1.Text := '';                      //очищаем поле
 EditCom1.SetFocus;                     //устанавливаем курсор в начало
 exit;                                               //выходим
end;
if length(pole1) = 4  then   //опять какие то проверки и установки
begin
EditCom2.SetFocus;
end;
end; // всё
Так вот, объясните кто нибудь. Почему в строковую переменную Pole1 не помещается символ введённый с клавиатуры. После первого прохода, почему-то пустая строка. После второго прохода введённый символ есть. Как добиться, чтобы после первого нажатия, символ всё таки помещался в переменную. Может у кого такая проблема возникала. Заранее благодарен.А то уже 2 дня бьюсь и ни чего.
Отвечает: Архангельский Андрей 
А потому что ты еще не вставил символ. Строка должна быть следующая
pole1 := editcom1.text; // это не правильно
pole1 := Key; // так правильно, потому что введенный символ еще находиться в Key, а вот когда из этого события выйдешь он попадает в Edit
Отвечает: #One® 
Попробуй использовать событие OnChange вместо OnKeyPress
Отвечает: dmitriy _dmi3_@excite.com 
При нажатии любой клавиши результат, будь то символ или код ANSI, помещается в переменную key, a переменная text содержит то, что было до нажатия, то есть, вот так будет правильно:

procedure TComBox.EditCom1KeyPress(Sender: TObject; var Key: Char);
var pole1:string;
begin
if (33>ord(key)) or (ord(key)>255) then exit;
// Записываем только
// прописные символы (пробел,enter,delete и т.п. не учитываются, в зависимости от задачи)
SetLength (pole1,length(pole1)+1);
pole1[length(pole1)] := key;
//добавляем введенный символ в конец строки
if pole1 = '' then // проверяем на пустую стоку, нет символа в
переменной Pole1
begin
MessageBox(handle,PChar(' Поле ввода пустое, попытайтесь ещё раз
!!!'),PChar(' Сообщение !!!'),0);
//оповещаем об этом
EditCom1.Text := ''; //очищаем поле
EditCom1.SetFocus; //устанавливаем курсор в начало
exit; //выходим
end;
if length(pole1) = 4 then
//опять какие то проверки и установки
begin
EditCom2.SetFocus;
end;
end;
// всё
Отвечает: DarkRatt 
"OnKeyDown
Происходит при нажатии на клавишу. События OnKeyDown и OnKeyPress - это чередующиеся, повторяющиеся события, которые происходят до тех пор, пока не будет отпущена удерживаемая клавиша (в этот момент происходит событие OnKeyUp)
OnKeyPress
Происходит, когда пользователь нажимает клавишу, которая генерирует печатаемый символ. Может происходить также при нажатии клавиши печатаемого символа с "Ctrl". He происходит при нажатии клавиш "Tab", "Enter", клавиш перемещения курсора
OnKeyUp
Происходит при отпускании нажатой клавиши"

То есть символ не только отображается на экране, но и вводится в свойство Text компонента EditCom1 лишь при событии OnKeyUp.

Отвечает: Igoshin Konstantin 
Дело в том, что событие KeyPress возникает при нажатии на клавишу. И как ты видел, в обработчик (в процедуру) передается символ, который (как правило) необходимо обработать. Затем этот символ уже помещается в Edit.Text.
По-этому, для твоего кода советую использовать событие KeyUp - срабатывает при отпускании клавиши - к этому моменту символ уже занесен в Edit
Отвечает: Трифонов Владимир 
Потому что в Edit еще не добавлен вводимый символ.

Вам надо изменить строку pole1 := editcom1.text;
на вот такой код :
pole1 := editcom1.text+key;//Добавляем символ
key:='';//обнуляем вводимое значение чтоб не добавлять 2 раз один и тот же символ.
Отвечает: Ярослав Давыденко 
попробуй события onKeyDown, onKeyUp
Отвечает: Артём 
Правильно и будет так делать для того чтобы определиться с введенной буквой передаётся параметр Key.
вот шапка твоей процедуры

procedure TComBox.EditCom1KeyPress(Sender: TObject; var Key: Char);

он передаёться в параметрах функции используй его.

Отвечает: Dasha 
Просто событие KeyPress происходит раньше, чем символ отображается на форме. Возьми событие OnKeyUp, и все будет нормально работать.
Отвечает: toa 
При первом проходе editcom1.text ничего не содержит так как событие не дошло до обработчика editcom1. Символ нажатой клавиши лежит переменной Key. Его-то и можно анализировать. При втором проходе переменной editcom1.text уже присвоен предыдущий символ. Если в переменную pole1 нужно заносить более одного символа лучше это обрабатывать после нажатия клавиши Enter
Отвечает: mail.ru 
Потому что только после вашей процедуры срабатывает стандартный обработчик событий и key заносится в EditCom1.Text .


Статья:   Установка ловушек в системе Windows. Автор: Delist. Сайт: http://www.noil.pri.ee/
Если заглянуть в англо-русский словарь и посмотреть значение слова Hook то мы увидим, что Hook переводиться как крюк или крючок, кому как понравиться.
Итак, какой же крюк можно поставить на Windows и что мы им сможем зацепить. На первый вопрос я постараюсь ответить в самом тексте статьи и ответ на второй же ответ напрашивается сам собой, да, в системе Windows и цеплять-то больше нечего как события. Можно смело сказать что всё ОС основана на взаимодействии различных событий. Пользователь пошевелил мышкой - событие, нажал на кнопку на клавиатуре тоже событие, Windows повис - событие, да ещё какое(!), только отловить вот его трудно.
Да и наверно, любой человек, который хоть немножко знаком со средой Delphi (хотя почему именно Delphi, тут можно перечислить большинство языков программирования под Win) замечал, что код пишется, именно, для определённого события, которое может произойдет, а может и нет. Наверно, это не плохо, по крайне мере логично и понятно.

Со вступлением я закончил и воды, наверно, достаточно.

В данной статье я планирую рассказать а процессе установки ловушек в Delphi. Упор я собираюсь делать на практическое применение hook'ов, поэтому теория буду стараться объяснять уже после приведения примера.

Идея ловушек заключается в том чтобы создать такой код, который бы реагировал на определённое событие в системе. Скорее всего, ловушки были задуманы компанией Microsoft для того, что бы облегчить отладку программ, но hook'и можно применять и для решения других задач. Например с их помощью не трудно можно написать клавиатурный шпион. Его примерное создание мы рассмотрим в качестве примера, но чуть по-позже. А пока рассмотрим другой пример, который по нажатию определённого сочетания клавиш будет показывать нам спрятанные под звёздочками пароли.

Для начала необходимо выполнить команду File->New->Other... и в открывшемся окошке выбрать Dll Wizard(Посмотреть screenshot). Далее следует удалить все
модули которые Delphi автоматически подключил в наш проект, а вместо них вписать модули Windows и Messages. Когда это будет сделано, то можно перейти к написанию основной функции. Эта функция будет отвечать за действие, которое должно выполняться при наступлении определённого события в системе. Но для начала надо объявить две глобальные переменные:
var
  HookHandle: HHook=0;
  Wnd: HWND;

В первой переменной будет храниться дескриптор созданной ловушке, в последствии он может быть использован для уничтожения hook?а. Вторая переменная будет содержать указатель на поле поле ввода (Edit), в котором мы будем менять
У меня получился такой код:
function HookProc(Code: Integer; wParam: Word; lParam: Longint): longint; stdcall;
begin
CallNextHookEx(HookHandle, Code, wParam, lParam);
if Code=HC_ACTION then begin
  if (TMsg(Pointer(lParam)^).message=WM_LBUTTONDOWN) 
       and ((TMsg(Pointer(lParam)^).wParam and MK_SHIFT)=MK_SHIFT) then begin
    Wnd:=TMsg(Pointer(lParam)^).hwnd;
    SendMessage(Wnd, EM_SETPASSWORDCHAR, 0, 0);
    InvalidateRect(Wnd, nil, true);
    end;
  end;
end;

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

Далее мы проверяем, если пользователь нажал на левую кнопку и при этом удерживал кнопку Shift, то показываем, то что спрятано под звёздочками. Но что же тогда TMsg(Pointer(lParam)^).xxx? Всё довольно просто. В этой структуре храниться указатель на объект, данные о котором будут получены при выполнении
ловушки. И эти данные, как раз хранятся в виде структуры Msg, поэтому-то мы вначале и пишем TMsg.

Если все условия выполнились, то получаем указатель(Handle) объекта, который сгенерировал событие, а после посылаем ему сообщение о том, что надо отобразить спрятанные под звёздочками символы. Это делается функцией SendMessage в которую надо передать четыре параметра:
1. Указатель на компонент, которому посылаем сообщение.
2. Тип сообщения, от него зависят следующие два параметра. Мы указываем здесь EM_SETPASSWORDCHAR, потому что меняем символ, скрывающий вводимые символы.
3. Здесь вводим нужный символ, если это 0, то никакой новый символ задан не будет, и заодно исчезнут звёздочки. Желающие по экспериментировать могут
набрать здесь integer(LPCTSTR(?$?)) и посмотреть на результат.
4. Для этого типа сообщения должен быть 0.

Функцией InvalidateRect обновляем нужное окно, для того что бы сразу же увидеть результат.

Можно считать, что основная часть работы уже сделана, однако осталось написать функцию, которая установить hook в систему.
procedure SetHook(State: Boolean) exportstdcall;
begin
if State then
  if HookHandle=0 then
     HookHandle:=SetWindowsHookEx(WH_GETMESSAGE, @HookProc, HInstance, 0)
else begin
  UnhookWindowsHookEx(HookHandle);
  HookHandle:=0;
  end;
end;

В основном здесь должно быть всё понятно, единственно на чём остановлюсь подробней, так это пара функций SetWindowsHookEx и UnhookWindowsHookEx. Первая из них устанавливает ловушку в систему. У неё четыре параметра:
1. Тип устанавливаемой ловушки. Может принимать одно из следующих значений:
Тип ловушки Описание
WH_CALLWNDPROC
Фильтр процедуры окна. Функция-фильтр ловушки вызывается, когда процедуре окна посылается сообщение. Windows вызывает этот хук при каждом вызове функции SendMessage.
WH_CALLWNDPROCRET
Функция, контролирующая сообщения после их обработки процедурой окна приемника.

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

WH_DEBUG
Функция, предназначенная для отладки. Функция ловушки вызывается перед любой другой ловушкой Windows. Удобный инструмент для отладки и контроля ловушек.

WH_GETMESSAGE
Функция обработки сообщений. Функция ловушки вызывается всегда, когда из очереди приложения считывается любое сообщение.

WH_HARDWARE
Функция, обрабатывающая сообщения оборудования. Функция ловушки вызывается, когда из очереди приложения считывается сообщение оборудования.

WH_JOURNALPLAYBACK
Функция вызывается, когда из очереди системы считывается любое сообщение. Используется для вставки в очередь системных событий.

WH_JOURNALRECORD
Функция вызывается, когда из очереди системы запрашивается какое-либо событие. Используется для регистрации системных событий.

WH_KEYBOARD
Функция "обработки" клавиатуры. Наверное, наиболее часто используемый тип ловушки. Функция-фильтр ловушки вызывается, когда из очереди приложения
считывается сообщения wm_KeyDown или wm_KeyUp.

WH_MOUSE
Функция, обрабатывающая сообщения мыши. Функция ловушки вызывается, когда из очереди приложения считывается сообщение мыши.

WH_MSGFILTER
Функция ловушки вызывается, когда сообщение должно быть обработано диалоговым окном приложения, меню или окном приложения.

WH_SHELL
Функция ловушки вызывается, когда создаются и разрушаются окна верхнего уровня или когда приложению-оболочке требуется стать активным.

Есть ещё два параметра WH_KEYBOARD_LL и WH_MOUSE_LL. Официально они называются низкоуровневым фильтром клавиатуры и мышки. Однако реально я их не разу не использовал.

2. Здесь указываем на нашу процедуру, которой будет передаваться управление при наступлении события, кстати, параметры передаваемой функции заранее определены, то есть Вы не может их изменять их без потери функциональности приложения. Их должно быть три. Первый параметр code (тип integer) указывает на тип получаемого сообщения, в то время как следующие два зависят от первого параметра и могут различаться.

3. Указатель на Dll библиотеку в которой находиться функция. Необходимо оставить HInstance.

4. id потока, который Ваша программа будет контролировать. Если Ваша ловушка должна контролировать все потоки в системе, иными словами она должна быть
глобальной ловушкой, то желательно поставить 0.

Вторая функция UnhookWindowsHookEx отключает ловушку. Для этого её надо передать параметр SysHook, который мы получили в результате выполнения функции SetWindowsHookEx.

И ещё хочу добавить, что процедуру setHook нужно добавь в список экспортируемых процедур. Для этого в конце динамической библиотеки допишем такую строку:
exports SetHook index 1;
Это значит, что эту функцию можно будет вызвать из любой другой программы.

Всё библиотека готова осталось только сохранить её и скомпилировать. Лично я её назвал hook.dll.

Теперь приступим к созданию приложения из которого и будет запускаться ловушка. Для этого выполним команду File->New->Application, поставим две кнопки (StartHook и StopHook), создадим для них обработчик события onClick, а также onShow и onClose у главной формы, после чего перейдем в редактор кода и напишем немного кода. Лично я, обычно пользуюсь явным вызовом функции из динамических библиотек, поэтому здесь и приведу именно его, хотя сам код подробно описывать не буду.

Для начала объявим новый в разделе type новый тип
HookProc=procedure(State: Boolean); stdcall;
А в разделе private две переменных
DllHandle: HWND;
SetHook: HookProc;

Далее у меня получилось следующее

procedure TForm1.StartHookClick(Sender: TObject);
begin
Sethook(true);
end;

procedure TForm1.StopHookClick(Sender: TObject);
begin
Sethook(true);
end;

procedure TForm1.FormShow(Sender: TObject);
begin
DllHandle:=LoadLibrary('hook.dll');
if DllHandle=0 then
  ShowMessage(IntToStr(GetLastError))
else
  @SetHook:=GetProcAddress(DllHandle, 'SetHook');
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if DllHandle<>0 then
  FreeLibrary(DllHandle);
end;

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

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

function HookProc(Code: Integer; wParam: Word; lParam: Longint): longint; stdcall;
begin
if (Code=HC_ACTION) and (((lParam shr 16) and KF_UP)=0) then
  if wParam>33 then
    ShowMessage(chr(wparam));

Result:=CallNextHookEx(0, Code, wParam, lParam);
end;


В моём примере каждая нажатая клавиша показывается на экран в виде сообщения, для этого я дополнительно подключил модуль Dialogs.

Обсудить статью можно на форуме.
Скачать исходник библиотеки и программу для установки ловушек
Обсуждение материала

Важно:
  • Форма предназначена для оцениванивания материала, его содержания, полезности, соответствия действительности и так далее.
  • При голосовании учитывайте уровень, на который рассчитан материал. "Интересность и полезность" имеет смысл оценивать относительно того, кому именно предназначался материал.
  • При голосовании за вариант "Написано неверно" не забывайте указывать ошибку на форуме, в случае если ошибка в течении 24 часов указана не будут голос будет аннулирован.
Всегда легче осудить сделанное, нежели сделать самому. Поэтому, пожалуйста, соблюдайте правила приличия и уважайте друг друга.


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

Компоненты:   

FreeSkinEngine 1.0.0

SkinEngine это VCL библиотека, которая позволяет динамически изменять практически любые атрибуты внешнего вида форм или элементов управления вашего приложения. Позволяет обеспечивать поддержку "шкур" (skins) для вашего приложения. Можно даже настраивать внешний вид вашего приложения как у приложений, работающих под управлением любых других операционных систем, или создавать ваши собственные "шкуры"

RbControls

RbControls компоненты анимируются при перемещении и нажатии мышки. Эти компоненты позволяют значительно улучшить внешний вид приложений. Доступны 7 компонентов: RbButton, RbRadioButton, RbCheckBox, RbPanel, RbSplitter, RbProgressBar и RbStyleManager. Менеджер стилей позволяет изменять цвета компонентов во время выполнения. Есть возможность загрузить стиль из файла для изменения внешнего вида приложения. С исходными текстами.


Модули:   

Работа с консолью

Многие кто писал консольные приложения наверное сталкивался с такой проблеммой:
В окне консоли используется кодировка OEM, т.е. DOS-кодировка. Поэтому, если в программе написать:

WriteLn('Вася+Маша=Лубов');

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

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

Мне приходилось часто писать консольные приложения. Так вот, что бы не заниматься постоянной перекодировкой и не заботиться об необработанных программой исключениях, я написал свой модулек awConsole.
Просто добавление этого модуля в проект вызывает несколько изменений в поведении программы:
1. Весь консольный ввод/вывод осуществляется в кодировке OEM;
Достигается это подменой "драйвера" обслуживания консольных файлов Input, Output, ErrOutput.
2. Исключения не обработанные программой вызывают окно сообщения вместо системной ошибки.
Ну и есть там еще несколько полезных и не очень полезных функций.

Работа с сетью

Очень хороший модуль для работы с сетью.

Измерения времени исполнения процедур

Модуль позволяет измерить времени исполнения процедур и даже отдельные фрагментов кода. Разрешающая способность составляет 1 такт процессора. Точность измерения конечно ниже, поскольку зависит от работы кэша процессора. Но она все равно значительно выше нежели все остальные известные мне способы использующие те или иные аппаратные таймеры.

Автоматический уничтожитель объектов и компонентов

Модуль позволяет автоматический уничтожитать объекты и компоненты.

Получение метаданные из файла JPEG

Модуль для получения метаданные из файла JPEG

Модуль работы с ресурсами в PE файлах

Возможности:
1. Извлечение иконок из ресурсов без потери их цветовой гаммы и с сохранением всех вложенных иконок.
2. Добавление нового ресурса
3. Изменение существующего ресурса
4. Удаление ресурса
5. Работа с ресурсами различных языков

Модуль для упрощенного вызова сообщений

Вывод диалоговых окон посредством Windows. MessageBox.

Матрицы в Delphi

Алгоритмы матричного исчисления.

Функции для записи и чтение своих данных в, ЕХЕ- файле

Модуль состоит: 1. AppendStringToFile - Дописывает строку к файлу 2. AppendedStringFromFile - Возвращает строку дописаную к файлу процедурой AppendStringToFile

Функции работы со строками

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


Исходники  

Bez BDE

Исходник программы, с помощью которого пользователь может запускать свои базы данных на компьютере без установленного на нем BDE. Для работы исходника требуется установить компонент BDE32 (содержится в исходнике)
Смотреть скриншот

SQL Zapros

Bсходник программы, содержащей в себе набор различных примеров работы с SQL-запросами (фильтрация данных в таблице, сортировка, выборка).
Смотреть скриншот.

Task Alert

Исходник программы, предназначенной для выдачи напоминаний о запланированных задачах. В программе имеется возможность выводить напоминания по расписанию: как раз в день, так и в строго определенное пользователем время.
Программа использует компонент TTrayIcon который находится в файле TrayIcon.pas. Для нормальной компиляции необходимо установить этот компонент.
Смотреть Скриншот

Zlib Compress / Uncompress

Исходник программы-архиватора, предназначенной для архивирования / разархивирования данных с помощью библиотеки zLib
Смотреть скриншот

Simple WinAmp

Исходник программы, показывающей пример создания аудиоплеера. Плеер умеет проигрывать MP3, WMA и MPG форматы
Смотреть скриншот
Для нормальной компиляции исходника требуются компоненты JCL - JEDI.

Verbs

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


Интересные и полезные сайты по Delphi: Если Вы хотите, чтобы Ваш сайт был в этом разделе пишите.

http://www.noil.pri.ee/ - Здесь вы можете почитать статьи, скачать исходники и компоненты, пообщаться на форуме.


Немного юмора:  :))

Сообщение об ошибке Windows, которое я видел своими глазами.
"Невозможно завершить операцию потому что занят Неизвестный"


Математик, физик, инженер и компьютерщик доказывают одну и ту же теорему:
все нечетные числа, большие двух, - простые.
Математик говорит: 3 - простое, 5 - простое, 7 - простое, 9 - не простое.
Это контрпример, значит, теорема неверна.
Физик, с карандашом и бумагой: 3, 5 и 7-простые, 9 - ошибка эксперимента,
11 - простое и т. д.
Инженер, взяв в руки калькулятор: 3 - простое, 5 - простое, 7 - простое, 9
- простое, 11 -тоже простое...
Компьютерщик написал программу и смотрит на экран: 1 - простое, 1 -
простое, 1 - простое, 1 - простое... Да все они простые!


Из жизни ICQ:
Вчера пришлось возвращаться домой в маршрутном такси. Звонит сотовый.
Начинаю говорить. Остальные пассажиры, затаив дыхание, начинают прислушиваться, стараясь не пропустить ни одного слова.
По ходу дела я спрашиваю: "Ты мою аську знаешь?"
В ответ: "Диктуй!"
Я диктую: "167-66-168."
Сидящая рядом миловидная барышня поворачивает на меня изумленное лицо и диким шепотом произносит: "Это что, грудь-талия-бедра?!"


Infernal error: чёрт сломал ногу, пытаясь разобраться в вашем коде


Мудрым пользуйся девизом "Будь всегда готов к релизу"


Мыши плакали, давились, но продолжали жрать коврик.


А у вас котом мышь опознается ?


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

Рассылки Subscribe.Ru
Программирование на Delphi


Все кто хочет изучить Delphi и реально научиться писать свои программы, ЦПИ "Эверест" поможет Вам.
Всё, что Вам нужно это компьютер и доступ к интернету - для получения уроков.

10 причин в пользу платного обучения в ЦПИ "Эверест"…

1. Когда Вы платите деньги- появляется дополнительный стимул против лени: надо учиться, ведь деньги уже уплачены….
2. Учась платно, получаете удобный для Вас график работы.
3. Весь необходимый справочный материал Вы получите в свое время и на русском языке.
4. Используя интернет в качестве бесплатной библиотеки, Вы получаете все ее минусы:

  • трата времени на поиск необходимого материала (а это потерянные деньги и время). А у Вас есть лишние время и деньги?;
  • отсутствие гарантии, что Вы "осилите" данный материал, ведь пишут его, в основном, не педагоги- профессионалы, а программисты- профессионалы, а они пишут для таких же, как они. А Вы программист- профессионал?
  • отсутствие системности в скачиваемом материале (ведь человек, писавший для Вас материал, не знает, чем Вы владеете). А Вы обладаете системой знаний по Delphi?;

5. Стоимость обучения одного месяца в ЦПИ "Эверест" сравнима с ценой хорошей книги. Но часто ли Вам попадались книги, рассчитанные именно на Вас. Мы же работаем индивидуально.
6. Автор книги или магазин не несет никакой ответственности за то, поняли ли Вы материал или нет, мы же закрепляем за каждым курсантом преподавателя, курирующего Вас.
7. Освоив программирование в Delphi - Вы освоите:

  • основы настоящего программирования- структурного и процедурного программирования ;
  • систему работы с базами данных и SQL- запросами, а это одно из самых перспективных направлений в программировании;
  • язык программирования ObjectPascal, что позволит Вам легко перейти, при желании, на С или Паскаль;
  • работу с компьютерной графикой;
  • при желании - основы низкоуровневого программирования ( Ассемблер).

8. А это значит, что …Мы предлагаем получить "высшее образование" - профессию программиста всего за 1 год и 144 доллара, любой ВУЗ попросит в 3 раза больше за один только семестр.
9. Вы получаете самый практический курс в сети, поскольку теория дается только тогда, когда она действительно необходима…
10. Учиться у нас легко и просто. Весь материал доступен и простым людям, не имеющим никогда дел с программированием….


По всем вопросам обращайтесь ко мне.

Если вы встретили в интернете интересный сайт или статью, да и вообще, что угодно связанное с Delphi, поделитесь ссылкой.
Если можете написать статью связанную с Delphi - присылайте с радостью выложу.
Давайте поможем друг другу!  Архив рассылки.

Предложения, критику и пожелания пишите на e-mail.


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

В избранное