Возникла
проблема: Hеобходимо вызывать функцию, которая
находится в 16-битной dll из 32-битного приложения. const
Gfsr_SystemResources = 0;
Gfsr_GdiResources = 1;
Gfsr_UserResources = 2;
var
hInst16: THandle;
GFSR: Pointer;
{ Undocumented Kernel32 calls. }
function LoadLibrary16(LibraryName: PChar): THandle; stdcall; external
kernel32 index 35;
procedure FreeLibrary16(HInstance: THandle); stdcall; external kernel32
index 36;
function GetProcAddress16(Hinstance: THandle; ProcName: PChar): Pointer;
stdcall; external kernel32 index 37;
procedure QT_Thunk; cdecl; external kernel32 name 'QT_Thunk';
{ QT_Thunk needs a stack frame. }
{$StackFrames On}
{ Thunking call to 16-bit USER.EXE. The ThunkTrash argument
allocates space on the stack for QT_Thunk. }
function NewGetFreeSystemResources(SysResource: Word): Word;
var
ThunkTrash: array[0..$20] of Word;
begin
{ Prevent the optimizer from getting rid of ThunkTrash. }
ThunkTrash[0] := hInst16;
hInst16 := LoadLibrary16('user.exe');
if hInst16 < 32 then
raise Exception.Create('Can''t load USER.EXE!');
{ Decrement the usage count. This doesn't really free the
library, since USER.EXE is always loaded. }
FreeLibrary16(hInst16);
{ Get the function pointer for the 16-bit function in USER.EXE. }
GFSR := GetProcAddress16(hInst16, 'GetFreeSystemResources');
if GFSR = nil then
raise Exception.Create('Can''t get address of
GetFreeSystemResources!');
{ Thunk down to USER.EXE. }
asm
push SysResource { push arguments }
mov edx, GFSR { load 16-bit procedure pointer }
call QT_Thunk { call thunk }
mov Result, ax { save the result }
end;
end;
(Автор - Quality freeware from Sight&Sound, Slovenia :
http://www.sight-sound.si/ )
"CPL-щина"
Файл примера можно скачать здесь
Уважаемые
любители нетрадиционного использования Delphi 4
вашему вниманию предлагается поразмять мозги,
руки, ноги, другие части тела (по вкусу).
____________________________________________________________________________
Итак
главная новость сезона - cpl - это на самом деле DLL.
Поэтому, приступая к работе создайте пустой
проект DLL (по настоящему отвязные программеры
могут сваять ActiveX DLL - это привнесет приятное
разнообразие в работу и создаст небольшую кучку
проблем, впрочем легко разрешимых- но зато вы
сможете управлять вашей cpl извне, правда зачем
это нужно не знаю).
Момент номер два, вам позарез нужен
файл ресурсов (с таким же названием как и
название библиотеки DLL- по умолчанию это название
проекта)-в противном случае ваша cpl- так никогда и
не появиться в панельке управления. Для
написания файла ресурсов (*.res) необходим какой
нибудь редактор ресурсов, в крайнем случае
сойдет и ImageEditor из стандартной поставки Дельфей.
Вы, мужественно сжав мышь в руке, постарайтесь
сваять иконку с названием MAINICON и запихнуть ее в
файл ресурсов с таким же названием как и ваша DLL.
Момент номер три. Файл DLL должен
ОБЯЗАТЕЛЬНО экспортировать функцию с именем
CPlApplet (не cplApplet и не как то иначе ТОЛЬКО так)-иначе
панель управления не сможет инициализировать
вашу cpl-и даже хуже, как выяснилось, при открытии
панельки управления Windows КАЖДЫЙ РАЗ
просматривает каталог ...\System (либо ...\System32) в
поисках cpl-ок и посылает им запросы через эту
эспортируемую функцию. Т.е. если у вас имя функции
отличается может произойти полное зависание
системы при открытии панели управлени (лечиться
Reset). Кстати можно экпортировать и другие функции
(кстати так делают Screen Saver'ы)- это не возбраняется.
При эспорте функции используйте
прототип функции находящийся в файле cpl.pas
вида
function CPlApplet(hwndCPl: THandle; uMsg: DWORD;lParam1, lParam2: Longint):
Longint;export;stdcall;
Вот и все что я хотел бы сообщить об
увлекательном занятии русских программистов:
попытках заставить систему программирования БАЗ
ДАННЫХ выполнять черт знает, что-но я тоже люблю
этим заниматься ;-).
P.S. Учите C++ так как подобные штуки легонько на нем
пишуться. Да и я портировал этот пример из MSDN от
Visual C++ 6.0
P.P.S. В тексте программы вы наткнетесь на фукцию
Form.Create в которой вызывается ShowWindowsAsync (данная
кривость используется, чтобы не показывалось
окошко на таск баре). В ФИДО ходило много
материалов на эту тему но здесь (в Дельфи)
Params.ExStyle:=Params.ExStyle and ( not WS_EX_APPWINDOW); в CreateParams
не работает, поэтому ногами не бить (сейчас
тружусь на проблемкой - работаю с SH_-объектами )
тех кого сей трабл не устраивает могут спокойно
ее выбросить
1.Установка.
Проста до ужаса. Необходимо записать файл cpl в
каталог Windows\System (Win95) либо WindowsNT\System32 (WinNT)
после этого ОБЯЗАТЕЛЬНО (особенно для NT)
перезагрузить компьютер
можно в софт-режиме (т.е не полность а с Shift-ом, но
это в мастдайке'95).
2. Програмулька отлаживалась и разрабатывалась
на Delphi 4 (sp3,sp4) так, что
если не будет работать у вас проверьте наличие
необходимых сервис-паков
(хотя по идее, должно работать везде, даже по
D3.02)-не будет чего
работать - пишите.
3. В дельфях в каталоге Source\RTL\Win усть библиотека
cpl.pas проверьте,
чтобы она у вас была.
4. Программа проверялась на корректность работы
под Windows 95, Windows 98
WindowsNT (Workststion +Server)- глюков нет, если у вас
получиться заглючить
программу- пишите, мне будет интересно.
5. Ссылки на авторство не обязательны но
желательны (я тоже не за час ее написал)
6. В качестве нагрузки могу выслать аналогичные
примеры написания cpl
выдернутые из MSDN (там два примера общим тоннажем
в ~100 КВ)-возможно
это заинтересует любителей C++Builder
P.S. ну вот и все, что касается такой интересной
феньки как cpl.
28 июля 1999 года
Спорик Алексей Евгеньевич |