Полный исходный текст на языке C++ для библиотеки (DLL) с моделью блока, изображение которого может вращаться и мигать одновременно (используется два циклических таймера).
// Мигающий и вращающийся блок #include <windows.h> #include <math.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; } //========= Конец главной функции ========= //=== Структура личной области данных ===== struct TRotateFlashData { RDS_TIMERID FlashTimer; // Таймер мигания RDS_TIMERID RotTimer; // Таймер вращения }; //============= Модель блока ============== extern "C" __declspec(dllexport) int RDSCALL RotateFlash( int CallMode, RDS_PBLOCKDATA BlockData, LPVOID ExtParam) { // Макроопределения для статических переменных #define pStart ((char *)(BlockData->VarTreeData)) #define Start (*((char *)(pStart))) #define Ready (*((char *)(pStart+RDS_VSZ_S))) #define Flash (*((char *)(pStart+2*RDS_VSZ_S))) #define Rotate (*((char *)(pStart+2*RDS_VSZ_S+RDS_VSZ_L))) #define State (*((char *)(pStart+2*RDS_VSZ_S+2*RDS_VSZ_L))) #define Angle (*((double *)(pStart+2*RDS_VSZ_S+3*RDS_VSZ_L))) // Вспомогательная переменная – указатель на личную область TRotateFlashData *data=(TRotateFlashData*)(BlockData->BlockData); // Структура для получения параметров таймера RDS_TIMERDESCRIPTION descr; switch(CallMode) { // Инициализация блока case RDS_BFM_INIT: // Отведение памяти под личную область BlockData->BlockData=data=new TRotateFlashData; // Создание двух одинаковых таймеров data->FlashTimer=rdsSetBlockTimer(NULL,0, RDS_TIMERM_LOOP|RDS_TIMERS_TIMER,FALSE); data->RotTimer=rdsSetBlockTimer(NULL,0, RDS_TIMERM_LOOP|RDS_TIMERS_TIMER,FALSE); break; // Очистка данных блока case RDS_BFM_CLEANUP: // Уничтожение таймеров rdsDeleteBlockTimer(data->FlashTimer); rdsDeleteBlockTimer(data->RotTimer); // Освобождение памяти, занятой под личную область delete data; break; // Проверка типа статических переменных case RDS_BFM_VARCHECK: if(strcmp((char*)ExtParam,"{SSLLLD}")) return RDS_BFR_BADVARSMSG; return RDS_BFR_DONE; // Такт расчета case RDS_BFM_MODEL: // Подготовка структуры descr к чтению данных таймера descr.servSize=sizeof(descr); // Управление миганием rdsGetBlockTimerDescr(data->FlashTimer,&descr); if(Flash) // Включить мигание { if(!descr.On) // Таймер остановлен { // Запускаем таймер и “зажигаем" индикатор rdsRestartBlockTimer(data->FlashTimer,1000); State=1; } } else // Выключить мигание { if(descr.On) // Таймер работает { // Останавливаем и “гасим" индикатор rdsStopBlockTimer(data->FlashTimer); State=0; } } // Управление вращением rdsGetBlockTimerDescr(data->RotTimer,&descr); if(Rotate) // Включить врашение { if(!descr.On) // Таймер остановлен – запускаем rdsRestartBlockTimer(data->RotTimer,100); } else // Выключить вращение { if(descr.On) // Таймер работает – останавливаем rdsStopBlockTimer(data->RotTimer); } break; // Срабатывание таймера case RDS_BFM_TIMER: // Сравниваем с имеющимися таймерами if(ExtParam==((LPVOID)data->FlashTimer)) // Это – таймер мигания State=!State; else // Если не таймер мигания, значит, вращения Angle=fmod(Angle+0.4,2*M_PI); break; } return RDS_BFR_DONE; // Отмена макроопределений для переменных #undef Angle #undef State #undef Rotate #undef Flash #undef Ready #undef Start #undef pStart } //=================================================