Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.56/9: Рейтинг темы: голосов - 9, средняя оценка - 4.56
2 / 2 / 2
Регистрация: 16.02.2014
Сообщений: 153
1

Выделение произвольной области экрана для скриншота

13.10.2020, 00:20. Показов 1882. Ответов 6

Author24 — интернет-сервис помощи студентам
Здравствуйте!
Как правильно реализовать выделение произвольной области экрана?
Делал скриншотер на основе этой статьи http://delphiexpert.ru/sozdani... elphi.html и столкнулся с проблемой мерцания формы, которая служит для выделения области.
Как это можно устранить?(doublebuffered не помог)
на всякий случай прикрепил проект, в нем оставлен только этот функционал (выделение области экрана)

Ну или может есть какие то другие способы реализовать выделение произвольной области?
Вложения
Тип файла: zip d.zip (54.9 Кб, 19 просмотров)
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
13.10.2020, 00:20
Ответы с готовыми решениями:

Выделение области для скриншота
Хочу сделать программку для снятия области скриншота, которая заливала бы файлы на imgur. Сам...

Создание скриншота определенной области экрана
Добрый день. Стоит передо мной задача делать скриншоты определенной части экрана и последующая...

Выделение произвольной области изображения
Пишу прогу для обработки изображения,ламер в С#. Подскажите как выделить произвольную область...

Выделение определённой области экрана
Если в кратце, то мне надо чтобы по нажатию на кнопку надо было сделать 2 клика и выделить область...

6
884 / 586 / 179
Регистрация: 28.02.2017
Сообщений: 2,359
Записей в блоге: 1
13.10.2020, 17:12 2
Лучший ответ Сообщение было отмечено CTAJIuH как решение

Решение

Зачем вы назвали главную форму как Form2, а дополнительную служебную как Form1? Переименуйте их обе нормально (чтоб вообще без циферок).
Зачем вы создаёте дополнительную служебную при инициализации, если не пользуетесь ею, а создаёте другую динамически?

Добавлено через 3 минуты
Вместо:
Delphi
1
2
3
4
ScreenForm.Width := Screen.DesktopWidth;
ScreenForm.Height := Screen.DesktopHeight;
ScreenForm.Left := 0;
ScreenForm.Top := 0;
Лучше:
Delphi
1
ScreenForm.SetBounds(0, 0, Screen.DesktopWidth, Screen.DesktopHeight);
Или вовсе:
Delphi
1
ScreenForm.BoundsRect := Screen.DesktopRect;
Добавлено через 4 минуты
А мерцание из-за того что вы в событии движения мыши сначала делаете:
Delphi
1
Self.Repaint;
Что так-то верно (только Self нафиг не нужен).
Но вот после этого вы зачем-то начинаете лезть в Canvas и даже что-то рисовать - так уже нельзя.
Рисовать надо в OnPaint - который будет вызываться в рамках Repaint;, а не когда уже поздно.

Добавлено через 3 минуты
Delphi
1
2
3
4
5
6
7
8
9
10
begin
  Result := TBitMap.Create;
  with Result, aRect do
  begin
    Result.Free;
    Result := TBitMap.Create;
    Result.Width := aRect.Right - aRect.Left;
    Result.Height := aRect.Bottom - aRect.Top;
    ...
    ... Result.Canvas.Handle, ... , Result.Width, Result.Height, ... , aRect.Left, aRect.Top, ...
1
2 / 2 / 2
Регистрация: 16.02.2014
Сообщений: 153
14.10.2020, 13:27  [ТС] 3
Цитата Сообщение от GoodWeather Посмотреть сообщение
Но вот после этого вы зачем-то начинаете лезть в Canvas и даже что-то рисовать - так уже нельзя.
Рисовать надо в OnPaint - который будет вызываться в рамках Repaint;, а не когда уже поздно.
В процедуре FormMouseMove оставил только запоминание координат и reapint, код "рисования" перенес в OnPaint, но мерцание осталось.
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  // если нажата клавиша мыши, то мы рисуем рамку выделения
  if isDown then
  begin
    finX := X;
    finY := Y;
   // перерисовываем форму
    Self.repaint;
  end;
end;
procedure TForm1.FormPaint(Sender: TObject);
begin
   Self.Canvas.Pen.Width := 0; //1
   Self.Canvas.Pen.Style := psClear;
   // вот здесь мы заливаем область зеленым цветом, благодаря чему она становиться прозрачной
   Self.Canvas.Brush.Color := clGreen;
   Self.Canvas.Rectangle(downX, downY, finX, finY);
end;
0
Модератор
3629 / 2150 / 759
Регистрация: 15.11.2015
Сообщений: 8,631
14.10.2020, 16:22 4
Цитата Сообщение от CTAJIuH Посмотреть сообщение
но мерцание осталось.
Конечно останется, ведь, сначала заливается вся форма и затем прозрачным заливается только часть.
0
884 / 586 / 179
Регистрация: 28.02.2017
Сообщений: 2,359
Записей в блоге: 1
14.10.2020, 17:58 5
Возможно могут быть нюансы зависящие от версии Делфи/VCL. Но в любом случае теперь у вас должно работать DoubleBuffered.

Добавлено через 2 минуты
Self. там зачем? Если убрать будет тож самое.
1
Модератор
3629 / 2150 / 759
Регистрация: 15.11.2015
Сообщений: 8,631
14.10.2020, 18:02 6
Можно закрашивать серым области, которые стали непрозрачны, и закрашивать зелёным новую область, тогда не будет мерцать. Вот переделка, и переменные, которые добавил:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
type
  TForm1 = class(TForm)
...
  private
    oX, oY: integer;
...
 
implementation
...
 
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
// устанавливаем флаг нажатия мыши в true
  isDown := true;
  // и запоминаем текущие координаты
  downX := X;
  downY := Y;
  oX := X; // Добавлено
  oY := Y; // Добавлено
end;
 
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  // если нажата клавиша мыши, то мы рисуем рамку выделения
  if isDown then
  begin
   // перерисовываем форму
//   Repaint;
    Canvas.Pen.Width := 0; //1
    Canvas.Pen.Style := psClear;
    Canvas.Brush.Color := clGrayText;
    // Добавлена затирка областей, которые сейчас стали не прозрачными
    if (oX > downX) and (oY > downY) then begin
      Canvas.Rectangle(X, downY, oX+1, Y+1);
      Canvas.Rectangle(downX, Y, oX+1, oY+1);
    end;
    if (oX > downX) and (oY <= downY) then begin
      Canvas.Rectangle(X, oY, oX+1, downY+1);
      Canvas.Rectangle(downX, oY, oX+1, Y+1);
    end;
    if (oX <= downX) and (oY > downY) then begin
      Canvas.Rectangle(oX, downY, X+1, Y+1);
      Canvas.Rectangle(oX, Y, downX+1, oY+1);
    end;
    if (oX <= downX) and (oY <= downY) then begin
      Canvas.Rectangle(oX, oY, X+1, downY+1);
      Canvas.Rectangle(oX, oY, downX+1, Y+1);
    end;
 
    oX := X;
    oY := Y;
 
   // вот здесь мы заливаем область зеленым цветом, благодаря чему она становиться прозрачной
    Canvas.Brush.Color := clGreen;
    Canvas.Rectangle(downX, downY, X, Y); // И как раньше закрашиваем новую прозрачную область
  end;
end;
1
2 / 2 / 2
Регистрация: 16.02.2014
Сообщений: 153
15.10.2020, 02:06  [ТС] 7
Цитата Сообщение от GoodWeather Посмотреть сообщение
Но в любом случае теперь у вас должно работать DoubleBuffered.
Да, действительно, забыл DoubleBuffered включить) теперь мерцание пропало)
0
15.10.2020, 02:06
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
15.10.2020, 02:06
Помогаю со студенческими работами здесь

Выделение области экрана без перерисовки
Добрый день. Может знает кто, как выделить область экрана без перерисовки(без вызова FormPaint) или...

Получение скриншота экрана
Привет всем! Пытаюсь получить скриншот экрана: QDesktopWidget *desktop =...

Сохранение скриншота выделенной области(?)
Здравствуйте! Требуется ваша помощь, а именно как можно реализовать сохранение нужной мне части...

Способы получения скриншота экрана
Всем привет. Есть ли способ сделать скрин экрана помимо использования метода CopyFromScreen? Мне...

Передача скриншота экрана (clientsocket)
Всем привет! Проблемма заключаеться в том что не могу разобраться с компонентами clientsocket и...

Снимок экрана - Отправка скриншота на почту
Imports System.Net.Mail Public Class Vault Private Sub Form1_Load(ByVal sender As...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru