AutoHotkey.chm: PixelGetColor wrote:
The pixel must be visible; in other words, it is not possible to retrieve the pixel color of a window hidden behind another window.
...
A window that is partially transparent or that has one of its colors marked invisible (TransColor) typically yields colors for the window behind itself rather than its own.
To retrieve the pixel color from a window, which is out of screen (fully or partially), transparent/translucent, or behind (an)other window(s), use this function:
Code:
PixelColor(pc_x, pc_y, pc_wID)
{
If pc_wID
{
pc_hDC := DllCall("GetDC", "UInt", pc_wID)
WinGetPos, , , pc_w, pc_h, ahk_id %pc_wID%
pc_hCDC := CreateCompatibleDC(pc_hDC)
pc_hBmp := CreateCompatibleBitmap(pc_hDC, pc_w, pc_h)
pc_hObj := SelectObject(pc_hCDC, pc_hBmp)
pc_hmCDC := CreateCompatibleDC(pc_hDC)
pc_hmBmp := CreateCompatibleBitmap(pc_hDC, 1, 1)
pc_hmObj := SelectObject(pc_hmCDC, pc_hmBmp)
DllCall("PrintWindow", "UInt", pc_wID, "UInt", pc_hCDC, "UInt", 0)
DllCall("BitBlt" , "UInt", pc_hmCDC, "Int", 0, "Int", 0, "Int", 1, "Int", 1, "UInt", pc_hCDC, "Int", pc_x, "Int", pc_y, "UInt", 0xCC0020)
pc_fmtI := A_FormatInteger
SetFormat, Integer, Hex
DllCall("GetBitmapBits", "UInt", pc_hmBmp, "UInt", VarSetCapacity(pc_bits, 4, 0), "UInt", &pc_bits)
pc_c := NumGet(pc_bits, 0)
SetFormat, Integer, %pc_fmtI%
DeleteObject(pc_hBmp), DeleteObject(pc_hmBmp)
DeleteDC(pc_hCDC), DeleteDC(pc_hmCDC)
DllCall("ReleaseDC", "UInt", pc_wID, "UInt", pc_hDC)
Return pc_c
}
}
CreateCompatibleDC(hdc=0) {
return DllCall("CreateCompatibleDC", "UInt", hdc)
}
CreateCompatibleBitmap(hdc, w, h) {
return DllCall("CreateCompatibleBitmap", UInt, hdc, Int, w, Int, w)
}
SelectObject(hdc, hgdiobj) {
return DllCall("SelectObject", "UInt", hdc, "UInt", hgdiobj)
}
DeleteObject(hObject) {
Return, DllCall("DeleteObject", "UInt", hObject)
}
DeleteDC(hdc) {
Return, DllCall("DeleteDC", "UInt", hdc)
}
It's based on
infogulch's
RegionGetColor As expected, won't work on minimized windows, or area "out of scroll".
Also you can't get the color of a video (overlayed or not), and using this function on a video application window brings the video control on top, and the video '
twitchs' (I want to say: stops for a moment) when this function is called (maybe not an issue if you've got a "supercomputer"

).
Scrolling a window which is monitored by this function may result in artifacts (at least IE).
Video and scroll problems are same as with
LiveWindows.
Memory leak -tested.
Variables used by the script (preceeded by pc_ to make it simple to insert it to scripts as non-function) are:
Code:
pc_bits
pc_c
pc_fmtI
pc_h
pc_hBmp
pc_hCDC
pc_hDC
pc_hmBmp
pc_hmCDC
pc_hmObj
pc_hObj
pc_w
pc_wID
pc_x
pc_y
I used the following script to verify that the function is working.
It shows how you can get pixel color using a loop (more efficient without creating + deleting/releasing DCs, bitmaps ans selecting/deleting objects each time). Also a timer could be employed to call those 3 dll functions.
The value shown by the tooltip should change almost every second: digits 5 and 6 vs. 0 and 9 have same pixel at that position with default(?) font (seems to be Tahoma), normal size (8 points).
Esc to exit.
Code:
Run timedate.cpl
WinWaitActive ahk_class #32770
Loop
{
WinGet clock?, ControlList, A
IfInString clock?, ClockWndMain1
Break
Sleep 100
}
SendMessage, 0x1330, 0, , SysTabControl321 ; Select first tab
ControlGetPos, pc_x, pc_y, , , Edit5 ; Edit5 = seconds
pc_x += 8, pc_y +=6
pc_wID := WinExist()
If pc_wID
{
pc_hDC := DllCall("GetDC", "UInt", pc_wID)
WinGetPos, , , pc_w, pc_h, ahk_id %pc_wID%
pc_hCDC := CreateCompatibleDC(pc_hDC)
pc_hBmp := CreateCompatibleBitmap(pc_hDC, pc_w, pc_h)
pc_hObj := SelectObject(pc_hCDC, pc_hBmp)
pc_hmCDC := CreateCompatibleDC(pc_hDC)
pc_hmBmp := CreateCompatibleBitmap(pc_hDC, 1, 1)
pc_hmObj := SelectObject(pc_hmCDC, pc_hmBmp)
Loop
{
DllCall("PrintWindow", "UInt", pc_wID, "UInt", pc_hCDC, "UInt", 0)
DllCall("BitBlt" , "UInt", pc_hmCDC, "Int", 0, "Int", 0, "Int", 1, "Int", 1, "UInt", pc_hCDC, "Int"
, pc_x, "Int", pc_y, "UInt", 0xCC0020)
pc_fmtI := A_FormatInteger
SetFormat, Integer, Hex
DllCall("GetBitmapBits", "UInt", pc_hmBmp, "UInt", VarSetCapacity(pc_bits, 4, 0), "UInt", &pc_bits)
pc_c := NumGet(pc_bits, 0)
ToolTip % pc_c
SetFormat, Integer, %pc_fmtI%
Sleep 500
}
Esc::
DeleteObject(pc_hBmp), DeleteObject(pc_hmBmp)
DeleteDC(pc_hCDC), DeleteDC(pc_hmCDC)
DllCall("ReleaseDC", "UInt", pc_wID, "UInt", pc_hDC)
ExitApp
}
CreateCompatibleDC(hdc=0) {
return DllCall("CreateCompatibleDC", "UInt", hdc)
}
CreateCompatibleBitmap(hdc, w, h) {
return DllCall("CreateCompatibleBitmap", UInt, hdc, Int, w, Int, w)
}
SelectObject(hdc, hgdiobj) {
return DllCall("SelectObject", "UInt", hdc, "UInt", hgdiobj)
}
DeleteObject(hObject) {
Return, DllCall("DeleteObject", "UInt", hObject)
}
DeleteDC(hdc) {
Return, DllCall("DeleteDC", "UInt", hdc)
}