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

Полный исходный текст на языке C++ для библиотеки (DLL) с моделями блоков, имеющих прозрачные для щелчков мыши «окна». Библиотека содержит две модели:

  // Реакция на мышь в блоках с "окнами"
  #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;
  }
  //========= Конец главной функции =========

  // Блок с "окном" - первый вариант
  // (в режиме  "окно" не работает)
  extern "C" __declspec(dllexport)
    int  EditControlFrame_1(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;

    switch(CallMode)
      { // Проверка типов статических переменных
        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;
      }

    return ;
  // Отмена макроопределений
  #undef bypass
  #undef out
  #undef x_int
  #undef x_ext
  #undef Ready
  #undef Start
  #undef pStart
  }
  //=========================================

  // Блок с "окном" - второй вариант
  // (добавлена поддержка режима )
  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;

    switch(CallMode)
      { // Проверка типов статических переменных
        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 ; // В окно не попали - функция вернет break;
} return ; // Отмена макроопределений #undef bypass #undef out #undef x_int #undef x_ext #undef Ready #undef Start #undef pStart } //=========================================


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