Аналог LockWindowUpdate в лазарусе ?
Модератор: Модераторы
Аналог LockWindowUpdate в лазарусе ?
собственно сабж
Попробую поставить вопрос по другому: для Lunix схожая процедура?
Думаю, если и есть, то искать надо в тулкитах. А вам с какой целью? Насколько мне известно, большинство тех, кто пользуется этой функцией делает это не правильно и всё равно не достигает цели.
Цель этой функции - чисто декоративная, "заморозить" форму на период выполнения различных операций, которые изменяют содержимое этой формы в период своей работы. В Windows я своей цели достиг
. Но хотелось бы что то универсальное...
Как было написано по ссылке - вы достигли своей цели только в частном случае. Тормоза, связанные с отрисовкой (которая не отображается) никуда не делись. Лучше посмотрите на предмет .BeginUpdate/.EndUpdate методов компонентов и более правильной организации работы приложения.
1. Как прикрутить .BeginUpdate/.EndUpdate к TForm?
2. или 1. Мне надо кроссплатформенное решение.
2. или 1. Мне надо кроссплатформенное решение.
.BeginUpdate/.EndUpdate прикручиваются не к форме. Они уже есть у TStrings и, следовательно, во всех местах, где они используются. Собственно, к TForm прикручивать ничего и не надо. У вас проблема, как я понимаю, с тем, что она часто перерисовывается. Ну тут совет только доктора из анекдота: "Так не делайте так". Т.е. сначала считаете всё, что вам надо обновить, потом одним махом обновляете.
У меня проблема с DataSource, точнее с DBGrid.
Ну, в принципе, интернет тоже молчит по данному вопросу (точнее, тоже советует отображать готовые данные).
К счастью, жизнь разнообразней. Не всегда подходят общие решения.
pda, Спасибо за помощь.
Ну, в принципе, интернет тоже молчит по данному вопросу (точнее, тоже советует отображать готовые данные).
К счастью, жизнь разнообразней. Не всегда подходят общие решения.
pda, Спасибо за помощь.
У TDataSet и потомков (всякие *Query) должны быть методы .DisableControls/.EnableControls, которые позволяют проводить операции с набором данных, без обновления экрана. Только потом вернуться надо на старую запись при помощи .Bookmark или .BookmarkStr. Правда я никогда не проверял, как это работает в FPC/Lazarus.
Но, может и работает уже.
У меня, прикольней: я вообще отключаю базу, что бы сделать backup (backup делает внешняя программа из пакета базы). А т.к. программа состоит из одной формы, отсюда и нюансы. Я уже говорил, что блокировка формы - чисто декоративная функция. Просто хотел разобраться с моментом, так на всякий случай, на будущее. Может попозже что то появиться для подобных целей.
На такой случай я бы не пожалел сделать диалоговую форму с сообщением "идёт резервное копирование" и прогрессбаром. Если прогресс снять с внешней утилиты невозможно (и не получается считать объём нового архивного файла), то просто переливающимся.
Блокировать интерфейс не комильфо. Пользователь может решить, что программа повисла, если она перестала реагировать и не успокаевает его.
Простого универсального решения вашего случая нет, потому что тулкиты справедливо полагают, что это - работа приложения, а стандартные db компоненты на такой фокус не рассчитаны.
Однако, если бы мне кровь из носу надо было воспроизвести такой эффект, я бы сделал следущее:
1. Попробовал бы установить свойство .Enabled главной формы в False. В Windows, в Delphi это приводило к тому, что форма становилась неактивной, но компоненты на ней продолжали выглядеть активными.
2. Потом я бы создал своего потомка TDataSource (или покопался бы в его событиях) и в нём попытался бы заблокировать рассылку уведомления "набор данных отключен" (не помню на память, как он называется). И тогда бы компоненты были бы не доступны для пользователя и продолжали бы думать, что база ещё подключена.
3. После подключения вернул бы текущую запись (но, боюсь здесь Bookmark может не сработать, придётся искать по значению ключевого поля) и только потом разрешил бы отправку сообщений через DataSource.
Это, конечно, тоже хак, но у него больше шансов стать кроссплатформенным решением.
Блокировать интерфейс не комильфо. Пользователь может решить, что программа повисла, если она перестала реагировать и не успокаевает его.
Однако, если бы мне кровь из носу надо было воспроизвести такой эффект, я бы сделал следущее:
1. Попробовал бы установить свойство .Enabled главной формы в False. В Windows, в Delphi это приводило к тому, что форма становилась неактивной, но компоненты на ней продолжали выглядеть активными.
2. Потом я бы создал своего потомка TDataSource (или покопался бы в его событиях) и в нём попытался бы заблокировать рассылку уведомления "набор данных отключен" (не помню на память, как он называется). И тогда бы компоненты были бы не доступны для пользователя и продолжали бы думать, что база ещё подключена.
3. После подключения вернул бы текущую запись (но, боюсь здесь Bookmark может не сработать, придётся искать по значению ключевого поля) и только потом разрешил бы отправку сообщений через DataSource.
Это, конечно, тоже хак, но у него больше шансов стать кроссплатформенным решением.
У меня давно (как только понял, что средствами Lazarus ничего не получиться) крутиться дурацкая мысль, сделать "фотку" формы, и наложить ее на реальную. Выберу свободную минутку, попробую это выкурить. 
Доломал...
Кому интересно (а может кто и улучшит мою писанину), кусок:
Пробовал по Windows (пока нет возможности попробовать под Lunix). Есть смаргивание при отключении Panel.
Ну а так... вроде нормально.
Кому интересно (а может кто и улучшит мою писанину), кусок:
Код: Выделить всё
// ******************************//
// * блокировка изменения формы *//
// ******************************//
unit myLockWindow;
{$mode objfpc}
interface
uses
Classes, SysUtils, Graphics, Forms, ExtCtrls, LCLType, LCLIntf, Controls;
function myLockWindowOn(Form: TForm): Boolean;
procedure myLockWindowOff;
implementation
var
Bitmap: TBitmap;
Panel: TPanel;
Image: TImage;
// получение "фотки" формы и отрисовка изображения
function myLockWindowOn(Form: TForm): Boolean;
var
ScreenDC: HDC;
begin
Result := True;
try
Bitmap := TBitmap.Create;
Bitmap.Width := Form.Width;
Bitmap.Height := Form.Height;
ScreenDC := GetDC(Form.Handle);
try
Bitmap.LoadFromDevice(ScreenDC);
finally
ReleaseDC(0, ScreenDC);
end;
Panel := TPanel.Create(Form);
Panel.Visible := False;
Panel.Parent := Form;
Image := TImage.Create(Form);
Image.Parent := Panel;
Image.Picture.Bitmap := Bitmap;
Image.Left := 0;
Image.Top := 0;
Image.Width := Form.Width;
Image.Height := Form.Height;
Panel.BringToFront;
Panel.Align := alClient;
Panel.Visible := True;
except
Result := False;
Bitmap.Free;
Bitmap := nil;
Image.Free;
Image := nil;
Panel.Free;
Panel := nil;
raise;
end;
end;
// закрытие рисунка
procedure myLockWindowOff;
begin
if Panel <> nil then
begin
Panel.SendToBack;
Panel.Visible := False;
Bitmap.Free;
Bitmap := nil;
Image.Free;
Image := nil;
Panel.Free;
Panel := nil;
end;
end;
end.
Пробовал по Windows (пока нет возможности попробовать под Lunix). Есть смаргивание при отключении Panel.
Ну а так... вроде нормально.
