Можно ли как то уменьшить мерцание при перерисовке компонента


Как устранить мерцание панели при перерисовке?

У меня есть панель, которую я подклассифицировал и установил DoubleBuffered true, мне постоянно нужно обновлять чертеж, но он мерцает и не имеет понятия, почему.

Поэтому после каждого «вычисления» и добавил что-то к моей воображаемой сетке, мне нужно обновить панель, чтобы показать этот новый элемент в моей сетке. Я попытался сделать недействительным панель перед функцией displayGrid() , но она кажется еще более мерцающей.

Функция heartbeat() в настоящее время вызывается в отдельном потоке.

Вот мой новый класс Panel .

Использование CreateGraphics() и включение двойной буферизации является наихудшей возможной комбинацией. CreateGraphics() предоставляет объект Graphics, который рисует непосредственно на экране. Двойная буферизация устанавливает объект Graphics, который рисует растровое изображение, буфер, используемый в двойной буферизации. Затем отображает растровое изображение на экране в конце цикла рисования.

Итак, что происходит в вашем коде, так это то, что вы рисуете экран напрямую, что-то, что вы едва можете увидеть, но видно, если оно достаточно медленное. Затем сразу после этого буфера, который вы никогда не рисуете, нарисовывается. Что вытирает то, что вы нарисовали раньше. Чистый эффект — это тяжелый мерцание с вашим изображением, видимым только в течение нескольких миллисекунд.

Использование CreateGraphics() было ошибкой. Вы всегда хотите визуализировать через объект e.Graphics, который вы получаете из события Paint, чтобы вы отображали буфер. Передайте этот объект Graphics вашему методу drawMonomers(). Таким образом:

В общем, CreateGraphics() имеет очень ограниченную полезность. Вы только когда-либо используете его, когда хотите рисовать прямо на экране, и вы можете позволить себе все, что вы нарисовали, чтобы исчезнуть. Это обычно полезно только в виде программы, в которой постоянно работает цикл визуализации, создавая новый выход с высокой скоростью, например, 20+ кадров в секунду. Как видеоигра.

[Статья] VCL, избавляемся от мерцания, раз и навсегда

Рекомендуемые сообщения

Похожий контент

Приветствую. Имеется необходимость получить список всех видимых (GUI) компонентов, установленных в Delphi. Я видел где-то, что можно как-то попробовать через ToolsAPI это сделать, но ничего толкового на эту тему так и не нашел. Может есть у кого мысли по этому поводу?
Если возникнет вопрос: для чего тебе это?
Ответ: Для приложения LivePreview, которое идет вместе со студией для того, чтобы видеть то, что размещаю на форме непосредственно на устройстве.

Всем привет, вот и я решил внести свою лепту в жизнь форума и сегодня мы разберемся с разрешениями на Delphi Rio под Андроид.
Для примера мы будем использовать разрешения на чтение и запись с памяти устройства, для начала в нашем проекте выставим в Delphi>Project>Application>Uses Permissions галочки на Read External Storage и Write External Storage.
в uses проекта добавьте следующее
uses System.Permissions, Androidapi.Jni.Os, Androidapi.Helpers, далее создадим переменные
var Form: TForm; . FPermissionWrite: string; FPermissionRead: string; в Form.Create добавим следующий код
procedure TForm.FormCreate(Sender: TObject); begin FPermissionWrite := JStringToString(TJManifest_permission.Java > procedure TForm.Button1Click(Sender: TObject); begin PermissionsService.RequestPermissions ([FPermissionWrite, FPermissionRead], nil); end; //это вызовет окно с запросом разрешения прав ну и для проверки бросим на форму TMemo и пару TButton , в них реализуем сохранение и чтение из файла с памяти устройства
procedure TForm.Button1Click(Sender: TObject); begin Memo1.Lines.LoadFromFile(TPath.Combine(TPath.GetSharedDocumentsPath, ‘test.txt’)); end; procedure TForm.Button2Click(Sender: TObject); begin Memo1.Lines.SaveToFile(TPath.Combine(TPath.GetSharedDocumentsPath, ‘test.txt’)); end; P.S. Напоминаю что для работы TPath нам понадобится подключить в Uses
uses System.system.ioutils; Надеюсь материал будет полезен!

Доброго времени суток, возникло пару вопросов по поводу нового релиза студии, а конкретно Delphi 10.3 community:
1) В каком месте находится презентованный z-order для компонентов и как он работает?
2) Почему на inline объявление переменных ругается редактор кода, но при этом компилятор спокойно пережевывает и не давится?

Доброго дня!
Проясните пожалуйста ситуацию: при запуске программы под Андроидом на различных устройствах я получаю размеры формы, которые вроде всегда в разы меньше чем максимальное разрешение экрана конкретного устройства. Я пробовал планшеты и разные смартфоны. Написал тестовую прогу, которая выводит СlientScreen и ClientWidth формы, на которой ничего больше нет. Например для крайне бюджетного смартфона Fly FS-549 получилось 497 х 320, а по паспорту 854×480. Разрешение и так хреновое, а Delphi его еще сильнее уменьшает. — Почему это происходит и можно ли как то это обойти?

Создал проект там куча компонентов. Но разворачивании формы на весь экран компоненты размер не меняют:
Прочитал про свойства align Но как только я выставлю Group box например left другим right все сбивается в кучу и поправить это не могу.
Как настроить align ?


Как сделать форму с компонентами под все разрешения?

Как задать градиентную заливку TChart? именно самих столбцов.

Последние посетители 0 пользователей онлайн

Ни одного зарегистрированного пользователя не просматривает данную страницу

Мерцание при перемещении и изменении размеров окна

Хочу написать свои контролы. Столкнулся со всем известной проблемой — мерцанием. Облазил все овэрфлоуи, сайберфорумы, рсдны и т.д.

В общем, основной ответ — Двойная Буферизация. Ещё проскакивают варианты с обработкой WM_ERASEBKGND , для случая, когда мерцание происходит при перетаскивании окна. В общем, либо я дурак, либо . Вот код, мерцание происходит при изменении размеров экрана, в связи с рисовкой прямоугольника перед кругом(НО Я ЖЕ ИСПОЛЬЗУЮ ДВОЙНУЮ БУФЕРИЗАЦИЮ). При перетаскивании второго(розоватого) над первым, за ним остаётся след.

Можно ли как то уменьшить мерцание при перерисовке компонента?

100 просмотра

1 ответ

229 Репутация автора

Короткая версия : я использую элемент управления WinForms, который часто мигает при перерисовке. Я обнаружил, что ни одно из существующих решений типа «Включение двойного буфера» не является эффективным, поскольку этот элемент управления буквально выполняет две различные операции рисования непосредственно на своей поверхности рисования при перерисовке. Этот элемент управления должен быть интерактивным (следовательно, самым верхним в форме). Учитывая то, что я могу выполнить инструкции непосредственно перед тем, как этот элемент управления начнет перерисовываться, и сразу после того, как он заканчивает перерисовку, может ли что-нибудь сделать родительский контейнер или содержащая его форма для устранения мерцания этого элемента управления?

Полное объяснение : я делаю пользовательский контроль. ListView как один из детей на нем. Я использую ListView, чтобы в моем элементе управления были столбцы и все функции, которые предоставляют столбцы ListView (следовательно, на моем элементе управления фактически видна только часть заголовка столбца ListView). Мне нужно нарисовать некоторую дополнительную информацию (назовем это «оверлей»), где находится заголовок столбца ListView, но в противном случае я не хочу изменять «внешний вид» заголовка столбца. Очевидно, что я никак не могу просто нарисовать оверлей из моего пользовательского элемента управления (ListView — это дочерний элемент моего элемента управления, и он скрывает поверхность моего элемента управления). У меня не может быть элемента управления в верхней части ListView, чтобы функционировать как наложение WM_NCHITTEST сообщений, но теперь ListView не перерисовывается, и я застрял либо с перерисовкой всего ListView при любых событиях мыши, либо вручную отслеживая, какие области ListView необходимо перерисовать на основе событий, которые получает мой элемент управления наложением (способ тоже хлопотно).

Илон Маск рекомендует:  Почему тормозят игры Как убрать лаги и тормоза

Таким образом, очевидное решение состоит в том, чтобы переопределить заголовок столбца ListView WndProc (как это делает ObjectListView) и добавить туда мой код для наложения чертежа. Так что я:

Выглядит отлично! Но при перерисовке часто, иногда я вижу на экране результат рисования только до marker 2 . Разумеется, это имеет смысл, поскольку теперь у меня есть две различные операции рисования прямо на поверхности рисования заголовка столбца ListView. Тем не менее, я могу установить любое состояние, в котором захочу, marker 1 и marker 3 поэтому у меня должен быть какой-то способ, чтобы приостановить какое-то рисование где-то, верно? Ну, я не могу придумать, как это сделать. Так вот мой вопрос — возможно ли это?

По сути, любые решения, которые я пытался каким-то образом приостановить перерисовку, явно вызывают перерисовку «un-suspend», что приводит к бесконечным WM_PAINT s. Я действительно старался избегать просто избавления base.WndProc(ref m) и рисования заголовков столбцов самостоятельно, наряду с любым стилем рисования, который должен сопровождать его, чтобы сохранить «родной» вид заголовков столбцов. Но после WndProc нескольких дней работы с s я начинаю думать, что рисование заголовков столбцов с нуля на самом деле является наименее болезненным решением .


Ответы (1)

плюса

229 Репутация автора

Ну, я только что понял, что все это время я пропускал одно довольно простое решение — просто нарисовать базовый ListView на другой поверхности! Итак, теперь у меня есть:

Нет больше мерцания! Самое приятное то, что это отвечает на исходный вопрос в общем смысле, поскольку эту технику можно использовать для «исправления» любого плохо рисуемого элемента управления (или добавления дополнительного кода рисования к одному), при условии, что элемент управления правильно обрабатывает WM_PRINT сообщения.

Можно ли уменьшить мерцание VCL?

Это как-то поправить можно, чтобы не мерцало?

В свойствах Windows отключить «отображать содержимое кона при перетаскивании».

В свойствах Windows отключить «отображать содержимое кона при перетаскивании».

Всем привет, а вот еще вопрос про VCL. Есть форма, где много всяких контролов с резиновой версткой. Сделано это все с помощью алигнов и анкоров. Если начать изменять размеры формы, то начинаются мерцания множества контролов. Двойную буфферизацию — пробовал, не помогает. Используем Делфи 2010. Это как-то поправить можно, чтобы не мерцало?

Всем привет, а вот еще вопрос про VCL. Есть форма, где много всяких контролов с резиновой версткой. Сделано это все с помощью алигнов и анкоров. Если начать изменять размеры формы, то начинаются мерцания множества контролов. Двойную буфферизацию — пробовал, не помогает. Используем Делфи 2010. Это как-то поправить можно, чтобы не мерцало?

Можно ли как то уменьшить мерцание при перерисовке компонента?

Рассылка выходит в тестовом режиме

Доброе время суток !

Новости сайта «Все о Дельфи от Чертенка » от 22.01 выпуск 4

Последние изменения на нашем сайте:


«Советы по программированию (FAQ)«

VCL

  1. Как TMainMenu к TCoolBar’у прикрутить?
  2. Как обратиться к свойству компонента по имени свойства?
  3. Как «отловить» выход курсора мыши за пределы компонента?
  4. Как сделать курсор невидимым в Edit, Memo, RichEdit и т.п.?
  5. Как сделать прозрачный TMemo?
  6. Как сделать фоновую картинку в TMemo?
  7. Как создать компонент во время выполнения?
  8. Как создать компонент, который объединяет несколько компонентов?
  9. Как создать не визуальный компонент без иконки, которая изображается в палитре компонентов в «design-time» (вроде TField)?
  10. Как создать у одного приложения 2 или более окон, которые бы отображались на панели задач как отдельные приложения?
  11. Можно ли как-то уменьшить мерцание при перерисовке компонента?
  12. От кого лучше наследоваться при создании компонентов?
  13. Получение позиции курсора для TabControl: над какой закладкой находится курсор?
  14. Процедуры управления потоком исполнения (exit,break,continue)

WIN API

  1. Как вызвать стандартное окно About?
  2. Как вызвать стандартный диалог форматирования дисков?
  3. Как использовать функцию Shell API SHBrowseForFolder,
    чтобы позволить пользователю выбрать каталог?
  4. Как можно имея полное имя файла, вывести для него стандартный
    диалог «Свойства»?
  5. Как прочесть атрибут файла «последний доступ»?
  6. Малоизвестные команды Windows 9xx для запуска из командной
    строки
  7. Как закрыть активное приложение?

Железо

  1. Как найти все компьютеры в рабочей группе?
  2. Как программно выключить компьютер (даже если к нему подключены другие пользователи или работает DOS-программа)?

Прочие

  1. Как вывести текст под углом ?
  2. Как вычислить разницу времени в виде: дни, часы, минуты,
    секунды?
  3. Как динамически считать номер версии EXE-шника?
  4. Как зарегистрировать расширение файла за своим приложением и контекстное меню, связанное с этим типом?
  5. Как заставить иконку минимизированного приложения мигать на таскбаре?
  6. Как лучше всего сравнить две строки без учета регистра, но с учетом текущего языка системы ?
  7. Как можно увеличить дату на произвольное число месяцев?
  8. Как подсчитать занимаемое директорией место?
  9. Как сделать бегущую стpоку?
  10. Как скопировать все файлы вместе с подкаталогами?
  11. Можно ли скопировать ( удалить,переместить,переименовать) группу файлов, используя стандартный диалог с анимацией Копирование Файлов?
  12. Перетаскивание файла(например из проводника) на форму.
  13. Как получить активный URL из браузера?
  14. Как проверить существование определённого адреса(URL) ?

Жду Ваших идеи и предложений (в том числе по оформлению рассылки) .

С наилучшими пожеланиями, Ваш Владимир aka Чертёнок.

Удаление мерцания

Тонкие линии и резкие края в изображениях иногда мерцают при просмотре на экране с чересстрочной разверткой, то есть, на многих телевизионных экранах. Элемент управления «Фильтр мерцаний», расположенный на вкладке «Элементы управления эффектами» > «Движение», уменьшает или удаляет это мерцание. Чем выше его интенсивность, тем меньше мерцание, но изображение становится более мягким. Может потребоваться задать ему относительно высокое значение, для изображений с большим количеством острых краев и высокой контрастностью.

Можно изменить интенсивность фильтра мерцаний по всему клипу, задав разные значения для ключевых кадров фильтра мерцаний.

Справки по другим продуктам


На посты, размещаемые в Twitter™ и Facebook, условия Creative Commons не распространяются.

Adobe Premiere Pro

Вопросы сообществу

Получайте помощь от экспертов по интересующим вас вопросам.

Можно ли как то уменьшить мерцание при перерисовке компонента?

1) На Раздел распространяются все Правила Форума.
2) Перед тем, как создать новый топик, убедитесь, что Вы читали Правила создания тем в Разделе.
3) Вопросы, не связанные с программированием (настройки MS Visual Studio, книги, библиотеки и т.д.),
обсуждаются в разделе C/C++: Прочее
4) Вопросы разработки .NET (Windows Form, C++/CLI и т.п.) приложений на Visual C++/C# обсуждаются в разделе .NET.
5) Нарушение Правил может повлечь наказание со стороны модераторов.

Илон Маск рекомендует:  IsNaN - Функция Delphi

500+ FAQ по Delphi

Перейти на: Главную | Индексную | Предыдущую | Следующую страницу

Как сделать прямоугольник для выделения части картинки для редактирования?

Самый простой способ — воспользоваться функцией Windows API DrawFocusRect. Функция DrawFocusRect использует операцию XOR при рисовании — таким образом вывод прямоугольника дважды с одними и теми же координатами стирает прямоугольник, и прямоугольник всегда будет виден, на фоне какого бы цвета он не выводился.
Пример:

type
TForm1 = class(TForm)
procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private

Capturing : bool;
Captured : bool;
StartPlace : TPoint;
EndPlace : TPoint;
public

end;

var
Form1: TForm1;

function MakeRect(Pt1 : TPoint; Pt2 : TPoint) : TRect;
begin
if pt1.x Можно ли использовать иконку как картинку на кнопке TSpeedButton?

Можно.
uses ShellApi;

procedure TForm1.FormShow(Sender: TObject);
var
Icon: TIcon;
begin
Icon := TIcon.Create;
Icon.Handle := ExtractIcon(0,’C:\WINDOWS\NOTEPAD.EXE’,1);
SpeedButton1.Glyph.W > SpeedButton1.Glyph.Height := Icon.Height;
SpeedButton1.Glyph.Canvas.Draw(0, 0, Icon);
Icon.Free;
end;
Как поместить прозрачную фоновую каринку на компонент CoolBar?

procedure TForm1.Button1Click(Sender: TObject);
var
Bm1 : TBitmap;
Bm2 : TBitmap;
begin
Bm1 := TBitmap.Create;
Bm2 := TBitmap.Create;
Bm1.LoadFromFile(‘c:\download\test.bmp’);
Bm2.W > Bm2.Height := Bm1.Height;
bm2.Canvas.Brush.Color := CoolBar1.Color;
bm2.Canvas.BrushCopy(Rect(0, 0, bm2.Width, bm2.Height), Bm1,
Rect(0, 0, Bm1.width, Bm1.Height), ClWhite);
bm1.Free;
CoolBar1.Bitmap.Assign(bm2);
bm2.Free;
end;
Ползунок компонента TScrollBar все время мигает. Как это отключить?


Установите свойтсво ScrollBar.TabStop в False.
Как программно перевести DBgrid в режим редактирования и установить курсор в окошке редактирования в требуемую позицию?

Переведите таблицу в режим редактирования, затем получите дескриптор (handle) окна редактирования и перешлите ей сообщение EM_SETSEL. В качестве параметров вы должны переслать начальную позицию курсора, и конечную позицию, определяющую конец выделения текста цветом. В приведенном примере курсор помещается во вторую позицию, текст внутри ячейки не выделяется.

procedure TForm1.Button1Click(Sender: TObject);
var
h : THandle;
begin
Application.ProcessMessages;
DbGrid1.SetFocus;
DbGr > Application.ProcessMessages;
h:= Windows.GetFocus;
SendMessage(h, EM_SETSEL, 2, 2);
end;
Как поместить курсор в определенную позицию edit’а и подобных ему элементов управления?

Можно использовать методы Delphi SelStart() и SelectLength().
procedure TForm1.Button1Click(Sender: TObject);
begin
Edit1.SetFocus;
<переводим курсор во вторую позицию>
Edit1.SelStart := 2;
<не выделяем никакого текста>
Edit1.SelLength := 0;
end;
Как среагировать на минимизацию-максимизацию формы перед тем как произойдет изменение размера формы?

В примере перехватывается сообщение WM_SYSCOMMAND. Если это сообщение говорит о
минимизации или максимизации формы — пищит динамик.

type
TForm1 = class(TForm)
private

procedure WMSysCommand(var Msg: TWMSysCommand);
message WM_SYSCOMMAND;
public

end;

var
Form1: TForm1;

procedure TForm1.WMSysCommand;
begin
if (Msg.CmdType = SC_MINIMIZE) or (Msg.CmdType = SC_MAXIMIZE) then
MessageBeep(0)
else
inherited;
end;
Можно ли сделать так — одна форма показывает другую и остается позади нее, но фокус ввода не переходит к новой форме, а остается у старой?

В примере показывается не автосоздаваемая (non auto-created) форма, но фокус ввода ей
не передается.

procedure TForm1.Button1Click(Sender: TObject);
begin
Form2 := TForm2.Create(Application);
Form2.Visible := FALSE;
ShowWindow(Form2.Handle, SW_SHOWNA);
end;
На некоторых laptop компьютерах может не быть флоппи дисковода. Можно ли удалять из списка TDriveComboBox диски которые отключены?

В примере TDriveComboBox не показывает дисководы, которые не готовы. (not ready).
Учтите что на многих компьютерах будет ощутимая задержка при поверке plug&play
флоппи дисковода.

procedure TForm1.FormCreate(Sender: TObject);
var
i : integer;
OldErrorMode : Word;
OldDirectory : string;
begin
OldErrorMode := SetErrorMode(SEM_NOOPENFILEERRORBOX);
GetDir(0, OldDirectory);
i := 0;
while i 0 then
DriveComboBox1.Items.Delete(i)
else
inc(i);
end;
ChDir(OldDirectory);
SetErrorMode(OldErrorMode);
end;
Как сообщить всем формам моего приложения (в том числе и не видимым в данный момент) об изминении каких-то глобальных значений?

Один из способов — создать пользовательское сообщение и использовать метод preform
чтобы разослать его всем формам из массива Screen.Forms.

const
UM_MyGlobalMessage = WM_USER + 1;

type
TForm1 = class(TForm)
Label1: TLabel;
Button1: TButton;
procedure FormShow(Sender: TObject);
procedure Button1Click(Sender: TObject);
private

procedure UMMyGlobalMessage(var AMessage: TMessage); message
UM_MyGlobalMessage;
public

end;

var
Form1: TForm1;


procedure TForm1.FormShow(Sender: TObject);
begin
Form2.Show;
end;

procedure TForm1.UMMyGlobalMessage(var AMessage: TMessage);
begin
Label1.Left := AMessage.WParam;
Label1.Top := AMessage.LParam;
Form1.Caption := ‘Got It!’;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
f: integer;
begin
for f := 0 to Screen.FormCount — 1 do
Screen.Forms[f].Perform(UM_MyGlobalMessage, 42, 42);
end;

const
UM_MyGlobalMessage = WM_USER + 1;
type
TForm2 = class(TForm)
Label1: TLabel;
private

procedure UMMyGlobalMessage(var AMessage: TMessage);
message UM_MyGlobalMessage;
public

end;

var
Form2: TForm2;

procedure TForm2.UMMyGlobalMessage(var AMessage: TMessage);
begin
Label1.Left := AMessage.WParam;
Label1.Top := AMessage.LParam;
Form2.Caption := ‘Got It!’;
end;
Как обновить список дисков компонента TDriveComboBox, учитывая, что могут быть подключены/отключены сетевые диски и произведена «горячая замена» plug&play дисков?

Следующий пример вызывает защищенный (protected) метод класса TDriveComboBox
BuildList() для регеирации списка дисков. (использовая так наз. «class cracer»)

type
TNewDriveComboBox = class(TDriveComboBox) //это наш «class cracer»
end;

procedure TForm1.Button1Click(Sender: TObject);
var
Drive : char;
begin
Drive := DriveComboBox1.Drive;
TNewDriveComboBox(DriveComboBox1).BuildList;
//вызываем защищенный метод родительского класса
DriveComboBox1.Drive := Drive;
end;
Как программно заставить выпасть меню?

В примере показано как показать меню и выбрать в нем какой-то пункт, эмулируя нажатие «быстрой кдавиши» пункта меню. Если у Вашего пункта меню нет «быстрой клавиши» Вы можете посылать комбинации VK_MENU, VK_LEFT, VK_DOWN, и VK_RETURN, чтобы программно «путешествовать» по меню.
Пример:

procedure TForm1.Button1Click(Sender: TObject);
begin
//Allow button to finish painting in response to the click
Application.ProcessMessages;

keybd_Event(VK_MENU, 0, 0, 0);

keybd_Event(ord(‘F’), 0, 0, 0);

keybd_Event(ord(‘F’), 0, KEYEVENTF_KEYUP, 0);

keybd_Event(VK_MENU, 0, KEYEVENTF_KEYUP, 0);

keybd_Event(ord(‘S’), 0, 0, 0);

keybd_Event(ord(‘S’), 0, KEYEVENTF_KEYUP, 0);
end;
Как сделать клавишу-акселератор (keyboard shortcut) компонету у которого нет заголовка?

Возможный вариант — присвоить ссылку на этот компонент свойству FocusControl TLabel’а. В примере используется невидимый Label для создания «быстрой» клавиши (Alt+M) компонента Memo. Чтобы использовать пример, разместите на форме компонет TMemo, Label и несколько других компонентов, которые могут принимать фокус ввода. Запустите программу, перевидите фокус ввода куда-нибудь вне Memo и нажмите Alt+M — фокус ввода вернется в Memo.
Пример:

procedure TForm1.FormCreate(Sender: TObject);
begin
Label1.Visible := false;
Label1.Caption := ‘&M’;
Label1.FocusControl := Memo1;
end;
Можно ли как-то уменьшить мерцание при перерисовке компонента?

Если добавить флаг csOpaque (непрозрачный) к свойству ControlStyle компонента
— то фон компонента перерисовываться не будет.

constructor TMyControl.Create;
begin
inherited;
ControlStyle := ControlStyle + [csOpaque];
end;
Как запретить изменение размера моего компонента в design-time?

Поместите в конструктор компонента код, устанавливающий размеры по умолчанию.
Переопределите метод SetBounds и проверяйте в нем «componentstate». Если компонет
находится режиме «design-time» (csDesigning in ComponentState) просто передавайте
значения ширины и высоты (width и heights) компонента по умолчанию (в нашем
примере 50) методу класса-предка.


procedure TVu.SetBounds(ALeft : integer; ATop : integer; AWidth : integer;
AHeight : integer);
begin
if csdesigning in componentstate then
begin
AW > AHeight := 50;
inherited; //вызываем унаследованный от предка метод
end;
end;
Можно ли уменьшить потребляемые компонентами TNotebook и TTabbedNotebook ресурсы?

Да. Можно уничтожать обьекты, расположенные не на текущей странице TNotebook или
TTabbedNotebook. В примере вызывается защищенный (Protected) метод путем создания
так называемый «class cracer’ов».

type TMyTabbedNotebook = class(TTabbedNotebook); //это наш «class cracer»
type TMyNotebook = class(TNotebook);

Илон Маск рекомендует:  Добавление треугольника

500+ FAQ по Delphi

Перейти на: Главную | Индексную | Предыдущую | Следующую страницу

Как сделать прямоугольник для выделения части картинки для редактирования?

Самый простой способ — воспользоваться функцией Windows API DrawFocusRect. Функция DrawFocusRect использует операцию XOR при рисовании — таким образом вывод прямоугольника дважды с одними и теми же координатами стирает прямоугольник, и прямоугольник всегда будет виден, на фоне какого бы цвета он не выводился.
Пример:

type
TForm1 = class(TForm)
procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private

Capturing : bool;
Captured : bool;
StartPlace : TPoint;
EndPlace : TPoint;
public

end;

var
Form1: TForm1;

function MakeRect(Pt1 : TPoint; Pt2 : TPoint) : TRect;
begin
if pt1.x Можно ли использовать иконку как картинку на кнопке TSpeedButton?

Можно.
uses ShellApi;

procedure TForm1.FormShow(Sender: TObject);
var
Icon: TIcon;
begin
Icon := TIcon.Create;
Icon.Handle := ExtractIcon(0,’C:\WINDOWS\NOTEPAD.EXE’,1);
SpeedButton1.Glyph.W > SpeedButton1.Glyph.Height := Icon.Height;
SpeedButton1.Glyph.Canvas.Draw(0, 0, Icon);
Icon.Free;
end;
Как поместить прозрачную фоновую каринку на компонент CoolBar?

procedure TForm1.Button1Click(Sender: TObject);
var
Bm1 : TBitmap;
Bm2 : TBitmap;
begin
Bm1 := TBitmap.Create;
Bm2 := TBitmap.Create;
Bm1.LoadFromFile(‘c:\download\test.bmp’);
Bm2.W > Bm2.Height := Bm1.Height;
bm2.Canvas.Brush.Color := CoolBar1.Color;
bm2.Canvas.BrushCopy(Rect(0, 0, bm2.Width, bm2.Height), Bm1,
Rect(0, 0, Bm1.width, Bm1.Height), ClWhite);
bm1.Free;
CoolBar1.Bitmap.Assign(bm2);
bm2.Free;
end;
Ползунок компонента TScrollBar все время мигает. Как это отключить?

Установите свойтсво ScrollBar.TabStop в False.
Как программно перевести DBgrid в режим редактирования и установить курсор в окошке редактирования в требуемую позицию?

Переведите таблицу в режим редактирования, затем получите дескриптор (handle) окна редактирования и перешлите ей сообщение EM_SETSEL. В качестве параметров вы должны переслать начальную позицию курсора, и конечную позицию, определяющую конец выделения текста цветом. В приведенном примере курсор помещается во вторую позицию, текст внутри ячейки не выделяется.

procedure TForm1.Button1Click(Sender: TObject);
var
h : THandle;
begin
Application.ProcessMessages;
DbGrid1.SetFocus;
DbGr > Application.ProcessMessages;
h:= Windows.GetFocus;
SendMessage(h, EM_SETSEL, 2, 2);
end;
Как поместить курсор в определенную позицию edit’а и подобных ему элементов управления?


Можно использовать методы Delphi SelStart() и SelectLength().
procedure TForm1.Button1Click(Sender: TObject);
begin
Edit1.SetFocus;
<переводим курсор во вторую позицию>
Edit1.SelStart := 2;
<не выделяем никакого текста>
Edit1.SelLength := 0;
end;
Как среагировать на минимизацию-максимизацию формы перед тем как произойдет изменение размера формы?

В примере перехватывается сообщение WM_SYSCOMMAND. Если это сообщение говорит о
минимизации или максимизации формы — пищит динамик.

type
TForm1 = class(TForm)
private

procedure WMSysCommand(var Msg: TWMSysCommand);
message WM_SYSCOMMAND;
public

end;

var
Form1: TForm1;

procedure TForm1.WMSysCommand;
begin
if (Msg.CmdType = SC_MINIMIZE) or (Msg.CmdType = SC_MAXIMIZE) then
MessageBeep(0)
else
inherited;
end;
Можно ли сделать так — одна форма показывает другую и остается позади нее, но фокус ввода не переходит к новой форме, а остается у старой?

В примере показывается не автосоздаваемая (non auto-created) форма, но фокус ввода ей
не передается.

procedure TForm1.Button1Click(Sender: TObject);
begin
Form2 := TForm2.Create(Application);
Form2.Visible := FALSE;
ShowWindow(Form2.Handle, SW_SHOWNA);
end;
На некоторых laptop компьютерах может не быть флоппи дисковода. Можно ли удалять из списка TDriveComboBox диски которые отключены?

В примере TDriveComboBox не показывает дисководы, которые не готовы. (not ready).
Учтите что на многих компьютерах будет ощутимая задержка при поверке plug&play
флоппи дисковода.

procedure TForm1.FormCreate(Sender: TObject);
var
i : integer;
OldErrorMode : Word;
OldDirectory : string;
begin
OldErrorMode := SetErrorMode(SEM_NOOPENFILEERRORBOX);
GetDir(0, OldDirectory);
i := 0;
while i 0 then
DriveComboBox1.Items.Delete(i)
else
inc(i);
end;
ChDir(OldDirectory);
SetErrorMode(OldErrorMode);
end;
Как сообщить всем формам моего приложения (в том числе и не видимым в данный момент) об изминении каких-то глобальных значений?

Один из способов — создать пользовательское сообщение и использовать метод preform
чтобы разослать его всем формам из массива Screen.Forms.

const
UM_MyGlobalMessage = WM_USER + 1;

type
TForm1 = class(TForm)
Label1: TLabel;
Button1: TButton;
procedure FormShow(Sender: TObject);
procedure Button1Click(Sender: TObject);
private

procedure UMMyGlobalMessage(var AMessage: TMessage); message
UM_MyGlobalMessage;
public

end;

var
Form1: TForm1;

procedure TForm1.FormShow(Sender: TObject);
begin
Form2.Show;
end;

procedure TForm1.UMMyGlobalMessage(var AMessage: TMessage);
begin
Label1.Left := AMessage.WParam;
Label1.Top := AMessage.LParam;
Form1.Caption := ‘Got It!’;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
f: integer;
begin
for f := 0 to Screen.FormCount — 1 do
Screen.Forms[f].Perform(UM_MyGlobalMessage, 42, 42);
end;


const
UM_MyGlobalMessage = WM_USER + 1;
type
TForm2 = class(TForm)
Label1: TLabel;
private

procedure UMMyGlobalMessage(var AMessage: TMessage);
message UM_MyGlobalMessage;
public

end;

var
Form2: TForm2;

procedure TForm2.UMMyGlobalMessage(var AMessage: TMessage);
begin
Label1.Left := AMessage.WParam;
Label1.Top := AMessage.LParam;
Form2.Caption := ‘Got It!’;
end;
Как обновить список дисков компонента TDriveComboBox, учитывая, что могут быть подключены/отключены сетевые диски и произведена «горячая замена» plug&play дисков?

Следующий пример вызывает защищенный (protected) метод класса TDriveComboBox
BuildList() для регеирации списка дисков. (использовая так наз. «class cracer»)

type
TNewDriveComboBox = class(TDriveComboBox) //это наш «class cracer»
end;

procedure TForm1.Button1Click(Sender: TObject);
var
Drive : char;
begin
Drive := DriveComboBox1.Drive;
TNewDriveComboBox(DriveComboBox1).BuildList;
//вызываем защищенный метод родительского класса
DriveComboBox1.Drive := Drive;
end;
Как программно заставить выпасть меню?

В примере показано как показать меню и выбрать в нем какой-то пункт, эмулируя нажатие «быстрой кдавиши» пункта меню. Если у Вашего пункта меню нет «быстрой клавиши» Вы можете посылать комбинации VK_MENU, VK_LEFT, VK_DOWN, и VK_RETURN, чтобы программно «путешествовать» по меню.
Пример:

procedure TForm1.Button1Click(Sender: TObject);
begin
//Allow button to finish painting in response to the click
Application.ProcessMessages;

keybd_Event(VK_MENU, 0, 0, 0);

keybd_Event(ord(‘F’), 0, 0, 0);

keybd_Event(ord(‘F’), 0, KEYEVENTF_KEYUP, 0);

keybd_Event(VK_MENU, 0, KEYEVENTF_KEYUP, 0);

keybd_Event(ord(‘S’), 0, 0, 0);

keybd_Event(ord(‘S’), 0, KEYEVENTF_KEYUP, 0);
end;
Как сделать клавишу-акселератор (keyboard shortcut) компонету у которого нет заголовка?

Возможный вариант — присвоить ссылку на этот компонент свойству FocusControl TLabel’а. В примере используется невидимый Label для создания «быстрой» клавиши (Alt+M) компонента Memo. Чтобы использовать пример, разместите на форме компонет TMemo, Label и несколько других компонентов, которые могут принимать фокус ввода. Запустите программу, перевидите фокус ввода куда-нибудь вне Memo и нажмите Alt+M — фокус ввода вернется в Memo.
Пример:

procedure TForm1.FormCreate(Sender: TObject);
begin
Label1.Visible := false;
Label1.Caption := ‘&M’;
Label1.FocusControl := Memo1;
end;
Можно ли как-то уменьшить мерцание при перерисовке компонента?

Если добавить флаг csOpaque (непрозрачный) к свойству ControlStyle компонента
— то фон компонента перерисовываться не будет.

constructor TMyControl.Create;
begin
inherited;
ControlStyle := ControlStyle + [csOpaque];
end;
Как запретить изменение размера моего компонента в design-time?

Поместите в конструктор компонента код, устанавливающий размеры по умолчанию.
Переопределите метод SetBounds и проверяйте в нем «componentstate». Если компонет
находится режиме «design-time» (csDesigning in ComponentState) просто передавайте
значения ширины и высоты (width и heights) компонента по умолчанию (в нашем
примере 50) методу класса-предка.

procedure TVu.SetBounds(ALeft : integer; ATop : integer; AWidth : integer;
AHeight : integer);
begin
if csdesigning in componentstate then
begin
AW > AHeight := 50;
inherited; //вызываем унаследованный от предка метод
end;
end;
Можно ли уменьшить потребляемые компонентами TNotebook и TTabbedNotebook ресурсы?

Да. Можно уничтожать обьекты, расположенные не на текущей странице TNotebook или
TTabbedNotebook. В примере вызывается защищенный (Protected) метод путем создания
так называемый «class cracer’ов».

type TMyTabbedNotebook = class(TTabbedNotebook); //это наш «class cracer»
type TMyNotebook = class(TNotebook);

Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL