http://www.autohotke...t=screencapture
I was able to adjust Sean's script so that it just saves the cursor in the clipboard as a bitmap image. Although you don't really need to read this part, it might help you understand my problem.
;This script's purpose is to make a bitmap image of the active cursor and save it to the clippboard ^z:: VarSetCapacity(mi, 20, 0), mi := Chr(20) DllCall("GetCursorInfo", "Uint", &mi) bShow := NumGet(mi, 4) ;1 ==> cursor is visible (MSDN) hCursor := NumGet(mi, 8) ;cursor handle xCursor := NumGet(mi,12) ;not really needed for this script, but might want later yCursor := NumGet(mi,16) ;same as ^ If bShow && hCursor:=DllCall("CopyIcon", "Uint", hCursor) { VarSetCapacity(ni, 20, 0) DllCall("GetIconInfo", "Uint", hCursor, "Uint", &ni) bIcon := NumGet(ni, 0) ;is cursor ==> false, is icon ==> true xHotspot := NumGet(ni, 4) ;I think this is the click location yHotspot := NumGet(ni, 8) hBMMask := NumGet(ni,12) ;again not used in script hBMColor := NumGet(ni,16) ;same as ^ ;the tiny part I added starts here mDC := DllCall("CreateCompatibleDC", "Uint", 0) ;make a DC compatible with screen hBM := CreateDIBSection(mDC, 32, 32) ;I think this makes a blank bitmap based on mDC (except dimensions) oBM := DllCall("SelectObject", "Uint", mDC, "Uint", hBM) ;put hBM into the DC but save original DC in oBM ;ends here DllCall("DrawIcon", "Uint", mDC, "int", 0, "int", 0, "Uint", hCursor) ;draw the icon into the DC DllCall("DestroyIcon", "Uint", hCursor) ;clear the memory of uneeded objects If hBMMask DllCall("DeleteObject", "Uint", hBMMask) If hBMColor DllCall("DeleteObject", "Uint", hBMColor) } DllCall("SelectObject", "Uint", mDC, "Uint", oBM) ;switch back to original DC then delete DllCall("DeleteDC", "Uint", mDC) SetClipboardData(hBM) ;put the image on the clipboard return 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") }
My problem is in the next code section, and I'm pretty sure it has something to do with how I treat the DC's. This is the script that I want to compare two bitmaps loaded into device contexts. I decided to use the GetPixel() function, I am planning to refine this code, but not until it's working. I believe I have traced the problem to the bitmap not succsesfully loading into the DC. The returned handle for hBM1 is negative, and according to MSDN the return value will be NULL if it didn't work. Is a negative handle NULL?
;this script is supposed to take two .bmp files and compare them pixel for pixel when you press CTRL + C ;(doesn't work yet) #p::Pause ^c:: hBM1 := LoadBMPIntoDC ("file_address") ;put in address of a 32X32 bitmap hBM2 := LoadBMPIntoDC ("file_address") ;put in address of a 32X32 bitmap result := CompareBMP32(hBM1, hBM2) if result = 1 MsgBox, "didn't match" else MsgBox, "matched" return 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) } ;this function is the broken one, I cant seem to get the .bmp from file into DC LoadBMPIntoDC(bmpfile) { hBmp := DllCall("LoadImage","Uint", 0, "str", bmpfile, "Uint", 0, "int", 32, "int",32, "Uint", 0x00000010) ;load the image [color=red](check my syntax here)[/color] mDC := DllCall("CreateCompatibleDC", "Uint", 0) ;create screen compatible DC hBM := CreateDIBSection(mDC, 32, 32) ;I suspect that this part is not really needed (makes blank bmp based on mDC) oBM := DllCall("SelectObject", "Uint", mDC, "Uint", hBM) ;puts hBM in mDC DllCall("BitBlt", "Uint", mDC, "int", 0, "int", 0, "int", 32, "int", 32, "Uint", hBmp, "int", 0, "int", 0, "Uint", 0x40000000 | 0x00CC0020) ;blits hBmp over mDC DllCall("SelectObject", "Uint", mDC, "Uint", oBM) ;puts original DC back in mDC then deletes DllCall("DeleteDC", "Uint", mDC) return hBM } ;comparison function CompareBMP32(hBM1, hBM2) { mDC1 := DllCall("CreateCompatibleDC", "Uint", 0) mDC2 := DllCall("CreateCompatibleDC", "Uint", 0) oBM1 := DllCall("SelectObject", "Uint", mDC1, "Uint", hBM1) oBM2 := DllCall("SelectObject", "Uint", mDC2, "Uint", hBM2) DllCall("SelectObject", "Uint", mDC1, "Uint", oBM1) DllCall("SelectObject", "Uint", mDC2, "Uint", oBM2) while x < 32 { while y < 32 { color1 := DllCall("GetPixel", "Uint", mDC1, "int", x, "int", y) color2 := DllCall("GetPixel", "Uint", mDC2, "int", x, "int", y) if color1<>color2 return 1 y+=1 } x+=1 } DllCall("DeleteDC", "Uint", mDC1) DllCall("DeleteDC", "Uint", mDC2) DllCall("DeleteObject", "Uint", hBM1) DllCall("DeleteObject", "Uint", hBM2) return 0 }
I really don't know much about DC's. I have been reading about them on MSDN, but I still dont fully understand them. I would appreciate any help.