mirror a window
Posted: Tue Jul 10, 2007 9:33 am
The following is also (as the result) in "Coding Questions" "mirror a window".
The point is:
Find the handle of any desktop window by mouseclick and copy it's content and all it's subwindows into the imagegadget of your own window. The critical hints where given by netmaestro + srod:
Because I'm on a Win2000 I have to take the somewhat long-winded way to solve the copy:
**each** loop,
instead of a:
at program start with XP.
I use it as a subroutine in a more complex program.
And I ripped it out and put here only because I want to show you its funny effect.
And...well, I have almost no knowledge of Windows Internal and I don't
possess VB and yet I'm able to realize things like that thanks to PB (and it's experts!)
start the code (here an XP).
A small window "PrintWindow" is displayed.
Now click any window on the desktop and/or create new ones.
...The content is displayed in "PrintWindow" and updated according some timesteps.
Best to choose a window, whose content is changing continuously, e.g. some websites.
When you click into the "PrintWindow" image, the display above will turn to red.
and the window choice is locked. You may cover the window by others or move the window aside (almost out of the visible desktop) and still it's (changing) content is beeing displayed.
Again click into the "PrintWindow" image to unlock.
As you will see soon, the result is not always perfect
I have the feeling that the "PrintWindow" function disrupts the window's buildup on the desktop.
Also you'll see that with complex windows some subwindows are not "PrintWindowed".
Perhaps someone finds a solution for that.
../tomio
The point is:
Find the handle of any desktop window by mouseclick and copy it's content and all it's subwindows into the imagegadget of your own window. The critical hints where given by netmaestro + srod:
Code: Select all
GetAncestor_(hwnd,#GA_ROOT) ;==find the handel
CallFunction(0, "PrintWindow", hWnP, hdc, 0) ;==copy content
Because I'm on a Win2000 I have to take the somewhat long-winded way to solve the copy:
Code: Select all
OpenLibrary(0, "user32.dll")
CallFunction(0, "PrintWindow", hWnP, hdc, 0)
CloseLibrary(0)
instead of a:
Code: Select all
OpenLibrary(0, "user32.dll")
*Ffx = GetFunction(0, "PrintWindow")
I use it as a subroutine in a more complex program.
And I ripped it out and put here only because I want to show you its funny effect.
And...well, I have almost no knowledge of Windows Internal and I don't
possess VB and yet I'm able to realize things like that thanks to PB (and it's experts!)
start the code (here an XP).
A small window "PrintWindow" is displayed.
Now click any window on the desktop and/or create new ones.
...The content is displayed in "PrintWindow" and updated according some timesteps.
Best to choose a window, whose content is changing continuously, e.g. some websites.
When you click into the "PrintWindow" image, the display above will turn to red.
and the window choice is locked. You may cover the window by others or move the window aside (almost out of the visible desktop) and still it's (changing) content is beeing displayed.
Again click into the "PrintWindow" image to unlock.
As you will see soon, the result is not always perfect
I have the feeling that the "PrintWindow" function disrupts the window's buildup on the desktop.
Also you'll see that with complex windows some subwindows are not "PrintWindowed".
Perhaps someone finds a solution for that.
Code: Select all
Enumeration
#GUPW ;GetUppermostParentWindow
#GUPWg ;GetUppermostParentWindowGadgt
#GUPWi ;ImageGadet
#GUPWim ;ImagegadgetImage
#GUPWir ;"PrintWindow"Image
EndEnumeration
ExamineDesktops():DTB=DesktopWidth(0):DTH=DesktopHeight(0)
GUPWait=500 ;timestep between "PrintWindow"
GUPWR.rect:GUPWR0.rect
#GA_ROOT =$2:
WText$="Press a window!"
IGB=260:IGH=260 ;imagegadget size: defines OpenWindows() size also.
;mywindow:
Wrd=2: TGB=IGB: TGH=20:WB=IGB+2*Wrd:WH=Wrd+TGH+Wrd+IGH+Wrd
If OpenWindow(#GUPW, 0, 0, WB,WH, "PrintWindow", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(#GUPW))
StringGadget(#GUPWg, Wrd, Wrd,TGB ,TGH, WText$,#PB_Text_Border )
SetGadgetColor(#GUPWg,#PB_Gadget_BackColor,#Yellow)
LFT=LoadFont(#PB_Any,"Arial",8)
SetGadgetFont(#GUPWg, FontID(LFT))
CreateImage(#GUPWim,IGB,IGH): ;"PrintWindow" ends up here.
ImageGadget(#GUPWi,Wrd,Wrd+TGH+Wrd,IGB,IGH,ImageID(#GUPWim),#PB_Image_Border)
;
WText$=Space(255)
Wd0=WindowID(#GUPW)
;mousebuttons switched?
If GetSystemMetrics_(#SM_SWAPBUTTON) = 0 : Btn=#VK_LBUTTON
Else: Btn=#VK_RBUTTON: EndIf
;the loop:
Repeat
Ev = WindowEvent() :If Ev=0:Delay(10):EndIf
If Ev = #PB_Event_CloseWindow: Break: EndIf
;check if we want selected window be [un]locked:
If Ev=#PB_Event_Gadget And EventGadget()=#GUPWi
GAKSlock !1: ;yes, [un]lock it
If GAKSlock=1:SetGadgetColor(#GUPWg,#PB_Gadget_BackColor,#Red)
Else:SetGadgetColor(#GUPWg,#PB_Gadget_BackColor,#Yellow)
EndIf
EndIf
GAKS=GetAsyncKeyState_(Btn)
If GAKS=0 And GAKS0<>0 ;ButtonUP?
GetCursorPos_(@cp.point) ;..yes
hWnd=WindowFromPoint_(cp\x,cp\y)
;the topwindowID of the window clicked into:
hWnP0=GetAncestor_(hwnd,#GA_ROOT)
;need the Dims only to fit into mywindow with width-to-height ratio maintained.
GetWindowRect_(hWnP0,@GUPWR.rect)
GUPWirB=GUPWR\right-GUPWR\left: GUPWirH=GUPWR\bottom-GUPWR\top
;don't want mywindow and the background (desktop),
;...but don't know how to detect desktop directly:
If hWnP0<>Wd0 And (GUPWirB<>DTB Or GUPWirH<>DTH) And GAKSlock=0
;a "real" window was pressed; could be the previous one, but size may have changed
hWnP=hWnP0
;load windowtitle:
GetWindowText_ (hWnP, @WText$, 255) :GUPWT$ = PeekS (@WText$)
;WindowRect changed?
If PeekQ(@GUPWR+0)<>PeekQ(@GUPWR0+0) Or PeekQ(@GUPWR+8)<>PeekQ(@GUPWR0+8)
;..yes, save new values first
PokeW(@GUPWR0+0,PeekQ(@GUPWR+0)):PokeW(@GUPWR0+8,PeekQ(@GUPWR+8))
;calculate the new width+height and the resizefactor to fit into gadget:
GUPWirB=GUPWR\right-GUPWR\left: GUPWirH=GUPWR\bottom-GUPWR\top
If GUPWirB>GUPWirH:
ff.f=IGB/GUPWirB:GUPWirB1=IGB:GUPWirH1=ff*GUPWirH:
Else: ff.f=IGH/GUPWirH:GUPWirH1=IGH:GUPWirB1=ff*GUPWirB:
EndIf
;"PrintWindow" container has new dims:
CreateImage(#GUPWir, GUPWirB,GUPWirH , 24)
EndIf
GUPWait0=0 ;force next "PrintWindow"
Else
EndIf
EndIf
GAKS0=GAKS ;save last button
;time for next "PrintWindow"?
If hWnP<>0 And ElapsedMilliseconds()- GUPWait0>GUPWait
GUPWait0=ElapsedMilliseconds()+GUPWait
;here finally happens the "PrintWindow"...
hdc=StartDrawing(ImageOutput(#GUPWir))
OpenLibrary(0, "user32.dll")
CallFunction(0, "PrintWindow", hWnP, hdc, 0)
CloseLibrary(0)
StopDrawing()
;copy "PrintWindow" resized and centered into gadget "PrintWindow":
StartDrawing(ImageOutput(#GUPWim))
Box(0,0,GUPWirB,GUPWirH,0)
DrawImage(ImageID(#GUPWir),(IGB-GUPWirB1)/2,(IGH-GUPWirH1)/2,GUPWirB1,GUPWirH1)
StopDrawing()
;display the new "PrintWindow"
Debug "Q.6="+Str(GUPWirB1)+" "+Str(GUPWirH1)+" "+Str(hWnP)+" "+t$+"##"+" "+Str(GAKSlock)
SetGadgetText(#GUPWg,GUPWT$)
SetGadgetState(#GUPWi,ImageID(#GUPWim))
EndIf
Delay(20)
Until Ev = #PB_Event_CloseWindow
EndIf
CloseWindow(#GUPW)