Полный исходный текст на языке 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 } //=========================================