in reply to Re: Drawing an outline around a window
in thread Drawing an outline around a Win32 window

I am trying to write something like WinSpy in Perl - for the exercise and the learning mostly. When their cursor icon is moved over windows it outlines the window under the cursor.
  • Comment on Re^2: Drawing an outline around a window

Replies are listed 'Best First'.
Re^3: Drawing an outline around a window
by GrandFather (Saint) on Aug 16, 2005 at 03:40 UTC

    In that case you need to get a DC for the descktop and draw to that.

    Yell if you need more help. I may be able to provide a little, but I can't take you all the way there. (I know Win32 API somewhat, but haven't driven it from Perl).


    Perl is Huffman encoded by design.
      With some help from the Win32 Advanced Perl group, here is what I have so far. I started playing with getWindowDC and Rectangle functions but I am having problems setting the drawn Rectangle as transparent. Also, when I am done dragging, how do I dispose of the DC and refresh all the windows?
      #!perl -w # Left-Click on the target image, and drag use warnings; use strict; use Win32::GUI; use Win32::API; use Win32::GUI::BitmapInline(); my $mw = Win32::GUI::Window->new( -name => "MainWindow", -title => "Win32::GUI Spy++", -pos => [100,100], -size => [100,100], ); my $cursor = get_cursor(); $mw->AddLabel( -name => "Target", -icon => $cursor, -notify => 1, -onMouseDown => \&mouseDown, -onMouseUp => \&mouseUp, -onMouseMove => \&mouseMove, ); $mw->Show(); Win32::GUI::Dialog(); exit(0); ########################### ########################### sub mouseDown{ my $label = shift; Win32::GUI::SetCursor($cursor); $label->SetCapture(); return; } ################ sub mouseUp{ my $label = shift; $label->ReleaseCapture(); return; } ################# sub mouseMove{ my ($label, $x, $y) = @_; # x,y in client co-ordinates return unless Win32::GUI::GetCapture(); Win32::GUI::SetCursor($cursor); my $hwnd=getWindowXY($x,$y); my $class=getWindowClass($hwnd) || ''; my $text=getWindowText($hwnd) || ''; $text=substr($text,0,30) if length($text) > 30; my $exe=getWindowExe($hwnd) || ''; my ($left,$top,$right,$bottom)=getWindowRect($hwnd); my $hdc=getWindowDC(getDesktopWindow()); my $ok=drawRectangle($hdc,$left,$top,$right,$bottom); #print qq|$hwnd\ ($x,$y) [$exe] {$class} "$text"\n|; return; } ############### sub getWindowDC{ #usage: my $hwnd=getWindowDC($hwnd); #info: returns the handle of a device context for the specified wind +ow. my $hwnd=shift || return; my $GetWindowDC = new Win32::API("user32", "GetWindowDC", ['N'], 'N' +) || return $^E; my $hdc=$GetWindowDC->Call($hwnd); return $hdc; } ############### sub getDesktopWindow{ #usage: my $hwnd=getWindowDC($hwnd); #info: returns the handle of a device context for the specified wind +ow. my $GetDesktopWindow = new Win32::API("user32", "GetDesktopWindow", +[], 'N') || return $^E; my $hwnd=$GetDesktopWindow->Call(); return $hwnd; } ############### sub drawRectangle{ #usage: my $ok=drawRectangle($hdc,$left,$top,$right,$bottom); #info: returns the handle of a device context for the specified wind +ow. my $hdc=shift || return; my $left=shift || 0; my $top=shift || 0; my $right=shift || 0; my $bottom=shift || 0; my $Rectangle = new Win32::API("gdi32", "Rectangle", ['N','I','I','I +','I'], 'N') || return $^E; my $ok=$Rectangle->Call($hdc,$left,$top,$right,$bottom); return $hdc; } ############### sub getWindowXY{ #usage: my $hwnd=getWindowXY($x,$y); #info: returns the window handle of window at x,y my $x=shift || return; my $y=shift || return; my $WindowFromPoint = new Win32::API("user32", "WindowFromPoint", [' +N','N'], 'N') || return $^E; my $POINT = pack("LL", $x, $y); return $WindowFromPoint->Call($x,$y); } ############### sub getWindowClass{ my $hwnd = shift || return; my $GetClassName = new Win32::API("user32", "GetClassName", ['N', 'P +', 'N'], 'N') || return $^E; my $name = " " x 1024; my $nameLen = 1024; my $result = $GetClassName->Call($hwnd, $name, $nameLen); if($result){return substr($name, 0, $result);} } ############### sub getWindowExe { #GetModuleFileName my $hwnd = shift || return; my $GetModuleFileName = new Win32::API("kernel32", "GetModuleFileNam +e", ['N', 'P', 'N'], 'N') || return "unable to create new API"; my $name = " " x 1024; my $Len = 1024; my $result = $GetModuleFileName->Call($hwnd, $name, $Len); if($result) {return substr($name, 0, $result);} return "unknown"; } ############### sub getWindowRect { my $hwnd = shift || return; my $GetWindowRect = new Win32::API("user32", "GetWindowRect", ['N', +'P'], 'N') || return $^E; my $RECT = pack("iiii", 0, 0); $GetWindowRect->Call($hwnd, $RECT); return wantarray ? unpack("iiii", $RECT) : $RECT; } ############### sub getWindowText{ my $hwnd = shift || return; my $GetWindowText = new Win32::API("user32", "GetWindowText", ['N', +'P', 'N'], 'N') || return $^E; my $title = " " x 1024; my $titleLen = 1024; my $result = $GetWindowText->Call($hwnd, $title, $titleLen); my $text=substr($title, 0, $result); if($text){return $text;} #if no result send a WM_GetText message to the window my $WmSendMessage = new Win32::API("user32", "SendMessageA", ['N','N +','N','P'],'N') || return $^E; my $WM_GETTEXT=13; my $txt = " " x 2048; my $textLen = 2048; $result = $WmSendMessage->Call($hwnd,$WM_GETTEXT, $textLen, $txt); $text= substr($txt, 0, $result); return $text; } ##################### sub get_cursor{ return Win32::GUI::BitmapInline->newCursor( q( AAACAAEAICAAAA8AEAAwAQAAFgAAACgAAAAgAAAAQAAAAAEAAQAAAAAAAAEAAAAAAAAAAA +AAAAAA AAAAAAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHwAAAGDAAACbIAABQFA +AApsoA AUAFAAECgQACoAqAAqgqgAIBAIACqCqAAqAKgAECgQABQAUAAKbKAABQFAAAJsgAABgwAA +AHwAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////////////////////////// +g////g D///wAf//4gj//8YMf/+ODj//nx8//wMYH/8A4B//AOAf/wDgH/8DGB//nx8//44OP//GD +H//4gj ///AB///4A////g///////////////////////////////////////8= ) ); }