How to define area of desktop capture?

Windows specific forum
cecilcheah
Enthusiast
Enthusiast
Posts: 168
Joined: Wed Jun 04, 2003 8:44 am
Location: Switzerland

How to define area of desktop capture?

Post by cecilcheah »

Hi there

I want to know how can one do a screen capture of user chosen desktop size by drawing a rectangle line like in Snagit.

From this forum i have found this:

To Draw a rectangle:

Code: Select all

StarDrawing(WindowOuput()) with an XOR mode (DrawingMode(xx))
To capture part of desktop:

Code: Select all

Procedure CaptureScreen(Left.l, Top.l, Width.l, Height.l)
dm.DEVMODE ;structure for CreateDC()
srcDC.l
trgDC.l
BMPHandle.l
srcDC = CreateDC_("DISPLAY", "", "", dm)
trgDC = CreateCompatibleDC_(srcDC)
BMPHandle = CreateCompatibleBitmap_(srcDC, Width, Height)
SelectObject_( trgDC, BMPHandle)
BitBlt_( trgDC, 0, 0, Width, Height, srcDC, Left, Top, #SRCCOPY)
OpenClipboard_(#NULL) 
EmptyClipboard_()
SetClipboardData_(2, BMPHandle)
CloseClipboard_()
DeleteDC_( trgDC)
ReleaseDC_( BMPHandle, srcDC)
ProcedureReturn
EndProcedure
So obviously i have to insert the code from drawing the line into the capture desktop code, but how do i capture the position of the cursor the capture area?

Thanks

Cecil
Froggerprogger
Enthusiast
Enthusiast
Posts: 423
Joined: Fri Apr 25, 2003 5:22 pm
Contact:

Post by Froggerprogger »

Something like this ?

Code: Select all


;Drag with left mouse button to select a part of the screen
;Click the right button to paste it as a bitmap to the clipboard and end

Global Window_Width  : Window_Width  = GetSystemMetrics_(#SM_CXSCREEN)
Global Window_Height : Window_Height = GetSystemMetrics_(#SM_CYSCREEN)
Global corner1.POINT
Global corner2.POINT

Procedure CaptureScreen(Left.l, Top.l, Width.l, Height.l) 
  dm.DEVMODE ;structure for CreateDC() 
  srcDC.l 
  trgDC.l 
  BMPHandle.l 
  srcDC = CreateDC_("DISPLAY", "", "", dm) 
  trgDC = CreateCompatibleDC_(srcDC) 
  BMPHandle = CreateCompatibleBitmap_(srcDC, Width, Height) 
  SelectObject_( trgDC, BMPHandle) 
  BitBlt_( trgDC, 0, 0, Width, Height, srcDC, Left, Top, #SRCCOPY) 
  OpenClipboard_(#NULL) 
  EmptyClipboard_() 
  SetClipboardData_(2, BMPHandle) 
  CloseClipboard_() 
  DeleteDC_( trgDC) 
  ReleaseDC_( BMPHandle, srcDC) 
  ProcedureReturn 
EndProcedure

Pic_desktop = CreateImage(1,Window_Width,Window_Height) 

hDC = StartDrawing(ImageOutput()) 
   BitBlt_(hDC,0,0,Window_Width,Window_Height,GetDC_(GetDesktopWindow_()),0,0,#SRCCOPY) 
StopDrawing() 

OpenWindow(1,0,0,Window_Width,Window_Height,#WS_POPUP,"") 
   CreateGadgetList(WindowID()) 
   ImageGadget(1,0,0,Window_Width,Window_Height,Pic_desktop) 

Layer1_desktop = CreateImage(2,Window_Width,Window_Height) 

Repeat 
  If drawbox
    UseImage(2)
    StartDrawing(WindowOutput())
      DrawImage(UseImage(1),0,0)      
      FrontColor(255,255,255)
      DrawingMode(2|4)
      GetCursorPos_(corner2) 
      Box(corner1\x, corner1\y, corner2\x-corner1\x , corner2\y-corner1\y, $FFFFFF)
    StopDrawing()
  EndIf

  Select WindowEvent() 
     Case #WM_LBUTTONDOWN 
         GetCursorPos_(corner1)              
         drawbox = 1     

     Case #WM_RBUTTONDOWN 
         StartDrawing(WindowOutput()) ; don't grab the boxlines
           DrawImage(UseImage(1),0,0)                   
         StopDrawing()
         ;CreateCompatibleBitmap_ cannot handle negative width/height values...
         If corner1\x > corner2\x : temp.l = corner2\x : corner2\x = corner1\x : corner1\x = temp : EndIf
         If corner1\y > corner2\y : temp.l = corner2\y : corner2\y = corner1\y : corner1\y = temp : EndIf
         CaptureScreen(corner1\x, corner1\y, corner2\x-corner1\x , corner2\y-corner1\y)
         MessageRequester("","Copied to clipboard...",#MB_ICONINFORMATION)
         End 
     Case #WM_LBUTTONUP : drawbox = 0
     
  EndSelect 

  Delay(1)
ForEver  
%1>>1+1*1/1-1!1|1&1<<$1=1
cecilcheah
Enthusiast
Enthusiast
Posts: 168
Joined: Wed Jun 04, 2003 8:44 am
Location: Switzerland

Post by cecilcheah »

Wow, thanks a lot for the code. This is one of the best forum i have ever seen.

Does your code give the option to include mouse cursor or not? How do i include a mouse capture capture or exclude it?

Cecil
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

> Does your code give the option to include mouse cursor or not?

The mouse cursor is not part of the actual screen image, but a "sprite" (of
sorts) which is "above" the screen, which is why it isn't captured when you
capture the screen. Maybe someone else here knows how to capture its
image/position and draw it onto the captured screen image.
User avatar
Inner
PureBasic Expert
PureBasic Expert
Posts: 714
Joined: Fri Apr 25, 2003 4:47 pm
Location: New Zealand

Post by Inner »

get the current cursor icon, load it in, find the cords for it on the desktop and draw the ico image to the bitmap at that position.
El_Choni
TailBite Expert
TailBite Expert
Posts: 1007
Joined: Fri Apr 25, 2003 6:09 pm
Location: Spain

Post by El_Choni »

Hi, very cool tip, I'll use it in the ImageViewer. I've modified it so it doesn't repaint when the cursor is not moving and so the cursor is drawn at the correct position:

Code: Select all

;Drag with left mouse button to select a part of the screen 
;Click the right button to paste it as a bitmap to the clipboard and end 

Window_Width  = GetSystemMetrics_(#SM_CXSCREEN) 
Window_Height = GetSystemMetrics_(#SM_CYSCREEN) 

corner1.POINT
corner2.POINT

Procedure CaptureScreen(Left, Top, Width, Height) 
  dm.DEVMODE ;structure for CreateDC() 
  srcDC.l 
  trgDC.l 
  BMPHandle.l 
  srcDC = CreateDC_("DISPLAY", "", "", dm) 
  trgDC = CreateCompatibleDC_(srcDC) 
  BMPHandle = CreateCompatibleBitmap_(srcDC, Width, Height) 
  SelectObject_(trgDC, BMPHandle) 
  BitBlt_(trgDC, 0, 0, Width, Height, srcDC, Left, Top, #SRCCOPY) 
  OpenClipboard_(#NULL) 
  EmptyClipboard_() 
  SetClipboardData_(2, BMPHandle) 
  CloseClipboard_() 
  DeleteDC_(trgDC) 
  ReleaseDC_(BMPHandle, srcDC) 
  ProcedureReturn 
EndProcedure 

Pic_desktop = CreateImage(1, Window_Width, Window_Height) 

hDC = StartDrawing(ImageOutput()) 
  
BitBlt_(hDC, 0, 0, Window_Width, Window_Height, GetDC_(GetDesktopWindow_()), 0, 0, #SRCCOPY)

StopDrawing() 

OpenWindow(1, 0, 0, Window_Width, Window_Height, #WS_POPUP, "")
  CreateGadgetList(WindowID())
  ImageGadget(1, 0, 0,  Window_Width, Window_Height, Pic_desktop)
  Layer1_desktop = CreateImage(2, Window_Width, Window_Height)
  Repeat
  Select WindowEvent()
    Case #WM_MOUSEMOVE
      If drawbox And SettingCursor=0
        UseImage(2)
        StartDrawing(WindowOutput())
          DrawImage(UseImage(1), 0, 0)      
          FrontColor(255, 255, 255) 
          DrawingMode(2|4)
          GetCursorPos_(corner2)
          Box(corner1\x, corner1\y, corner2\x-corner1\x, corner2\y-corner1\y, $FFFFFF) 
        StopDrawing()
        SettingCursor = 1
        SetCursorPos_(corner2\x, corner2\y)
      Else
        SettingCursor = 0
      EndIf
    Case #WM_LBUTTONDOWN
      GetCursorPos_(corner1)
      drawbox = 1
    Case #WM_RBUTTONDOWN 
      StartDrawing(WindowOutput()) ; don't grab the boxlines 
        DrawImage(UseImage(1),0,0)                    
        StopDrawing() 
        ;CreateCompatibleBitmap_ cannot handle negative width/height values...
        If corner1\x>corner2\x:temp = corner2\x:corner2\x = corner1\x:corner1\x = temp:EndIf 
        If corner1\y>corner2\y:temp = corner2\y:corner2\y = corner1\y:corner1\y = temp:EndIf 
        CaptureScreen(corner1\x, corner1\y, corner2\x-corner1\x, corner2\y-corner1\y)
        MessageRequester("", "Copied to clipboard...", #MB_ICONINFORMATION)
        End
    Case #WM_LBUTTONUP:drawbox = 0
  EndSelect
  Delay(1)
  ForEver
End
El_Choni
cecilcheah
Enthusiast
Enthusiast
Posts: 168
Joined: Wed Jun 04, 2003 8:44 am
Location: Switzerland

But the key definition?

Post by cecilcheah »

That is exactly right. However, it is still not like snagit.

Basically i need to define a key say Shift + CTRL + F11, then the programme will sit at the background until the user press the three keys together and then start the Capture.

How do i do this? This is really out of my reach. Anyone can help, please?

Cecil
El_Choni
TailBite Expert
TailBite Expert
Posts: 1007
Joined: Fri Apr 25, 2003 6:09 pm
Location: Spain

Post by El_Choni »

You'll have to do some research starting with this:

Code: Select all

SetWindowsHookEx_(#WH_KEYBOARD, @KeyboardHook(), hInstance, 0)

Procedure KeyboardHook(code, wParam, lParam)
EndProcedure

hInstance = GetModuleHandle_(0)
Don't have time for more now, tomorrow I'll be able to help you further.
El_Choni
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Re: But the key definition?

Post by PB »

> Basically i need to define a key say Shift + CTRL + F11, then the
> programme will sit at the background until the user press the three
> keys together and then start the Capture.

Here's a hotkey example for your app:

Code: Select all

If OpenWindow(0,100,150,400,200,#PB_Window_SystemMenu,"Test")
  CreateGadgetList(WindowID())
  TextGadget(0,50,50,200,20,"Press  Shift+Control+F11  to hear a chime!")
  RegisterHotKey_(WindowID(),1,#MOD_SHIFT|#MOD_CONTROL,#VK_F11)
  Repeat
    Select WindowEvent()
      Case 0 : Sleep_(1) ; Sleep while no events are pending.
      Case #WM_CLOSE
        UnregisterHotKey_(WindowID(),1)
        End
      Case #WM_HOTKEY
        MessageBeep_(#MB_ICONASTERISK)
    EndSelect
  ForEver
EndIf
Post Reply