Как изменить цвет в области холста - PullRequest
0 голосов
/ 30 декабря 2018

Я пытаюсь щелкнуть и перетащить TCanvas и изменить цвет фона на clHighlight, когда я перетаскиваю вниз, и изменить его на clWhite, если мне нужно изменить направление перетаскивания.Что бы случилось, если бы вы щелкнули по тексту, который вы читаете, и перетащили его вниз или вверх, в любом случае, та же идея.Я почерпнул все, что мог из этой ссылки

, и с тех пор, как я впервые опубликовал этот код, я тщательно редактировал приведенный ниже код. Теперь приведенный ниже код выполняет то, что я намеревался сделать, крометекст в выделении может испортиться, если вы не перетаскиваете его равномерно, что недопустимо.Если вы на самом деле быстро двигаете мышь вверх и вниз, это определенно испортится.Если вы двигаете мышь в устойчивом темпе, это работает хорошо, что заставляет меня бояться, что, возможно, не будет решения этой проблемы.Я продолжаю смотреть на это, если у кого-нибудь есть какие-нибудь предложения, которые были бы великолепны.Я также получил пару ошибок «Нет ресурсов», но пока не уверен, что с этим случилось, я освобождаю растровые изображения, другие ресурсы, о которых я знаю, не задействованы.

Следующий код в событии MouseMove. Прямой выделенный прямоугольник в холсте TImage.прямое такое же прямое переведено на 0,0.bm1 содержит выбранный прямоугольник, скопированный с холста TImage с использованием CopyRect.bm2 содержит bm1 с clWhite (фон), измененным на clHighlight (или наоборот) с помощью BrushCopy.Затем BitBlt используется для копирования bm2 обратно в выбранный исходный прямоугольник TImage.

    // vp is derived from TImage
    if (Y > sel_data->_last_y)
    {
      TRect srect = Rect(sel_data->_rect.Left,sel_data->_last_y,sel_data->_rect.Right, Y);
      TRect drect = Rect(sel_data->_rect.Left,0,sel_data->_rect.Right, sel_data->_rect.Height() - 1);
      Graphics::TBitmap* bm1 = new Graphics::TBitmap;
      bm1->Width = srect.Width();
      bm1->Height = srect.Height();
      Graphics::TBitmap* bm2 = new Graphics::TBitmap;
      bm2->Width = srect.Width();
      bm2->Height = srect.Height();

      bm1->Canvas->CopyRect(drect, vp->Canvas, srect);

      bm2->Canvas->Brush->Color = clHighlight;
      bm2->Canvas->BrushCopy(drect, bm1, drect, clWindow);

      BitBlt(vp->Canvas->Handle, srect.Left, srect.Top, srect.Width(), srect.Height(),
         bm2->Canvas->Handle, 0, 0, SRCCOPY);  
      vp->Refresh();
      delete bm1;
      delete bm2;
    }
    else if (Y < sel_data->_last_y)
    {
      TRect srect = Rect(sel_data->_rect.Left, Y,sel_data->_rect.Right, sel_data->_last_y);
      TRect drect = Rect(sel_data->_rect.Left,0,sel_data->_rect.Right, sel_data->_rect.Height() - 1);
      Graphics::TBitmap* bm1 = new Graphics::TBitmap;
      bm1->Width = srect.Width();
      bm1->Height = srect.Height();
      Graphics::TBitmap* bm2 = new Graphics::TBitmap;
      bm2->Width = srect.Width();
      bm2->Height = srect.Height();

      bm1->Canvas->CopyRect(drect, vp->Canvas, srect);

      bm2->Canvas->Brush->Color = clWhite;
      bm2->Canvas->BrushCopy(drect, bm1, drect, clHighlight);

      int w = srect.Width();
      int h = srect.Height();
      BitBlt(vp->Canvas->Handle, srect.Left, srect.Top, w, h, bm2->Canvas->Handle, 0, 0, SRCCOPY);  
      vp->Refresh();
      delete bm1;
      delete bm2;
    }
    sel_data->_last_y = Y;
  }

1 Ответ

0 голосов
/ 02 января 2019

Это то, что я закончил, все глюки были исправлены, насколько я знаю, я включаю весь обработчик событий MouseMove.Упомянутая выше ссылка дала мне понять, что мне нужен CopyRect, BrushCopy, а затем BitBlt.

void __fastcall Tviewer_ui::viewerPageMouseMove(TObject *Sender, TShiftState Shift, int X, int Y)
{
  if (_selecting)
  {
    TColor to_color = 0;
    TColor from_color = 0; 
    Tviewer_page* vp = static_cast<Tviewer_page *>(Sender);
    Tsel_data* sel_data = &vp->_sel_datas[vp->_c_sel];

    // Scroll window if needed
    int sb_pos = _scrollBox->VertScrollBar->Position;
    if (Y > sb_pos - vp->_top + _scrollBox->Height - 10)
      _scrollBox->VertScrollBar->Position += 10;
    else 
      if (Y < sb_pos - vp->_top + 10)
        _scrollBox->VertScrollBar->Position -= 10;

    int y1 = 0;
    int y2 = 0;
    if (Y > sel_data->_start_y)
    {
      if (Y > sel_data->_last_y)
      {
        y1 = sel_data->_last_y;
        y2 = Y;
        from_color = clWhite;
        to_color = clHighlight;
      }
      else if (Y < sel_data->_last_y)
      {
        y1 = Y;
        y2 = sel_data->_last_y;
        from_color = clHighlight;
        to_color = clWhite;
      }
      sel_data->_rect.Bottom = Y;
    }
    else if (Y < sel_data->_start_y)
    {
      if (Y < sel_data->_last_y)
      {
        y1 = Y;
        y2 = sel_data->_last_y;
        from_color = clWhite;
        to_color = clHighlight;
      }
      else if (Y > sel_data->_last_y)
      {
        y1 = sel_data->_last_y;
        y2 = Y;
        from_color = clHighlight;
        to_color = clWhite;
      }
      sel_data->_rect.Top = Y;
    }
    int height = abs(y1 - y2);
    if (height > 0)
    {
      TRect srect = Rect(sel_data->_rect.Left, y1, sel_data->_rect.Right, y2);
      int width = srect.Width();
      TRect drect = Rect(sel_data->_rect.Left,0,sel_data->_rect.Right, height);
      Graphics::TBitmap* bm1 = new Graphics::TBitmap;
      bm1->Width = width;
      bm1->Height = height;
      Graphics::TBitmap* bm2 = new Graphics::TBitmap;
      bm2->Width = width;
      bm2->Height = height;

      bm1->Canvas->CopyRect(drect, vp->Canvas, srect);
      bm2->Canvas->Brush->Color = to_color;
      bm2->Canvas->BrushCopy(drect, bm1, drect, from_color);

      BitBlt(vp->Canvas->Handle, srect.Left, srect.Top, width, height, bm2->Canvas->Handle, 0, 0, SRCCOPY);  
      vp->Refresh();
      delete bm1;
      delete bm2;
    } 
    sel_data->_last_y = Y;
  }
}
...