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

Описания RDS

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

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

§2.7. Настройка параметров блока

§2.7.6. Открытие модальных окон в режиме расчета

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

- ModalWindowTestBad – неправильно написанная модель, не дающая потоку расчета работать (отличия от модели из §2.7.5 выделены цветом);
- ModalWindowTest2 – правильно написанная модель, не блокирующая поток расчета (отличия от ModalWindowTestBad выделены цветом).

      // Открытие модального окна в режиме расчета
      #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;
      }
      //========= Конец главной функции =========

      //====== Неправильная модель блока ========
      //=== (открытие окна остановит расчет) ====
      extern "C" __declspec(dllexport)
        int RDSCALL ModalWindowTestBad(int CallMode,
                                    RDS_PBLOCKDATA BlockData,
                                    LPVOID ExtParam)
      {
      // Макроопределения для статических переменных
      #define pStart ((char *)(BlockData->VarTreeData))
      #define Start (*((char *)(pStart)))
      #define Ready (*((char *)(pStart+RDS_VSZ_S)))
      #define Color (*((RDSINT32 *)(pStart+2*RDS_VSZ_S)))
        // Вспомогательная структура для работы с диалогом цвета
        CHOOSECOLOR cc;
        // Массив дополнительных цветов для диалога
        static COLORREF CustomColors[16]=
                        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
        // Возвращаемое функцией модели значение
        int result=RDS_BFR_DONE;
        // Вспомогательная переменная – результат вызова диалога
        BOOL ok;

        switch(CallMode)
          { // Проверка типа переменных
            case RDS_BFM_VARCHECK:
              if(strcmp((char*)ExtParam,"{SSI}")==0)
                return RDS_BFR_DONE;
              return RDS_BFR_BADVARSMSG;

            // Функция настройки или нажатие кнопки мыши
            case RDS_BFM_SETUP:
            case RDS_BFM_MOUSEDOWN:
              // Установка параметров структуры для работы с диалогом
              memset(&cc,0,sizeof(cc));
              cc.lStructSize=sizeof(cc);
              cc.hwndOwner=rdsGetAppWindowHandle();
              cc.lpCustColors=CustomColors;
              cc.rgbResult=Color;
              cc.Flags=CC_RGBINIT;
              // Уведомление RDS об открытии модального окна
              rdsBlockModalWinOpen(NULL);
              // Вызов диалога
              ok=ChooseColor(&cc);
              // Уведомление RDS о закрытии модального окна
              rdsBlockModalWinClose(NULL);
              if(ok) // Пользователь выбрал цвет
                { // Запись цвета в Color
                  Color=cc.rgbResult;
                  if(CallMode==RDS_BFM_SETUP) // Функция настройки
                    { // Установка этого значения Color по умолчанию
                      // (2 – порядковый номер переменной Color в блоке)
                      rdsSetBlockVarDefValueByCur(BlockData->Block,2);
                      // Возвращаемое значение должно сигнализировать
                      // о наличии изменений в схеме
                      result=RDS_BFR_MODIFIED;
                    }
                  else // Нажатие кнопки мыши
                    // Нужно перерисовать окно подсистемы
                    rdsRefreshBlockWindows(BlockData->Parent,FALSE);
                }
              break;
          }
        return result;
      // Отмена макроопределений
      #undef Color
      #undef Ready
      #undef Start
      #undef pStart
      }
      //=========================================

      //======= Правильная модель блока =========
      //== (открытие окна не остановит расчет) ==
      // Функция вызова диалога
      int RDSCALL ModalWindowTest2Callback(LPVOID data)
      {
        return ChooseColor((CHOOSECOLOR*)data);
      }
      //=========================================
      // Собственно модель блока
      extern "C" __declspec(dllexport)
        int RDSCALL ModalWindowTest2(int CallMode,
                                    RDS_PBLOCKDATA BlockData,
                                    LPVOID ExtParam)
      {
      // Макроопределения для статических переменных
      #define pStart ((char *)(BlockData->VarTreeData))
      #define Start (*((char *)(pStart)))
      #define Ready (*((char *)(pStart+RDS_VSZ_S)))
      #define Color (*((RDSINT32 *)(pStart+2*RDS_VSZ_S)))
        // Вспомогательная структура для работы с диалогом цвета
        CHOOSECOLOR cc;
        // Массив дополнительных цветов для диалога
        static COLORREF CustomColors[16]=
                        {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
        // Возвращаемое функцией модели значение
        int result=RDS_BFR_DONE;
        // Вспомогательная переменная – результат вызова диалога
        BOOL ok;

        switch(CallMode)
          { // Проверка типа переменных
            case RDS_BFM_VARCHECK:
              if(strcmp((char*)ExtParam,"{SSI}")==0)
                return RDS_BFR_DONE;
              return RDS_BFR_BADVARSMSG;

            // Функция настройки или нажатие кнопки мыши
            case RDS_BFM_SETUP:
            case RDS_BFM_MOUSEDOWN:
              // Установка параметров структуры для работы с диалогом
              memset(&cc,0,sizeof(cc));
              cc.lStructSize=sizeof(cc);
              cc.hwndOwner=rdsGetAppWindowHandle();
              cc.lpCustColors=CustomColors;
              cc.rgbResult=Color;
              cc.Flags=CC_RGBINIT;
              // Уведомление RDS об открытии модального окна
              rdsBlockModalWinOpen(NULL);
              // Вызов диалога
              if(rdsCalcProcessIsRunning()) // Идет расчет
                { // Вызов со снятием блокировки
                  int ret;
                  rdsUnlockAndCall(ModalWindowTest2Callback,&cc,&ret);
                  ok=ret;
                }
              else // Режим редактирования или моделирования
                ok=ChooseColor(&cc);
              // Уведомление RDS о закрытии модального окна
              rdsBlockModalWinClose(NULL);
              if(ok) // Пользователь выбрал цвет
                { // Запись цвета в Color
                  Color=cc.rgbResult;
                  if(CallMode==RDS_BFM_SETUP) // Функция настройки
                    { // Установка этого значения Color по умолчанию
                      // (2 – порядковый номер переменной Color в блоке)
                      rdsSetBlockVarDefValueByCur(BlockData->Block,2);
                      // Возвращаемое значение должно сигнализировать
                      // о наличии изменений в схеме
                      result=RDS_BFR_MODIFIED;
                    }
                  else // Нажатие кнопки мыши
                    // Нужно перерисовать окно подсистемы
                    rdsRefreshBlockWindows(BlockData->Parent,FALSE);
                }
              break;
          }
        return result;
      // Отмена макроопределений
      #undef Color
      #undef Ready
      #undef Start
      #undef pStart
      }
      //=========================================