Иногда, желательно чтобы программа состояла
только из одного исполняемого файла.
А что делать, если для работы программы нужны другие файлы, например,
динамические библиотеки подпрограмм (DLLки)?
Если их немного и они имеют небольшой размер, то вполне реально
разместить их в теле исполняемого файла.
Для примера используем программу, требующую для своей работы файл
inpout32.dll.
Это драйвер доступа к портам компа.
Программа определяет текущую температуру процессора и системной платы,
а также текущую загрузку процессора.
Код программы
Код:
#ADR_REG = $295 ;Это адреса регистров системной платы, с помощью которых можно узнать температуру
#DATA_REG = $296
*HModule=LoadLibraryM(?DLL) ; Загрузка динамической библиотеки из тела исполняемого файла
*Inp32_address=GetProcAddressM(*HModule, "Inp32") ; Узнаём адрес функции "Inp32" DLLки
*Out32_address=GetProcAddressM(*HModule, "Out32") ; Узнаём адрес функции "Out32" DLLки
Procedure Termo(z) ; Эта процедура работает в параллельном потоке
Shared *Inp32_address, *Out32_address
Repeat ; Начало "безконечного" цикла Repeat ForEver
CallFunctionFast(*Out32_address, #ADR_REG, $2B) ; Получает текущую температуру процессора
x=CallFunctionFast(*Inp32_address, #DATA_REG)
SetGadgetItemText(0,0,StrU(x, #PB_Byte)+" °C",1) ; отображаем её в таблице
CallFunctionFast(*Out32_address, #ADR_REG, $29) ; Получает текущую температуру системной платы
x=CallFunctionFast(*Inp32_address, #DATA_REG)
SetGadgetItemText(0,1,StrU(x, #PB_Byte)+" °C",1) ; отображаем её в таблице
SetGadgetText(3, Str(CpuUsage())+" %" ) ; Получаем и отображаем текущую загрузку процессора
Delay(1000) ; Пауза, равная 1 секунде.
ForEver
EndProcedure
OpenWindow(0,0,0,274,100,"TermoControl",#PB_Window_MinimizeGadget|#PB_Window_Invisible|#PB_Window_ScreenCentered)
ListIconGadget(0,2,2,270,70,"Имя",120,#PB_ListIcon_GridLines) ; Таблица
SetGadgetFont(0,LoadFont(0,"MS Sans Serif",10) ) ; Шрифт используемый в таблице
AddGadgetColumn(0, 1, "Температура", 140) ; Добавление колонки в таблицу
AddGadgetItem(0, 0, "Процессор") ; Добавление строк в таблицу
AddGadgetItem(0, 1, "Мат. плата")
TextGadget(2,10, 80,140,16,"Процессор загружен на ")
TextGadget(3,150, 80,50,16,"") ; Здесь будет отображаться текущая загрузка процессора
CreateThread(@Termo(), 0) ; Запуск кода процедуры "Termo" в параллельном потоке
HideWindow(0,0) ; Отображение окна
Repeat ; Главный цикл программы
Event=WaitWindowEvent()
Until Event=#PB_Event_CloseWindow
FreeLibraryM(*HModule) ; При завершении работы проги, выгружаем DLLку из памяти
End
DataSection ; Добавление файла inpout32.dll в секцию кода, исполняемого файла
DLL:
IncludeBinary "inpout32.dll"
EndDataSection
Для компиляции программы нужна специальная библиотека с
дополнительными функциями для PureBasic, именуемая PBOSL
Найти её можно
здесь
В начале программы, в константы
#ADR_REG
и
#DATA_REG записываются адреса
регистров, из которых можно прочитать текущие температуры.
Далее с помощью функции
LoadLibraryM из
библиотеки
PBOSL регистрируем DLLку,
находящуюся в теле исполняемого файла и получаем её начальный адрес в
памяти. Потом с помощью функции
GetProcAddressM
определяем адреса функций DLLки - "Inp32" и "Out32".
Зная эти адреса, можно без проблем работать с функциями DLLки
В процедуре
Termo производится
периодическое считывание температуры и отображение её в таблице. Код
данной процедуры выполняется в параллельном потоке и можно так сказать,
"живёт" сам по себе.
Вот скрин проги.
PS.
Этот метод определения температуры работает только при условии что в
компе интеловский процессор и системная плата поддерживает данную
функцию.
Архив с программой TermoControl и её исходным текстом, можно скачать
здесь