mirror a window

Share your advanced PureBasic knowledge/code with the community.
Tomio
Enthusiast
Enthusiast
Posts: 291
Joined: Sun Apr 27, 2003 4:54 pm
Location: Germany

mirror a window

Post by Tomio »

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:

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) 
**each** loop,
instead of a:

Code: Select all

         OpenLibrary(0, "user32.dll") 
         *Ffx = GetFunction(0, "PrintWindow")  
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.

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) 
../tomio
techjunkie
Addict
Addict
Posts: 1126
Joined: Wed Oct 15, 2003 12:40 am
Location: Sweden
Contact:

Post by techjunkie »

Cool! 8)
Image
(\__/)
(='.'=) This is Bunny. Copy and paste Bunny into your
(")_(") signature to help him gain world domination.
JCV
Enthusiast
Enthusiast
Posts: 580
Joined: Fri Jun 30, 2006 4:30 pm
Location: Philippines

Post by JCV »

yeah cool 8)

[Registered PB User since 2006]
[PureBasic 6.20][SpiderBasic 2.2]
[RP4 x64][Win 11 x64][Ubuntu x64]
Derek
Addict
Addict
Posts: 2354
Joined: Wed Apr 07, 2004 12:51 am
Location: England

Post by Derek »

Useful bit of code, thanks for sharing.
Post Reply