AutoIt PixelGetColor从背景/无效/未聚焦的窗口 [英] AutoIt PixelGetColor from background/inactive/unfocused window

查看:340
本文介绍了AutoIt PixelGetColor从背景/无效/未聚焦的窗口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

PixelGetColor 具有可选参数 hwnd >(从中读取像素的窗口句柄).因此,我认为可以从未聚焦的窗口中读取(即没有最小化,而是在另一个窗口后面);但我无法让它那样工作.

PixelGetColor has an optional parameter hwnd (handle of window the pixel is read from). Therefore I assume it is possible to read from unfocused windows (i.e not minimized, but behind another window); but I can't get it to work like that.

  • 我的假设是否错误?如果没有,该怎么做?如果是这样

  • Is my assumption wrong? If not, how would this be done? If so;

  • 为什么使用hwnd参数?
  • 还有另一种涉及像素识别的方法吗?

推荐答案

摘要

您要创建一个简单的空位图,并将隐藏窗口的DeviceContext内容传输到其中.然后,您可以在任何位置读取任何值.

Abstract

You want to create a simple empty bitmap and transfer the DeviceContext content of the hidden window into it. Then you can read any value at any position.

包含

我们将需要包含WinAPI定义和常量.

We will need to include the WinAPI definitions and constants.

#include <WinAPI.au3>
#include <WindowsConstants.au3>

就是这样.

初始结构

现在,我们必须从$tagBITMAPINFO模板创建一个新的DLL结构.我们需要用位图参数填充该结构.为了确保所有AutoIt版本的兼容性,我将按索引访问结构项.

Now we have to create a new DLL struct from the $tagBITMAPINFO template. We need to fill the struct with the bitmaps parameters. To ensure compatibility across all AutoIt version, I will access the struct items by index.

1)创建兼容的设备上下文:

1) Create compatible Device Context:

Local $hCompDC = _WinAPI_CreateCompatibleDC(0)

2)从模板创建结构,并填充数据:

2) Create struct from template, fill with data:

Local $tBMI = DllStructCreate($tagBITMAPINFO)
DllStructSetData($tBMI, 1, DllStructGetSize($tBMI) - 4) ; size of struct
DllStructSetData($tBMI, 2, 400) ; width
DllStructSetData($tBMI, 3, 400) ; height
DllStructSetData($tBMI, 4, 1)
DllStructSetData($tBMI, 5, 32)  ; bits per pixel

您需要调整宽度和高度参数以匹配要传输的区域.对于您的情况,我认为窗口的大小将是一个不错的选择,尽管区域越小,速度越快.

You need to adjust the width and height parameters to match the region you want to transfer. In your case, I guess the size of the window would be a good choice, though the smaller the region, the faster.

3)创建GDI对象

创建一个CreateDIBSection并保存重要的变量(对象句柄和结构指针):

Create a CreateDIBSection and save the important variables (object handle and struct pointer):

$aDIB = DllCall('gdi32.dll', 'ptr', 'CreateDIBSection', 'hwnd', 0, 'ptr', DllStructGetPtr($tBMI), 'uint', 0, 'ptr*', 0, 'ptr', 0, 'uint', 0)
$hGDIObj = $aDIB[0]
$hPtr = $aDIB[4]

4)激活

选择要使用的对象:

_WinAPI_SelectObject($hCompDC, $hGDIObj)

5)创建一个像素图

这是颜色值的双字数组.将160000替换为您所在地区的width*height:

This is a dword-array of color values. Replace 160000 with width*height of your region:

$hPixelStruct = DllStructCreate("dword[160000]", $hPtr)

捕获窗口

现在,我们需要将隐藏的窗口DeviceContext转移到我们的虚拟"上下文中,但首先是目标的DC(我以Paint为例):

Capture window

Now we need to transfer the hidden window DeviceContext into our "virtual" context, but first the DC of the target (I'm using Paint as an example):

$hWnd = WinGetHandle("Paint")
$hWndDC = _WinAPI_GetDC($hWnd)

让我们使用PrintWindow将DC转移到我们的DC中:

Let's transfer the DC into our DC, using PrintWindow:

Local $iX = 20 ; x coord of pixel in window DC (incl. title bar)
Local $iY = 20 ; y coord
DllCall("User32.dll", "int", "PrintWindow", "hwnd", $hWnd, "ptr", $hCompDC, "int", 0)

读取单个像素

由于$hPixelStruct是连续的值流,所以我们必须做一点数学运算以指向正确的像素:

Reading single pixels

Since $hPixelStruct is a continuous stream of values, we have to do a little bit of math to point at the right pixel:

$iColor = MsgBox(0, "Color", '0x' & Hex(DllStructGetData($hPixelStruct, 1, $iY * 400 + $iX + 1), 6))

清理

最后,销毁资源:

Cleaning up

Lastly, destroy the resources:

_WinAPI_ReleaseDC(0, $hCompDC)
_WinAPI_ReleaseDC($hWnd, $hWndDC)

结果

完美运行.尽管这仅对隐藏的窗口有效,但没有最小化,因为最小化的窗口没有任何绘制的上下文.

Results

Works perfectly. Though this is only valid for hidden windows, NOT minimized, as minimized windows do not have any drawn context.

以下是包含以下脚本的要点: minxomat/readcolor.au3

Here's a Gist containing the script: minxomat/readcolor.au3

这篇关于AutoIt PixelGetColor从背景/无效/未聚焦的窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆