Полный исходный текст на языке C++ для библиотеки (DLL) с моделью блока, увеличивающего и уменьшающего выход по щелчкам мыши и нажатию клавиш (клавиши настраиваются пользователем). Изменения относительно предыдущей версии этой модели из §2.12.1 выделены цветом.
// Реакция блока на клавиатуру #include <windows.h> #include <RdsDef.h> // Подготовка описаний сервисных функций #define RDS_SERV_FUNC_BODY GetInterfaceFunctions #include <RdsFunc.h> //========== Главная функция DLL ========== int WINAPI DllMain(HINSTANCE /*hinst*/, unsigned long reason, void* /*lpReserved*/) { if(reason==DLL_PROCESS_ATTACH) // Загрузка DLL { // Получение доступа к функциям RDS if(!GetInterfaceFunctions()) RDS_SERV_ERROR_MSGW // Сообщение: старая версия RDS } return 1; } //========= Конец главной функции =========//====== Класс личной области данных ====== class TPlusMinusData { public: int KeyPlus; // Клавиша увеличения DWORD ShiftsPlus; // и ее флаги int KeyMinus; // Клавиша уменьшения DWORD ShiftsMinus; // и ее флаги int Setup(void); // Функция настройки клавиш void SaveBin(void);// Сохранение параметров int LoadBin(void); // Загрузка параметров // Конструктор класса TPlusMinusData(void) { KeyPlus=ShiftsPlus=KeyMinus=ShiftsMinus=0;}; }; //=========================================// Функция задания клавиш // ВАЖНО: Исходный текст программы должен быть записан в UTF8, // в противном случае необходимо использовать версии функций // с суффиксом "W" и символьные константы с префиксом "L" int TPlusMinusData::Setup(void) { RDS_HOBJECT window; // Идентификатор вспомогательного объекта BOOL ok; // Пользователь нажал "OK" // Создание окна window=rdsFORMCreate(FALSE,-1,-1,"Плюс/минус"); // Добавление полей ввода rdsFORMAddEdit(window,0,1,RDS_FORMCTRL_HOTKEY, "Клавиша увеличения:",80); rdsFORMAddEdit(window,0,2,RDS_FORMCTRL_HOTKEY, "Клавиша уменьшения:",80); // Занесение исходных значений кодов клавиш в поля ввода rdsSetObjectInt(window,1,RDS_FORMVAL_VALUE,KeyPlus); rdsSetObjectInt(window,1,RDS_FORMVAL_HKSHIFTS,ShiftsPlus); rdsSetObjectInt(window,2,RDS_FORMVAL_VALUE,KeyMinus); rdsSetObjectInt(window,2,RDS_FORMVAL_HKSHIFTS,ShiftsMinus); // Открытие окна ok=rdsFORMShowModalEx(window,NULL); if(ok) { // Нажата кнопка OK - запись кодов клавиш в класс KeyPlus=rdsGetObjectInt(window,1,RDS_FORMVAL_VALUE); ShiftsPlus=rdsGetObjectInt(window,1,RDS_FORMVAL_HKSHIFTS); KeyMinus=rdsGetObjectInt(window,2,RDS_FORMVAL_VALUE); ShiftsMinus=rdsGetObjectInt(window,2,RDS_FORMVAL_HKSHIFTS); } // Уничтожение окна rdsDeleteObject(window); // Возвращаемое значение return ok?RDS_BFR_MODIFIED:RDS_BFR_DONE; } //=========================================// Сохранение параметров void TPlusMinusData::SaveBin(void) { BYTE tag; // Переменная для байта тега tag=1; // Тег 1 - клавиша увеличения rdsWriteBlockData(&tag,sizeof(tag)); rdsWriteBlockData(&KeyPlus,sizeof(KeyPlus)); rdsWriteBlockData(&ShiftsPlus,sizeof(ShiftsPlus)); tag=2; // Тег 2 - клавиша уменьшения rdsWriteBlockData(&tag,sizeof(tag)); rdsWriteBlockData(&KeyMinus,sizeof(KeyMinus)); rdsWriteBlockData(&ShiftsMinus,sizeof(ShiftsMinus)); tag=0; // Тег 0 - конец данных rdsWriteBlockData(&tag,sizeof(tag)); } //=========================================// Загрузка параметров int TPlusMinusData::LoadBin(void) { BYTE tag; for(;;) // Цикл до тех пор, пока данные не кончатся { // Читаем байт тега if(!rdsReadBlockData(&tag,sizeof(tag))) break; // Тег не считан - данные кончились // Анализируем считанный тег switch(tag) { case 0: // Конец данных блока return RDS_BFR_DONE; // Загрузка успешно завершена case 1: // Данные клавиши увеличения rdsReadBlockData(&KeyPlus,sizeof(KeyPlus)); rdsReadBlockData(&ShiftsPlus,sizeof(ShiftsPlus)); break; case 2: // Данные клавиши уменьшения rdsReadBlockData(&KeyMinus,sizeof(KeyMinus)); rdsReadBlockData(&ShiftsMinus,sizeof(ShiftsMinus)); break; default: // Неопознанный тег return RDS_BFR_ERROR; // Сообщаем RDS об ошибке } } // Данные кончились до тега 0 - сообщаем об ошибке return RDS_BFR_ERROR; } //=========================================// Увеличение/уменьшение значения по щелчку и клавишам extern "C" __declspec(dllexport) int RDSCALL PlusMinus(int CallMode, RDS_PBLOCKDATA BlockData, LPVOID ExtParam) { // Макроопределения для статических переменных #define pStart ((char *)(BlockData->VarTreeData)) #define Start (*((char *)(pStart))) #define Ready (*((char *)(pStart+RDS_VSZ_S))) #define v (*((RDSINT32 *)(pStart+2*RDS_VSZ_S))) // Вспомогательная — указатель на структуру события мыши RDS_PMOUSEDATA mouse;// Вспомогательная — указатель на структуру события клавиатуры RDS_PKEYDATA key; // Указатель на личную область данных блока,приведенный к // правильному типу TPlusMinusData *data=(TPlusMinusData*)(BlockData->BlockData);switch(CallMode) { // Проверка типа статических переменных case RDS_BFM_VARCHECK: return strcmp((char*)ExtParam,"{SSI}")? RDS_BFR_BADVARSMSG:RDS_BFR_DONE; // Реакция на нажатие кнопки мыши case RDS_BFM_MOUSEDOWN: // Приведение ExtParam к нужному типу mouse=(RDS_PMOUSEDATA)ExtParam; if(mouse->Button==RDS_MLEFTBUTTON) { // Нажата левая кнопка // Проверяем, есть ли у блока картинка (получаем // описание блока) RDS_BLOCKDESCRIPTION descr; descr.servSize=sizeof(descr); rdsGetBlockDescription(BlockData->Block,&descr); if(descr.Flags & RDS_BDF_HASPICTURE) { // Картинка есть – определяем идентификатор // элемента под курсором int id=rdsGetMouseObjectId(mouse); v+=id; } else if(mouse->y<mouse->Top+mouse->Height/2) v++; // В верхней половине блока - увеличиваем else v--; // В нижней половине блока — уменьшаем // Взводим сигнал готовности Ready=1; } break;case RDS_BFM_INIT: // Инициализация BlockData->BlockData=new TPlusMinusData(); break; case RDS_BFM_CLEANUP: // Очистка данных delete data; break; case RDS_BFM_SETUP: // Настройка параметров return data->Setup(); case RDS_BFM_SAVEBIN:// Сохранение параметров data->SaveBin(); break; case RDS_BFM_LOADBIN: // Загрузка параметров return data->LoadBin(); // Реакция на нажатие клавиши case RDS_BFM_KEYDOWN: // Приведение ExtParam к нужному типу key=(RDS_PKEYDATA)ExtParam; // Сравнение нажатой клавиши с клавишами уменьшения // и увеличения if(key->KeyCode==data->KeyPlus && key->Shift==data->ShiftsPlus) { v++; Ready=1; } else if(key->KeyCode==data->KeyMinus && key->Shift==data->ShiftsMinus) { v--; Ready=1; } break;} return RDS_BFR_DONE; // Отмена макроопределений #undef v #undef Ready #undef Start #undef pStart } //=========================================