Help - Search - Members - Calendar
Full Version: Screen Capture Dll
Game Maker Community > Working with Game Maker > Extending Game Maker > DLLs [DLL]
localmotion34
I'm new to this forum, and not really a game creator. I use PureBasic, C, and some ASM to write regular apps. However, I have found your forum while looking for graphics as well as ID3 DLL and other files I need.

I plan on using some DLLs found here which are really cool, so I feel it is appropriate to contribute a DLL of my own. I have NO knowledge of HOW to make this work in GM, but some of you gurus can take this and make a script. the DLL is 100% free for anyone to use, in whatever you want. This is written in PureBasic, which is translated into ASM, so it is very fast and stable. Ive included an EXE app that i slammed together just to demonstrate what this can do. Hotkeys are Ctl+Shift+ F9/F10/F11,F12 to snap window, fixed rectangle, any area, and ellipse respectively.

This DLL has 2 functions:

StartCapture(Type, zoomstate, soundstate, rectwidth=0, rectheight=0)

Type can be a constant equal to:

#cap_rectangle - fixed rectangle specified by rectwidth and rectheight
#cap_any - user defined drawn rectangle
#cap_ellipse - user-defined drawn ellipse with #color_gray as the tranparent color

Zoomstate=1 will show a magnifying window at the cursor position.
Zoomstate=0 will not

soundstate=1 specifies a WAV resource of a camera snap sound
soundstate=0 plays no sound

rectwidth and rectheight MUST be used with the #cap_rectangle, but dont mean anything for the other 2 types.

WindowCapture(#cap_window,soundstate)

i make users type #cap_window for error checking

soundstate=1 specifies a WAV resource of a camera snap sound
soundstate=0 plays no sound

DO NOT MESS WITH WindowCaptureCallbackin the DLL. it is a shared exported system hook that hooks the mouse in order to capture entire windows. nothing will crash your app like calling a moushook that you dont know what it does.


All procedures return a windows hbitmap. you can use getobject, bitblt, and other API functions with this hbitmap.

Constants:

#cap_rectangle=#WM_USER+1
#cap_any=#WM_USER+2
#cap_ellipse=#WM_USER+3
#wm_user+4= RESERVED for internal use. DO NOT USE
#cap_window=#WM_USER+5

any questions, please post here and we will try and get this working for everyone.

This was an absolute nightmare to work out, so id appreciate credit somewhere if you use it.


DL LINK:

http://www.penguinbyte.com/apps/pbwebstor/.../screenshot.zip
Shaltif
After downloading the DLL, I found there was no Game Maker example or scripts included. I am also questioning whether this DLL is actually compatabile with Game Maker.

At the moment, Game Maker can only send PCHAR (char *) and double parameters to a dll, and can only get returns of the same types. If a DLL includes functions which use any other variable types (for passing and returns), then Game Maker will crash with an 'unexpected error'.

Also, not enough information was given (in the topic) to actually formulate scripts to access the DLL. At bare minimum, you need to specify the variable type for arguments and the return for each function. Also, the calling convention for your exports.

Currently, someone (with knowledge of PureBasic) would have to take the source and recompile it to make it compatable with Game Maker. Then make Game Maker scripts to access the DLL.

So I'll leave this topic open for 24 hours to see if this type of correction is made. Otherwise, I will close the topic on the grounds that this isn't a DLL made for Game Maker.

~Brandon
localmotion34
All parameters to the DLL are currently LONGs. I didnt realize that GM required doubles being passed as parameters.

If i recompile the DLL making it take doubles or quads, and return the hbitmap as a double handle, will that be OK?

I just thought this might be useful to the community, i have all the source, and if someone will work with me, it can be fixed in a few minutes.

Calling convention is STDCALL by the way.
Shaltif
Well, I could develop the GML scripts if I knew the argument types and return types.

Basically, in Game Maker, you make a init() script which inializes the DLL (prototypes the functions for use).

This is done by using external_define();

ex:

CODE
//external_define ( dllName,FunctionName,calltype,restype,argnumb,arg1
type, arg2type,...)

//Below is assuming return type of double and all parameters are double
//Also using a stdcall (again, assuming here)
function_id =  external_define("ScreenCapture.dll","StartCapture", dll_stdcall,ty_real,5, ty_real,ty_real,ty_real,ty_real)


I could then call this function by doing:
CODE
external_call ( function_id,type,zoomstate,soundstate,recwidth, recheight);


Another note, Game Maker can't access DLL only variables/constants directly. So for those constants to work, you'd have to make the equavilants in Game Maker (probably in the init() script). This is usually done by storing the same values in Game Maker variables...tho, since you are also using WM_USER, this slightly complicates the problem since Game Maker doesn't know the value of WM_USER.

EDIT: This forum seems to have some issue with display these functions correctly...so just ignore the random spaces I thru in there xD

~Brandon
localmotion34
The whole point of this DLL is to return a hbitmap that shown the screen area or window selected.

can GM deal directly with windows hbitmaps?

like in a game, you have the option to select and capture the screen, and after the function is done, the hbitmap is used in a static control, or other image container to display what was captured.

example from my program:

hbitmap.l=startcapture( #cap_any,zoomstate,soundstate)

sendmessage( imagehwnd.l, #stm_setimage, #imagebitmap, hbitmap.l)

getobject(hbitmap, sizeof(bitmap), bm.bitmap)

debug bm\bmwidth
debug bm\bmheight

the return value from the DLL is an actual bitmap image, capable of any GDI function calling. can GM work with this hbitmap? the hbitmap is really just a handle, so i can bitshift or transform the LONG parameter to a double before i return. the handle number would for example just be 0000000023232323 instead of 23232323 for the handle to Windows. but the ? is, can GM deal with the handle to a hbitmap?

what i also could do is make #cap_any ect equal to 600, 601, 602 ect, which are passed as doubles. all id have to do in my PureBasic code is change those constant values in the DEF. basically, make them an obsure numer that wont conflict with GM.

People (from other communities) have been screaming for me to release this DLL, and its source. There is only one other free screen capture DLL out there, it there is no source.

I feel like if i use DLLs from here, i should contribute back.
Shaltif
QUOTE
The whole point of this DLL is to return a hbitmap that shown the screen area or window selected.

can GM deal directly with windows hbitmaps?


No, it can't. Game Maker is very limited in that respect. The only way to accomplish this would be to have your DLL capture the area, save it to file (in bitmap), then have Game Maker open this file as a sprite, in which case it can be displayed.

DLL's can't access the resources of Game Maker directly and likewise, Game Maker can't access the resources of DLL's directly.

~Brandon
localmotion34
QUOTE (Shaltif @ Oct 16 2006, 05:04 PM)
QUOTE
The whole point of this DLL is to return a hbitmap that shown the screen area or window selected.

can GM deal directly with windows hbitmaps?


No, it can't. Game Maker is very limited in that respect. The only way to accomplish this would be to have your DLL capture the area, save it to file (in bitmap), then have Game Maker open this file as a sprite, in which case it can be displayed.

DLL's can't access the resources of Game Maker directly and likewise, Game Maker can't access the resources of DLL's directly.

~Brandon
*




OK, can i have 48 hours to come up with a workaround? i think i can rework this library to take input as doubles, with the last input as the string (CHAR) as the file to save it to. I can make a pseudoprotype function as the actual DLL
export, which then calls the "startcapture" function internally. all parameters from GM would be converted to longs before i call the internal capture. the return will be about 100 msec slower before the hbitmap file is accessible, but this is very doable.

Ex:

Startcapture(Type DOUBLE, Zoomstate DOUBLE, Soundstate DOUBLE, rectwidth DOUBLE, rectheight, DOUBLE, Filename CHAR)

if type=600 --capture any area
--convert all doubles to longs here

hbitmap=callfunction (Getprocessaddress( hDLL, Pointer "InternalCapture", type LONG, zoomstate LONG)

if hbitmap
--save the hbitmap to the filename passed
endif


endif


this way, i wont have to modify the DLL, only add 2 exports that are formatted for GM that save a bitmap as a file. its like 20 lines of code, and a few tests getting the pseudoprototypes right. sound OK?
Shaltif
Sure, I can give the extra time. Just a note here:

QUOTE
Startcapture(Type DOUBLE, Zoomstate DOUBLE, Soundstate DOUBLE, rectwidth DOUBLE, rectheight, DOUBLE, Filename CHAR)


Another Game Maker limitation is that if a PCHAR is used as any argument, the function can only have up to four parameters. So the above couldn't be done. However, you 'could' do the common work around here. In which you have two functions, one which takes in all the PCHAR information and the other taking in the doubles and actually executes the command.

CODE
Startcapture1(Filename CHAR)
/*All that would do is store the filename in a global variable in the DLL*/

Startcapture2(Type DOUBLE, Zoomstate DOUBLE, Soundstate DOUBLE, rectwidth DOUBLE, rectheight, DOUBLE)
/*This would actually execute the function, using the global variable stored earlier*/


Good luck,
~Brandon
localmotion34
I was right. Only around 40 more lines of code.

I just convert the doubles to longs, and call the process address of the functions i originally posted, and then take the hbitmap and save it to a file.

it works perfectly, although there is some memory leaks i might have created by doing this, and i will need around 24 hours to work it out. NO SOUND functions, as the playsoundA API function doesnt seem to like being called through the method i am doing. the sound was just kinda fluff anyway.

for those interested:

4 exported functions

GM_Capture_Any(zoomstate DOUBLE, FileName STRING/CHAR)

zoomstate must be 0 or 1
1= zoom window
0= no zoom window
filename - string/Char that you want the BMP saved to

GM_Capture_Rect(zoomstate DOUBLE ,rectwidth DOUBLE ,rectheight DOUBLE ,FileName STRING/CHAR)

rectwidth=width of the rectangle
rectheight=height of the rectangle
zoomstate--same as above
filename - same as above

GM_Capture_Ellipse(zoomstate DOUBLE, FileName STRING/CHAR)
zoomstate--same as above
filename - same as above

GM_Capture_Win(FileName STRING/CHAR)
filename - same as above

The image that is saved is a BMP file, although i can add support for JPG, PNG, ICO and a few others if you REALLY need it.
gmjab
Yes add support for those file types, This will help me and people here, we really need them, since doing it another way takes another whole lot longer to put in.
localmotion34
which types of images are MOST IMPORTANT for you guys to have?

give me a priority listing, as some of the image plugins i use can add hundreds of KB to the DLL.
Shaltif
QUOTE (localmotion34 @ Oct 16 2006, 09:42 PM)
which types of images are MOST IMPORTANT for you guys to have?

give me a priority listing, as some of the image plugins i use can add hundreds of KB to the DLL.
*

Well this should help shorten your list. If users want to import a sprite dynamically (or while Game Maker is running) it can only support BMP, JPG or GIF. So, if you support these three formats, you got your sprite_add() base covered.

Of course, once Game Maker 7.0 comes out, we may be able to add PNG to that list.

~Brandon
L0rdCyrus
Could any1 add expample in gm6 when they get it to work?
gmjab
He has not finished the DLL, check back in 24 hours.

@ localmotion34 - Here is the list we need:
  • Bmp < Low priority
  • Jpeg < High priority
  • Gif < Medium priority
  • Png < High priority
If you can do that it'll be great.
L0rdCyrus
Jpeg quality level should be changeable
localmotion34
PNG=done
JPEG=done
GIF - need to be sure the last patent has expired before i make an encoder available
BMP - already implemented

The DLL is pretty much finished. I painfully wrote this thing over weeks, and am using the final version in a shareware app im writing. now it is just a matter of tweaking the exports to work with GM.

with only allowing 4 parameters when using strings to pass to the DLL i will do this:

the filename parameter will serve as both the filename AND as the type/quality of image to save:

EX: string Filetosave= "C\:test.jpg"
string imagetype= "JPEG"
string quality = "10" (best quality)

Finalstring= filetosave + "|" + imagetype + "|" + quality

so the final string result would be "C\:test.jpg|JPEG|10"

then i can parse the string to get the needed information. this gets around the 4 parameters limit, and still gives a method to have many options with the DLL, including specifying what type of image you want back out.

I have a TON of other code that might be useful to you guys as well. most anything i write can be compiled into a DLL.
L0rdCyrus
Great. Im wondering maybe you have some kind dll that supports, upload, reading info from web (txt files), changing data over web and download, someone made similar dll, but ppl said that upload does not work correctly and download links are broken.
localmotion34
Here it is, as promised.

4 functions STD_CALL convention
GM_Capture_Any(zoomstate DOUBLE, FileName STRING/CHAR)

zoomstate must be 0 or 1
1= zoom window
0= no zoom window
filename - string/Char that you want the image saved to

filename goes like this:

filename|imagetype|quality "|" is the delimeter

stringfilename="test.bmp|Bitmap|0"

bitmaps and PNG take no quality parameter, as my encoders by default use 24 bits. so just type a 0. you can leave it out, but id reccomend not to. its just 2 extra characters.

JPEG can be quality 1-10 10 being the best
string= "test.jpg|JPEG|9"

GM_Capture_Rect(zoomstate DOUBLE ,rectwidth DOUBLE ,rectheight DOUBLE ,FileName STRING/CHAR)

rectwidth=width of the rectangle
rectheight=height of the rectangle
zoomstate--same as above
filename - same as above

GM_Capture_Ellipse(zoomstate DOUBLE, FileName STRING/CHAR)
zoomstate--same as above
filename - same as above

GM_Capture_Win(FileName STRING/CHAR)
filename - same as above

These procedures return strings "True" if the image was successfully saved or "False" if it was not, or one of the parameters was mistyped. This DLL will NEVER perform operations on a mistyped or non-existent file. it will just exit and return "False". Any mistakes you make in parameters will result in a return of "False". "Bitmap" or "bitmap, "JPEG", or "jpeg", "PNG", or "png" are valid ways to type the image parameters of the filename string.

There is a problem with the GIF encoder. the C code i ported it over to for my PureBasic App does not seem to want to work in this context of this particular DLL calling method. It crashes the DLL hard. Even using prototypes to trick the DLL into thinking it was the one i created for PureBasic is not fooling it.


the "screenshot.exe" file in the ZIP will demonstrate what the DLL can do. it will allow you to capture the screen in 4 ways using Ctl+Shift+F9/F10/F11/F12 keys like i described before, and save it to "C\:test.bmp". MAKE SURE YOU EXTRACT BOTH THE EXE AND DLL.


LINK:
http://www.penguinbyte.com/apps/pbwebstor/...reenCapture.zip
gmjab
This is so awsome, File is corrupt or somthing, upload it somewhere else please. I can't wait.
gmjab
Now all we need is a gm6 example...
localmotion34
Brandon said he would help write one, because i know almost nothing about GM6.

I am using Ultracrypt DLL, and felt it was good Karma to contribute back to this community.

I have LED meter controls, methods to use Freeimage DLL and Nview image DLL to load and save almost ANY format. Now that i know what types of params GM6 takes, its so easy to tweak the calling method to the DLLs.

i can even take any DLL, and compress/wrap it inside another DLL, and execute it from memory so that people cant steal your custom DLLs, or know what exact functions you are calling when. makes for good registration schemes.

the whole GIF thing has annoyed me, and ill probably spend a few days writing my own custom encoder, along with MP3 ID3 tag DLL too.
Shaltif
Alright, here is a gm6 with the functions wrapped according to the previous post arguments and returns.

[Link Removed to Avoid Confusion, read later posts]

Not to hard to follow. However, there is a problem.

localmotion34, three of the four functions don't work properly. The only one I could get working was Capture_Any. Rect and Ellipse I could see 'working' but they don't save a resulting image. Lastly, trying to use Win completely crashes the entire GM application.

Now, I am sending all the calls and returns correctly according to your previous post, and since I see the reaction to the DLL (like the cursor allowing me to take a shot using rect and the circle effect when taking a ellispse screenshot) I assume there is a bug somewhere in the DLL that is not saving the result.

Win, on the other hand, crashes the moment I click a window I want to screen capture.

Now, I assume you don't have a registered version of Game Maker 6.0. So I made an EXE build of the program so that you can see the results yourself and try to fix the possible bugs in the build on your end.

If you want to see how the scripts are formulated GML side, you'll need GM 6.0 to open the .gm6 file. However, if not registered, you won't be able to actually use those scripts (since using a DLL is a registered only feature).

~Brandon
localmotion34
totally, totally my fault.. I apologize for the mental mistake.

when i said that "Bitmap" and bitmap" ect could be accepted at parameters for the type, only in the CM_capture_any procedure did i do this:

select type
case "Bitmap", "bitmap"

endselect

i failed to use multiple case selection in the other 3 procedures, which resulted in failure of the routine because you typed "bitmap" instead of "Bitmap" with a capital B

The DLL is fixed, and consequently, the window capture does now work at least on my system. Some antivirus programs do not like system wide hooks like the capture window uses. some people may have to just use the capture any, but i have tried the capture window on winXP and win200 with Norton and Mcafee, and they both worked.

i successfully returned a bitmap from all 4 functions, which are included in this ZIP archive.

http://www.penguinbyte.com/apps/pbwebstor/...reenCapture.zip
localmotion34
DLL updated with a 5th function per the request of a Member.

New Funtion: snaps a predefined rectangle on the screen at point x,y of the given dimensions of rectwidth,rectheight.

uses WinAPI BitBlt, so it is lightning fast with no extra open windows or user-defined selection. The SourceDC i use is that of the desktop window, so the system metrics of the screen are always correct. you can capture the whole desktop by specifying "0|0" as the x,y point, and the entire width and height of the screen if youd like. I use CreateCompatibleBitmap using an independent TargetDC, so the bitmap is always valid for any device context, and your DesktopDC is never altered.


GMCapture_Fast(point STRING ,rectwidth DOUBLE ,rectheight DOUBLE ,FileName STRING)

point takes the following: "pointX|pointY"

The functions i call require a point structure for the WinAPI, so its very easy to take this string format and transform it into an LPpoint structure.

Ex: "100|200"

X= xcoordinate of the upper left corner of the rectangle
Y= top left corner of the rectangle
width= rectangle width
height=rectangle height

Ex:
GMCapture_Fast("100|100" ,640,480 ,"C:\test.bmp|Bitmap|0")

Any function requests are more than welcome. Im having a total blast making this work, as it is a good challenge. Plus, this also helps test out my ScreenCapture DLL that will be included in my shareware suite, so try and break this thing if you can.
Don't worry, this DLL will always be free for GM because it is only a VERY small part of my shareware. i wrote this because of the lack of solutions available in a DLL.

Possible quick additions are:

-Capture the active window
-Quick snap your own GM window using the GM function that returns the window handle of GM
-timed screen capture

-whatever you can think of!

NOTE: to "fast capture" in the screenshot.exe, Ctl+Shift+F8 is the hotkey.
The GM6 example is not updated to include this function!!!!

http://www.penguinbyte.com/apps/pbwebstor/...reencapture.zip
gmjab
I don't know but something is wrong with either brendon's gm6 he put together or yourr dll, because only the first function works for me.
localmotion34
try the new DL link 2 posts above this one. i just checked that right now. it works on both my home machine, and my work machine.
gmjab
LOL, sorry I didn't ready those last posts. Anyway I have Updates the GM6 file for that new GM Capture Fast and I have packaged it so it just contain the dll and gm6:

LINK: Download - Host-a.net - 72KB

@ localmotion34 - You should add this link to your first post so people don't download the old version
jackal69
localmotion34, please include the capture of the active window. I was going to create a game in which it draws a picture in the game window and this would be an easy way to save/capture/print the image. Unless the dll already does something like that and I misunderstood.

great work, very useful.

jackal
localmotion34
you will need to pass the argument of the HWND (window handle) of the gamemaker window.

then i can use the Win32 API getwindowrect() function and BitBlt the rectangle.

make sure the window is visible, otherwise ill make the function return "false"

actually, it will only take 30 lines of code to do that. consider it added, and i will update the DLL.
jackal69
excellent, thanks.
rinkuhero
This is a great dll, thanks. Is there any chance it could include the ability to save images scaled (such as half-size, quarter-size)?
cdm319
i doubt he'll update it. He last logged on November 2006 wink1.gif
Bander
Would it be possible to record avi from GM games using this technique? I would really like to see that. smile.gif
..:: CLAW ::..
QUOTE (Bander @ Apr 2 2007, 12:30 AM)
Would it be possible to record avi from GM games using this technique? I would really like to see that. smile.gif
*


Yes it would, but it's really hard to to that and I think it will really slow down the game.
There would be a lot of parameters and the gm user will have to know all available codecs in his computer etc.
I think you understand what I'm saying. cool.gif
cdm319
not really that hard - just use a BMP to AVI DLL
DefuzionGames
hey would it be possible to make another function which is EXACTLY like GM_Capture_Fast() but it lets you specify the exact window(by giving the window handle) to capture from.

Not so important but useful:
Also allowing to capture from that window even if the window specified was not visible.

This would be great. Thanks. Your dll is very usefeul
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Invision Power Board © 2001-2010 Invision Power Services, Inc.