簡體   English   中英

如何更改畫布區域的顏色

[英]How to change a color in an area of a canvas

我試圖在TCanvas上單擊並拖動,並在向下拖動時將背景顏色更改為clHighlight,如果要反轉拖動方向,則將其更改回clWhite。 如果您單擊您正在閱讀的文本並向下或向上拖動,無論如何都會發生幾乎所有的事情。 我已經從這個鏈接中收集了

自從我第一次發布此代碼以來,我已經對下面的代碼進行了廣泛的編輯,下面的代碼現在可以執行我打算要做的事情,除了如果您不以均勻的速度拖動時所選內容中的文本可能會弄亂,這就是不能接受的。 如果您確實真正快速地上下移動鼠標,則肯定會弄亂它。 如果您以穩定的速度移動鼠標,則效果很好,這使我擔心可能無法解決該問題。 如果有人有什么好建議,我會繼續研究。 我還遇到了幾個“資源不足”錯誤,不確定是怎么回事,我正在釋放位圖,沒有其他我知道的資源參與其中。

以下代碼位於MouseMove事件中。srect是TImage畫布中的選定矩形。 drect與轉換為0,0的相同srect。 bm1包含使用CopyRect從TImage的畫布復制的選定矩形。 bm2包含bm1,並且使用BrushCopy將clWhite(背景)更改為clHighlight(或相反)。 然后使用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;
  }

這就是我最終得到的結果,據我所知,所有故障均已修復,其中包括整個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;
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM