DI_USERCONTROL

Свобода выбора! Элемент диалога DI_USERCONTROL описывает элемент управления, определяемый программистом: отрисовка, реагирование на события и прочие операции с элементом - все это возлагается "на хрупкие плечи" плагина.
struct FarDialogItem
{
  int Type          = DI_USERCONTROL
  int X1            = X1
  int Y1            = Y1
  int X2            = X2
  int Y2            = Y2
  int Focus         = User Defined
  CHAR_INFO *VBuf   = виртуальный буфер отрисовки
  DWORD Flags       = Flags
  int DefaultButton = 0
  char Data[512]    = User Defined
};

Внимание! Внимание!

Виртуальный буфер отрисовки

Параметр VBuf задает адрес виртуального буфера типа CHAR_INFO.

Если значение VBuf = NULL, то это значит, что плагин сам должен отрисовывать элемент DI_USERCONTROL после прихода события DN_DRAWDLGITEM, используя сервисную функцию Text.

Если VBuf не равен NULL, то Менеджер Диалогов считает, что это адрес буфера типа CHAR_INFO. Здесь обработчик диалога, в ответ на событие DN_DRAWDLGITEM, должен отрисовать этот элемент в виртуальный буфер, после чего Менеджер Диалогов выдаст содержимое VBuf на экран.

Типичный сценарий следующий (см. плагин Reversi):

// перед вызовом DialogEx, распределим память под виртуальный буфер
#define DIM(Item) (((Item).X2-(Item).X1+1)*((Item).Y2-(Item).Y1+1))
CHAR_INFO *VBuf=new CHAR_INFO[DIM(DialogItems[11])];
DialogItems[11].VBuf=VBuf;
  .
  .
  .
// в обработчике диалога
struct FarDialogItem DialogItem;

case DN_DRAWDLGITEM:
  if(Param1 == 11)
  {
    char Face[4]="   ";
    SMALL_RECT Rect;
    BYTE AddColor=0x00;

    // получим координаты диалога и описание самого элемента
    Info.SendDlgMessage(hDlg,DM_GETDLGRECT,0,(LONG_PTR)&Rect);
    Info.SendDlgMessage(hDlg,DM_GETDLGITEM,11,(LONG_PTR)&DialogItem);

    // цикл отрисовки игрового поля
    for(Y=0; Y < 8; ++Y)
    {
      for(X=0; X < 8; ++X)
      {
        // подготовим один прямоугольник

        // если ячейка не занята...
        if (GAME[0].Field[Y*8+X]==0)
          Face[1]=' ';
        // для белого игрока
        else if (GAME[0].Field[Y*8+X]==GAME[0].Pl1)
        {
          Face[1]=FaceWhite;
          AddColor=0x00;
        }
        // для черного игрока
        else if (GAME[0].Field[Y*8+X]==GAME[0].Pl2)
        {
          Face[1]=FaceBlack;
          AddColor=0x0F;
        }

        // если не получилось когда-то выделить память
        // то рисуем с использованием Text
        if(!DialogItem.VBuf)
        {
          Info.Text(Rect.Left+DialogItem.X1+X*3,
                   Rect.Top+DialogItem.Y1+Y,
                  ColorsPanel[Y&1][X&1]|AddColor,
                  Face);
        }
        else // рисуем прямо в виртуальный буфер
        {
          CHAR_INFO *VBuf=&DialogItem.VBuf[Y*8*3+X*3];

          VBuf[0].Char.AsciiChar=Face[0];
          VBuf[1].Char.AsciiChar=Face[1];
          VBuf[2].Char.AsciiChar=Face[2];

          VBuf[0].Attributes=
             VBuf[1].Attributes=
             VBuf[2].Attributes=ColorsPanel[Y&1][X&1]|AddColor;
        }
      }
    }
  }
  return TRUE;

Флаги

Для элемента DI_USERCONTROL имеют значения следующие флаги:
ФлагОписание
DIF_NOFOCUS управляющий элемент не получает клавиатурный фокус ввода
DIF_DISABLE элемент является недоступным.
DIF_NOTCVTUSERCONTROL не конвертировать символы (CHAR_INFO::Char) перед выводом виртуального буфера на экран.

События

СобытиеОписание
DN_DRAWDLGITEM начало отрисовки элемента
DN_KEY нажата клавиша.
DN_MOUSECLICK "кликнули" клавишей мыши; начало координат - левый верхний угол элемента
DN_KILLFOCUS элемент потерял фокус (при условии, что не используется флаг DIF_NOFOCUS).
DN_GOTFOCUS элемент получил фокус (при условии, что не используется флаг DIF_NOFOCUS).

Замечания

  1. Замечания по работе с курсором см. в описании сообщений DM_GETCURSORPOS или DM_SETCURSORPOS.
  2. Элемент не имеет эффекта в случае использования функции Dialog.
Смотрите также:
FarDialogItem