Issuu on Google+

VR-online JOURNAL Фленов Михаил and VR-Team

VR-online для программистов №11

Работа с реестром на низком уровне .........................................................................3 WinAPI: Функции работы с файлами..........................................................................6 Новое в Delphi 6.................................................................................................... 13 Delphi: Улучшаем компоненты TShellTreeView .......................................................... 17 Delphi: Наследственность форм .............................................................................. 22 Delphi и базы данных: Очень полезный пример часть 2 ............................................ 24 Visual Basic: Просмотрщик картинок........................................................................ 26 DirectX: Картинки с прозрачным фоном................................................................... 29 Приколы на Delphi................................................................................................. 33 WinAPI: Работа с курсором ..................................................................................... 36

Copyright: VR-online Journal http://www.vr-online.ru


VR-online Journal (Horrific and VR-Team)

Судя по трафику на сайте, каждый день журнал качают по 1000 человек. Да, для онлайнового журнала я считаю это слишком малым, но для любого оффлайного журнала это уже достаточно, потому что в месяц получается цифра в 30000 читателей.

Для программистов №11

VR-online JOURNAL Horrific aka Фленов Михаил

INFO:

Трафик возрос с переходом на отдельный хостинг, смены дизайна и формата журнала. Конечно же, журнал потяжелел, но и рост трафика был громадным. Количество посетителей на сайте также растёт и на форуме уже наблюдается по 70 сообщений в день. Хотя нет, сегодня захожу и вижу, что статистика упала до 33 сообщений. Народ!!! Неужели не о чем говорить? Я даже не могу понять причины такого резкого падения, почти в два раза. Получается, что вы вешаете по одному сообщению в час? Не может быть. Или статистика врёт или я глючу :). Когда было 20-30 сообщений в день, я без проблем успевал просмотреть все эти сообщения и на половину ответить. В те времена моих сообщений за несколько месяцев набралось 666, а тут за пол года и 500 нет. Это значит, что и без меня общения достаточно. После этого возникает вопрос – как можно доверять статистам, которые выводят потенциальных победителей на выборах? Трудно сказать, стоит ли верить статистике… К чему это я? Уже прошли выборы Путина Российской Федерации. Я не ошибся, именно выборы Путина, потому что лучше кандидатуры просто нет. Да, у него есть недостатки – держал плохое правительство, и только перед выборами признал ошибку и разогнал их, но нас стали уважать в мире, нас начинают боятся. Вот ещё бы жить стало легче, но этим пока не пахнет.

ИДЕЯ И РЕАЛИЗАЦИЯ: Флёнов Михаил (Horrific) ГРАФИКА: Фленов Михаил, tr4sh, Slider

VR-Team: Crazy_Script, Del, Demogorgon, Fighter, Mish!, Negus, Spider NET, tr4sh, Slider, Neon_Kaligula INTERNET: WWW: http://www.vr-online.ru E-MAIL: horrific@vr-online.ru ДИЗАЙН САЙТА: tr4sh КОДИНГ САЙТА: Mish!

Данный журнал распространяется в виде PDF файлов. Вы можете выкладывать номера на любые носители без изменения внешнего вида журнала, без перевода в другие форматы, без изменения самого файла. В журнал запрещается вносить изменения. Перепечатка материалов запрещена. Журнал распространяется бесплатно, и ты можешь скачать его с нашего сайта, поэтому мы не смысла в перепечатывании видим материалов. Если ты хочешь стать автором журнала, то присылай свою статью на наш e-mail и мы обязательно включим её в очередной номер.

Жаль, что только дума президентская и кроме коммуны некого противопоставить единству. Так что у нас сейчас монопольное правительство Путина. Фленов Михаил

http://www.vr-online.ru

2


VR-online Journal (Horrific and VR-Team)

Для программистов №11

Работа с реестром на низком уровне Мне уже несколько раз приходили вопросы от программистов Windows NT типа: "Почему, когда я создаю ключи в реестре с помощью TRegIniFile все ключи строковые, хотя я хочу создать целое число". Некоторые думают, что это глюк Delphi, но это не глюк, а специфика TRegIniFile. Если ты хочешь, чтобы твои проги правильно работали с реестром в любой ОС, то эта статья для тебя. Объект TRegIniFile работает с реестром на высоком уровне так, как будто он работает с ini файлом. Если ты не застал Win3.11, то напомню, ini файлы - это файлы конфигурации, которые уже устарели и используются только для совмеситмости со старым софтом. Сейчас для этих целей есть реестр. TRegIniFile - объект, который позволяет работать с реестром как с ini файлом. А так, как файл может содержать только строки, то и объект работает со строками. Так что реально, TRegIniFile все данные сохраняет и читает из реестра в виде строк. Только после чтения строки происходит преобразование в формат указанный тобой. Реестр, в отличии от ini файлов - это база данных. Поэтому она позволяет реально хранить не только строки, но и числа, и данные, и логические операторы. Если ты хочешь, чтобы данные сохранялись и читались в виде типов отличных от строк, то ты должен работать через TRegistry. Он так же объявлен в модуле registry, поэтому ты должен подключать этот модуль в раздел uses. Работа с TRegistry проктически такая же, как и с TRegIniFile: var Reg:TRegistry; begin Reg:=TRegIniFile.Create; //Инициализация Reg.RootKey:=HKEY_LOCAL_MACHINE;//Выбираю корень реестра //По умолчанию это HKEY_CURRENT_USER Reg.OpenKey('SYSTEM', true); //Открываю раздел SYSTEM Reg.OpenKey('CurrentControlSet', true);//Открываю раздел CurrentControlSet Reg.OpenKey('Control', true); Reg.OpenKey('Session Manager', true); Reg.OpenKey('Memory Management', true); //Записываю параметр ClearPageFileAtShutdown Reg.WriteInteger('ClearPageFileAtShutdown', 112); //Читаю параметр Hidden RegIni.ReadInteger('Hidden') Reg.CloseKey;//Закрываю ключ Reg.Free; //Освобождаю объект end; В этом примере чтение и запись будет происходить с числами, а не со строками с последующим преобразованием в число. Всё очень просто, даже больше, чем просто.

http://www.vr-online.ru

3


VR-online Journal (Horrific and VR-Team) Исходников примера сегодня не будет что ты простишь меня ☺.

Для программистов №11

, поэтому придётся писать руками. Надеюсь,

Copyright: Фленов Михаил

http://www.vr-online.ru

4


VR-online Journal (Horrific and VR-Team)

Для программистов №11

Тебя мучает одна проблема, которую ты не можешь решить? Заходи на форум на нашем сайте, подумаем вместе!!! На нашем форуме ты можешь задать любой вопрос и получить ответ по следующим темам: • Программирование (Delphi, JBuilder, C++ Builder, Kylix, Visual C++Visual Basic и другие); • Технологии программирования (сети, мультимедиа, DirectX, OpenGL); • Администрирование; • Операционные системы; • Базы данных (SQL Server, язык SQL и другие); • Железо; • Internet технологии (Perl, PHP, Flash, XML); • Софт; • Сети; Адрес сайта http://www.vr-online.ru

http://www.vr-online.ru

5


VR-online Journal (Horrific and VR-Team)

Для программистов №11

WinAPI: Функции работы с файлами GetDiskFreeSpaceEx Функция возвращает информацию о доступном дисковом пространстве. Существует в: Win NT, Win9x начиная с Win95 OSR2. До этого сущиствовала версия GetDiskFreeSpace, которая не учитывает диски большого размера. Для С/С++ объявлена в winbase.h. Для Delphi в модуле windows. Объявление: Для С/С++ BOOL GetDiskFreeSpaceEx( LPCTSTR lpDirectoryName, // Имя диска PULARGE_INTEGER lpFreeBytesAvailableToCaller,// Здесь вернут количество доступных байт PULARGE_INTEGER lpTotalNumberOfBytes, // Общее количество байт на диске PULARGE_INTEGER lpTotalNumberOfFreeBytes // Здесь вернут количество свободных байт );

Для Delphi function GetDiskFreeSpaceEx( lpDirectoryName: PChar; // Имя диска var lpFreeBytesAvailableToCaller, // Здесь вернут количество доступных байт lpTotalNumberOfBytes; // Общее количество байт на диске lpTotalNumberOfFreeBytes: PLargeInteger // Здесь вернут количество свободных байт ): BOOL; stdcall; Первый параметр содержат имя диска, например 'c:\' или 'D:\'. В остальных параметрах нужно указать переменные типа Int64 (для Delphi), в которые будут помещены данные о диске. Если всё ничтяк, то функция вернёт TRUE

GetCompressedFileSize Функция возвращает сжатый размер файла если он находится на диске поддерживающем сжатие. Если диск не сжат, то функция вернёт актуальное значение размера. Существует в: Win NT Для С/С++ объявлена в winbase.h. Для Delphi в модуле windows.

http://www.vr-online.ru

6


VR-online Journal (Horrific and VR-Team)

Для программистов №11

Объявление: Для С/С++ DWORD GetCompressedFileSize( LPCTSTR lpFileName, // Имя файла LPDWORD lpFileSizeHigh // Сдесь вернут указатель на размер файла );

Для Delphi function GetCompressedFileSize( lpFileName: PChar; // Имя файла lpFileSizeHigh: PDWORD // Сдесь вернут указатель на размер файла ): DWORD; stdcall; В параметре lpFileSizeHigh возвращается только верхние два байта. Нижние два байта вернёт сама функция. Если всё ничтяк, то функция возвращает младшие два байта размера диска, иначе возвращает 0xFFFFFFFF.

GetDriveType Возвращяет тип драйва, такого как диск, CD-ROM, сетевой диск и так далее. Существует в: Win NT, Win32s, Win9x. Для С/С++ объявлена в winbase.h. Для Delphi в модуле windows. Объявление: Для С/С++ UINT GetDriveType( LPCTSTR lpRootPathName // Описатель устройства ); Для Delphi function GetDriveType( lpRootPathName: PChar // Описатель устройства ): UINT; stdcall; В качестве параметра ты можешь передавать буквы диска в виде 'a:\', 'B:\', 'C:\' и такм далее. Если всё нормально, то функция вернёт: 0 - Устройство не определено. 1 - The root directory does not exist. DRIVE_REMOVABLE - переностное устройства (типа дисковвода). DRIVE_FIXED - не переносное устройство (типа жёсткого диска). DRIVE_REMOTE - удалённое стройство (типа сетевого диска). DRIVE_CDROM - CD-ROM, он и в африке .... DRIVE_RAMDISK - диск памяти.

GetFileSize Функция возвращает размер файла. Существует в: Win NT, Win32s, Win9x. Для С/С++ объявлена в winbase.h. Для Delphi в модуле windows.

http://www.vr-online.ru

7


VR-online Journal (Horrific and VR-Team)

Для программистов №11

Объявление: Для С/С++ DWORD GetFileSize( HANDLE hFile, // Указатель на файл LPDWORD lpFileSizeHigh // Здесь вернут старший байт размера файла ); Для Delphi function GetFileSize( hFile: THandle; // Указатель на файл lpFileSizeHigh: Pointer // Здесь вернут старший байт размера файла ): DWORD; stdcall; В параметре lpFileSizeHigh возвращается только верхние два байта. Нижние два байта вернёт сама функция. Если всё ничтяк, то функция возвращает младшие два байта размера файла, иначе возвращает 0xFFFFFFFF.

GetFileType Функция ��озвращает тип файла. Существует в: Win NT, Win32s, Win9x. Для С/С++ объявлена в winbase.h. Для Delphi в модуле windows. Объявление: Для С/С++ DWORD GetFileType( HANDLE hFile, // Указатель на файл ); Для Delphi function GetFileType( hFile: THandle; // Указатель на файл ): DWORD; stdcall; Функция возвращает тип файла. Если всё ничтяк, то результатом будет: FILE_TYPE_UNKNOWN - тип файла не определён FILE_TYPE_DISK - простой дисковый файл FILE_TYPE_CHAR - консольный файл или LPT-устройство FILE_TYPE_PIPE - именованный или анонимный канал.

GetLogicalDrives

Функция возвращает маску доступных дисков Существует в: Win NT, Win32s, Win9x. Для С/С++ объявлена в winbase.h. Для Delphi в модуле windows. Объявление: Для С/С++ DWORD GetLogicalDrives(VOID) Для Delphi function GetLogicalDrives: DWORD; stdcall;

http://www.vr-online.ru

8


VR-online Journal (Horrific and VR-Team)

Для программистов №11

Функции не нужны параметры. Она возвращает маску доступных в системе дисков. Пример использования функции на Delphi: var ct: byte; drives: set of 0..25; begin integer(drives) := GetLogicalDrives; for ct := 0 to 25 do if ct in drives then begin Драйв по имени "char(ct + ord('A')) + ':\'" существует. Можно выполнить операцию: Добавить_в_Список_драйвов(char(ct + ord('A')) + ':\'); end;

GetShortPathName Возвращает укороченный путь к файлу (без использования длинных имён, как в старом добром DOS). Существует в: Win NT, Win32s, Win9x. Для С/С++ объявлена в winbase.h. Для Delphi в модуле windows. Объявление: Для С/С++ DWORD GetShortPathName( LPCTSTR lpszLongPath, //Указатель на длинный путь к файлу LPTSTR lpszShortPath, // Сюда поместять результат DWORD cchBuffer // Длинна буфера, куда поместят результат ); Для Delphi function GetShortPathNameA( lpszLongPath: PAnsiChar; //Указатель на длинный путь к файлу lpszShortPath: PAnsiChar;// Сюда поместять результат cchBuffer: DWORD // Длинна буфера, куда поместят результат ): DWORD; stdcall; Если всё ничтяк, то функция вернёт длинну строки lpszShortPath, где будет находится короткий путь к файлу.

GetTempPath Возвращает путь к директории, в которой хранятся временные файлы. По умолчанию это c:\Windows\Temp. Существует в: Win NT, Win32s, Win9x. Для С/С++ объявлена в winbase.h. Для Delphi в модуле windows. Объявление: Для С/С++ DWORD GetTempPath( DWORD nBufferLength, // Размер буфера LPTSTR lpBuffer // Буфер ); Для Delphi

http://www.vr-online.ru

9


VR-online Journal (Horrific and VR-Team)

Для программистов №11

function GetTempPath( nBufferLength: DWORD;// Размер буфера lpBuffer: PChar // Буфер ): DWORD; stdcall; Если всё ничтяк, то функция вернёт длинну строки содержащей путь. Сам путь будет находится в буфере (второй параметр).

GetVolumeInformation Получение информации о диске. Существует в: Win NT, Win32s, Win9x. Для С/С++ объявлена в winbase.h. Для Delphi в модуле windows. Объявление: Для С/С++ BOOL GetVolumeInformation( LPCTSTR lpRootPathName, // Какой диск LPTSTR lpVolumeNameBuffer, // Буфер для имени метки DWORD nVolumeNameSize, // Размер буфера метки LPDWORD lpVolumeSerialNumber, // Серийный номер LPDWORD lpMaximumComponentLength,// Максимальная длинна компонентов LPDWORD lpFileSystemFlags, // Системные флаги LPTSTR lpFileSystemNameBuffer,// Буфер имени файловой системы DWORD nFileSystemNameSize // Размер буфера имени файловой сист. ); Для Delphi function GetVolumeInformationA( lpRootPathName: PAnsiChar; // Какой диск lpVolumeNameBuffer: PAnsiChar;// Буфер для имени метки nVolumeNameSize: DWORD; // Размер буфера метки lpVolumeSerialNumber: PDWORD; // Серийный номер var lpMaximumComponentLength, // Максимальная длинна компонентов lpFileSystemFlags: DWORD; // Системные флаги lpFileSystemNameBuffer: PAnsiChar;// Системные флаги nFileSystemNameSize: DWORD // Размер буфера имени файловой сист. ): BOOL; stdcall; Просто передай в качестве первого параметра имя диска (например 'C:\') и получи кучу инфы про этот диск.

MoveFile Переместить существующий файл на новое место. Существует в: Win NT, Win32s, Win9x. Для С/С++ объявлена в winbase.h. Для Delphi в модуле windows. Объявление: Для С/С++ BOOL MoveFile( LPCTSTR lpExistingFileName, // Полный путь к исходному файлу LPCTSTR lpNewFileName // Полный путь к новому месту );

http://www.vr-online.ru

10


VR-online Journal (Horrific and VR-Team)

Для программистов №11

Для Delphi function MoveFile( lpExistingFileName, // Полный путь к исходному файлу lpNewFileName: PChar// Полный путь к новому месту ): BOOL; stdcall; Если все нормально, то функция возвражает TRUE. Пример на Delphi: MoveFile('c:\Temp.txt', 'C:\Windows\Temp.txt') Эта команда переместит файл c:\Temp.txt в C:\Windows\Temp.txt, при этом он удалится из исходного месторасположения. Ну всё, на сегодня хватит. В следующий раз закончим расмотрение API функций работы с файлами. Copyright © Фленов Михаил

http://www.vr-online.ru

11


VR-online Journal (Horrific and VR-Team)

Для программистов №11

Реклама в журнале VR-online Почему вы обязаны разместить рекламу на страницах VRonline:

4. 5. 6. 7.

1. Таких низких цен вы не видели ни где. 2. У нас располагается нестареющая информация. Которая будет актуальна всегда. 3. Вы имеете возможность пожизненно расположить свой банер на наших страницах по самым низким ценам. Пожизненность гарантируется в не зависимости от роста числа посещаемости. У нас есть потенциал для роста, как в объемах страниц, так и в посещаемости. Наши материалы очень часто сохраняются на дисках посетителей. Ваша реклама будет доступна в любых вариантах журнала. Журнал распространяется не только с сайта VR-online, но и другими сайтами и даже на CD, поэтому тираж огромен.

Если вы собираетесь рекламировать не просто сайт в интернете, а компанию, которая занимается информационными технологиями, то ваша дорога лежит сюда. Это лучшее рекламное место, которое можно найти в сети. Торопитесь такие цены не надолго. Расценки на размещение рекламы на страницах VR-online: • Банер 100х100 на главной странице сайта в течении месяца-$25 • Банер 468х60 на главной странице сайта в течении месяца-$30 • Банер 100х100 на странице оглавления на сайте 1-го номера (пожизненно)-$25 • Банер 468х60 на странице оглавления на сайте 1-го номера (пожизненно)-$30 • Страница в журнале-$200 • Половина страницы в журнале-$100 • Банер на странице статьи журнала.-$50

http://www.vr-online.ru

12


VR-online Journal (Horrific and VR-Team)

Для программистов №11

Новое в Delphi 6 В этой статье я раскажу про некоторые новые компоненты и как ими пользоваться. Я буду рассматривать только простые компоненты не связанные с интернетом и базами данных, потому что эти вопросы за одну статью не опишешь. Тем более, что работа с базой данных изменилась очень сильно.

Рис. 1 Рабочая форма. На рисунку 1 показана рабочая форма проги, с которой мы будем сегодня играть. На форме у меня находяться основные компоненты: • • • •

TValueListEditor c палитры Additional TColorBox c палитры Additional TLabeledEdit c палитры Additional TComboBoxEx c палитры Win32

Установи их на форму, можешь это сделать так же, как и я. Давай рассмотрим эти компоненты в отдельности. ТValueListEditor - очень удобный компонент для редактирования различных свойств. В моём примере я в качестве свойств задал "человеческие" параметры, такие как ФИО, адрес, телефон ... Они теперь очень удобно располагаются и для пользователя их удобно редактировать. Рассмотрим основные свойства. В дезайнере тебе доступны несколько интересных вещей:

http://www.vr-online.ru

13


VR-online Journal (Horrific and VR-Team) •

• • •

Для программистов №11

TitleCaptions - имена заголовков. Щёлкни дважды по этому свойтству и ты увидешь простой текстовый редактор, в котором можешь изменять, добавлять и удалять имена заголовков. Я ввёл там только два заголовка - "свойство" и "значение". FixedColor - Цвет фиксированной колонки. FixedCols - Индекс фиксирванной колонки. По умолчанию стоит 0, т.е. фиксированной колонки нет. Измени это значение на 1, чтобы сделать первую колонку фиксированной. Strings - Имена свойств. Здесь я уже забил кучу значений: o Фамилия o Имя o Отчество o Ник o Год рождения o Место рождения o Адрес o Телефон

Больше в дезайнере пока нет ничего особо заслуживающего нашего внимания. Теперь давай немного поШкодим. Создай обработчик события для формы OnShow. В нём мы напишем следующее: procedure TForm1.FormShow(Sender: TObject); begin ValueListEditor1.ItemProps[6].EditStyle:=esPickList; ValueListEditor1.ItemProps[6].PickList.Add('Москва'); ValueListEditor1.ItemProps[6].PickList.Add('Питер'); ValueListEditor1.ItemProps[6].PickList.Add('Ростов-на-Дону'); end; У компонента ТValueListEditor есть свойство ItemProps, в котором можно указывать свойство любой строки. Я изменяю свойство шестой строки (это у меня адрес) с помощью ValueListEditor1.ItemProps[6]. У ItemProps есть свойство EditStyle, которое указывает, как будет выглядить строка в режиме редактирования. В первой строке моего кода я изменяю режим редактирования шестой строки на esPickList. Это означает, что у меня свойство будет редактироватся в виде выпадающего списка (когда пользователь щёлкнет по строке, появится Combobox). Ты такое уже должен был видеть в объектном инспекторе Delphi. Остальные строки заполняют выпадающий список. Отлично, маленький редактор свойств почти готов. Теперь выдели его и создай для него обработчик события OnGetEditMask. Тут я написал: procedure TForm1.ValueListEditor1GetEditMask(Sender: TObject; ACol, ARow: Integer; var Value: String); begin if ARow=5 then Value:='99/99/9999'; end; Это событие вызывается каждый раз, когда какой-нибудь строке нужна масска ввода. Я проверяю, если это пятая строка (год рождения), то я задаю маску присваивая её переменной Value, передаваемой мне в качестве параметра функцией обработчиком события.

http://www.vr-online.ru

14


VR-online Journal (Horrific and VR-Team)

Для программистов №11

Параметры задания маски такие же, как и для компонента TMaskEdit. Если ты ни разу не работал с массками, то '99/99/9999' означает, что на месте цифры 9 может быть любое число, а разделитель "/" будет ставится автоматически. "/" - разделитель даты, и в Windows по умолчанию он меняется на точку. Теперь посмотрим на TTColorBox. В принципе, это простейший ComboBox, который отображает цвета. Давай создадим для него обработчик события OnChange, чтобы прочитать знечение выделенного цвета: procedure TForm1.ColorBox1Change(Sender: TObject); begin ValueListEditor1.Font.Color:=ColorBox1.Selected; end; По событию OnChange (выделенный цвет изменился) я присваиваю выделенный цвет ColorBox1.Selected в значение цвета шрифта компонента ValueListEditor1. Это значит, что цвет текста в ValueListEditor1 изменится на выделенный. В принцепе с цветным ComboBox больше нечего мусолить. Он прост как три копейки. Давай перейдём в ComboBoxEx1. У этого компонента есть свойство ItemsEx. щёлкни дважды по нему и перед тобой появится окно для создания элементов ComboBoxEx1. В этом окне нажми клавишу на клавиатуре "Ins" и создастся новый элемент. В объектном инспекторе ты можешь указать его заголовок (Caption), картинку (ImageIndex) и ещё несколько параметров, которыми ты будешь пользоватся очень редко. Вот и всё. Остался только LabeledEdit. У него все свойства похожи на TEdit. Все свойства относящиеся к заголовку находятся в свойстве EditLabel. Щёлкни по нему дважды и ты увидешь свойства схожие с TLabel. Copyright © Фленов Михаил aka Horrific

http://www.vr-online.ru

15


VR-online Journal (Horrific and VR-Team)

Для программистов №11

Программирование в Delphi глазами хакера Автор: Фленов Михаил aka Horrific Из книги ты узнаешь: • Кто такой Хакер и как им стать; • Как создавать программы маленького размера; • Как оптимизировать код программы; • Как заставить летать кнопку «Пуск»; • Научишься контролировать системную палитру; • Научишься изменять разрешение экрана из своих программ; • Увидишь множество шуточного кода; • Узнаешь, как подсматриваем пароли, спрятанные под звездочками; • Напишешь программу мониторинга запускных файлов и клавиатурный шпион; • Сможешь портить окна чужих программ; • Как создавать окна неправильной формы; • Научишься работать с сетью через компоненты Delphi и увидишь как создаются сканеры портов, утилиты ping и др. • Узнаешь, как работать с сетью на уровне библиотеки WinSock; • Узнаешь, как работать с железом И многое другое. Посмотри на содержимое диска, и ты поймёшь, что он стоит того, чтобы купить эту книгу с диском: \Headers - Все необходимые заголовочные файлы, которые нужно будет подключать к Delphi для компиляции некоторых примеров \Source - Исходные коды своих простых программ, чтобы вы могли ознакомиться с реальными приложениями. Их немного, но посмотреть стоит. \Soft - Инсталляционный пакет программы Adobe Acrobat Reader v5.0. Если у вас нет этой программы, то вы должны её установить, чтобы можно было читать документацию, расположенную на диске. \Vr-online - Полная копия сайта автора, а это 100 мегабайт документации, полезной информации, исходных кодов и компонентов. Здесь же вы можете найти мою книгу "Библия Delphi" - в электронном виде. В ней вы найдёте все необходимые для понимания этого материала основы и если вы ещё ни разу не видели Delphi, то после прочтения этой книги вы сможете понять всё описанное здесь. \Документация - Дополнительная документация, которая может понадобиться для понимания каких-то глав. \Иконки - В этой директории вы найдёте большую коллекцию иконок, которые вы можете использовать в своих программах. Эту коллекцию я подбирал достаточно долго и все иконки хорошего качества. \Компоненты - Дополнительные компоненты, которые будут использоваться в примерах книги. \Программы - Программы, которые пригодятся в программировании. Среди них Header Convert - программа, которая конвертирует заголовочные файлы с языка С на Delphi и ASPack - программа сжатия запускных файлов. Спрашивай книгу в книжных магазинах своего города!!!

http://www.vr-online.ru

16


VR-online Journal (Horrific and VR-Team)

Для программистов №11

Delphi: Улучшаем компоненты TShellTreeView В Delphi6 появилось несколько инетерных компонентов: TShellTreeView, TShellComboBox и TShellListView. Они прекрасно подходят для встраивания в твою прогу различных просмотрщиков, пролистывальщиков каталогов и файлов. Но в них заложены ны все необходимые возможности. Сегодня я покажу, как улучшить эти компоненты. Как я уже сказал во вступлении к этому номеру, в конце июля я уезжаю в Москву. В настоящий момент, а именно сейчас, когда я набираю текст этого документа, я нахожусь в поезде и до Москвы осталось 3 часа езды. Именно так. Я пишу статью прямо в поезде используя свой notebook с процем pentium2. Хотя он не мой, мне его одолжили на время поездки, чтобы я смог работать. Но теперь я влюбился в эту игрушку и когда-нибудь обязательно куплю себе. Ну ладно, не буду тратить время аккумуляторов, постараюсь как можнобольше написать. А когда приеду в гостиницу закончу начатую статью. Как я уже сказал, в составе Delphi есть несколько полезных компонентов. Их функциональность можно расширить за счёт того, что они поставляются в исходниках. Можно конечно воспользоватся наследственностью объектно-ориентированного программированияи вывести потомков. Потом можно наелить их новыми свойствами. Я решил поступить по другому, а просто изменил исходники и перекомпилировал их. Прежде чем приступать к коду, нужно удалить из Delphi уже установленные варианты компонентов. Это необходимо, потому что они встроены не из исходников, а из рантайм файлов. Это значит, что если ты модифицируешь исходники и попробуешь установить их в Delphi, то произойдёт ошибка. Delphi скажет, что у него уже есть такие компоненты, и не может установть ещё одни, с такими же именами. Удаление происходит достаточно просто. Для этого закрой в Delphi все проекты File-> Close All (просто на всякий случай). После этого выбери меню Project->Options... Перед тобой появится окно настроек проекта по умлчанию. Перейди на закладку Packages и найди в списке строку "Shell ControlProperty and Component Editors", убери галочку напротив этой строки и потом нажми кнопку "Remove". Всё, теперь в Delphi Нет этих компонентов. Теперь найди директорию Delphi6 (Диск:\Program files\Borland\Delphi6\). Здесь есть директория Demos. Если ты во время установки отказался от установки примеров, то вставь диск с Delphi и ищи эту папку здесь "Диск CD:\Install\Program files\Borland\Delphi6\". В папке Demos ты найдёшь другую интересную папку "ShellControls". Вот здесь и есть исходники этих компонентов. Точнее сказать. Здесь уже есть пакет включающий в себя исходники. Мы не будем использовать уже готовый пакет, а создадим новый. Для этого выбери меню Component->Install Component. Перед тобой появится окно, как на рис 1. В этом окне перейди на закладку "Into new package" (В новый пакет).

http://www.vr-online.ru

17


VR-online Journal (Horrific and VR-Team)

Для программистов №11

Рис 1. Создание нового пакета Теперь напротив первой строки ("Unit file name") щёлкни кнопку "Browse". Появится окно открытия файла. Выбери файл ShellCtrls.pas (он находится в директории "ShellControls" демонстрашек). Едем дальше. Щёлкни напротив третей строки (Package file name) пимпу Browse. Опять будет окно открытия файла. Перейди в директорию демонстрашек, в папку "ShellControls", где находятся файлы исходников нужных нам компонент. Введи какоенибудь имя (я ввёл CyDshell.dpk) и нажми "Открыть". Всё. Все поля заполнены. Можешь жать "ОК". Перед тобой появится окно нового пакета (рис 2). Внутри окна будет имя только одного файла (ShellCtrls.pas). Дважды щёлкни по нему, чтобы увидеть его содержимое. Если ты сейчас попытаешься проинсталировать этот пакет, то в Delphi ничего нового не появится. Это потому, что код регистрации компонентов находится в другом файле. Давай внесём этот код в файл ShellCtrls.pas, чтобы не пришлось подключать другие файлы. Для этого найди строку с Рис 2. Окно нового пакета текстом "implementation" и добавь перед ней строку: procedure Register; //Объявляю процедуру Register implementation Этим я объявил процедуру Register - стандартная процедура, в которой пишется код регистрации компонентов. Теперь напишем саму процедуру:

http://www.vr-online.ru

18


VR-online Journal (Horrific and VR-Team)

Для программистов №11

procedure Register; begin RegisterComponents('CyD', [TShellTreeView]); RegisterComponents('CyD', [TShellComboBox]); RegisterComponents('CyD', [TShellListView]); end; Внутри процедуры три строчки длч регистрации трёх компонентов TShellTreeView, TShellComboBox и TShellListView. Я написал этот код в конце файла перед строкой со словом "initialization". Вообще-то непомешало бы объяснить, что означает строка "initialization". Хотя это мы не будем сегодня использовать, я решил объяснить. В принципе все просто: initialization Здесь находится код, который выполняется при старте модуля. То есть при первом обращении к любому из содержащимуся в модуле компоненту. При втором обращении к компоненту или другому компоненту код вызыватся не будет. finalization Здесь находится код, который выполняется после уничожения последней ссылки на компонент содержащийся в модуле, то есть в самом конце. end. Обрати внимание, что после слова initialization ты не можешь релизовывать процедуры. Все процедуры и функции должны находится до этого слова. Концом конструкции initialization и finalization является конец модуля, т.е. слово "END.". Но это всё небольшое полезное отступление. Теперь вернёмся к нашим баранам. Посмотрим на компонент TCustomShellListView:

TShellListView.

Он

происходит

от

компонента

TShellListView = class(TCustomShellListView) В свою очередь, TCustomShellListView происходит от TCustomListView. Это значит, что TShellListView должен обладать всеми свойствами TCustomListView, плюс свои новые свойства (это правило наследования Объектно-ориентированного программирования). Но это не совсем так. Почему-то разработчики наследовали не все возможности. Например, отсутствует HotTrackStyles. Мы можем сами добавить это свойство. Просто добавь строку "property HotTrackStyles;" в объявления объекта TShellListView. Например так: TShellListView = class(TCustomShellListView) published property HotTrack; property HotTrackStyles; property OnSelectItem; property AutoContextMenus; .... ....

http://www.vr-online.ru

19


VR-online Journal (Horrific and VR-Team)

Для программистов №11

Всё. Мы добавили новое свойство. Больше ничего добавлять не надо, потому что это свойство уже реализовано у предка TCustomListView. Весь код теперь унаследуется автоматически. Исходники находятся в файле Delphi.zip. Copyright © Фленов Михаил

http://www.vr-online.ru

20


VR-online Journal (Horrific and VR-Team)

Для программистов №11

Ты ищешь хорошую книгу по Delphi? Зайди на www.vr-online.ru и скачай полный электронный вариант Библии Delphi от Фленова Михаила абсолютно бесплатно. Эта книгу научит тебя программировать, даже если ты никогда в жизни не написал ни строчки кода. В ней описано всё, начиная от основ программирования и заканчивая реальными примерами программ и задач, которые программисты решают каждый день. Библия Delphi – самая иллюстрированная и самая бесплатная книга. По ней научились программировать множество людей и ты тоже сможешь. ТЕПЕРЬ ТЫ МОЖЕШЬ КУПИТЬ ПОЛНЫЙ ВАРИАНТ КНИГИ (РАСШИРЕННЫЕ И ДОРАБОТАННЫЙ) В КОМПЬЮТЕРНОМ МАГАЗИНЕ СВОЕГО ГОРОДА). Если в магазинах твоего города ещё нет этой книги, то заходи на наш сайт и ты узнаешь, где её можно заказать в Интернете.

http://www.vr-online.ru

21


VR-online Journal (Horrific and VR-Team)

Для программистов №11

Delphi: Наследственность форм Сегодня я решил вернутся к вопросу наследственности. Это достаточно сложная тема, поэтому я решил показать тебе наследственность на примере форм. После этого у тебя отпадёт громадное количество вопросов, и ты убедишься в можности визуализации Delphi. Создай новый проект. Брось на форму две кнопки. На одной напиши "Главное окно", на другой "Дочернее окно". Посмотри на рисунок 1, где показана моя форма. Сделай чтонибудь подобное. Теперь создадим ещё одну форму. Для этого выбери меню File->New- Рис 1. Главная форма >Form. На форму брось несколько компонентов TLabel, несколько TEdit и кнопку. Я выстроил это, как на рисунке 2. Это у нас будет основная форма. Имя формы оставлю по умолчанию (Form2). Сейчас мы выведем из неё дочернюю форму. Для этого выбери из меню File->New (для Delphi6 это File->New>Other) смотри на рисунок 3. Перед тобой появится окно создания новой формы. Перейди на закладку с именем твоего проекта. Здесь щёлкни дважды по форме 2 (Form2). Этим ты создашь новую форму, дочернюю к Рис 2. Вторая форма Form2. Это значит, что она будет обладать всеми свойствами своей главной формы, плюч с новые возможности.

Рис 3. Создание новой формы

http://www.vr-online.ru

22


VR-online Journal (Horrific and VR-Team)

Для программистов №11

Теперь попробуй поигратся с формами. Если ты на форму 2 (Form2) поставишь ещё какой-нибудь компонент, то форма 3 (Form3) сразу наследует этот компонент. Если ты напишешь какой-нибудь код по событию на нажатие кнопки в главной форме (Form2), то дочерняя форма (Form3) моментально получит те же свойства. Хотя в дочерней форме ты не увидешь этого кода, потому что они наследуются. В то же время, если ты в дочерней форме напишешь какой-нибудь код для той же кнопки, то старый код уже не будет наследоватся и выполняться. Это уже называется переопределение методов. То есть на одни и те же события, родственные формы могут отвечать одинаково, а могут и по разному, если в дочерней форме тот же метод реализован по другому. В то же время, ты можешь добавлять новые свойства дочерней форме, на главной они появлятся не будут. Так ты можешь ставить новые кнопки и писать новый код. Поиграй с формами, напиши какой-нибудь код. Ты долен окончательно разобратся с наследственностью. Это действительно сильная вещь. Исходники примера смотри в файле delphi1.zip Copyright © Фленов Михаил aka Horrific

http://www.vr-online.ru

23


VR-online Journal (Horrific and VR-Team)

Для программистов №11

Delphi и базы данных: Очень полезный пример часть 2 Я продолжаю улучшать мой пример работы с базой данных. Сегодня в нём тебя ожидает очень много интересного. Примерчик преобразится и станет на много лучше. Сегодня я добавлю в него кардинально новые вещи.

Рис. 1 DataModule. Прежде всего я добавил в DataModule два компонента - DataSource и ADOTable дава им имена DataSourceТ и ADOTableТ. ADOTableТ я подвязал к нашей базе и указал таблицу "Справочник городов", и сделал её активной. Ну и само собой связал компоненты DataSourceТ и ADOTableТ, чтобы можно было отображать данные содержимого таблицы. На рисунке 1 ты можешь видеть обновлённое окно DataModule. Второе действие - я создал окно для редактирования содержимого таблицы "Справочник городов". Название окна я не стал менять, так что его имя Form5. Я создал ворму и бросил на неё только лишь один компонент DBGrid, и подвязал его к таблице ADOTableT. Только не забудь подключить к новой форме модуль Unit2, иначе ты не сможешь подвязать. На рисунке 2 показано окно этой формы.

Рис. 2 Новое окно.

http://www.vr-online.ru

24


VR-online Journal (Horrific and VR-Team)

Для программистов №11

После этого я вернулся к главной форме. Добавил одну кнопку на панель инструментов, и по её нажатию написал вызов окна редактирования новой таблицы: procedure TForm1.ToolButton1Click(Sender: TObject); begin Form5.ShowModal; end; Едем далее. Я создал ещё одно окно, которое буду использовать для редактирования строк в главной таблицы. Его вид показан на рисунке 3. Я не буду расписывать, как я его сделал, потому что ты и так должен догадаться, мы уже не раз такое проделывали. Если что-то неясно, посмотришь в исходнике.

Рис. 3 Окно для редактирования. Единственное, что я хочу объяснить - это поле для редактирования поля "Город". Для него стоит компонент ТDBLookupComboBox. Я установил у него следующие свойства: • • • • •

DataSource = DataModule2.DataSource1. DataField = Город KeyField = Key1 ListField = Город ListSource = DataModule2.DataSourceT

Первые два поля указывают на поле "Город" в главной таблицы. Поле ListSource указывает на таблцу "Справочник городов", эта таблица будет использоваться в качестве данных в выпадающем списке. Полем указанном в ListField будет заполнен выпадающий список. Поле указанное в KeyField будет использоватся в качестве связующего. Эти параметры делают следующее. Выпадающий список заполняется данными поля "Город" таблицы "Справочник городов". Когда ты выберешь какое-то поле из выпадающего списка, значение поля указанного в KeyField будет записано в поле указанное в поле DataField. Вызов этого окна я сделал по двойному щелчку по DBGrid главного окна и по событию AfterInsert главной таблицы. Для создания второго сообщения я выделил компонент ADOTable1 и создал его на закладке Event. Теперь после создания новой строки автоматически будет появлятся созданное мной окно редактирования. Попробуй запусти пример и посмотри на результат. Исходники примера можете взять в файле delphi4.zip. Copyright © Фленов Михаил aka Horrific

http://www.vr-online.ru

25


VR-online Journal (Horrific and VR-Team)

Для программистов №11

Visual Basic: Просмотрщик картинок Статья расчитана на начальный и средне-начальный уровень. Все желающие после прочтения статьи организовать свою компанию MacroHard для создания эксклюзивного супер-гипер-мега софта круто обломаются. Моя цель при написании статей - научить новичков основам языка.Как раз написание софта помогает постигать эти основы. Желающим узнать побольше могу посоветовать RTFM. Читайте HELP, доки на сайтах, спрашивайте в техподдержке (маловероятно, что вам ответят что-то стоящее - я пробовал), у более опытных кодеров. Например наша группа [DLC] специализируется в программировании на написании софта для работы с графикой и с Inet'oм. Вполне возможно, что через некоторое время на нашем сайте появятся серьёзные статьи по этим темам. Часть 2. Смотрелка картинок. Цель : написать программу просмотра графических изображений(jpg,bmp, gif,ico,cur,emf,wmf). На этот раз ограничимся стандартными компонентами.Расположим на форме компоненты DrivelistBox,DirlistBox,FilelistBox,Image и PictureBox как показано на скрине,причем Image поместим на PictureBox(у них должен быть общий левый-верхний угол).У меня помимо этого используются компоненты HScroll и VScroll (но это не обязательно). Также добавим вторую форму (Project-Add Form).Первая форма будет главной, вторая вспомогательной. На второй форме разместим всего одну кнопку.Два раза шёлкнем на ней и напишем в появившемся окне. Form1.Show Unload me

Этот код загрузит первую форму и уберёт вторую. С помощью этого очень легко делать кнопочные меню с выбором форм. В первой форме изменим некоторые св-ва. Например Caption - по усмотрению (JPGviewer), у PictureBox background=black и у FileListBox pattern= *.bmp;*.jpg. Сюда можно дописать и другие графические форматы.

http://www.vr-online.ru

26


VR-online Journal (Horrific and VR-Team)

Для программистов №11

Теперь приступим собственно к кодингу : Private Sub Dir1_Change() File1.Path = Dir1.Path 'Выводим список файлов в директории End Sub Private Sub Drive1_Change() On Error GoTo fuck Dir1.Path = Drive1.Drive 'Выводим список директорий на диске Exit Sub fuck: Dir1.Path = File1.Path MsgBox Err.Description, vbCritical, "Error" End Sub Private Sub File1_Click() Image1.Left = 0 Image1.Top = 0 HScroll1 = 0 VScroll1 = 0 Image1.Picture = LoadPicture(File1.Path & "\" & File1.filename)' Загрузка картинки If Image1.Width > Picture1.Width Then ' Дальше следуют операторы работы с HScroll1.Max = Image1.Width - Picture1.Width 'размерами и положением картинки на экране. HScroll1.Enabled = True Else HScroll1.Enabled = False End If If Image1.Height > Picture1.Height Then VScroll1.Max = Image1.Height - Picture1.Height VScroll1.Enabled = True Else VScroll1.Enabled = False End If End Sub Private Sub HScroll1_Change() Image1.Left = -HScroll1 End Sub Private Sub VScroll1_Change() Image1.Top = -VScroll1 End Sub

После этого программу можно компилировать.

http://www.vr-online.ru

27


VR-online Journal (Horrific and VR-Team)

Для программистов №11

Как всегда улучшенная версия на http://www.dlc.hut.ru. Правда она будет доступна где-то в конце августа Copyright © U1traDIMM

http://www.vr-online.ru

28


VR-online Journal (Horrific and VR-Team)

Для программистов №11

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

Рис 1. Фон На рисунке 1 пок��зана картинка, которая будет использоватся в качестве фона. Её я уже использовал в прошлом примере и регулярно буду использовать в будущем. Поверх этой картинки будет выведен спрайт указанный на рисунке 2. Сегодня я не буду писать новую прогу, а воспользуюсь предыдущим примером улучшив его код. Поэтому, если ты повторяешь за мной и пишешь код сам, то открой предыдущий пример. Если нет, то ты сможешь, как всегда, скачать готовые исходники в конце статьи. Итак, приступим. Идея примера следующая. Всё так же выводится фон в виде рисунка. Картинка указанная на рисунке 2 будет выводится как прозрачная. В Рис 2. качестве прозрачного цвета я выбрал розовый (кажется, я не дальтоник, но названия цветов не знаю :)), потому что он очень редко используется в растрах. Некоторые любят использовать чёрный, но он слишком распространённый и я тебе не советую это делать.

http://www.vr-online.ru

29


VR-online Journal (Horrific and VR-Team)

Для программистов №11

Картинка с прозрачным фоном будет выводится в текущей позиции курсора, то есть вместо него. Сам курсор я спрячу, чтобы его вообще не было видно. Таким образом я покажу тебе, как выводить картинки с прозрачным фоном и как самому сделать свой курсор. Итак, приступим к кодингу. Открывай пример из предыдущей статьи и читай дальше (или качай пример в конце этой статьи и читай дальше, чтобы разобраться с происходящим). Для начала нам понадобится несколько новых переменных. В разделе private добавь следующее: private { Private declarations } //Новые переменные FTransparentImage : IDirectDrawSurface7; MouseX, MouseY : Integer; //Дальше идут объявления уже использованных нами переменных FDirectDraw : IDirectDraw7; FPrimarySurface : IDirectDrawSurface7; FBackGround : IDirectDrawSurface7; //И так далее FTransparentImage - эта поверхность будет использоваться для хранения картинки с рисунка 2. MouseX и MouseY - эти переменные будут хранить текущее положение курсора. Теперь в самом начале обработчика события OnCreate нужно обнулить все новые переменные: FTransparentImage := nil; MouseX:=0; MouseY:=0; Теперь перейдём в конец этого обработчика. В самый конец добавляй следующее: //Это у тебя уже должно быть. Этот текст я просто для напоминания. //Здесь мы получали вторичную поверхность. FillChar(fcaps, SizeOf(fcaps), 0); fcaps.dwCaps := DDSCAPS_BACKBUFFER; hRet := FPrimarySurface.GetAttachedSurface(fcaps, FBackGround); if hRet <> DD_OK then begin ErrorOut(hRet); Close; Exit; end; //А вот дальше идёт новый текст. //Это я загружаю вторую картинку. Это делается так же, как я загружал фон. FTransparentImage := DDLoadBitmap(FDirectDraw, 'bart.bmp', 0, 0); if FTransparentImage = nil then begin ErrorOut(hRet); Close; Exit; end; //Устанавливаю прозрачный цвет.

http://www.vr-online.ru

30


VR-online Journal (Horrific and VR-Team)

Для программистов №11

DDSetColorKey (FTransparentImage, RGB(255, 0, 255)); if hRet <> DD_OK then begin ErrorOut(hRet); end; //Прячу курсор. Функции для работы с курсором //описаны в этом же номере в статье "WinAPI". ShowCursor(false); Здесь есть одна новая функция - DDSetColorKey. Она устанавливает прозрачный цвет в картинке. Первым параметром передаётся поверхность содержащая картинку. Второй параметр - цвет, который будет использоватся в качестве прозрачного. Я его задаю в качестве трёх составляющих: RGB(Красный, Зелёный, Голубой). В обработчике события OnDestroy нужно добавить уничтожение поверхности второй картинки и снова показать курсор: procedure TForm1.FormDestroy(Sender: TObject); begin //Уничтожаю вторую картинку. if Assigned(FTransparentImage) then FTransparentImage := nil; //Далее всё уже знакомо. if Assigned(FImageSurface) then FImageSurface := nil; if Assigned(FBackGround) then FBackGround := nil; if Assigned(FPrimarySurface) then FPrimarySurface := nil; if Assigned(FDirectDraw) then FDirectDraw := nil; //Включаю курсор. ShowCursor(true); end; И вот тут мы подошли к самому вкусненькому - рисование. Заходим в обработчик события OnPaint. Там у нас сейчас должно быть следующее: //В начале идёт закрашивание экрана и проверка на потерянность //поверхностей. //Не забудь добавить восстановление поверхности со второй картинкой. //Я это опускаю, потому что это делается так же, как и с первой. //Это вывод на экран фона (первый рисунок) FBackGround.BltFast (175, 75, FImageSurface, nil, DDBLTFAST_WAIT); //Переключение поверхности FPrimarySurface.Flip(nil, DDFLIP_WAIT); end; После вывода фона и перед переключением поверхности нам нужно вывести нашу вторую картинку, чтобы она оказалась наверху: FBackGround.BltFast (175, 75, FImageSurface, nil, DDBLTFAST_WAIT); //Выводим вторую картинку. FBackGround.BltFast(mouseX-20, mouseY-47, FTransparentImage, nil, DDBLTFAST_WAIT or DDBLTFAST_SRCCOLORKEY); FPrimarySurface.Flip(nil, DDFLIP_WAIT); end; Для вывода второй картинки я использую ту же функцию BltFast. Я её уже расписывал. Единственное, что изменилось - в флагах добавился параметр DDBLTFAST_SRCCOLORKEY. Он говорит о том, что нужно учитывать прозрачный цвет

http://www.vr-online.ru

31


VR-online Journal (Horrific and VR-Team)

Для программистов №11

источника. В качестве источника используется FTransparentImage (вторая картинка), значит именно её прозрачный цвет (который мы установили в обработчике OnCreate) не будет копироватся. Вот и всё. Осталось только добавить обработчик события OnMouseMove: mouseX := X; mouseY := Y; FormPaint(nil);

Рис 3. Результат Здесь я запоминаю текущую позицию курсора и заставляю перерисовать сцену с помощью вызова функции FormPaint(nil). Вот и всё. Можешь запустить прогу и подёргать мышкой. На рисунке 3. ты можешь видеть результат сегодняшней работы. Как видешь вторая картинка скопировалась на экран без своего фона (розовый цвет). Обрати также внимание на то, что когда ты подводишь мышку к краю, картинка исчезает раньше, чем достигает конца экрана. Это связано с тем, что если хотя бы один пиксел не попадает в область экрана, картинка не рисуется полностью. Copyright © Флёнов Михаил

http://www.vr-online.ru

32


VR-online Journal (Horrific and VR-Team)

Для программистов №11

Приколы на Delphi Автор: Артём Сухобоков chimaf@mail.ru или artem2@beep.ru Мне сказали, что не все приколы работают в Win2k, поэтому в программах и статьях я буду писать, что где работает. Вернемся к предыдущей статье "Приколы c помощью Delphi: Общие приколы": 1) Невидимка работает только в Win9x; 2) Отключение комбинаций клавиш Ctrl-Alt-Del, Alt-Tab, Ctrl-Esc работает только в Win9x; 3) Изменение надписи на окнах открытых приложений работает в Win9x и Win2k; Итак, что у нас на сегодня? 1) Окно, которое не возможно закрыть штатными средствами Windows. (работает только в Win9x) Для этого нужно вызвать функцию DeleteMenu: BOOL DeleteMenu( HMENU hMenu, // хэндл меню UINT uPosition, // позиция или элемент меню для удаления Рис. 1 Общие приколы. UINT uFlags // флаг элемента. От него зависит смысл параметра uPosition ); uFlags может принимать одно из следующих значений: • •

MF_BYCOMMAND показывает, что uPosition указывает на элемент меню MF_BYPOSITION показывает, что uPosition - относительная позиция элемента меню, отсчитываемая от 0.

DeleteMenu возвращает ненулевое число, если завершается успешно. В случае ошибки она возвращает 0. Чтобы узнать информацию об ошибке нужно вызвать функцию GetLastError. Пишем программу. Создаем форму Form2. В событии OnCreate Form2 пишем:

http://www.vr-online.ru

33


VR-online Journal (Horrific and VR-Team)

Для программистов №11

procedure TForm2.FormCreate(Sender: TObject); Var MenuHandle:HMENU; //хэндл системного меню begin if Form1.Button1.Enabled=true then Form1.Button1.Click; //Убираем приложение из списка //Ctrl-Alt-Del (смотри предыдущую статью) MenuHandle:=GetSystemMenu(Handle,False); //Получаем хэндл системного меню if MenuHandle<>0 then //удаляем из меню команду закрытия DeleteMenu(MenuHandle,SC_CLOSE,MF_BYCOMMAND); end; Приколы с клавиатурой. 2) Программно нажимаем на Num Lock, Caps Lock и Scroll Lock (работает только в Win9x) //Программно нажимаем на Num Lock procedure TForm1.Button7Click(Sender: TObject); Var KeyboardState: TKeyboardState; //состояние клавиатуры-массив begin GetKeyboardState(KeyboardState); //получвем состояние клавиатуры //изменяем состояние клавиши с номером 144 KeyboardState[144]:=KeyboardState[144] xor 1; SetKeyboardState(KeyboardState); //устанавливаем новое состояние клавиатуры end; Чтобы изменить состояние клавиши Caps Lock и Scroll Lock нужно в предыдущей процедуре изменить только одну строчку: • • • •

• • • •

Для Caps Lock: //изменяем состояние клавиши с номером 20 KeyboardState[020]:= KeyboardState[020] xor 1; Для Scroll Lock: //изменяем состояние клавиши с номером 145 KeyboardState[145]:= KeyboardState[145] xor 1;

3) Цветомузыка на клавиатуре (работает только в Win9x) Помещаем на форму таймер и в его событии OnTimer пишем:

Рис. 2 Приколы с клавиатурой.

procedure TForm1.Timer1Timer(Sender: TObject); begin // Нажимаем на Num Lock, Caps Lock и Scroll Lock Button7.Click;

http://www.vr-online.ru

34


VR-online Journal (Horrific and VR-Team)

Для программистов №11

Button8.Click; Button9.Click; end; Пишем процедуры включения и выключения цветомузыки: // Включение цветомузыки procedure TForm1.Button10Click(Sender: TObject); begin GetKeyboardState(OldKeyboardState); //сохраняем состояние клавиатуры //Разрешаем/запрещаем кнопки Button11.Enabled:=true; Button10.Enabled:=false; Timer1.Enabled:=true; //запускаем таймер end; // Выключение цветомузыки procedure TForm1.Button11Click(Sender: TObject); begin Timer1.Enabled:=false; //останавливаем таймер //Разрешаем/запрещаем кнопки Button11.Enabled:=false; Button10.Enabled:=true; SetKeyboardState(OldKeyboardState); //восстанавливаем состояние клавиатуры end; Еще в начале модуля Unit1 нужно описать переменную OldKeyboardState: ... Var OldKeyboardState: TKeyboardState; ... 4) Установка русской/английской раскладки клавиатуры (работает в Win9x и Win2k) Установка раскладки клавиатуры производится с помощью функции HKL LoadKeyboardLayout( LPCTSTR pwszKLID, // название раскладки для загрузки UINT Flags // флаги ); Из флагов нас интересует только KLF_ACTIVATE, который загружает указанную раскладку и активирует ее. Если раскладка уже загружена, то происходит только ее активация. Если функция выполняется успешно, то она возвращает хэндл раскладки клавиатуры, в противном случае NULL. Все. В следующий раз я расскажу о том, что можно сделать с CD-ROMом и монитором.

http://www.vr-online.ru

35


VR-online Journal (Horrific and VR-Team)

Для программистов №11

WinAPI: Работа с курсором Сегодня я расскажу про API функции используемые при работе с курсором. В принципе, при написании офисных программ, они используются очень редко, но всё же мне иногда приходят вопросы связанные с курсоро��. Поэтому я решил описать их сегодня. Сегодня ты узнаешь про: ClipCursor CopyCursor CreateCursor DestroyCursor GetClipCursor GetCursorPos SetCursorPos ShowCursor ClipCursor Функция ограничивает движение курсора определённой областью. Если позиция курсора находится за пределами указанной области, windows автоматически переносит его в ближайшую точку в этой области. Существует в: Win NT, Win9x, Win32s. Для С/С++ объявлена в winuser.h. Для Delphi в модуле windows. Объявление: Для С/С++ BOOL ClipCursor( CONST RECT *lpRect );

// Указатель на структуру области

Для Delphi function ClipCursor( lpRect: PRect ): BOOL; stdcall; Функции передаётся единственный параметр в виде указателя на структуру в которой содержатся координаты области. Если всё ничтяк, то функция возвращает не ноль. Пример использования в Delphi: ClipCursor(Rect(10,15,50,55)). В этом случае курсор ограничивается прямоугольником с координатами Х1=10, Х2=15, Y1=50, Y2=55. CopyCursor Функция копирования курсора. Точнее сказать, возвращает копию переданного ей курсора. Существует в: Win NT, Win9x, Win32s. Для С/С++ объявлена в winuser.h. Самое интересное, что для Delphi я объявления не нашёл. Но оно должно выглядеть где-то так, как приведено ниже. Объявление: Для С/С++ HCURSOR CopyCursor( HCURSOR pcur // Указатель на курсор

http://www.vr-online.ru

36


VR-online Journal (Horrific and VR-Team)

Для программистов №11

); Для Delphi function CopyCursor( pcur: HICON ): HICON; stdcall; Функции передаётся единственный параметр в виде указателя на существующий курсор. После выполнения она вернёт копию переданного курсора. CreateCursor Функция создаёт новый курсор. Существует в: Win NT, Win9x, Win32s. Для С/С++ объявлена в winuser.h. Для Delphi в модуле windows. Объявление: Для С/С++ HCURSOR CreateCursor( HINSTANCE hInst, // Указатель на экземпляр приложения int xHotSpot, // Горизонтальная позиция горячей точки int yHotSpot, // Вертикальная позиция горячей точки int nWidth, // Ширина курсора int nHeight, // Высота курсора CONST VOID *pvANDPlane,// Указатель на AND битовую маску CONST VOID *pvXORPlane // Указатель на XOR битовую маску ); Для Delphi function CreateCursor( hInst: HINST; // Указатель на экземпляр приложения xHotSpot, // Горизонтальная позиция горячей точки yHotSpot, // Вертикальная позиция горячей точки nWidth, // Ширина курсора nHeight: Integer; // Высота курсора pvANDPlaneter, // Указатель на AND битовую маску pvXORPlane: Pointer// Указатель на XOR битовую маску ): HCURSOR; stdcall; Горячая точка - точка которой будет происходить касание. Например, у курсора в виде прицела горяцая точка должна быть в центре, а у стрелки на её конце. DestroyCursor Функция уничтожает курсор. Существует в: Win NT, Win9x, Win32s. Для С/С++ объявлена в winuser.h. Для Delphi в модуле windows. Объявление: Для С/С++ BOOL DestroyCursor( HCURSOR hCursor // Указатель на уничтожаемый курсор ); Для Delphi function DestroyCursor( hCursor: HICON // Указатель на уничтожаемый курсор ): BOOL; stdcall;

http://www.vr-online.ru

37


VR-online Journal (Horrific and VR-Team)

Для программистов №11

Функции передаётся единственный параметр в виде указателя на существующий курсор который надо уничтожить. GetClipCursor Функция возвращает облать в которой может перемещатся курсор. Эту область можно задать с помощью функции ClipCursor. Существует в: Win NT, Win9x, Win32s. Для С/С++ объявлена в winuser.h. Для Delphi в модуле windows. Объявление: Для С/С++ BOOL GetClipCursor( LPRECT lpRect // Структура типа Rect ); Для Delphi function GetClipCursor( var lpRect: TRect // Структура типа Rect ): BOOL; stdcall; Функции передаётся единственный параметр в виде указателя на структуру типа Rect. В неё будет записан результат, то есть размеры области курсора. Если всё ничтяк, то функция вернёт не ноль. GetCursorPos Функция возвращает текущее положение курсора. Существует в: Win NT, Win9x, Win32s. Для С/С++ объявлена в winuser.h. Для Delphi в модуле windows. Объявление: Для С/С++ BOOL GetCursorPos( LPPOINT lpPoint // Структура с позицией курсора. ); Для Delphi function GetCursorPos( var lpPoint: TPoint // Структура с позицией курсора. ): BOOL; stdcall; Функции передаётся единственный параметр в виде указателя на структуру типа Point. В неё будет записан результат, т.е. текущая позиция курсора. Пример на Delphi: var MousePos:TPoint; begin GetCursorPos(MousePos); end; После этого, чтобы получить Х позицию курсора, нужно прочитать MousePos.х, а для y позиции нужно прочитать MousePos.y. Если всё ничтяк, то функция вернёт не ноль. SetCursorPos Функция устанавливает текущее положение курсора. С её помощью ты можешь переместить указатель курсора в любое место экрана. Существует в: Win NT, Win9x, Win32s. Для С/С++ объявлена в winuser.h. Для Delphi в модуле windows. Объявление: Для С/С++

http://www.vr-online.ru

38


VR-online Journal (Horrific and VR-Team)

Для программистов №11

BOOL SetCursorPos( int X, // Горизонтальная позиция int Y // Вертикальная позиция ); Для Delphi function SetCursorPos( X, // Горизонтальная позиция Y: Integer // Вертикальная позиция ): BOOL; stdcall; Если всё ничтяк, то функция вернёт не ноль. ShowCursor Эта функция позволяет показывать и прятать курсор. Существует в: Win NT, Win9x, Win32s. Для С/С++ объявлена в winuser.h. Для Delphi в модуле windows. Объявление: Для С/С++ int ShowCursor( BOOL bShow );

// cursor visibility flag

Для Delphi function ShowCursor( bShow: BOOL ): Integer; stdcall; Функции передаётся только один параметр. Если он равен true, то курсор надо показать, а если равен false, то спрятать. Если всё ничтяк, то функция вернёт не ноль. Мне иногда приходят вопросы типа: "Как загрузить собственный курсор?". Признаюсь честно - не знаю. Я даже не могу знать всё. Я посмотрел помощь по Delphi и нашёл следующее: const crMyCursor = 5; procedure TForm1.FormCreate(Sender: TObject); begin Screen.Cursors[crMyCursor] := LoadCursor(HInstance, 'NewCursor'); Cursor := crMyCursor; end; Я попробовал воссоздать, но ничего не вышло. Разбиратся пока времени нет. Как только разбирусь, так сразу напишу статью. Copyright © Фленов Михаил

http://www.vr-online.ru

39


VR-Online для программистов #11