Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Screen clipping


  • Please log in to reply
37 replies to this topic
Learning one
  • Members
  • 1447 posts
  • Last active: Jul 02 2014 08:57 PM
  • Joined: 04 Apr 2009
Here you can find:
1. [module] Screen clipping - modular form of screen clipping script below. Easy to use & implement in any script.

2. Screen clipping - Basic screen clipping script. Saves selected area to clipboard.
The goal here was to create small, practical screen clipping script. Made obsolete by [module] Screen clipping.

3. [module] ScreenClip2Win - creates always on top windows from screen clippings.

4. Screen clipping collector - not maintained any more
Saves selected area to virtual container. Collects up to 4 pictures (screen clippings), and allows you to paste
them later. Always preserves current clipboard. Can be modified to collect much more pictures. I found this script useful when
extracting informations from web pages, documents, or when editing pictures. Please read description in script!

See also:
- Screen Capture with Transparent Windows and Mouse Cursor by Sean
- Sumon's branch of ScreenClipping script

For all scripts/modules: thanks to: Sean, wilhberg, and others...

Screen clipping - recommendation --> use the [module] Screen clipping
;===Description========================================================================
/*
Screen clipping script. Saves selected area to clipboard.
AHK forum location: http://www.autohotkey.com/forum/viewtopic.php?t=49950
Put together by Learning one
Thanks: Sean, wilhberg, and others...

To select area:
1. press Control + Left mouse button 
2. drag mouse
3. release Control and Left mouse button 
This area will be saved to clipboard.
Press Control + v to paste it.

Press Esc to exit.
*/


;===Functions==========================================================================
CaptureScreen(aRect)
{
	StringSplit, rt, aRect, `,, %A_Space%%A_Tab%
	nL := rt1
	nT := rt2
	nW := rt3 - rt1
	nH := rt4 - rt2
	znW := rt5
	znH := rt6

	mDC := DllCall("CreateCompatibleDC", "Uint", 0)
	hBM := CreateDIBSection(mDC, nW, nH)
	oBM := DllCall("SelectObject", "Uint", mDC, "Uint", hBM)
	hDC := DllCall("GetDC", "Uint", 0)
	DllCall("BitBlt", "Uint", mDC, "int", 0, "int", 0, "int", nW, "int", nH, "Uint", hDC, "int", nL, "int", nT, "Uint", 0x40000000 | 0x00CC0020)
	DllCall("ReleaseDC", "Uint", 0, "Uint", hDC)
	DllCall("SelectObject", "Uint", mDC, "Uint", oBM)
	DllCall("DeleteDC", "Uint", mDC)
	SetClipboardData(hBM)
}

CreateDIBSection(hDC, nW, nH, bpp = 32, ByRef pBits = "")
{
	NumPut(VarSetCapacity(bi, 40, 0), bi)
	NumPut(nW, bi, 4)
	NumPut(nH, bi, 8)
	NumPut(bpp, NumPut(1, bi, 12, "UShort"), 0, "Ushort")
	NumPut(0,  bi,16)
	Return	DllCall("gdi32\CreateDIBSection", "Uint", hDC, "Uint", &bi, "Uint", 0, "UintP", pBits, "Uint", 0, "Uint", 0)
}

SetClipboardData(hBitmap)
{
	DllCall("GetObject", "Uint", hBitmap, "int", VarSetCapacity(oi,84,0), "Uint", &oi)
	hDIB :=	DllCall("GlobalAlloc", "Uint", 2, "Uint", 40+NumGet(oi,44))
	pDIB :=	DllCall("GlobalLock", "Uint", hDIB)
	DllCall("RtlMoveMemory", "Uint", pDIB, "Uint", &oi+24, "Uint", 40)
	DllCall("RtlMoveMemory", "Uint", pDIB+40, "Uint", NumGet(oi,20), "Uint", NumGet(oi,44))
	DllCall("GlobalUnlock", "Uint", hDIB)
	DllCall("DeleteObject", "Uint", hBitmap)
	DllCall("OpenClipboard", "Uint", 0)
	DllCall("EmptyClipboard")
	DllCall("SetClipboardData", "Uint", 8, "Uint", hDIB)
	DllCall("CloseClipboard")
}


;===Hotkeys=========================================================================
^Lbutton::
CoordMode, Mouse ,Screen
MouseGetPos, MX, MY
Gui, +AlwaysOnTop -caption +Border +ToolWindow +LastFound
WinSet, Transparent, 80
Gui, Color, lime

While, (GetKeyState("LButton", "p"))
{
	MouseGetPos, MXend, MYend
	Send {control up}
	w := abs(MX - MXend)
	h := abs(MY - MYend)
	If ( MX < MXend )
	X := MX
	Else
	X := MXend
	If ( MY < MYend )
	Y := MY
	Else
	Y := MYend
	Gui, Show, x%X% y%Y% w%w% h%h%
	Sleep, 10
}

MouseGetPos, MXend, MYend
Gui, Destroy
If ( MX > MXend )
{
	temp := MX
	MX := MXend
	MXend := temp
}
If ( MY > MYend )
{
	temp := MY
	MY := MYend
	MYend := temp
}
Area = %MX%, %MY%, %MXend%, %MYend%
Sleep, 100	; if omitted, GUI sometimes stays in picture
CaptureScreen(Area)	; Saves selected area without cursor in Clipboard.
Return

Escape::
Suspend
ExitApp

Screen clipping collector
;===Description=========================================================================
/*
Screen clipping collector v1.01       by Learning one
AHK forum location: http://www.autohotkey.com/forum/viewtopic.php?t=49950
Thanks: Chris, Sean, wilhberg, and others...

Saves selected area to virtual container. Collects up to 4 pictures (screen clippings), and allows you to paste
them later. Always preserves current clipboard. Can be modified to collect much more pictures, but I don't think 
that's practical. It's better to paste collected pictures, empty container, and start collecting again.
After each successful screen clipping, small number will appear on center of the screen, indicating saved
picture's number. You can even apply color effect to your screen clipping by setting ApplyColorEffect = yes.
In that case, screen clipping will be merged with selection's color and transparency. Try it, just for fun.
I know that I should make GUI (especially for this color effect), but I currently don't have time and will
to do that. For now, you can change script's settings in Settings section, a few lines lower. I tried to write
this script in "newbie frendly style" so almost everyone can study it, and modify as he wish.

I found this script useful when extracting informations from web pages, documents, or when editing pictures.

Tested and works in MS Word, PowerPoint, Excel, OneNote and Paint. If it does not work properly, see description
for AppendClipboardSleep variable in Settings section.
Due to clipboard -> virtual container -> clipboard data transfer, this script might not work in some applications.
In that case, use my other script, "Screen clipping". Also see description for AppendClipboardSleep variable.


Hotkeys:
Control + Lbutton      Click and drag to select area to clip (once you started selecting, you can release Control)
C                      Cancel while selecting area (abort) (it is not real hotkey, it is condition, if statement)
Control + 1-4          Paste 1-4. picture
Control + E            Empty picture container
Escape                 Exit
*/


;===Settings - change this if you wish==================================================
SelectionColor = yellow         ; Allowed values: valid color name (see www.autohotkey.com/docs/commands/Progress.htm#colors)
SelectionTransparency = 80      ; Allowed values: 0 - 255 
ApplyColorEffect = no           ; Allowed values: yes, no
PhotoTrayIcon = yes             ; Allowed values: yes, no
ShowHotkeys = yes               ; Allowed values: yes, no
AppendClipboardSleep = 80       ; Control + 1-4 sometimes pastes your Clipboard, not picture. To fix this, you can: 1) simply press this hotkey again or 2) increase this value. Recommended values: 20 - 500


;===Auto-execute========================================================================
if PhotoTrayIcon = yes
Menu, Tray, Icon, Shell32.dll, 140      ; photo icon
StringTrimRight, Sname, A_ScriptName, 4
Menu, Tray, Tip, %Sname%

if ShowHotkeys = yes
{
   TrayTip, Screen clipping collector - Hotkeys,
   (
Control + Lbutton`tSelect area
C`t`t`tCancel while selecting area
Control + 1-4`t`tPaste 1-4. picture
Control + E`t`tEmpty container
Escape`t`t`tExit
   ), 10, 1
}

;===Functions===========================================================================
CaptureScreen(aRect)
{
   StringSplit, rt, aRect, `,, %A_Space%%A_Tab%
   nL := rt1
   nT := rt2
   nW := rt3 - rt1
   nH := rt4 - rt2
   znW := rt5
   znH := rt6

   mDC := DllCall("CreateCompatibleDC", "Uint", 0)
   hBM := CreateDIBSection(mDC, nW, nH)
   oBM := DllCall("SelectObject", "Uint", mDC, "Uint", hBM)
   hDC := DllCall("GetDC", "Uint", 0)
   DllCall("BitBlt", "Uint", mDC, "int", 0, "int", 0, "int", nW, "int", nH, "Uint", hDC, "int", nL, "int", nT, "Uint", 0x40000000 | 0x00CC0020)
   DllCall("ReleaseDC", "Uint", 0, "Uint", hDC)
   DllCall("SelectObject", "Uint", mDC, "Uint", oBM)
   DllCall("DeleteDC", "Uint", mDC)
   SetClipboardData(hBM)
}

CreateDIBSection(hDC, nW, nH, bpp = 32, ByRef pBits = "")
{
   NumPut(VarSetCapacity(bi, 40, 0), bi)
   NumPut(nW, bi, 4)
   NumPut(nH, bi, 8)
   NumPut(bpp, NumPut(1, bi, 12, "UShort"), 0, "Ushort")
   NumPut(0,  bi,16)
   Return   DllCall("gdi32\CreateDIBSection", "Uint", hDC, "Uint", &bi, "Uint", 0, "UintP", pBits, "Uint", 0, "Uint", 0)
}

SetClipboardData(hBitmap)
{
   DllCall("GetObject", "Uint", hBitmap, "int", VarSetCapacity(oi,84,0), "Uint", &oi)
   hDIB :=   DllCall("GlobalAlloc", "Uint", 2, "Uint", 40+NumGet(oi,44))
   pDIB :=   DllCall("GlobalLock", "Uint", hDIB)
   DllCall("RtlMoveMemory", "Uint", pDIB, "Uint", &oi+24, "Uint", 40)
   DllCall("RtlMoveMemory", "Uint", pDIB+40, "Uint", NumGet(oi,20), "Uint", NumGet(oi,44))
   DllCall("GlobalUnlock", "Uint", hDIB)
   DllCall("DeleteObject", "Uint", hBitmap)
   DllCall("OpenClipboard", "Uint", 0)
   DllCall("EmptyClipboard")
   DllCall("SetClipboardData", "Uint", 8, "Uint", hDIB)
   DllCall("CloseClipboard")
}


;===Hotkeys=============================================================================
^Lbutton::      ; Click and drag to select area to clip
no++
if no > 4
{
   MsgBox, 52, Container full!, Screen clipping container is full.`nPressing Control + E will empty it.`n`nDo you want to empty container now?`n(You will lose all 4 screen clippings)
   IfMsgBox, yes
   {
      Progress, m2 b fs13 zh0 WMn700, Container emptied!
      Gosub, EmptyAndProgressOff
      Return
   }
   Else
   Return
}

CoordMode, Mouse ,Screen
MouseGetPos, MX, MY
Gui, +AlwaysOnTop -caption +Border +ToolWindow +LastFound
WinSet, Transparent, %SelectionTransparency%
Gui, Color, %SelectionColor%

While, (GetKeyState("LButton", "p"))
{
   MouseGetPos, MXend, MYend
   Send {control up}
   w := abs(MX - MXend)
   h := abs(MY - MYend)
   If (MX < MXend)
   X := MX
   Else
   X := MXend
   If (MY < MYend)
   Y := MY
   Else
   Y := MYend
   Gui, Show, x%X% y%Y% w%w% h%h%
   if (GetKeyState("c", "p"))       ; Cancel while selecting area (abort)
   {
      Gui, Destroy
      no--
      Send, {control up}{c up}{LButton up}
      Return
   }
   Sleep, 10
}

MouseGetPos, MXend, MYend
if ApplyColorEffect = yes
{
   Gui, hide
   Gui, -Border
   Gui, Show, x%X% y%Y% w%w% h%h%
}
if ApplyColorEffect = no
Gui, Destroy
If (MX > MXend)
{
   temp := MX
   MX := MXend
   MXend := temp
}
If (MY > MYend)
{
   temp := MY
   MY := MYend
   MYend := temp
}
Area = %MX%, %MY%, %MXend%, %MYend%
OriginalClipboard = %ClipboardAll%		; save
Sleep, 100   ; if omitted, GUI sometimes stays in picture
CaptureScreen(Area)   ; Saves selected area without cursor in Clipboard.
if ApplyColorEffect = yes
Gui, Destroy
Picture%no% := ClipboardAll
Progress, m2 b fs13 zh0 WMn700 w40, %no%
Sleep, 600
Clipboard = %OriginalClipboard%		; restore
Progress, off
Return

^1::        ; Paste 1. picture
^2::        ; Paste 2. picture
^3::        ; Paste 3. picture
^4::        ; Paste 4. picture
Gosub, PastePicture
Return

^e::    	; Empty picture container and restart numbering
Progress, m2 b fs13 zh0 WMn700, Container emptied!
IfWinExist, Container full!
{
   SetControlDelay, -1
   ControlClick, &No, Container full!
   SetControlDelay, 20
}
Gosub, EmptyAndProgressOff
Return

Escape::       ; Exit
Suspend
ExitApp


;===Subroutines=========================================================================
PastePicture:
OriginalClipboard = %ClipboardAll%		; save
StringTrimLeft, PicNo, A_ThisHotkey, 1
if PicNo = 1
Clipboard := Picture1
Else if PicNo = 2
Clipboard := Picture2
Else if PicNo = 3
Clipboard := Picture3
Else if PicNo = 4
Clipboard := Picture4
Sleep, %AppendClipboardSleep% ; if omitted, next command sometimes paste OriginalClipboard, not Picture! Use Clipboard := "" and ClipWait if you wish.
Send, ^v
Clipboard = %OriginalClipboard%		; restore
Return

EmptyAndProgressOff:
Picture1 =
Picture2 =
Picture3 =
Picture4 =
no = 0
Sleep, 900
Progress, off
Return


AutoHotkeyFan
  • Guests
  • Last active:
  • Joined: --
w00000000000000000000000000t.

Thank you so much for this excellent script.
I can't believe how much I love AutoHotkey and it's community.

The combination of AutoHotey scripts and Desktops ( http://technet.micro... ... 17881.aspx ) has made my Windows XP machine TEH shit.

:D:D:D:D:D

AutoHotkeyFan
  • Guests
  • Last active:
  • Joined: --
Is there any way of running multiple instances of this script, i.e. one instance per windows desktop object (Desktop objects are created by Desktops v1.0)

AutoHotkeyFan
  • Guests
  • Last active:
  • Joined: --
Please disregard my question.

The problem is that the Desktops application doesn't enable the copy function to work between the different desktops objects. In other words starting the script on the different desktop objects works fine, but to paste a clipped image from one desktop and paste it to the other doesn't work. It sucks, but Desktops is far the most stable virtual desktop application I've come across, so I'll stick with it :-)

Learning one
  • Members
  • 1447 posts
  • Last active: Jul 02 2014 08:57 PM
  • Joined: 04 Apr 2009
@AutoHotkeyFan

Thank you so much for this excellent script.

Thank you for compliments.

Please disregard my question.

Ok.

:arrow: Soon I will post new, enhanced screen clipping script. So visit this topic for day or two.

ruespe
  • Members
  • 567 posts
  • Last active: Dec 20 2013 06:21 PM
  • Joined: 17 Jun 2008
Fantastic. I like it.

Some suggestions:

Other Hotkey without LButton, which freezes the screen (make a screenshot of whole screen and show it) while menues etc. are open and windows active, so that you can position your mouse. With LButton down drag the area, with LButton up take screenshot and unfreeze the screen.

That would be great. And cross hairs while positioning the mouse would be even greaterererer. And a magnifier for exact positioning. And... and... and...

I'm curious about your further development.

Learning one
  • Members
  • 1447 posts
  • Last active: Jul 02 2014 08:57 PM
  • Joined: 04 Apr 2009
@ruespe

Fantastic. I like it.

Thanks :D

Generally, study this:

<!-- m -->http://www.autohotke... ... our select<!-- m --> (Screen Capture with Transparent Windows and Mouse Cursor)


To make a screenshot of whole screen, while menues etc. are open and windows active
1. you must download ScreenCapture.ahk and #Include it in your script! Download it here: <!-- m -->http://www.autohotke... ... apture.zip<!-- m -->
2. type
^1::CaptureScreen(0,1,0)	; This will capture whole screen, with mouse cursor, and open menues to clipboard, when you press Control + 1

cross hairs while positioning the mouse
Study this:
<!-- m -->http://www.autohotke...pic.php?t=35600<!-- m -->
<!-- m -->http://www.autohotke...pic.php?t=27257<!-- m -->
<!-- m -->http://www.autohotke...opic.php?t=9192<!-- m -->

My further development:
Soon I will post script called Screen clipping collector
It saves selected area to virtual container. Collects a few pictures (screen clippings), and allows you to paste them later, when you wish. It always preserves current clipboard. I tried to write it in "newbie frendly style" so almost everyone can study it, and modify as he wish.

Learning one
  • Members
  • 1447 posts
  • Last active: Jul 02 2014 08:57 PM
  • Joined: 04 Apr 2009
:arrow: Check out new script, Screen clipping collector in the first post in this topic (Edited)

slim
  • Members
  • 6 posts
  • Last active: Nov 06 2009 11:15 PM
  • Joined: 16 Oct 2009
:D

I've just tried both the scripts out. They are excellent.

Screen clipper:
- Pure excellence. It will be incorporated as one of my startup scripts.

Screen collector:
- Good concept and well executed coding. However, I'm on the fence whether it will increase my productivity over the screen clipper.

Regardless, job well done! Thank you so much for your time and effort!

flak
  • Members
  • 283 posts
  • Last active: Jan 01 2012 06:20 PM
  • Joined: 02 Oct 2009
Screen Clipper is very nice indeed, I included it in my screenshot script, much thanks for sharing.

  • Guests
  • Last active:
  • Joined: --
is it possible to change the color of the selection window...

Learning one
  • Members
  • 1447 posts
  • Last active: Jul 02 2014 08:57 PM
  • Joined: 04 Apr 2009
Yes, of course.

If you are thinking on my Screen clipping script,
replace the following text:
Gui, Color, lime
with this:
; example
Gui, Color, blue ; or any other valid color name...

If you are thinking on my Screen clipping collector, set SelectionColor variable (you can find it in "Settings" section) to any other valid color name...
; example
SelectionColor = blue ; or any other valid color name...


  • Guests
  • Last active:
  • Joined: --
thx :D

Zonanic
  • Guests
  • Last active:
  • Joined: --
If you want to save to .jpeg instead of to clipboard this code is modified and working of the OP's code.

/*
 *   1. Keep script running.
 *   2. Limit to one running copy.
 *   3. Run script without pauses.
 */
#Persistent
#SingleInstance ignore
SetBatchLines, 10ms



/*
 *-------------------------------------------------------------------------------------
 *       Use hotkey:    Win + PrtScr
 *-------------------------------------------------------------------------------------
 */
^Lbutton::
CoordMode, Mouse ,Screen
MouseGetPos, MX, MY
Gui, +AlwaysOnTop -caption +Border +ToolWindow +LastFound
WinSet, Transparent, 80
Gui, Color, lime

While, (GetKeyState("LButton", "p"))
{
   MouseGetPos, MXend, MYend
   Send {control up}
   w := abs(MX - MXend)
   h := abs(MY - MYend)
   If ( MX < MXend )
   X := MX
   Else
   X := MXend
   If ( MY < MYend )
   Y := MY
   Else
   Y := MYend
   Gui, Show, x%X% y%Y% w%w% h%h%
   Sleep, 10
}

MouseGetPos, MXend, MYend
Gui, Destroy
If ( MX > MXend )
{
   temp := MX
   MX := MXend
   MXend := temp
}
If ( MY > MYend )
{
   temp := MY
   MY := MYend
   MYend := temp
}
Area = %MX%, %MY%, %MXend%, %MYend%
Sleep, 100   ; if omitted, GUI sometimes stays in picture
CaptureScreen(Area)   ; Saves selected area without cursor in Clipboard

   /*
    * Create folder.
    */
   IfNotExist, PrintScreen
   {
      FileCreateDir, PrintScreen
   }


   /*
    * Reset counter.
    */
   countLoop := 1


   /*
    * Repeat until we have unused name for file.
    */
   loopFileName:

      /*
       * Reset string.
       */
      countLoopString := countLoop
      
      /*
       * Add leading zeroes to string.
       */
      loopStringAddZeroes:
         if (StrLen(countLoopString) < 4)
         {
            countLoopString := "0" countLoopString
            Goto, loopStringAddZeroes
         }
      
      /*
       * Form the name of new file.
       */
      newFileName := "PrintScreen\img_" countLoopString ".jpg"
      
      /*
       * Check if file name is taken.
       */
      IfExist, % newFileName
      {
         countLoop++
         Goto, loopFileName
      }

      
   /*
    * Capture screenshot.
    */
   CaptureScreen(Area, False, newFileName, 100)
return



/*
 * If the script goes this far...
 */
Exit




/*
 *-------------------------------------------------------------------------------------
 *   Screen Capture with Transparent Windows and Mouse Cursor:
 *         http://www.autohotkey.com/forum/topic18146.html
 *-------------------------------------------------------------------------------------
   CaptureScreen(aRect, bCursor, sFileTo, nQuality)
      1) If the optional parameter bCursor is True, captures the cursor too.
      2) If the optional parameter sFileTo is 0, set the image to Clipboard.
         If it is omitted or "", saves to screen.bmp in the script folder,
         otherwise to sFileTo which can be BMP/JPG/PNG/GIF/TIF.
      3) The optional parameter nQuality is applicable only when sFileTo is JPG. Set it to the desired quality level of the resulting JPG, an integer between 0 - 100.
      4) If aRect is 0/1/2/3, captures the entire desktop/active window/active client area/active monitor.
      5) aRect can be comma delimited sequence of coordinates, e.g., "Left, Top, Right, Bottom" or "Left, Top, Right, Bottom, Width_Zoomed, Height_Zoomed".
         In this case, only that portion of the rectangle will be captured. Additionally, in the latter case, zoomed to the new width/height, Width_Zoomed/Height_Zoomed.

   Example:
      CaptureScreen(0)
      CaptureScreen(1)
      CaptureScreen(2)
      CaptureScreen(3)
      CaptureScreen("100, 100, 200, 200")
      CaptureScreen("100, 100, 200, 200, 400, 400")   ; Zoomed

   Convert:
      Convert(sFileFr, sFileTo, nQuality)
      Convert("C:\image.bmp", "C:\image.jpg")
      Convert("C:\image.bmp", "C:\image.jpg", 95)
      Convert(0, "C:\clip.png")   ; Save the bitmap in the clipboard to sFileTo if sFileFr is "" or 0.
*/

;CaptureScreen()
;Return

CaptureScreen(aRect = 0, bCursor = False, sFile = "", nQuality = "")
{
   If   !aRect
   {
      SysGet, nL, 76
      SysGet, nT, 77
      SysGet, nW, 78
      SysGet, nH, 79
   }
   Else If   aRect = 1
      WinGetPos, nL, nT, nW, nH, A
   Else If   aRect = 2
   {
      WinGet, hWnd, ID, A
      VarSetCapacity(rt, 16, 0)
      DllCall("GetClientRect" , "Uint", hWnd, "Uint", &rt)
      DllCall("ClientToScreen", "Uint", hWnd, "Uint", &rt)
      nL := NumGet(rt, 0, "int")
      nT := NumGet(rt, 4, "int")
      nW := NumGet(rt, 8)
      nH := NumGet(rt,12)
   }
   Else If   aRect = 3
   {
      VarSetCapacity(mi, 40, 0)
      DllCall("GetCursorPos", "int64P", pt)
      DllCall("GetMonitorInfo", "Uint", DllCall("MonitorFromPoint", "int64", pt, "Uint", 2), "Uint", NumPut(40,mi)-4)
      nL := NumGet(mi, 4, "int")
      nT := NumGet(mi, 8, "int")
      nW := NumGet(mi,12, "int") - nL
      nH := NumGet(mi,16, "int") - nT
   }
   Else
   {
      StringSplit, rt, aRect, `,, %A_Space%%A_Tab%
      nL := rt1
      nT := rt2
      nW := rt3 - rt1
      nH := rt4 - rt2
      znW := rt5
      znH := rt6
   }

   mDC := DllCall("CreateCompatibleDC", "Uint", 0)
   hBM := CreateDIBSection(mDC, nW, nH)
   oBM := DllCall("SelectObject", "Uint", mDC, "Uint", hBM)
   hDC := DllCall("GetDC", "Uint", 0)
   DllCall("BitBlt", "Uint", mDC, "int", 0, "int", 0, "int", nW, "int", nH, "Uint", hDC, "int", nL, "int", nT, "Uint", 0x40000000 | 0x00CC0020)
   DllCall("ReleaseDC", "Uint", 0, "Uint", hDC)
   If   bCursor
      CaptureCursor(mDC, nL, nT)
   DllCall("SelectObject", "Uint", mDC, "Uint", oBM)
   DllCall("DeleteDC", "Uint", mDC)
   If   znW && znH
      hBM := Zoomer(hBM, nW, nH, znW, znH)
   If   sFile = 0
      SetClipboardData(hBM)
   Else   Convert(hBM, sFile, nQuality), DllCall("DeleteObject", "Uint", hBM)
}

CaptureCursor(hDC, nL, nT)
{
   VarSetCapacity(mi, 20, 0)
   mi := Chr(20)
   DllCall("GetCursorInfo", "Uint", &mi)
   bShow   := NumGet(mi, 4)
   hCursor := NumGet(mi, 8)
   xCursor := NumGet(mi,12)
   yCursor := NumGet(mi,16)

   VarSetCapacity(ni, 20, 0)
   DllCall("GetIconInfo", "Uint", hCursor, "Uint", &ni)
   xHotspot := NumGet(ni, 4)
   yHotspot := NumGet(ni, 8)
   hBMMask  := NumGet(ni,12)
   hBMColor := NumGet(ni,16)

   If   bShow
      DllCall("DrawIcon", "Uint", hDC, "int", xCursor - xHotspot - nL, "int", yCursor - yHotspot - nT, "Uint", hCursor)
   If   hBMMask
      DllCall("DeleteObject", "Uint", hBMMask)
   If   hBMColor
      DllCall("DeleteObject", "Uint", hBMColor)
}

Zoomer(hBM, nW, nH, znW, znH)
{
   mDC1 := DllCall("CreateCompatibleDC", "Uint", 0)
   mDC2 := DllCall("CreateCompatibleDC", "Uint", 0)
   zhBM := CreateDIBSection(mDC2, znW, znH)
   oBM1 := DllCall("SelectObject", "Uint", mDC1, "Uint",  hBM)
   oBM2 := DllCall("SelectObject", "Uint", mDC2, "Uint", zhBM)
   DllCall("SetStretchBltMode", "Uint", mDC2, "int", 4)
   DllCall("StretchBlt", "Uint", mDC2, "int", 0, "int", 0, "int", znW, "int", znH, "Uint", mDC1, "int", 0, "int", 0, "int", nW, "int", nH, "Uint", 0x00CC0020)
   DllCall("SelectObject", "Uint", mDC1, "Uint", oBM1)
   DllCall("SelectObject", "Uint", mDC2, "Uint", oBM2)
   DllCall("DeleteDC", "Uint", mDC1)
   DllCall("DeleteDC", "Uint", mDC2)
   DllCall("DeleteObject", "Uint", hBM)
   Return   zhBM
}

Convert(sFileFr = "", sFileTo = "", nQuality = "")
{
   If   sFileTo  =
      sFileTo := A_ScriptDir . "\screen.bmp"
   SplitPath, sFileTo, , sDirTo, sExtTo, sNameTo

   If Not   hGdiPlus := DllCall("LoadLibrary", "str", "gdiplus.dll")
      Return   sFileFr+0 ? SaveHBITMAPToFile(sFileFr, sDirTo . "\" . sNameTo . ".bmp") : ""
   VarSetCapacity(si, 16, 0), si := Chr(1)
   DllCall("gdiplus\GdiplusStartup", "UintP", pToken, "Uint", &si, "Uint", 0)

   If   !sFileFr
   {
      DllCall("OpenClipboard", "Uint", 0)
      If    DllCall("IsClipboardFormatAvailable", "Uint", 2) && (hBM:=DllCall("GetClipboardData", "Uint", 2))
      DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", "Uint", hBM, "Uint", 0, "UintP", pImage)
      DllCall("CloseClipboard")
   }
   Else If   sFileFr Is Integer
      DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", "Uint", sFileFr, "Uint", 0, "UintP", pImage)
   Else   DllCall("gdiplus\GdipLoadImageFromFile", "Uint", Unicode4Ansi(wFileFr,sFileFr), "UintP", pImage)

   DllCall("gdiplus\GdipGetImageEncodersSize", "UintP", nCount, "UintP", nSize)
   VarSetCapacity(ci,nSize,0)
   DllCall("gdiplus\GdipGetImageEncoders", "Uint", nCount, "Uint", nSize, "Uint", &ci)
   Loop, %   nCount
      If   InStr(Ansi4Unicode(NumGet(ci,76*(A_Index-1)+44)), "." . sExtTo)
      {
         pCodec := &ci+76*(A_Index-1)
         Break
      }
   If   InStr(".JPG.JPEG.JPE.JFIF", "." . sExtTo) && nQuality<>"" && pImage && pCodec
   {
   DllCall("gdiplus\GdipGetEncoderParameterListSize", "Uint", pImage, "Uint", pCodec, "UintP", nSize)
   VarSetCapacity(pi,nSize,0)
   DllCall("gdiplus\GdipGetEncoderParameterList", "Uint", pImage, "Uint", pCodec, "Uint", nSize, "Uint", &pi)
   Loop, %   NumGet(pi)
      If   NumGet(pi,28*(A_Index-1)+20)=1 && NumGet(pi,28*(A_Index-1)+24)=6
      {
         pParam := &pi+28*(A_Index-1)
         NumPut(nQuality,NumGet(NumPut(4,NumPut(1,pParam+0)+20)))
         Break
      }
   }

   If   pImage
      pCodec   ? DllCall("gdiplus\GdipSaveImageToFile", "Uint", pImage, "Uint", Unicode4Ansi(wFileTo,sFileTo), "Uint", pCodec, "Uint", pParam) : DllCall("gdiplus\GdipCreateHBITMAPFromBitmap", "Uint", pImage, "UintP", hBitmap, "Uint", 0) . SetClipboardData(hBitmap), DllCall("gdiplus\GdipDisposeImage", "Uint", pImage)

   DllCall("gdiplus\GdiplusShutdown" , "Uint", pToken)
   DllCall("FreeLibrary", "Uint", hGdiPlus)
}

CreateDIBSection(hDC, nW, nH, bpp = 32, ByRef pBits = "")
{
   NumPut(VarSetCapacity(bi, 40, 0), bi)
   NumPut(nW, bi, 4)
   NumPut(nH, bi, 8)
   NumPut(bpp, NumPut(1, bi, 12, "UShort"), 0, "Ushort")
   NumPut(0,  bi,16)
   Return   DllCall("gdi32\CreateDIBSection", "Uint", hDC, "Uint", &bi, "Uint", 0, "UintP", pBits, "Uint", 0, "Uint", 0)
}

SaveHBITMAPToFile(hBitmap, sFile)
{
   DllCall("GetObject", "Uint", hBitmap, "int", VarSetCapacity(oi,84,0), "Uint", &oi)
   hFile:=   DllCall("CreateFile", "Uint", &sFile, "Uint", 0x40000000, "Uint", 0, "Uint", 0, "Uint", 2, "Uint", 0, "Uint", 0)
   DllCall("WriteFile", "Uint", hFile, "int64P", 0x4D42|14+40+NumGet(oi,44)<<16, "Uint", 6, "UintP", 0, "Uint", 0)
   DllCall("WriteFile", "Uint", hFile, "int64P", 54<<32, "Uint", 8, "UintP", 0, "Uint", 0)
   DllCall("WriteFile", "Uint", hFile, "Uint", &oi+24, "Uint", 40, "UintP", 0, "Uint", 0)
   DllCall("WriteFile", "Uint", hFile, "Uint", NumGet(oi,20), "Uint", NumGet(oi,44), "UintP", 0, "Uint", 0)
   DllCall("CloseHandle", "Uint", hFile)
}

SetClipboardData(hBitmap)
{
   DllCall("GetObject", "Uint", hBitmap, "int", VarSetCapacity(oi,84,0), "Uint", &oi)
   hDIB :=   DllCall("GlobalAlloc", "Uint", 2, "Uint", 40+NumGet(oi,44))
   pDIB :=   DllCall("GlobalLock", "Uint", hDIB)
   DllCall("RtlMoveMemory", "Uint", pDIB, "Uint", &oi+24, "Uint", 40)
   DllCall("RtlMoveMemory", "Uint", pDIB+40, "Uint", NumGet(oi,20), "Uint", NumGet(oi,44))
   DllCall("GlobalUnlock", "Uint", hDIB)
   DllCall("DeleteObject", "Uint", hBitmap)
   DllCall("OpenClipboard", "Uint", 0)
   DllCall("EmptyClipboard")
   DllCall("SetClipboardData", "Uint", 8, "Uint", hDIB)
   DllCall("CloseClipboard")
}

Unicode4Ansi(ByRef wString, sString)
{
   nSize := DllCall("MultiByteToWideChar", "Uint", 0, "Uint", 0, "Uint", &sString, "int", -1, "Uint", 0, "int", 0)
   VarSetCapacity(wString, nSize * 2)
   DllCall("MultiByteToWideChar", "Uint", 0, "Uint", 0, "Uint", &sString, "int", -1, "Uint", &wString, "int", nSize)
   Return   &wString
}

Ansi4Unicode(pString)
{
   nSize := DllCall("WideCharToMultiByte", "Uint", 0, "Uint", 0, "Uint", pString, "int", -1, "Uint", 0, "int",  0, "Uint", 0, "Uint", 0)
   VarSetCapacity(sString, nSize)
   DllCall("WideCharToMultiByte", "Uint", 0, "Uint", 0, "Uint", pString, "int", -1, "str", sString, "int", nSize, "Uint", 0, "Uint", 0)
   Return   sString
}




/*
 *====================================================================================
 *                           END OF FILE
 *====================================================================================
 */


vital
  • Members
  • 19 posts
  • Last active: Nov 29 2010 12:02 PM
  • Joined: 05 Oct 2005
That is what i wanted.I replace the Lcontrol key with Lwin key.
Very nice!
Thanks.