Solved

Is window viewable?

Posted on 2004-04-05
4
207 Views
Last Modified: 2010-04-05
I want to detect from my code whether a given window is visible to the user.  I would like a function something like this:

Function IsViewable( Awindow : HWND ) : boolean;
//returns true if the user can see any part of the window.
//even when other windows partially cover the specified window.


Any thought on how to do this?
0
Comment
Question by:wolsen
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
4 Comments
 

Expert Comment

by:Delian
ID: 10761531
Hello,

used API function:
BOOL IsWindowVisible(HWND hWnd );

Regards,
Delian
0
 
LVL 2

Author Comment

by:wolsen
ID: 10767411
I think that function only tells you whether the visible property of the window is set to true.  It does not return the result I want, if the window has the visible property set, but is coverred by another window.
0
 
LVL 3

Expert Comment

by:Aliev
ID: 10775690
Your points is very low to answer this question :)))))
0
 
LVL 34

Accepted Solution

by:
Slick812 earned 20 total points
ID: 10779846
hello wolsen, I hope you are still here? ?
I did a puzzel program which coverd an area with odd size Rectangles, and if you got the area covered, game over. . . It was very very difficult to determine if all of the area was covered mathamaticaly. I finally did a white Bitmap of the area, and then put Black rectangles on it, and would scanline the bitmap for a white pixel, if found a white pixel, the area was NOT covered. . . anyway here is some code that seems to do what you want. . . .




function SeeWindow(hWnd: Integer): Boolean;
var
zWnd, i, ScanWidth, x, y: Integer;
wndRect, TempRect: TRect;
aryRect: Array of TRect;
AreaBmp: TBitmap;
PCard: PDWord;

begin
{this is the function that will get a Top Level window and see if any pixel of it is visible, returns True}
Result := False;
GetWindowRect(hWnd, wndRect);
IntersectRect(TempRect, wndRect, Rect(0,0, Screen.Width, Screen.Height));
if IsRectEmpty(TempRect) then Exit;

zWnd := 0;
repeat
zWnd := FindWindowEx(0, zWnd, nil, nil);
if zWnd = hWnd then Break;
if (zWnd > 0) and IsWindowVisible(zWnd) then
  begin
  GetWindowRect(zWnd, TempRect);
  IntersectRect(TempRect, TempRect, wndRect);
  if not IsRectEmpty(TempRect) then
    begin
    SetLength(aryRect, Length(aryRect)+1);
    aryRect[High(aryRect)] := TempRect;
    end;
  end;
until zWnd =0;

if Length(aryRect) = 0 then
  begin
  Result := True;
  end else
  if Length(aryRect) = 1 then
  begin
  if not EqualRect(aryRect[0], wndRect) then
    Result := True;
  end else
  begin
  AreaBmp := TBitmap.Create;
  try
    AreaBmp.PixelFormat := pf4Bit;
    {I could not get any Math to get the coverage of these Rectangles on the wndRect.
    So I get a White Bitmap and draw all the rectangles on it as Black rectangles.
    Then I scanLine and if any pixel is still White, then the window is visible
    for at least one pixel}
    AreaBmp.Canvas.Brush.Color := clBlack;
    AreaBmp.Width := (wndRect.Right-wndRect.Left)+((wndRect.Right-wndRect.Left) mod 8);
    AreaBmp.Height := wndRect.Bottom-wndRect.Top;
    AreaBmp.Canvas.Brush.Color := clWhite;
    PatBlt(AreaBmp.Canvas.Handle,0,0,
             wndRect.Right-wndRect.Left, wndRect.Bottom-wndRect.Top, PATCOPY);
    AreaBmp.Canvas.Brush.Color := clBlack;
    for i := 0 to High(aryRect) do
      begin
      OffSetRect(aryRect[i], -wndRect.Left, -wndRect.Top);
      {Draw Black Rectangles on the white Bitmap}
      PatBlt(AreaBmp.Canvas.Handle,aryRect[i].Left,aryRect[i].Top,
           aryRect[i].Right-aryRect[i].Left, aryRect[i].Bottom-aryRect[i].Top, PATCOPY);
      end;

    ScanWidth := (AreaBmp.Width-1) div 8;
    for y := 0 to AreaBmp.Height -1 do
      begin
      PCard := AreaBmp.ScanLine[y];
      for x := 0 to ScanWidth do
        begin
        if PCard^ <> 0 then {this reads 8 pixels at a time, if one is white
                               then PCard is not Zero}
          begin
          Result := True;
          Exit;
          end;
        Inc(PCard);
        end;
      end;


    finally
    FreeAndNil(AreaBmp);
    end;
  end;

end;




//  Below is a Button Click to use the SeeWindow

procedure TForm1.sbut_WindowVisibleClick(Sender: TObject);
var
hNoteP: Integer;
begin
hNoteP := FindWindow(nil, 'Untitled - Notepad');
if hNoteP = 0 then
  begin
  ShowMessage('Could NOT find NotePad');
  Exit;
  end;

if SeeWindow(hNoteP) then
  ShowMessage('Can See');
end;

 - - - - - - - - - -  - - - - - - -  -- - - - - - - - - - - - - - - - - -  -

This is worth way more than 20 points

ask questions if you need more
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
How to renew a Delphi rad-studio licence? 5 77
Find and Replace Stream with 0s 8 72
Delphi...Split view - idea? 1 114
enhance the following code 3 42
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…

756 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question