Hi there all,

First of all, I warn you : I apologize (="Sorry", I believe) for my poor English but I am French, so say me if you don't understand me, I'll rewrite my sentences... :wink:

So my problem is that I want to take a capture of my screen, and put it into a Bitmap file.
I tried this code but it doesn't seem to run :
.386

.model flat, stdcall
option casemap :none

; INCLUDES ET BIBLIOTHEQUES (LIBRAIRIES)
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc
include \masm32\include\rasapi32.inc
include \masm32\include\advapi32.inc
include \masm32\include\shell32.inc
include \masm32\include\user32.inc

includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\shell32.lib
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\rasapi32.lib
includelib \masm32\lib\advapi32.lib
includelib \masm32\lib\user32.lib

.data
pathbmp db "c:\masm32\bin\testil.bmp"

.data?
handlecontenu dd ?

.code
start:
Push 0
Push 0
Push 0
Push VK_SNAPSHOT
Call keybd_event ; On simule l'appui sur la touche Print Screen

Push 0
Push KEYEVENTF_KEYUP
Push 0
Push VK_SNAPSHOT
Call keybd_event ; On simule le "relachement" de la touche Print Screen

Push CF_BITMAP
Call GetClipboardData

Mov handlecontenu, eax

Push handlecontenu
Push FILE_ATTRIBUTE_HIDDEN
Push OPEN_ALWAYS
Push 0
Push 0
Push GENERIC_READ
Push OFFSET pathbmp
Call CreateFile

end start


Does anybody know what the problem is ? And how can I do to resolve it ?

I precise that I looked for a lot on the board but I didn't find info about that. And for those who would say me that there is CapScreen which allows that I want to do, I would answer them that I wouldn't prefer to use that file because I don't understand very much its code (I'm a beginner in ASM yet)...

Thanks in advance (Merci d'avance... :wink: )...

PS : And thanks a lot to admins for their board, i learnt lots of things since i started the assembly language.
Posted on 2004-12-20 18:17:31 by azerty1000
I'm sorry that I am too tired to look at your code, I have to wake up in five hours ;) - but I would like to say that your english is quite understandable. But if you want help on improving your english as well as your code, just let us know :)
Posted on 2004-12-20 19:44:45 by f0dder
hi azerty1000,

i noticed a few Problems
You should use OpenClipboard and CloseClipboard also. Also i assume you want to write your Bitmap to hdd but you use GENERIC_READ in your CreateFile Api Call.
Posted on 2004-12-21 02:16:55 by Allanon
But if you want help on improving your english as well as your code, just let us know :)

Thanks. :) :wink:

You should use OpenClipboard and CloseClipboard also. Also i assume you want to write your Bitmap to hdd but you use GENERIC_READ in your CreateFile Api Call.


Thanks for your help, Allanon.
So I modified (I don't know if I can say that) my code like this :
.386

.model flat, stdcall
option casemap :none

; INCLUDES ET BIBLIOTHEQUES (LIBRAIRIES)
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc
include \masm32\include\rasapi32.inc
include \masm32\include\advapi32.inc
include \masm32\include\shell32.inc
include \masm32\include\user32.inc

includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\shell32.lib
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\rasapi32.lib
includelib \masm32\lib\advapi32.lib
includelib \masm32\lib\user32.lib

.data
pathbmp db "c:\masm32\bin\testil.bmp" ; path of the bitmap

.data?
handlecontenu dd ?

.code
start:
Push 0
Push 0
Push 0
Push VK_SNAPSHOT
Call keybd_event ; On simule l'appui sur la touche Print Screen

Push 0
Push KEYEVENTF_KEYUP
Push 0
Push VK_SNAPSHOT
Call keybd_event ; On simule le "relachement" de la touche Print Screen

Push 0
Call OpenClipboard ; We open the clipboard

Push CF_BITMAP
Call GetClipboardData

Mov handlecontenu, eax

Push handlecontenu
Push FILE_ATTRIBUTE_HIDDEN
Push OPEN_ALWAYS
Push 0
Push 0
Push GENERIC_WRITE
Push OFFSET pathbmp
Call CreateFile

Call CloseClipboard ; We close the clipboard

end start

There isn't error when I compile and when I link the program. But when I run it, my computer displays me that application error (="Erreur d'application"). I'm sorry it's in French :

I don't know why it talks me about breakpoint (="point d'arr?t") because I never use that... :? For those who wouldn't understand, it approximately says that I came on a breakpoint (="Un point d'arr?t a ?t? atteint.") during the execution.

Thanks again. :)
Posted on 2004-12-21 04:19:02 by azerty1000
Bonjour,

I guessed that you encountered a breakpoint from the error 0x80000003. There is actually int3 padding your code and this int3 are added to act as a safeguard. Just incase you did not add a ret or something. In your case, you forgot about a call to ExitProcess to terminate your program..

PS: Don't try to talk french to me as I only recongnise a few french words.

Regards,
Victor
Posted on 2004-12-21 05:48:50 by roticv
Yeah!! Thanks Victor!!

Indeed, adding :
Push 0

Call ExitProcess

...just before "end start", I don't have error anymore... :) I'll know it now. :wink:

But there is another problem. With this code, the bitmap isn't generated (**I'm not sure about this sentence**)... The program doesn't want to create the *.bmp file.
Does anyone know why ?
Please, all advices are welcome.

PS : For those who would say me that it's because I used "FILE_ATTRIBUTE_HIDDEN", I would answer that my OS displays hidden files. :wink:

Thanks... More and more.
Posted on 2004-12-21 07:09:32 by azerty1000
hi azerty1000

so far u create only the file(createfile), you have to write it also
i'm not sure if it's really that "easy" to get the Data from the clipboard and save them.
I assume (might be totally wrong) that you have to "convert" also your data to a bitmap and than you'll able to write it
Posted on 2004-12-21 07:20:13 by Allanon
if you use CreateFile, always close it after with CloseHandle.
oh, please reposts the code as it is now so we have a more clear view on what you've added and how :)

Btw, if you are looking for another way without making use of the PrintScreen button i can post it here if you like.
Posted on 2004-12-21 09:09:36 by Scorpie
i'm not sure if it's really that "easy" to get the Data from the clipboard and save them.

It seems you are right...:\

if you use CreateFile, always close it after with CloseHandle.

Hi Scorpie,
Are you sure ? Now, with my code, the program creates the bitmap but the only thing that it's empty...:? And I don't know why...

oh, please reposts the code as it is now so we have a more clear view on what you've added and how

No problem. :)
.386

.model flat, stdcall
option casemap :none

; INCLUDES ET BIBLIOTHEQUES (LIBRAIRIES)
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc
include \masm32\include\rasapi32.inc
include \masm32\include\advapi32.inc
include \masm32\include\shell32.inc
include \masm32\include\user32.inc

includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\shell32.lib
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\rasapi32.lib
includelib \masm32\lib\advapi32.lib
includelib \masm32\lib\user32.lib

.data
pathbmp db "c:\masm32\bin\testil.bmp"


.code
start:

Push 0
Push 0
Push 0
Push VK_SNAPSHOT
Call keybd_event [color=red]; Press key PrintScreen.[/color]

Push 0
Push KEYEVENTF_KEYUP
Push 0
Push VK_SNAPSHOT
Call keybd_event [color=red]; Key up PrintScreen.[/color]

Push 0
Call OpenClipboard [color=red]; We open the clipboard.[/color]

Push CF_BITMAP
Call GetClipboardData [color=red]; We get the handle of the screenshot (which is in the clipboard) in EAX.[/color]

Push EAX [color=red]; I didn't understand very well this parameter, so I SUPPOSED (lol) that it was the handle of what I want to put in the bitmap file.[/color]
Push FILE_ATTRIBUTE_NORMAL
Push OPEN_ALWAYS
Push 0
Push 0
Push GENERIC_WRITE
Push OFFSET pathbmp
Call CreateFile

Call CloseClipboard [color=red]; We close the clipboard.[/color]

Push 0
Call ExitProcess [color=red]; We quit the program.[/color]
end start

This one works but the bitmap is always empty :cry: ...

if you are looking for another way without making use of the PrintScreen button i can post it here if you like.

Yes, I would like :)... If it doesn't disturb you...
I will use it if I can understand it :wink:.

PS : And also :
Btw

What does it mean ? :-D
Posted on 2004-12-21 10:29:34 by azerty1000
I always read btw like butuwa :P dont know what mean ;).
Posted on 2004-12-21 11:39:28 by rea
BTW = By The Way .
Posted on 2004-12-21 11:43:14 by f0dder
hi azerty1000

Your bitmap file is empty because you didn't write anything to it. You write to a file using the WriteFile function. I don't think writing clipboard data to a file will work though I've never done it this way.
Posted on 2004-12-21 13:06:05 by QuantumMatrix1024
Hi azerty1000!
The following link shows some ways of capturing the screen and how to save it to disk: http://www.geocities.com/krishnapg/bitmap.html

I hope it helps.
Posted on 2004-12-21 14:23:07 by Cthulhu
Thanks Cthulhu but your link is in C (or C++ I don't know...) language, and me : language-that-I-don't-know + english = too much complicated for me.

Otherwise (="Sinon" I believe) I looked for WriteFile in the MSDN and I found that :
BOOL WriteFile(
HANDLE hFile, // handle to file to write to
LPCVOID lpBuffer, // pointer to data to write to file
DWORD nNumberOfBytesToWrite, // number of bytes to write
LPDWORD lpNumberOfBytesWritten, // pointer to number of bytes written
LPOVERLAPPED lpOverlapped // pointer to structure for overlapped I/O
);

And there is a few things that I didn't understand.
Well, "HANDLE hFile," is Ok, I get it in EAX with CreateFile.
"LPOVERLAPPED lpOverlapped" >> I didn't understand this but I'll put NULL, I think it should work :-D ...

So, OK at the moment...

But the others are more difficult...
"LPCVOID lpBuffer," >> I don't know what I can put here... Do you think I can put the handle oh what is in the clipboard...:roll:

"DWORD nNumberOfBytesToWrite," >> I understood this parameter but how can I know the number of bytes that I'll write ? I don't know it before.

"LPDWORD lpNumberOfBytesWritten," >> I didn't understood this one...

Thanks for those who help me, and thanks for future answers... :wink:
Posted on 2004-12-21 15:01:09 by azerty1000
"LPCVOID lpBuffer," >> I don't know what I can put here... Do you think I can put the handle oh what is in the clipboard...Rolling Eyes

Please correct this if it's wrong, I'm not an expert in this area. I think the function wants a pointer to the data you want to write(it says so).. e.g. If the buffer where your data is, is called buffer. I think it will be something like: "addr buffer"..
I have looked in the api documentation for the other things you are wondering about, I took a quick peek and It was a few paragraphs explaining this one: "LPOVERLAPPED lpOverlapped"
Posted on 2004-12-21 17:27:38 by dev_zero
dev_zero is correct you can't use a handle you need to use a pointer to a buffer. Have a look at GetDIBits, I think you need to file in a BITMAPFILEHEADER structure and write that to file first.

"DWORD nNumberOfBytesToWrite," >> I understood this parameter but how can I know the number of bytes that I'll write ? I don't know it before.



when WriteFile is complete it will set this to the number of bytes that where written so this needs to be the address of a dword variable.
I hope this helps you in some way
Posted on 2004-12-21 18:42:36 by QuantumMatrix1024
dev_zero is correct you can't use a handle you need to use a pointer to a buffer. Have a look at GetDIBits, I think you need to file in a BITMAPFILEHEADER structure and write that to file first.

"DWORD nNumberOfBytesToWrite," >> I understood this parameter but how can I know the number of bytes that I'll write ? I don't know it before.



when WriteFile is complete it will set this to the number of bytes that where written so this needs to be the address of a dword variable.
I hope this helps you in some way


dev_zero is correct yea :)

and your explanation is nice, but it is not, as you say, about NumberOfBytesToWrite but it is about lpNumberOfBytesWritten.

NumberOfBytesToWrite just needs to know how many bytes you want to write, these two are easy to mix up :)

edit: ill post that other screen capture methode later, cant find it atm.
Posted on 2004-12-22 04:11:51 by Scorpie
hi azerty1000

oki here a very quick hack
but NO error check so that?s something u have to do
also i didn't clean up everything here




.386
.model flat, stdcall
option casemap :none

; INCLUDES ET BIBLIOTHEQUES (LIBRAIRIES)
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc
include \masm32\include\rasapi32.inc
include \masm32\include\advapi32.inc
include \masm32\include\shell32.inc
include \masm32\include\user32.inc
include \masm32\include\gdi32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\shell32.lib
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\rasapi32.lib
includelib \masm32\lib\advapi32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\gdi32.lib

.data
pathbmp db "c:\testil.bmp",0

.data?
hWndNewOwner dd ?
hFile dd ?
bmpinfo BITMAPINFO <>
bmpFileHeader BITMAPFILEHEADER <>
hdc dd ?
SizeReadWrite dd ?
pBuf DWORD ?
hBitmap dd ?
.code
start:

invoke keybd_event,VK_SNAPSHOT,0,0,0
invoke keybd_event,VK_SNAPSHOT,0,KEYEVENTF_KEYUP,0
invoke IsClipboardFormatAvailable,CF_BITMAP
invoke OpenClipboard,0
mov hWndNewOwner,eax
invoke GetClipboardData,CF_BITMAP
mov hBitmap,eax
invoke CloseClipboard
invoke GetDC,NULL
mov hdc,eax
invoke RtlZeroMemory,addr bmpinfo,sizeof BITMAPINFO
mov bmpinfo.bmiHeader.biSize,sizeof BITMAPINFOHEADER
invoke GetDIBits,hdc,hBitmap,0,0,NULL,addr bmpinfo,DIB_RGB_COLORS
invoke LocalAlloc,LMEM_FIXED,bmpinfo.bmiHeader.biSizeImage
mov pBuf, eax
mov bmpinfo.bmiHeader.biCompression,BI_RGB
invoke GetDIBits,hdc,hBitmap,0,bmpinfo.bmiHeader.biHeight,pBuf, addr bmpinfo, DIB_RGB_COLORS
invoke CreateFile,ADDR pathbmp,GENERIC_READ or GENERIC_WRITE ,\
FILE_SHARE_READ or FILE_SHARE_WRITE,\
NULL,CREATE_NEW,FILE_ATTRIBUTE_ARCHIVE,\
0
mov hFile,eax
mov bmpFileHeader.bfReserved1,0
mov bmpFileHeader.bfReserved2,0

mov bmpFileHeader.bfSize, sizeof BITMAPFILEHEADER + sizeof BITMAPINFOHEADER ;+ bmpinfo.bmiHeader.biSizeImage
mov bmpFileHeader.bfType,'MB'
mov bmpFileHeader.bfOffBits, sizeof BITMAPFILEHEADER + sizeof BITMAPINFOHEADER
invoke WriteFile,hFile,addr bmpFileHeader,sizeof BITMAPFILEHEADER,ADDR SizeReadWrite,0
invoke WriteFile,hFile,addr bmpinfo.bmiHeader,sizeof BITMAPINFOHEADER,ADDR SizeReadWrite,0
invoke WriteFile,hFile,pBuf,bmpinfo.bmiHeader.biSizeImage,ADDR SizeReadWrite,0
invoke CloseHandle,hFile
invoke ExitProcess, 0
end start
Posted on 2004-12-22 06:21:29 by Allanon
Yeah!!! Thank you very much Allanon, really. :alright:
I'm going to study your code trying to understand it (There shouldn't have any problem, it seems to be relatively simple...)...

Also thank you Diablo2oo2 ( http://www.asmcommunity.net/board/viewtopic.php?t=20182 ), I didn't know how to use CapScreen function, but its code is still too much complicated for me.

Finally, I would like to thank all the members of this board... You resolved my problem, thanks. :wink:
Posted on 2004-12-22 11:48:48 by azerty1000