Page 1 of 1

How to define area of desktop capture?

Posted: Thu Jun 05, 2003 7:56 am
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

Posted: Thu Jun 05, 2003 9:46 am
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  

Posted: Thu Jun 05, 2003 10:00 am
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

Posted: Thu Jun 05, 2003 12:00 pm
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.

Posted: Thu Jun 05, 2003 1:09 pm
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.

Posted: Thu Jun 05, 2003 1:57 pm
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

But the key definition?

Posted: Thu Jun 05, 2003 11:06 pm
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

Posted: Fri Jun 06, 2003 12:11 am
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.

Re: But the key definition?

Posted: Fri Jun 06, 2003 3:19 am
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