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

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

  // Добавление пунктов в системное меню
  #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;
  }
  //========= Конец главной функции =========

  // Класс личной области данных блока
  class TOpenSysWinData
  { public:
       MenuItem; // Идентификатор созданного пункта меню
      // Настроечные параметры
      char *Caption;   // Название пункта
      int Key;         // Клавиша (или 0,если ее нет)
       KeyShifts; // Состояние Ctrl, Alt и Shift

      // Создание пункта меню с заданными параметрами или
      // изменение параметров уже созданного пункта
      void RegisterMenuItem(void);

      int Setup(void);    // Открыть окно настройки
      void SaveBin(void); // Сохранить параметры
      int LoadBin(void);  // Загрузить параметры

      // Конструктор класса
      TOpenSysWinData(void)
        { Caption=NULL;
          Key=0; KeyShifts=0;
          MenuItem=NULL;
        };
      // Деструктор класса
      ~TOpenSysWinData()
        { // Освободить память, занятую строкой Caption
          (Caption);
          // Удалить пункт меню
          (MenuItem);
        };
  };
  //=========================================

  // Создание или модификация пункта меню
  // 
  // 
  // 
  void TOpenSysWinData::RegisterMenuItem(void)
  { // Вспомогательная переменная для заголовка пункта меню:
    // если Caption==NULL, пункт получит заголовок "Открыть окно"
    const char *text=Caption?Caption:"Открыть окно";
    // Флаги пункта меню: если клавиша определена (Key!=0),
    // пункт будет иметь "горячую клавишу"
     options=Key?:0;

    if(MenuItem) // Пункт уже есть - изменяем
      (MenuItem,text,options,Key,KeyShifts,0,0);
    else // Пункта еще нет - создаем
      MenuItem=(text,options,Key,KeyShifts,0,0);
  }
  //=========================================

  // Запись параметров блока
  void TOpenSysWinData::SaveBin(void)
  {  tag; // Переменная для байта тега
    int len=Caption?strlen(Caption):0; // Длина строки Caption

    tag=1; // Тег 1 – название пункта меню
    (&tag,sizeof(tag));
    (&len,sizeof(len)); // Длина строки
    if(len) // При ненулевой длине – запись самой строки
      (Caption,len);

    tag=2; // Тег 2 – "горячая клавиша"
    (&tag,sizeof(tag));
    (&Key,sizeof(Key));
    (&KeyShifts,sizeof(KeyShifts));

    tag=0; // Тег 0 – конец данных
    (&tag,sizeof(tag));
  }
  //=========================================

  // Загрузка параметров блока
  int TOpenSysWinData::LoadBin(void)
  {  tag; // Переменная для байта тега
    int len;

    // Прежде всего, освобождаем память, которую занимало старое
    // название пункта меню – сейчас загрузится новое
    (Caption);
    Caption=NULL;

    for(;;)
      { if(!(&tag,sizeof(tag)))
          break; // Тег не считан – данные неожиданно кончились
        switch(tag)
          { case 0: // Конец данных
              RegisterMenuItem(); // Создаем или изменяем пункт меню
              return ;
            case 1: // Название пункта
              (&len,sizeof(len));	// Читаем длину
              if(len) // Длина ненулевая – читаем len байтов строки
                { // Отводим место с учетом нуля в конце строки
                  Caption=(char*)(len+1);
                  (Caption,len);	// Читаем строку
                  Caption[len]=0;	// Дописываем нулевой байт в конец
                }
              break;
            case 2: // Данные "горячей клавиши"
              (&Key,sizeof(Key));
              (&KeyShifts,sizeof(KeyShifts));
              break;
            default: // Тег не опознан – ошибка
              return RDS_BFR_ERROR;
          }
      }
    // Вышли из цикла из-за неожиданного конца данных блока - ошибка
    return RDS_BFR_ERROR;
  }
  //=========================================

  // Настройка параметров блока
  // 
  // 
  // 
  int TOpenSysWinData::Setup(void)
  {  window; // Идентификатор объекта-окна
     ok; // Пользователь нажал "OK"
    // Создание окна
    window=(FALSE,-1,-1,"Открытие окна");
    // Поле ввода для строки названия
    (window,0,1,,
        "Текст пункта меню:",200);
    (window,1,,Caption);
    // Поле ввода для "горячей клавиши"
    (window,0,2,,
        "Клавиша:",150);
    (window,2,,Key);
    (window,2,,KeyShifts);
    // Открытие окна
    ok=(window,NULL);
    if(ok)
      { // Нажата кнопка OK – запись параметров в блок
        (Caption); // Уничтожение старой строки
        // Создание динамической копии введенной строки
        Caption=((window,1,
            ));
        // Чтение параметров клавиши
        Key=(window,2,);
        KeyShifts=(window,2,);
        // Создание пункта меню на основе изменившихся параметров
        RegisterMenuItem();
      }
    // Уничтожение окна
    (window);
    // Возвращаемое значение
    return ok?:;
  }
  //=========================================

  // Блок, открывающий окно родительской подсистемы
  extern "C" __declspec(dllexport)
    int  OpenSysWin(int CallMode,
                       BlockData,
                       ExtParam)
  { // Указатель на личную область данных блока,приведенный к
    // правильному типу
    TOpenSysWinData *data=(TOpenSysWinData*)(BlockData->BlockData);
    switch(CallMode)
      { case : // Инициализация
          BlockData->BlockData=data=new TOpenSysWinData();
          break;
        case : // Очистка
          delete data;
          break;
        case : // Настройка
          return data->Setup();
        case : // Сохранение параметров
          data->SaveBin();
          break;
        case : // Загрузка параметров
          return data->LoadBin();
        case :// Выбор пункта меню
          (BlockData->Parent);
          break;
      }
    return ;
  }
  //=========================================


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