Capture Part or Full of Screen using mouse [Windows]

Share your advanced PureBasic knowledge/code with the community.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4954
Joined: Sun Apr 12, 2009 6:27 am

Capture Part or Full of Screen using mouse [Windows]

Post by RASHAD »

Tested with PB 4.61 x86 - Win 7 x64
Included a few of small tips

Code: Select all

#CAPTUREBLT  = $40000000
#VK_STARTKEY = $5B

UseJPEGImageEncoder()
UsePNGImageEncoder()

FWidth = GetSystemMetrics_(#SM_CXSCREEN)
FHeight = GetSystemMetrics_(#SM_CYSCREEN)

Procedure MinimizeAll()

keybd_event_(#VK_STARTKEY, 0, 0, 0)
keybd_event_(#VK_M, 0, 0, 0)
keybd_event_(#VK_M, 0, #KEYEVENTF_KEYUP, 0)
keybd_event_(#VK_STARTKEY, 0, #KEYEVENTF_KEYUP, 0)

EndProcedure

Procedure RestoreAll()

keybd_event_(#VK_STARTKEY, 0, 0, 0)
keybd_event_(#VK_SHIFT,0,0,0)
keybd_event_(#VK_M,0, 0, 0)
keybd_event_(#VK_M,0, #KEYEVENTF_KEYUP, 0)
keybd_event_(#VK_SHIFT,0,#KEYEVENTF_KEYUP,0)
keybd_event_(#VK_STARTKEY, 0, #KEYEVENTF_KEYUP, 0)

EndProcedure

Procedure HideFromTaskBar(hWnd, Flag)
  Protected TBL.ITaskbarList

  CoInitialize_(0)
  If CoCreateInstance_(?CLSID_TaskBarList, 0, 1, ?IID_ITaskBarList, @TBL) = #S_OK
    TBL\HrInit()
    If Flag
      TBL\DeleteTab(hWnd)
    Else
      TBL\AddTab(hWnd)
    EndIf
    TBL\Release()
  EndIf
  CoUninitialize_()

  DataSection
    CLSID_TaskBarList:
    Data.l $56FDF344
    Data.w $FD6D, $11D0
    Data.b $95, $8A, $00, $60, $97, $C9, $A0, $90
    IID_ITaskBarList:
    Data.l $56FDF342
    Data.w $FD6D, $11D0
    Data.b $95, $8A, $00, $60, $97, $C9, $A0, $90
  EndDataSection
EndProcedure

hWnd = OpenWindow(0,-300,-300,0,0,"",#PB_Window_BorderLess)
SetWindowColor(0,#Red)
SetWindowLong_(WindowID(0),#GWL_EXSTYLE,#WS_EX_LAYERED)
SetLayeredWindowAttributes_(WindowID(0),#Red,0,#LWA_COLORKEY)

OpenWindow(1,0,0,300,52,"Test",#WS_POPUP|#PB_Window_SystemMenu| #PB_Window_ScreenCentered|#PB_Window_Tool,WindowID(0))
ButtonGadget(1,5,5,90,40,"Capture"+Chr(10)+"Part of Screen",#BS_MULTILINE|#BS_CENTER|#BS_VCENTER|#WS_DLGFRAME)
ButtonGadget(2,105,5,90,40,"Capture"+Chr(10)+"Full Screen",#BS_MULTILINE|#BS_CENTER|#BS_VCENTER|#WS_DLGFRAME)
ButtonGadget(3,205,5,90,40,"Save As...",#BS_MULTILINE|#BS_CENTER|#BS_VCENTER|#WS_DLGFRAME)
HideFromTaskBar(WindowID(0), 1)

r.RECT
pen = CreatePen_(#PS_SOLID, 1, #Red)
brush = GetStockObject_(#NULL_BRUSH)
Repeat
  Select WaitWindowEvent()
      
      Case #PB_Event_CloseWindow
            Quit = 1
      
      Case #PB_Event_Gadget
          Select EventGadget()
           Case 1
                 Run ! 1
                 If Run = 1
                    ResizeWindow(0,0,0,FWidth,FHeight)
                 EndIf
                 
           Case 2
                If IsImage(0)
                   FreeImage(0)
                EndIf
                  MinimizeAll()
                  HideWindow(1,1)
                  Delay(300)
                  hBitmap = CreateImage(0,FWidth,FHeight)
                  hdc = StartDrawing(ImageOutput(0))
                  SelectObject_(hdc, hBitmap)
                  BitBlt_(hdc, 0, 0, FWidth,FHeight, GetDC_(GetDesktopWindow_()), 0, 0, #SRCCOPY | #CAPTUREBLT)
                  StopDrawing()
                  HideWindow(1,0)
                  RestoreAll()
                ;DeleteDC_(hdc)              
                  ReleaseDC_(hWnd, hdc)
                  
                 
           Case 3
                 SFile$ = SaveFileRequester("Save image as", "Image.bmp", "bmp|*.bmp|jpg|*.jpg;*.jpeg|png|*.png", 0)
                 Ext$ = GetExtensionPart(SFile$)
                 If Ext$ = "bmp"
                    SaveImage(0,SFile$,#PB_ImagePlugin_BMP)
                 ElseIf Ext$ = "jpg"
                    SaveImage(0,SFile$,#PB_ImagePlugin_JPEG)
                 ElseIf Ext$ = "png"
                    SaveImage(0,SFile$,#PB_ImagePlugin_PNG)
                 EndIf
                 
          EndSelect
          
      Case #WM_MOUSEMOVE
            If Flag = 1
                GetCursorPos_(p.POINT)
                Rectangle_(hdc, r\left,r\top,r\right,r\bottom)
                r\right = p\x
                r\bottom = p\y
                Rectangle_(hdc, r\left,r\top,r\right,r\bottom)
            EndIf 
        
  
      Case #WM_LBUTTONDOWN
            If GetActiveGadget() <> 1
                InvalidateRect_(hWnd, 0,1)
                GetCursorPos_(p.POINT)
                SetRect_(r,p\x,p\y,p\x-1,p\y-1)
                hdc = GetDC_(hWnd)
                SelectObject_(hdc, pen)
                SelectObject_(hdc, brush)
                SetROP2_(hdc, #R2_NOT)
                Rectangle_(hdc, r\left,r\top,r\right,r\bottom)
                Flag = 1
            EndIf
        
      Case #WM_LBUTTONUP
            If Flag = 1
              If IsImage(0)
                 FreeImage(0)
              EndIf
              width = r\right-r\left-2
              height = r\bottom-r\top-2
              If width > 0 And height > 0
                hBitmap = CreateImage(0,width,height)
                hdc = StartDrawing(ImageOutput(0))
                SelectObject_(hdc, hBitmap)
                BitBlt_(hdc, 0, 0, width, height, GetDC_(GetDesktopWindow_()), r\left+1, r\top+1,#SRCCOPY | #CAPTUREBLT)
                StopDrawing()
              EndIf
              ;DeleteDC_(hdc)              
              ReleaseDC_(hWnd, hdc)
              If Run = 0
                 ResizeWindow(0,-300,-300,0,0)
              EndIf              
              Flag = 0
            EndIf          

             
  EndSelect 

Until Quit = 1 Or GetAsyncKeyState_(#VK_ESCAPE)
End

Egypt my love
User avatar
falsam
Enthusiast
Enthusiast
Posts: 632
Joined: Wed Sep 21, 2011 9:11 am
Location: France
Contact:

Re: Capture Part or Full of Screen using mouse [Windows]

Post by falsam »

Good trick Rashad. thank you for sharing. :)

➽ Windows 11 64-bit - PB 6.21 x64 - AMD Ryzen 7 - NVIDIA GeForce GTX 1650 Ti

Sorry for my bad english and the Dunning–Kruger effect 🤪
User avatar
Bisonte
Addict
Addict
Posts: 1313
Joined: Tue Oct 09, 2007 2:15 am

Re: Capture Part or Full of Screen using mouse [Windows]

Post by Bisonte »

Nice... Like the Window Snipping Tool that shipped with Win7 Image

To be "perfect", how about capture the fullscreen first, then open your window... so your window is not on the capture image...
PureBasic 6.21 (Windows x64) | Windows 11 Pro | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
English is not my native language... (I often use DeepL.)
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Capture Part or Full of Screen using mouse [Windows]

Post by Kwai chang caine »

Apparently the capture with mouse not works on XP with 4.61 :(
ImageThe happiness is a road...
Not a destination
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4954
Joined: Sun Apr 12, 2009 6:27 am

Re: Capture Part or Full of Screen using mouse [Windows]

Post by RASHAD »

falsam,Bisonte and KCC
Thanks guys
KCC there is a problem bet #LWA_COLORKEY and XP
Next is rework using direct draw to DeskTop
It needs some enhancement
Try it

Code: Select all

#SHCNE_ASSOCCHANGED = $8000000
#CAPTUREBLT  = $40000000
#VK_STARTKEY = $5B

UseJPEGImageEncoder()
UsePNGImageEncoder()

FWidth = GetSystemMetrics_(#SM_CXSCREEN)
FHeight = GetSystemMetrics_(#SM_CYSCREEN)

Procedure MinimizeAll()

keybd_event_(#VK_STARTKEY, 0, 0, 0)
keybd_event_(#VK_M, 0, 0, 0)
keybd_event_(#VK_M, 0, #KEYEVENTF_KEYUP, 0)
keybd_event_(#VK_STARTKEY, 0, #KEYEVENTF_KEYUP, 0)

EndProcedure

Procedure RestoreAll()

keybd_event_(#VK_STARTKEY, 0, 0, 0)
keybd_event_(#VK_SHIFT,0,0,0)
keybd_event_(#VK_M,0, 0, 0)
keybd_event_(#VK_M,0, #KEYEVENTF_KEYUP, 0)
keybd_event_(#VK_SHIFT,0,#KEYEVENTF_KEYUP,0)
keybd_event_(#VK_STARTKEY, 0, #KEYEVENTF_KEYUP, 0)

EndProcedure

Procedure HideFromTaskBar(hWnd, Flag)
  Protected TBL.ITaskbarList

  CoInitialize_(0)
  If CoCreateInstance_(?CLSID_TaskBarList, 0, 1, ?IID_ITaskBarList, @TBL) = #S_OK
    TBL\HrInit()
    If Flag
      TBL\DeleteTab(hWnd)
    Else
      TBL\AddTab(hWnd)
    EndIf
    TBL\Release()
  EndIf
  CoUninitialize_()

  DataSection
    CLSID_TaskBarList:
    Data.l $56FDF344
    Data.w $FD6D, $11D0
    Data.b $95, $8A, $00, $60, $97, $C9, $A0, $90
    IID_ITaskBarList:
    Data.l $56FDF342
    Data.w $FD6D, $11D0
    Data.b $95, $8A, $00, $60, $97, $C9, $A0, $90
  EndDataSection
EndProcedure

hWnd = OpenWindow(0,0,0,FWidth,FHeight,"",#PB_Window_BorderLess|#PB_Window_Invisible)
SetWindowLong_(WindowID(0),#GWL_EXSTYLE,#WS_EX_LAYERED)
If OSVersion() >= #PB_OS_Windows_Server_2008
SetWindowColor(0,#Red)
   SetLayeredWindowAttributes_(WindowID(0),#Red,0,#LWA_COLORKEY)
Else
   SetLayeredWindowAttributes_(WindowID(0),0,1,#LWA_ALPHA)
EndIf

OpenWindow(1,0,0,300,52,"Test",#WS_POPUP|#PB_Window_SystemMenu| #PB_Window_ScreenCentered|#PB_Window_Tool,WindowID(0))
ButtonGadget(1,5,5,90,40,"Capture"+Chr(10)+"Part of Screen",#PB_Button_Toggle|#BS_MULTILINE|#BS_CENTER|#BS_VCENTER|#WS_DLGFRAME)
ButtonGadget(2,105,5,90,40,"Capture"+Chr(10)+"Full Screen",#BS_MULTILINE|#BS_CENTER|#BS_VCENTER|#WS_DLGFRAME)
ButtonGadget(3,205,5,90,40,"Save As...",#BS_MULTILINE|#BS_CENTER|#BS_VCENTER|#WS_DLGFRAME)
HideFromTaskBar(WindowID(0), 1)

r.RECT
pen = CreatePen_(#PS_SOLID, 1, #Green)
brush = GetStockObject_(#NULL_BRUSH)
Repeat
  Select WaitWindowEvent()
      
      Case #PB_Event_CloseWindow
            Quit = 1
      
      Case #PB_Event_Gadget
          Select EventGadget()
           Case 1                 
                 If GetGadgetState(1) = 1
                    HideWindow(0,0)
                 Else
                    HideWindow(0,1)
                 EndIf
                 
           Case 2
                If IsImage(0)
                   FreeImage(0)
                EndIf
                  MinimizeAll()
                  HideWindow(1,1)
                  Delay(300)
                  hBitmap = CreateImage(0,FWidth,FHeight)
                  hdc = StartDrawing(ImageOutput(0))
                  SelectObject_(hdc, hBitmap)
                  BitBlt_(hdc, 0, 0, FWidth,FHeight, GetDC_(GetDesktopWindow_()), 0, 0, #SRCCOPY | #CAPTUREBLT)
                  StopDrawing()
                  HideWindow(1,0)
                  RestoreAll()
                  DeleteDC_(hdc)              
                  ;ReleaseDC_(hWnd, hdc)
                  
                 
           Case 3
                 SFile$ = SaveFileRequester("Save image as", "Image.bmp", "bmp|*.bmp|jpg|*.jpg;*.jpeg|png|*.png", 0)
                 Ext$ = GetExtensionPart(SFile$)
                 If Ext$ = "bmp"
                    SaveImage(0,SFile$,#PB_ImagePlugin_BMP)
                 ElseIf Ext$ = "jpg"
                    SaveImage(0,SFile$,#PB_ImagePlugin_JPEG)
                 ElseIf Ext$ = "png"
                    SaveImage(0,SFile$,#PB_ImagePlugin_PNG)
                 EndIf
                 
          EndSelect
          
      Case #WM_MOUSEMOVE
            If Flag = 1
                GetCursorPos_(p.POINT)
                Rectangle_(hdc, r\left,r\top,r\right,r\bottom)
                r\right = p\x
                r\bottom = p\y
                Rectangle_(hdc, r\left,r\top,r\right,r\bottom)
            EndIf 
        
  
      Case #WM_LBUTTONDOWN
            If GetActiveWindow() = 0
                InvalidateRect_(hWnd, 0,1)
                If OSVersion() <= #PB_OS_Windows_Vista
                  SHChangeNotify_(#SHCNE_ASSOCCHANGED, $1000, 0, 0)
                  hdc = CreateDC_("DISPLAY", 0, 0, 0)
                Else
                  hdc = GetDC_(hWnd)
                EndIf                
                GetCursorPos_(p.POINT)
                SetRect_(r,p\x,p\y,p\x-1,p\y-1)                
                SelectObject_(hdc, pen)
                SelectObject_(hdc, brush)
                SetROP2_(hdc, #R2_NOTXORPEN)
                Rectangle_(hdc, r\left,r\top,r\right,r\bottom)
                Flag = 1
            EndIf
        
      Case #WM_LBUTTONUP
            SetROP2_(hdc, #R2_COPYPEN	)
            Rectangle_(hdc, r\left,r\top,r\right,r\bottom)
            If Flag = 1
              If IsImage(0)
                 FreeImage(0)
              EndIf
              width = r\right-r\left-2
              height = r\bottom-r\top-2
              If width > 0 And height > 0
                hBitmap = CreateImage(0,width,height)
                hdc = StartDrawing(ImageOutput(0))
                SelectObject_(hdc, hBitmap)
                BitBlt_(hdc, 0, 0, width, height, GetDC_(GetDesktopWindow_()), r\left+1, r\top+1, #SRCCOPY | #CAPTUREBLT)
                StopDrawing()
              EndIf
              Flag = 0              
              DeleteDC_(hdc)
              ;ReleaseDC_(hWnd, hdc)
            EndIf          

             
  EndSelect 

Until Quit = 1 Or GetAsyncKeyState_(#VK_ESCAPE)
End
Last edited by RASHAD on Wed Oct 03, 2012 11:53 pm, edited 3 times in total.
Egypt my love
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Capture Part or Full of Screen using mouse [Windows]

Post by Kwai chang caine »

Yeeess !!! Works great now
Thanks a lot RASHAD for sharing your great code 8)
Believe you, this code also works with W7 ???
ImageThe happiness is a road...
Not a destination
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4954
Joined: Sun Apr 12, 2009 6:27 am

Re: Capture Part or Full of Screen using mouse [Windows]

Post by RASHAD »

Previous post updated for better performance

Have fun
Egypt my love
rsts
Addict
Addict
Posts: 2736
Joined: Wed Aug 24, 2005 8:39 am
Location: Southwest OH - USA

Re: Capture Part or Full of Screen using mouse [Windows]

Post by rsts »

Nice one.

Works fine on win 8.

cheers
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Capture Part or Full of Screen using mouse [Windows]

Post by Kwai chang caine »

Just for info RASHAD, you have replaced the previous code, and now that not works a new time with VISTA and 4.61 :wink:
Impossible to select with the mouse
The old code works always fine on VISTA 8)
ImageThe happiness is a road...
Not a destination
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4954
Joined: Sun Apr 12, 2009 6:27 am

Re: Capture Part or Full of Screen using mouse [Windows]

Post by RASHAD »

rsts Thanks
Well,moving to Win 8 it is fantastic OS much faster than Win 7
KCC I just updated the previous post :mrgreen:
Please check
Egypt my love
Post Reply