Форум: "Основная";
Текущий архив: 2006.01.08;
Скачать: [xml.tar.bz2];
ВнизКак определить видимость дочернего окна? Найти похожие ветки
← →
Aleksandr. (2005-12-07 14:44) [0]в MDI-приложении открыто несколько дочерних окон с таблицами данных.
Есть глобальные процедуры добавления данных, от дочерних окон не зависящие, в них при успешном добавлении всем дочерним окнам просто посылается сообщение с кодом таблицы.
В WndProc дочернего окна обработка этого сообщения осуществляется следующим образом - если окно является MainForm.ActiveMDIChild и код совпадает, то данные перечитываются, а если код совпадает, но окно не является ActiveMDIChild, то устанавливается флаг, чтобы они перечитались на FormActivate.
И выплыла одна проблема: если открыть два дочерних окна с разными таблицами, расположить их мозаикой, а затем при активном окне Child1 вызвать добавление данных в Table2, то в обработке WndProc с сообщением Код2 окно Child2 совершенно логично не будет считать себя активным и не перечитает данные до своей активации.
Возникает вопрос, как, чтобы не ломать логику, окну определить, что оно, не будучи ActiveMDIChild, видимо полностью или частично из-под верхнего MDIChild?
← →
Игорь Шевченко © (2005-12-07 15:07) [1]
> Возникает вопрос, как, чтобы не ломать логику, окну определить,
> что оно, не будучи ActiveMDIChild, видимо полностью или
> частично из-под верхнего MDIChild?
А не проще ли по активации обновляться ? Определить-то можно, я даже код могу дать, только вот сдается мне, что это кривое решение - обновлять, если видимо.unit main;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls;
type
TfMain = class(TForm)
Timer1: TTimer;
procedure Timer1Timer(Sender: TObject);
private
procedure DisplayVisiblePortion();
function CalcVisiblePortion() : Integer;
end;
var
fMain: TfMain;
implementation
{$R *.DFM}
function RectSquare (const Rect : TRect) : Integer;
begin
with Rect do
Result := (Right - Left) * (Bottom - Top);
if Result < 0 then
Result := - Result;
end;
type
TRectArray = array[0..16384] of TRect;
PRectArray = ^TRectArray;
function RgnSquare (Rgn : HRGN) : Integer;
var
DataSize : DWORD;
RgnData : PRGNDATA;
Rectangles : PRectArray;
I : Integer;
begin
Result := 0;
DataSize := GetRegionData(Rgn, 0, nil);
if DataSize > 0 then begin
GetMem(RgnData, DataSize);
try
GetRegionData(Rgn, DataSize, RgnData);
Rectangles := PRectArray(@RgnData.Buffer);
for I:=0 to Pred(RgnData^.rdh.nCount) do
Inc(Result, RectSquare(Rectangles^[I]));
finally
FreeMem(RgnData, DataSize);
end;
end;
end;
function CalcSquarePortion (SquareWhole, SquarePart : Integer) : Integer;
begin
if SquarePart >= SquareWhole then
Result := 100
else
Result := Trunc((SquarePart / SquareWhole) * 100);
end;
function TfMain.CalcVisiblePortion: Integer;
var
SiblingRect : TRect;
Workarea : TRect;
WinRect : TRect;
Tmp : TRect;
VisiblePortion : TRect;
Sibling : HWND;
WindowSquare : Integer;
WindowRgn, Rgn, TmpRgn : HRGN;
begin
if IsIconic(Handle) then begin
Result := 0;
Exit;
end;
Rgn := CreateRectRgn (0, 0, 0, 0);
try
SystemParametersInfo(SPI_GETWORKAREA, 0, @Workarea, 0);
GetWindowRect(Handle, WinRect);
WindowSquare := RectSquare(WinRect);
IntersectRect(VisiblePortion, WinRect, WorkArea);
Result := CalcSquarePortion(WindowSquare, RectSquare(VisiblePortion));
if Result > 0 then begin
WindowRgn := CreateRectRgnIndirect(VisiblePortion);
try
Sibling := GetWindow(Handle, GW_HWNDPREV);
while (Sibling <> 0) and (Result > 0) do begin
if IsWindowVisible(Sibling) and not IsIconic(Sibling) then begin
GetWindowRect(Sibling, SiblingRect);
IntersectRect(Tmp, VisiblePortion, SiblingRect);
if not IsRectEmpty(Tmp) then begin
TmpRgn := CreateRectRgnIndirect(Tmp);
try
if CombineRgn(Rgn, Rgn, TmpRgn, RGN_OR) = ERROR then
RaiseLastWin32Error();
finally
DeleteObject(TmpRgn);
end;
end;
TmpRgn := CreateRectRgn(0, 0, 0, 0);
if CombineRgn(TmpRgn, WindowRgn, Rgn, RGN_DIFF) = ERROR then
RaiseLastWin32Error();
Result := CalcSquarePortion(WindowSquare, RgnSquare(TmpRgn));
DeleteObject(TmpRgn);
end;
Sibling := GetWindow(Sibling, GW_HWNDPREV);
end;
finally
DeleteObject(WindowRgn);
end;
end;
finally
DeleteObject(Rgn);
end;
end;
procedure TfMain.DisplayVisiblePortion;
begin
Caption := Format ("%d%% percents visible", [CalcVisiblePortion()]);
end;
procedure TfMain.Timer1Timer(Sender: TObject);
begin
DisplayVisiblePortion();
end;
end.
← →
Aleksandr. (2005-12-07 15:18) [2]Игорь Шевченко © :
Спасибо за код, попробую применить его у себя. А насчет по активации обновляться - я рассуждал также, но тестировщики выдали требование, чтобы добавлении записи было видно, а то им непонятно происходящее - диалог они закрыли, а в таблице данных нет. А всякие там синие заголовки окон рассматривать - активны или нет, - им недосуг.
← →
Rouse_ © (2005-12-07 15:18) [3]Может быть лучше проверять - если дочернее окно не свернуто - то пусть перечитывает, или при большом их кол-ве заметные тормоза?
← →
Aleksandr. (2005-12-07 15:55) [4]Rouse_ © :
Да, наборы данных очень большие, и одновременная перезагрузка нескольких окон даст очень большой тормоз.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2006.01.08;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.007 c