Текущий раздел:

Описания RDS

Руководство программиста

Глава 2. Создание моделей блоков

§2.12. Реакция блоков на действия пользователя

§2.12.1. Реакция на мышь

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

- PlusMinus – увеличение выхода на единицу при щелчке на верхней половине изображения блока и уменьшение на единицу при щелчке на нижней половине;
- PlusMinus_a – аналогично PlusMinus, но при наличии у блока векторной картинки увеличение выхода на единицу происходит при щелчке на элементе с идентификатором 1, уменьшение на единицу – при щелчке на элементе с идентификатором −1;
- PlusMinus_b – аналогично PlusMinus, но при наличии у блока векторной картинки к выходу прибавляется идентификатор ее элемента, на который пришелся щелчок.

В каждой следующей версии модели изменения относительно предыдущей версии выделены цветом.

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

      // Увеличение/уменьшение значения по щелчку - первый вариант
      // (распознается щелчок по верхней/нижней части блока)
      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;

        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)
                { // Нажата левая кнопка
                  if(mouse->y<mouse->Top+mouse->Height/2)
                    v++; // В верхней половине блока - увеличиваем
                  else
                    v--; // В нижней половине блока — уменьшаем
                  // Взводим сигнал готовности
                  Ready=1;
                }
              break;
          }
        return RDS_BFR_DONE;
      // Отмена макроопределений
      #undef v
      #undef Ready
      #undef Start
      #undef pStart
      }
      //=========================================

      // Увеличение/уменьшение значения по щелчку - второй вариант
      // (распознается щелчок по элементам картинки)
      extern "C" __declspec(dllexport)
        int RDSCALL PlusMinus_a(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;

        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);
                      switch(id)
                        { case 1:  v++; break;
                          case -1: v--; break;
                        }
                    }
                  else if(mouse->y<mouse->Top+mouse->Height/2)
                    v++; // В верхней половине блока - увеличиваем
                  else
                    v--; // В нижней половине блока — уменьшаем
                  // Взводим сигнал готовности
                  Ready=1;
                }
              break;

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

      // Увеличение/уменьшение значения по щелчку - третий вариант
      // (распознается щелчок по элементам картинки, идентификатор элемента определяет приращение v)
      extern "C" __declspec(dllexport)
        int RDSCALL PlusMinus_b(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;

        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;

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