RitmInMe Описание программы Оператор цифровой трансформации - Dilibrium / Дилибриум
Facebook    Twitter    Google+    LiveJournal    Мой Мир
ВКонтакте     Одноклассники

Font Size

Глюки при работе с функцией CopyRect

В ходе работы над программой RitmInMe я предусмотрел несколько форматов вывода результата, но на практике для небольших стихов самым удобным оказалось элементарное PrintScreen. Естественно, скриншот приходилось обрезать, да и перед этой операцией окошко программы лучше было бы свести к необходимому минимуму... В общем, в контекстное меню окна редактирования была добавлена опция Mini-PrintScreen, которая реализовала всю эту нуднятину, да ещё и затирала ставшие лишними изображения кнопок в правом верхнем углу скриншота программы. Но тут влезло несовершенство программного обеспечения: функция CopyRect, с помощью которой я вырезал из полной копии экрана нужное мне, в некоторых случаях работала с артефактами – повторялись строки и/или столбцы пикселей (см. пример):

Глюк небольшой, но противно...

Для начала я заменил обращение к CopyRect на обычный цикл попиксельной переписи участка изображения. Артефакты исчезли, но работало это раздражающе медленно. Коллективный разум программистов на Delphi устами Google присоветовал мне аналог CopyRectAPIшную функцию BitBlt.

Вот полученный код (с заремленными неудачными вариантами):

  DC := GetDC(0);
  BackgroundCanvas  := TCanvas.Create;
  BackgroundCanvas.Handle := DC;
  w0 := Form1.Left+3;
  h0 := Form1.Top+3;
{
  BGBitmap.Canvas.CopyRect(Rect(0, 0, BGbitmap.Width-1, BGbitmap.Height-1)
   ,BackgroundCanvas
   ,Rect(w0, h0, Form1.Left+BGbitmap.Width-1, Form1.Top+BGbitmap.Height-1));
}
{
  for j := 0 to BGbitmap.Height-1 do
    for i := 0 to BGbitmap.Width-1 do
     BGBitmap.Canvas.Pixels[i,j] := BackgroundCanvas.Pixels[i+w0,j+h0];
}

try
  BitBlt(BGBitmap.Canvas.Handle,0,0, BGbitmap.Width-1, BGbitmap.Height-1
   ,BackgroundCanvas.Handle,w0, h0,SrcCopy);
except
//
end;

Резюме: В CopyRect работало растягивание, и мне бы следовало аккуратнее посчитать координаты исходного и результирующего прямоугольников (в исходном – добавка для координаты нижнего правого угла не "-1", а "+2"). Но... Я предпочёл применить функцию BitBlt, у которой размер прямоугольника задаётся только результирующим и растягивания заведомо нет.