Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
14-1134562199
BobbyDigital
2005-12-14 15:09
2006.01.08
сериал винта


2-1134929447
JazY
2005-12-18 21:10
2006.01.08
SQL запрос с разными условиями отбора.


2-1135240151
Вт
2005-12-22 11:29
2006.01.08
Виртуальный диск в памяти


1-1133946076
Kolan
2005-12-07 12:01
2006.01.08
Как управлять различными настройками программы?


2-1135170842
kizam
2005-12-21 16:14
2006.01.08
компаненты для toolbar-a





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский