 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
holomind
Joined: 11 Mar 2006 Posts: 300 Location: Munich, Germany
|
Posted: Thu Aug 24, 2006 8:00 pm Post subject: Save Screen (HDC) as BMP or PNG w/o external tools, GDIPlus |
|
|
i will try to give some useful screenshots of the screenshot-tool (created by itself but as this is gui-less its a bit hard
Update: I changed the subject so people recognize its not only yet-another-screenshot tool. but a way to save the screen fast in all formats supported by gdiplus (which is already installed in newer windows versions). as its gdiplus its quite fast.
Update: Now you can make a screenshot with win-c for (capture thumb) and win-v for (capture fullscreen). it also creates two folders for your images.
Finally i managed to create Screenshots with AHK without external DLLs or other *cheating*. its pure AHK and not using pixel by pixel reading.
all formats where gdiplus has an handler (bmp, jpg, png, tiff..) are supported.
to keep it simple it only works with png now.
for writing the png/bmp i used the code from PhiLho. (see more details there to use other formats and parameters, its easy to use it also for gif,jpg,bmp, tiff etc. )
http://www.autohotkey.com/forum/viewtopic.php?t=11860
i copied the 3 needed includes into one file so its easier to use.
see my other scripts with
ScreenMagnifier:
http://www.autohotkey.com/forum/viewtopic.php?t=11700
or
LiveWindows:
http://www.autohotkey.com/forum/viewtopic.php?t=11588
to see how you can play around with BitBlt and StrechBlt to modify the image.
there is also no cheating with hitting printkey and clipboard. etc.
this is honest copy DC to File
the missing link was "GdipCreateBitmapFromHBITMAP"
and learning that UIntP, is used for ByVal. This means the dllcall returns something "into" this variable.
Now i can get rid of iview.exe if i want
The speed should be anayzed, perhaps this bin2hex stuff copies every pixel in memory?
press win-x to exit
press win-c to save current desktop as thumbnail
press win-v to save current desktop 1:1
filename is automatic in the moment containing date+time.png
Version 0.1 : initial
Version 0.2 : bugfix of landvermesser, always gdistop (memory leak)
| Code: |
#Include GDIPlusHelper.ahk
; see: http://www.autohotkey.com/forum/viewtopic.php?t=11860 for orignal
OnExit, handle_exit
main:
FileCreateDir, screens
FileCreateDir, thumbs
WinGet, hw_frame, id, "Program Manager" ; Desktop ?
hdc_frame := DllCall( "GetDC", "uint", hw_frame )
hdc_frame_full := DllCall( "GetDC", "uint", hw_frame )
counter:=0 ; thumbnails
counter_f:=0 ; fullscreens
thumb_w:= 200
thumb_h:= ceil( thumb_w * A_ScreenHeight / A_ScreenWidth ) ; keep screenratio
use_antialize := 1
; buffer
hdc_buffer := DllCall( "gdi32.dll\CreateCompatibleDC" , "uint", hdc_frame )
hbm_buffer := DllCall( "gdi32.dll\CreateCompatibleBitmap" , "uint", hdc_frame, "int", thumb_w, "int", thumb_h )
r := DllCall( "gdi32.dll\SelectObject" , "uint", hdc_buffer, "uint", hbm_buffer )
hdc_buffer_full := DllCall( "gdi32.dll\CreateCompatibleDC" , "uint", hdc_frame_full )
hbm_buffer_full := DllCall( "gdi32.dll\CreateCompatibleBitmap" , "uint", hdc_frame_full, "int", A_ScreenWidth, "int", A_ScreenHeight )
r_full := DllCall( "gdi32.dll\SelectObject" , "uint", hdc_buffer_full, "uint", hbm_buffer_full )
; comment this line for speed but less quality
if use_antialize = 1
DllCall( "gdi32.dll\SetStretchBltMode", "uint", hdc_buffer, "int", 4 ) ; Halftone better quality with stretch
return
#c::
SaveImage:
counter := counter +1
FormatTime, myTime, , yyyyMMdd_hhmmss
fileNameDestP = thumbs\T_%myTime%_%counter%_%thumb_w%x%thumb_h%.png
If (GDIplus_Start() != 0)
Goto GDIplusError
; Copy BMP from DC
DllCall( "gdi32.dll\StretchBlt"
, "uint", hdc_buffer, "int", 0, "int", 0, "int", thumb_w, "int", thumb_h
, "uint", hdc_frame, "int", 0, "int", 0, "int", A_ScreenWidth, "int", A_ScreenHeight, "uint", 0x00CC0020 )
DllCall( "GDIplus\GdipCreateBitmapFromHBITMAP", uint, hbm_buffer, uint, 0, uintp, bitmap )
; Save to PNG
If (GDIplus_GetEncoderCLSID(pngEncoder, #GDIplus_mimeType_png) != 0)
Goto GDIplusError
noParams = NONE
If (GDIplus_SaveImage(bitmap, fileNameDestP, pngEncoder, noParams) != 0)
Goto GDIplusError
Gosub GDIplusStop
Return
#v::
SaveImage_Full:
counter_f := counter_f +1
FormatTime, myTime, , yyyyMMdd_hhmmss
fileNameDestP = screens\S_%myTime%_%counter_f%_%A_ScreenWidth%x%A_ScreenHeight%.png
If (GDIplus_Start() != 0)
Goto GDIplusError
; Copy BMP from DC
DllCall( "gdi32.dll\BitBlt"
, "uint", hdc_buffer_full, "int", 0, "int", 0, "int", A_ScreenWidth, "int", A_ScreenHeight
, "uint", hdc_frame_full, "int", 0, "int", 0, "uint", 0x00CC0020 )
DllCall( "GDIplus\GdipCreateBitmapFromHBITMAP", uint, hbm_buffer_full, uint, 0, uintp, bitmap )
; Save to PNG
If (GDIplus_GetEncoderCLSID(pngEncoder, #GDIplus_mimeType_png) != 0)
Goto GDIplusError
noParams = NONE
If (GDIplus_SaveImage(bitmap, fileNameDestP, pngEncoder, noParams) != 0)
Goto GDIplusError
Gosub GDIplusStop
Return
GDIplusError:
GDIplusStop:
If (#GDIplus_lastError != "")
MsgBox 16, GDIplus Test, Error in %#GDIplus_lastError%
GDIplus_Stop()
Return
#x::
handle_exit:
DllCall( "gdi32.dll\DeleteObject", "uint", hbm_buffer )
DllCall( "gdi32.dll\DeleteDC" , "uint", hdc_frame )
DllCall( "gdi32.dll\DeleteDC" , "uint", hdc_buffer )
ExitApp
|
you need to have
http://www.holomind.de/ahk/screenshot/GDIPlusHelper.ahk (includes 29kb)
in the same directory.
For quick downloads:
http://www.holomind.de/ahk/screenshot/screenshot.ahk (src 2kb)
http://www.holomind.de/ahk/screenshot/screenshot.exe (compiled 193kb)
variation with thumbnails:
http://www.holomind.de/ahk/screenshot/screenshot_thumb.ahk (src 2kb)
Last edited by holomind on Mon Oct 09, 2006 8:37 pm; edited 5 times in total |
|
| Back to top |
|
 |
PhiLho
Joined: 27 Dec 2005 Posts: 6721 Location: France (near Paris)
|
Posted: Fri Aug 25, 2006 8:23 am Post subject: Re: Make Screenshots with AHK with pure GDIplus |
|
|
Wow, I believe this will become popular.
I am happy somebody already used my library!
| holomind wrote: | | The speed should be anayzed, perhaps this bin2hex stuff copies every pixel in memory? | Uh? I don't see bin2hex neither in your code nor in mine (ie. in GDIplusWrapper).
I didn't looked at your GDIPlusHelper.ahk, but I hope you didn't took all the content of my DllCallStruct and BinaryEncodingDecoding files...
These are generic libraries that I use in several of my programs, so there are functions that are not used in some programs.
Let see... In DllCallStruct, I use GetUnicodeString, GetAnsiStringFromUnicodePointer (all strings in GDI+ are encoded in Unicode) and GetInteger/SetInteger.
Well, actually, BinaryEncodingDecoding functions are not even used! As I wrote, these files are generic and this file has to be included for other functions. I didn't edited them to suit this particular application.
I will edit my message to point this out, for those wanting, like you, a more compact file. _________________
vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2") |
|
| Back to top |
|
 |
holomind
Joined: 11 Mar 2006 Posts: 300 Location: Munich, Germany
|
Posted: Fri Aug 25, 2006 9:07 am Post subject: Re: Make Screenshots with AHK with pure GDIplus |
|
|
| PhiLho wrote: | | Wow, I believe this will become popular. |
I hope so, it was bogling my mind a long time, as i *knew* there is a way to do it
| PhiLho wrote: | I am happy somebody already used my library!  |
Im glad you showed me this great example, the important thing was this GDIStart() GDIStop() and returning objects via UINTP. I think with this technique you can use nearly all GDI functions others use with VB or C++.
| holomind wrote: | | ..perhaps |
you are right this isnt even called. i only stiched all files from your example together and at some time it worked. now we can get rid of all helper functions not used. and see what is really needed. Ideally the whole thing is only ddlcalls without much "processing" and "fixing" in AHK. because then its really fast.
my suggestion comes as it has an delay of about 1sec to make a png from a 1400x1050 screenshot on a 1GHz notebook. so i probably wrongly accussed this GDIHelper-Include.
I will do some speed comparisons with "Printkey-plus.exe" and "i_view32.exe" with eg. bmp format and add some stopclock functions to see / make it really fast.
sometimes its a small function you dont suspect. (like calling WinMove without parameters will force a redraw of the window, even if nothing happened).
Update:
i tried to remove unneeded things from the helperlib but they are much intertwined. so i will not touch it much, and do speedchecks/debugging to see if all things are smooth and fast
my results: all on notebook 1,4Ghz Dothan, 1400x1050
BMP: about 5-6 screens per second , about 5,6MB each
GIF: about 3-4 screens per second, about 200kb each
PNG: about 3-4 screens per second about 200kb each
JPG: about 2-3 screens per second about 200kb each
this means it isnt that bad(=slow), and using BMP your RAM usage can get very high.
the big differences are between BMP and JPG, which shows the compression algorythm has probably more impact than the communication arround? |
|
| Back to top |
|
 |
PhiLho
Joined: 27 Dec 2005 Posts: 6721 Location: France (near Paris)
|
Posted: Fri Aug 25, 2006 9:50 am Post subject: Re: Make Screenshots with AHK with pure GDIplus |
|
|
| holomind wrote: | | i tried to remove unneeded things from the helperlib but they are much intertwined. so i will not touch it much | Well, as I wrote, just replace "#Include DllCallStruct.ahk" with the functions GetUnicodeString, GetAnsiStringFromUnicodePointer, GetInteger and SetInteger.
| holomind wrote: | my results: all on notebook 1,4Ghz Dothan, 1400x1050
BMP: about 5-6 screens per second , about 5,6MB each
GIF: about 3-4 screens per second, about 200kb each
PNG: about 3-4 screens per second about 200kb each
JPG: about 2-3 screens per second about 200kb each
this means it isnt that bad(=slow), and using BMP your RAM usage can get very high.
the big differences are between BMP and JPG, which shows the compression algorythm has probably more impact than the communication arround? | Using JPEG images for screenshots are a bad idea anyway: either they are very compressed, and fuzzy/ugly, or they are lightly compressed, and offer no advantages over PNG format.
Plus it is a good idea to reduce color depth of screenshots if they show only GUIs, unless you want to show the subtilities of your theme. This reduce greatly the size of images.
This can be another area to explore in this library: manipulate color depth, since it seems to have to be done before saving. _________________
vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2") |
|
| Back to top |
|
 |
holomind
Joined: 11 Mar 2006 Posts: 300 Location: Munich, Germany
|
Posted: Fri Aug 25, 2006 10:08 am Post subject: |
|
|
This version saves the Screenshot directly as a thumbnail.
The resize is done with StrechBlt in the DC, which is quite fast. (slower than directx but else quite fast).
there is a similar function called image.getthumbnail or similar in gdi. but the point is to show how to manipulate the dc to get your results.
if you change the coordinates in the dllcall of StrechBlit you can change the region to shot/copy/zoom.
for reducting colors etc. like PhiLho suggested, i dont know where to put in the parameters, but this should probably be somewhere "noparams=NONE".
for me png is the best format in the moment. fast and small size and not loosing colors.
change "thumb_w" (thumbnail width) and "use_antialize = 0 or 1" to see the effects of StrechBlt
| Code: |
#Include GDIPlusHelper.ahk
; see: http://www.autohotkey.com/forum/viewtopic.php?t=11860 for orignal
OnExit, handle_exit
main:
WinGet, hw_frame, id, "Program Manager" ; Desktop ?
hdc_frame := DllCall( "GetDC", "uint", hw_frame )
counter:=0
thumb_w:= 200
; thumb_w:= A_ScreenWidth ; --- set to A_ScreenWidth if you want 1:1 copy
thumb_h:= thumb_w * A_ScreenHeight / A_ScreenWidth ; keep screenratio
use_antialize := 1
; buffer
hdc_buffer := DllCall( "gdi32.dll\CreateCompatibleDC" , "uint", hdc_frame )
hbm_buffer := DllCall( "gdi32.dll\CreateCompatibleBitmap" , "uint", hdc_frame, "int", thumb_w, "int", thumb_h )
r := DllCall( "gdi32.dll\SelectObject" , "uint", hdc_buffer, "uint", hbm_buffer )
; comment this line for speed but less quality
if use_antialize = 1
DllCall( "gdi32.dll\SetStretchBltMode", "uint", hdc_buffer, "int", 4 ) ; Halftone better quality with stretch
return
#c::
SaveImage:
counter := counter +1
FormatTime, myTime, , yyyyMMdd_hhmmss
fileNameDestP = Screenshot_%myTime%_%counter%_%thumb_w%.png
If (GDIplus_Start() != 0)
Goto GDIplusError
; Copy BMP from DC
DllCall( "gdi32.dll\StretchBlt"
, "uint", hdc_buffer, "int", 0, "int", 0, "int", thumb_w, "int", thumb_h
, "uint", hdc_frame, "int", 0, "int", 0, "int", A_ScreenWidth, "int", A_ScreenHeight, "uint", 0x00CC0020 )
DllCall( "GDIplus\GdipCreateBitmapFromHBITMAP", uint, hbm_buffer, uint, 0, uintp, bitmap )
; Save to PNG
If (GDIplus_GetEncoderCLSID(pngEncoder, #GDIplus_mimeType_png) != 0)
Goto GDIplusError
noParams = NONE
If (GDIplus_SaveImage(bitmap, fileNameDestP, pngEncoder, noParams) != 0)
Goto GDIplusError
Return
GDIplusError:
If (#GDIplus_lastError != "")
MsgBox 16, GDIplus Test, Error in %#GDIplus_lastError%
GDIplus_Stop()
Return
#x::
handle_exit:
DllCall( "gdi32.dll\DeleteObject", "uint", hbm_buffer )
DllCall( "gdi32.dll\DeleteDC" , "uint", hdc_frame )
DllCall( "gdi32.dll\DeleteDC" , "uint", hdc_buffer )
ExitApp
|
|
|
| Back to top |
|
 |
holomind
Joined: 11 Mar 2006 Posts: 300 Location: Munich, Germany
|
Posted: Fri Aug 25, 2006 10:20 am Post subject: Re: Make Screenshots with AHK with pure GDIplus |
|
|
| PhiLho wrote: | | This can be another area to explore in this library: manipulate color depth, since it seems to have to be done before saving. |
you mean usage of :
#EncoderColorDepth = {66087055-AD66-4C7C-9A18-38A2310B8337}
perhaps you can give a little example how to use it in this script. eg. setting output colordepth to 8 or 16.
another way could be to not create a CreateCompatibleBitmap, but only CreateBitmap and give your colordepth. ..compatible.. will use your current screensettings. |
|
| Back to top |
|
 |
holomind
Joined: 11 Mar 2006 Posts: 300 Location: Munich, Germany
|
Posted: Fri Aug 25, 2006 11:08 am Post subject: |
|
|
to give you more ideas of what to do with this.
you could even make screenshots of windows which are not in foreground without activating this window.
| Code: |
;task_id :=... window_ID
DllCall("PrintWindow", UInt,task_id, UInt,hdc_buffer, UInt,0)
|
then save the hdc_buffer to file.
if the window is minimized this would be a little bit more tricky. as you would need to do following steps.
a) make window invisible ?
b) restore (unminimize)
c) save the current position for later restore WinGetPos..
c) move it offscreen so nobody can see it, eg. winmove...x=A_ScreenWidth+1
d) make window visible
e) call printwindow
f) make it invisibel
g) move to original position
h) minimize again.
perhaps there is a better way, but this should work in theory and nobody can see what you are doing in background/offscreen.
printwindow also works fine if your window is not completely visible on the the "monitior". compared to bitblt which most of the times only copies "visible" pixels from desktop and also windows which are "in the way".
printwindow only does not work correctly if the window is minimized.
...
to simulate something like alt-printkey, means only active window (not desktop). you would need to read the size and position of Winget...A (active window) and create a hbm_buffer of this size. and use StrechBlt or BitBlt to copy only this region to your buffer.
this should not be to hard to do. but you will get the windows "in the way" as you make a shot "from top".
doing this with "printWindow" is perhaps a little bit slower but much easier to use as you per definition only screenshot one window and not the desktop!
there even is a trick to get the window-id of the client-window. which is the part of the window without titlebar and menus. there exists a dllcall for this which i dont remember.
....
related to this script are: (in this forum)
* get screenshot with nice gui (selecting region and preview)
* magnifier and livewindow (for showing bitblt and strechblt and selection)
* save file with irfanview. (actually most of them could use the gdiplus version now)
* process images PhiLho (load image and save in different format) |
|
| Back to top |
|
 |
PhiLho
Joined: 27 Dec 2005 Posts: 6721 Location: France (near Paris)
|
Posted: Fri Aug 25, 2006 11:26 am Post subject: Re: Make Screenshots with AHK with pure GDIplus |
|
|
| holomind wrote: | | PhiLho wrote: | | This can be another area to explore in this library: manipulate color depth, since it seems to have to be done before saving. | you mean usage of :
#EncoderColorDepth = {66087055-AD66-4C7C-9A18-38A2310B8337}
perhaps you can give a little example how to use it in this script. eg. setting output colordepth to 8 or 16. |
| Image conversions with GDI+ wrote: | ; For some reason, values 1, 4, 8 which are supposed to be legal, are rejected with Win32Error
; Perhaps it doesn't do conversion, so it accepts only values legal for the current file.
tiffColorDepth := 24
tiffColorDepth := 32
If (GDIplus_AddEncoderParameter(tiffEncoderParams, #EncoderColorDepth, tiffColorDepth) != 0)
Goto GDIplusError | As you can see, I tried already (not with PNG, I am not sure of what parameters this encoder accepts) and it wasn't successful. It seems (unless I am mistaken) that this parameter doesn't change the bitmap to fit the given color depth, but only specify values to be written in the header, so they must be compatible with the real color depth.
I suppose that GDI+ provides some API to manipulates that. I will investigate later (unless somebody else is faster...).
On the PrintWindow call, note this is specific to newer versions of Windows:
| MSDN wrote: | Requirements
Windows NT/2000/XP/Vista: Included in Windows XP and Windows Server 2003.
Windows 95/98/Me: Unsupported. |
I bookmarked an article: Window Contents Capturing using WM_PRINT Message but didn't read it fully.
It seems that one need some DLL injection to capture content of external windows (ie. not created by the capturing program).  _________________
vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2") |
|
| Back to top |
|
 |
holomind
Joined: 11 Mar 2006 Posts: 300 Location: Munich, Germany
|
Posted: Fri Aug 25, 2006 11:46 am Post subject: |
|
|
@PhiLho:
perhaps PNG is a special case as it always saves in 32bit (24+alpha) ? or was this jpg which always needs 24bit ?
but your anwer is good already, as you have to "find out" etc. i thought it would be a simple parameter like you pass x and y in dllcalls with the usage of UInt. seems to be a bit more difficult here.
it also would be nice if your gdi-helpers would be integrated into AHK, as they seem lowlevel things like "GetInteger" .
perhaps one could add some wrappers for dllcall bitblt and so on. and make ahk code look more nicely without tons of dllcalls and always defining variable type
eg.
| Code: |
GDI32_BitBlt( hdc_target , x, y, w, h, hdc_src, x0, y0 , SRCCOPY);
|
instead of
| Code: |
DllCall( "gdi32.dll\BitBlt"
, "uint", hdc_buffer, "int", 0, "int", 0, "int", a_screenwidth, "int", a_screenheight
, "uint", hdc_frame, "int", 0, "int", 0, "uint", 0x00CC0020 )
|
but using this wrappers you increase codesize of your script or need includes. so if they where built into ahk directly. (would increase the ahk-installer/binary about 20kb?) this would be much easier GDI-Programming.
even some people could use this functions and would not even know they use DLLcalls and GDI ?
...
this article about WM_Print is interesting. seems to be an alternative to GDI32.dll/PrintWindow ?
i guess you can use this PrintWindow also if you copy the gdi.dll to your systemsfolder. or is this so lowlevel it wont work in win98 ? |
|
| Back to top |
|
 |
PhiLho
Joined: 27 Dec 2005 Posts: 6721 Location: France (near Paris)
|
Posted: Fri Aug 25, 2006 12:20 pm Post subject: |
|
|
No, PNG is flexible and allow both "truecolor" images (ie. with pixel information stored directly in the bitmap) and indexed images (ie. only an index to a color table is stored), which allows compactness (an index is usually one byte or perhaps less, a true color pixel uses 3 or 4 bytes (if alpha channel).
That's Jpeg, indeed, that is always 24bit (no alpha).
As for the integration in AHK, I am not sure it is so interesting the way you put it.
One way would be to improve DllCall to accept syntaxes like Visual Basic Declare:
| Code: | Private Declare Function GdipSaveImageToFile Lib "GDIPlus" _
(ByVal Image As Long, _
ByVal filename As Long, _
ByRef clsidEncoder As UUID, _
ByVal encoderParams As Long) As GDIPlusStatusConstants
| ie. without the need to indicate the type of parameters on each call.
A simple thin wrapper around GDI would be useful only to those with good knowledge of this library. It is still quite technical (use of handles...).
A more useful / easier way would be to create a canvas component, ie. a Picture control accepting simple drawing commands: MoveTo, LineTo, CopyRegion, etc.
Another way, more in the spirit of your wish, would be to write such wrapper (I started one, I suppose you have another) and distribute it in the official install of AutoHotkey. I know that Chris plans to have a number of these official include files, with frequently used functions.
The advantage is that you only have to reference these files, not to have to distribute them. _________________
vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2") |
|
| Back to top |
|
 |
holomind
Joined: 11 Mar 2006 Posts: 300 Location: Munich, Germany
|
Posted: Sun Sep 17, 2006 1:17 pm Post subject: |
|
|
| Updated script in first post, so you can save your desktop/fullscreen as 1:1 or as 200x... thumbnail with win-c or win-v, exit with win-x. |
|
| Back to top |
|
 |
Terrapin
Joined: 15 Aug 2005 Posts: 107 Location: North Carolina
|
Posted: Sun Sep 24, 2006 12:31 pm Post subject: |
|
|
As requested in the LiveWindows thread (I'm sorry, I don't get to the forum every day)... here is all I did, just a little hack, without really completely understanding what is going on. I understand a lot of your code, but have not even looked at PhiLho's, as it sounds brain-bending. I have been thinking of some uses and ways to implement them, however.
This is (like I said) a hack of the #c:: hotkey thread. Instead of capturing the screen, it now captures the active window.
| Code: |
#c::
SaveImage:
WinGetActiveStats, myTitle, myW, myH, myX, myY
counter := counter +1
FormatTime, myTime, , yyyyMMdd_hhmmss
fileNameDestP = thumbs\T_%myTime%_%counter%_%thumb_w%x%thumb_h%.png
If (GDIplus_Start() != 0)
Goto GDIplusError
; Copy BMP from DC
DllCall( "gdi32.dll\StretchBlt"
, "uint", hdc_buffer, "int", 0, "int", 0, "int", thumb_w, "int", thumb_h
, "uint", hdc_frame, "int", myX, "int", myY, "int", myW, "int", myH, "uint", 0x00CC0020 )
DllCall( "GDIplus\GdipCreateBitmapFromHBITMAP", uint, hbm_buffer, uint, 0, uintp, bitmap )
; Save to PNG
If (GDIplus_GetEncoderCLSID(pngEncoder, #GDIplus_mimeType_png) != 0)
Goto GDIplusError
noParams = NONE
If (GDIplus_SaveImage(bitmap, fileNameDestP, pngEncoder, noParams) != 0)
Goto GDIplusError
Return
|
I'm sure I didn't optimize or anything, just stuck in the:
WinGetActiveStats
& substituted the resultant values (vars) in another line of your code.
myX, myY, myW, myH
I have been toying some with a new concept I think is good. At least, it is new to me, may well have been brought up many times. I found that it is very simple to get an alternate window menu (such as the standard one when you right-click on a titlebar)... I use ~RButton & LButton:: ... something like that... check to see that the mouse is not hovering a control... if it is not, it displays a custom menu. I think if something like this (could easily be Shift & RButton:: or another hotkey combo), would be a very nice standard for anyone who wants to act on a certain window.
An example would be to add to the standard altmenu, your menu item, such as "Window Snapshot" or in the case of LiveWindows, "Watch in LiveWindows".
One other thing... Evl said there could be problems with moving windows totally offscreen (if I am not mistaken?)... I wrote a little altmenu test, and have it add the window title to a small listview. If adding to the LV is successful, it then moves the window to x -20000, and remembers the proper coordinates. I didn't find any problems, but I suspect the possible problem would occur if the window was never returned to the screen? A sub-utility might be, to collect any visible windows which are not on the screen to a listview, with double-clicking any title bringing it back.
That's what my 'hidewindows' listview does. Pop it up with a hotkey, it contains the window names which have been moved, and double-click the one you want. It is removed from the listview, and the window put back in place, and the listview hidden again. Very simple stuff, I just wanted to test some concepts.
I want to look at the magnifier. I double-clicked the LiveWindows window,and it maximized, in spite of not having a maximize button. WOW, big and quite clear!
I know, I am talking about three different threads here, but this GDI and what it can do, are fascinating. I believe, Vista is supposed to have alt-tab with this type thing? It could be easily done with AHK!
Thanks again... if you want me to post any of my code I mentioned, let me know. It should be pretty simple to figure out, though. I may be away for a couple of days.
Bob |
|
| Back to top |
|
 |
holomind
Joined: 11 Mar 2006 Posts: 300 Location: Munich, Germany
|
Posted: Sun Sep 24, 2006 8:28 pm Post subject: |
|
|
thanks for the example, i will try it soon, if you save the screenshot as thumbnail it will be distorted a bit, as it uses the full screen/desktop-size for calculating the dimension. so the thumb_w and thumb_h have to consider the dimensions of the activewindowstats so it does not stretch. the width can be fix to 200 but the height must be something like
| Code: |
thumb_h := thumb_w * activewin_h / activewin_w ; instead of desktop_w..
|
if you want to make an windowswitching with thumbnails this is not so far away
http://www.autohotkey.com/forum/viewtopic.php?p=70769#70769
its only a prototype to show all windows refreshed every second.
it shoud not be too hard to convert this into a horizontal version of tabswitching. (this is also similar to the tab-switch in os/x)
there is little refreshproblems with the sourcewindows as they dont get refreshed correctly. perhaps this is a "bug" of the printwindow-function (dllcall) or the DC-Handle is not closed correctly early enough.
(if you bitblit instead of printwindow there are no refreshproblems)
as i use deskman, i have all my tasks all the time so i dont have much use for it (this is also the reason this prototype is vertical and not horizontal) . but as an standalone app this would be nice. also in combination with
fast alt-esc with wheelmouse:
http://www.autohotkey.com/forum/viewtopic.php?t=12687&
combine these two scripts add some nice borders and transparency and you are nearly done  |
|
| Back to top |
|
 |
SanskritFritz
Joined: 17 Feb 2005 Posts: 283 Location: Hungary, Budapest
|
Posted: Fri Sep 29, 2006 9:55 am Post subject: |
|
|
Lightning fast! Thanks holomind! _________________ Is there another word for synonym? |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3626 Location: Belgrade
|
Posted: Fri Sep 29, 2006 10:22 am Post subject: |
|
|
2 Holomid
I have a question for you, since you are dealing with graphics.
I want to create script that will sumulate one cool feature of XGL cube shell (for Linux). If you have several open windows overlaping, and you want to select one of them in windows you do ALT TABING. In XGL you do F12, and all windows are resized and ordered so all are visible on the screen. Then you click on one, and all windows are returned back with the one you clicked on the top.
I first thought this can be done by moving and resizing real windows around but then I realised that is no way to go since resizing window will change the internals of it (generaly) and I want the same window, just smaller.
So, I will have to create screenshot of wallpaper, screenshot of all windows on it, then do animation with those boxes myselef (resizing, moving, aranging) and then do animation backwards finishing with activating the clicked window (bitmap acctually).
Can I do this with GDIPlus or I need some external dll because speed must be such that animation works flowless. _________________
 |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|