Навигация:
<< >> Оглавление Указатель
Текст С++

Полный исходный текст на языке C++ для библиотеки (DLL) с моделью блока, иллюстрирующей прямой вызов функции у всех блоков подсистемы. В модель EditControlFrame (блок с прозрачным для щелчков мыши «окном», см. §2.12.3) добавлена возможность одновременного «открытия» и «закрытия» всех таких блоков в подсистеме. Изменения относительно предыдущей версии модели выделены цветом).

  // Прямой вызов функции всех блоков подсистемы
  #include <windows.h>
  #include <RdsDef.h>
  // Подготовка описаний сервисных функций
  
  #include <RdsFunc.h>

  //==========  ==========
  int WINAPI ( /*hinst*/,
                           unsigned long reason,
                           void* /*lpReserved*/)
  { if(reason==DLL_PROCESS_ATTACH) // Загрузка DLL
      { // Получение доступа к функциям RDS
        if(!GetInterfaceFunctions())
           // Сообщение: старая версия RDS
      }
    return 1;
  }
  //========= Конец главной функции =========

//========================================= // Функция управления состоянием блока //========================================= // Имя функции #define PROGGUIDEEDITCTRLFUNC_SET \ "ProgrammersGuide.EditCtrlFrame.Set" // Структура параметров функции typedef struct { servSize; // Размер этой структуры для проверки int Command; // Команда блоку (0, 1 или 2) } TProgGuideEditCtrlSetParams; //=========================================
// Идентификатор функции PROGGUIDEEDITCTRLFUNC_SET int EditCtrlFuncSet=0;
//============================================================================ // Блок с "окном" //============================================================================ extern "C" __declspec(dllexport) int EditControlFrame(int CallMode, BlockData, ExtParam) { // #define pStart ((char *)(BlockData->VarTreeData)) #define Start (*((char *)(pStart))) #define Ready (*((char *)(pStart+RDS_VSZ_S))) #define x_ext (*((double *)(pStart+2*RDS_VSZ_S))) #define x_int (*((double *)(pStart+2*RDS_VSZ_S+RDS_VSZ_D))) #define out (*((double *)(pStart+2*RDS_VSZ_S+2*RDS_VSZ_D))) #define bypass (*((char *)(pStart+2*RDS_VSZ_S+3*RDS_VSZ_D))) const int fr=20; // Толщина рамки // Вспомогательные переменные mouse; draw; int frz,x1,y1,x2,y2,xi1,yi1,xi2,yi2;
func; // Описание вызванной функции menu; // Описание выбранного пункта меню TProgGuideEditCtrlSetParams callparams; // Параметры функции
switch(CallMode) {
// Инициализация блока case : if(!EditCtrlFuncSet) EditCtrlFuncSet=(PROGGUIDEEDITCTRLFUNC_SET); break;
// Проверка типов статических переменных case : return strcmp((char*)ExtParam,"{SSDDDL}")? :; // Реакция на нажатие кнопки мыши case : mouse=()ExtParam; // Толщина рамки с учетом масштаба frz=fr*mouse->DoubleZoom; // В открытом состоянии при попадании курсора внутрь // прозрачного окна на щелчок реагировать не нужно if(bypass==0 && mouse->x>mouse->Left+frz && mouse->y>mouse->Top+frz && mouse->x<mouse->Left+mouse->Width-frz && mouse->y<mouse->Top+mouse->Height-frz) return ; // Если не левая кнопка - не обрабатываем щелчок // и разрешаем вывести контекстное меню, если нужно if(mouse->Button!=) return ; // Нажата левая кнопка мыши, причем курсор попал // в рамку или блок в закрытом состоянии bypass=!bypass; // Переключаем состояние Ready=1; // Взводим сигнал готовности // Здесь намеренно не поставлен оператор break: необходимо // выполнить действия в следующем case (такт расчета) // Один такт расчета case : // В зависимости от состояния, подаем на выход один из входов out=bypass?x_ext:x_int; break; // Рисование внешнего вида блока case : draw=()ExtParam; // Координаты описывающего прямоугольника блока x1=draw->Left; x2=draw->Left+draw->Width; y1=draw->Top; y2=draw->Top+draw->Height; // Толщина рамки с учетом масштаба frz=fr*draw->DoubleZoom; // Координаты окна внутри блока xi1=x1+frz; xi2=x2-frz; yi1=y1+frz; yi2=y2-frz; if(bypass) { // Закрытое состояние int w; char *text; // Рисуем красный прямоугольник с черной рамкой (0,,1,0,); (0,,0xff); (x1,y1,x2,y2); // Устанавливаем шрифт выстой в окно внутри блока (0,"Arial",yi2-yi1,0, ,0,FALSE,FALSE,FALSE,FALSE); // Преобразуем значение выхода в динамическую строку text=(out,-1,NULL); // Определяем ширину получившейся строки на экране (text,&w,NULL); // Выводим значение выхода туда, где в открытом // состоянии находится прозрачное окно (xi2-w,yi1,text); // Освобождаем динамическую строку (text); } else { // Открытое состояние (0,,0xff00); // Рисуем рамку вокруг прозрачного окна из четырех // зеленых прямоугольников (x1,y1,x2,yi1); (x1,yi2,x2,y2); (x1,yi1,xi1,yi2); (xi2,yi1,x2,yi2); // Обрамляем черными линиями (0,,1,0,); (0,,0); (x1,y1,x2,y2); (xi1,yi1,xi2,yi2); } break; // Проверка возможности выбора блока мышью case : mouse=()ExtParam; frz=fr*mouse->DoubleZoom; // Толщина рамки // Проверка попадания в прозрачное окно if(bypass==0 && mouse->x>mouse->Left+frz && mouse->y>mouse->Top+frz && mouse->x<mouse->Left+mouse->Width-frz && mouse->y<mouse->Top+mouse->Height-frz) return ; // В окно не попали - функция вернет RDS_BFR_DONE break; // Открытие контекстного меню блока case : // Добавление временных пунктов меню // // // (bypass?"Открыть":"Закрыть",0,1,2);
(NULL,,0,0); ("Открыть все",0,2,1); ("Закрыть все",0,2,0); ("Переключить все",0,2,2);
break; // Выбор пункта меню пользователем case : menu=()ExtParam; // Данные пункта меню switch(menu->Function) { case 1: // Открыть/закрыть bypass=!bypass; // Переключить режим out=bypass?x_ext:x_int; // Подать на выход Ready=1; // Взвести флаг готовности break; case 2: // Один из новых пунктов // Заполняем структуру параметров функции callparams.Command=menu->MenuData; callparams.servSize=sizeof(callparams); // Вызываем у всех блоков родительской подсистемы (BlockData->Parent, EditCtrlFuncSet, &callparams, 0); break; } break;
// Вызов функции блока case : // Приведение ExtParam к правильному типу func=()ExtParam; // Проверяем, какая функция вызвана if(func->Function==EditCtrlFuncSet) { // Вызвана нужная нам функция TProgGuideEditCtrlSetParams *params; // Приводим указатель на параметры к нужному типу // и проверяем размер переданной структуры params=(TProgGuideEditCtrlSetParams*)(func->Data); if(params->servSize<sizeof(TProgGuideEditCtrlSetParams)) break; // Размер недостаточен // В зависимости от Command меняем режим блока switch(params->Command) { case 0: bypass=1; break; // Закрыть case 1: bypass=0; break; // Открыть case 2: bypass=!bypass; break; // Переключить default: return ; // Ошибка } // Взводим сигнал готовности и передаем нужный вход // на выход Ready=1; out=bypass?x_ext:x_int; } break;
} return ; // Отмена макроопределений #undef bypass #undef out #undef x_int #undef x_ext #undef Ready #undef Start #undef pStart } //=========================================


<< >> Оглавление Указатель