DoctorLechter Posted March 18, 2008 Posted March 18, 2008 (edited) Hello there everyone! Long story short. I have a Dll in C++. There is a simple function. Function is getting a color using HWND and HDC. Using this function you can get pixel color from an inactive minimized or hidden (non-DirectX) window or an inactive but on-screen (DirectX) window. Function works fine (I tested it many times) except in AutoIt . When I call it via DllCall(), it returns zero. And @error is same, i.e. equals zero. ColorDll.h CODE #ifndef ColorDll #define ColorDll #include <windows.h> extern "C" COLORREF GetColor(int, int); #endif ColorDll.cpp CODE #include "ColorDll.h" extern "C" COLORREF GetColor(int x, int y) { HWND hWnd = FindWindow("SomeWndClass", "SomeWndName"); HDC hdc = GetDC(hWnd); COLORREF PixCol = GetPixel(hdc, x, y); // COLORREF is DWORD ReleaseDC(hWnd, hdc); return PixCol; } DllCall.au3 CODE Dim $TEMP = DllCall("ColorDll.dll", "dword", "GetColor", "int", X, "int", Y) MsgBox(0, "Color", $TEMP) MsgBox(0, "Error", @error) Could you please show me where I'm wrong? Or any ideas please. Thanks beforehand. Doctor Lechter Edited March 18, 2008 by DoctorLechter
Moderators SmOke_N Posted March 18, 2008 Moderators Posted March 18, 2008 (edited) COLORREF is defined as an "int" here. DllCall returns an array $TEMP[0] would contain your value not $TEMP. Where you have your @error check is after the MsgBox, which means it is going to check if MsgBox error'd not if your DllCall did. Are you hard coding the Win/Hwnd in the dll? ou could do it in AutoIt since you're using Windows API's anyway... Something like:Func _WinGetPix($hWnd, $xCoord, $yCoord) If IsHWnd($hWnd) = 0 Then $hWnd = WinGetHandle($hWnd) Local $aHDC = DllCall("USER32.DLL", "int", "GetDC", "hwnd", $hWnd) If @error Then Return SetError(1, 0, 0) Local $aGetPix = DllCall("GDI32.DLL", "long", "GetPixel", "int", $aHDC[0], "int", $xCoord, "int", $yCoord) DllCall("USER32.DLL", "int", "ReleaseDC", "hwnd", $hWnd, "int", $aHDC[0]) If @error Then Return SetError(2, 0, 0) If IsArray($aGetPix) = 0 Or $aGetPix[0] < 0 Then Return SetError(3, 0, 0) Return $aGetPix[0] EndFunc(Not tested) Edit: Forgot ReleaseDC Edited March 18, 2008 by SmOke_N Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.
DoctorLechter Posted March 18, 2008 Author Posted March 18, 2008 (edited) Many thanks! My fault in C++ was: CODE extern "C" COLORREF GetColor(int x, int y) // WRONG extern "C" __declspec(dllexport) COLORREF GetColor(int x, int y) // OK My fault in AutoIt were: CODE ;-------------------------------------------------; WRONG $TEMP = DllCall("ColorDll.dll", "dword", "GetColor", "int", X, "int", Y) MsgBox(0, "Error", $TEMP) MsgBox(0, "Error", @error ) ;-------------------------------------------------; OK $TEMP = DllCall("ColorDll.dll", "dword:cdecl", "GetColor", "int", 9, "int", 119) MsgBox(0, "Error", @error ) MsgBox(0, "Error", $TEMP[0]) Not hard coding one, just was fed up with watching those lines for 30+ hours. Thanks again! Edited March 18, 2008 by DoctorLechter
DoctorLechter Posted March 18, 2008 Author Posted March 18, 2008 I want to post my .dll here in case anyone needs a function to get pixel color from an inactive window. (.dll-file linked below)First of all, how to use it (example):CODE$COLOR = DllCall("ColorDll.dll", _ ; Don't forget to point the path to .dll if needed"dword:cdecl", "_WinGetPixColor", _ ; Don't edit this line"str", $WndClass, _ ; Your window class here"str", $WndTitle, _ ; Your window title here"ushort", $xAxis, _ ; xAxis to get color from"ushort", $yAxis) ; yAxis to get color fromSecond:- use "AutoIt v3 Window Info" to get "Window Class" and "Window Title" in "Summary" tab;- use only coords related to client area of window to work right, or do needed calculations to convert them from window-related to client area;- "dword" means that _WinGetPixColor returns some value in "DWORD" type, i.e. a 32 bit integer, so it's a decimal number of color in $COLOR[0], to view it in hexadecimal, use Hex($COLOR[0]);- _WinGetPixColor returns FFFFFFFF (if use hexadecimal) or -1 (if decimal) if unable to get the color from the window specified, reasons may be - typing error, arguments error, or window is DirectX-application and is not on the screen;- "str" means that _WinGetPixColor gets next after it argument as "string" type, i.e. as an ANSI string;- "ushort" means that _WinGetPixColor gets next after it argument as "unsigned short" type, i.e. as an unsigned an unsigned 16 bit integer;- Please do not forget to scan for viruses; http://www.virustotal.com (here is scanning result - http://www.virustotal.com/analisis/f55d43a...80c5e64f815986)- Use at your own risk;- Have fun Here is the .dll itself:ColorDll.rar
andrewseul Posted August 16, 2009 Posted August 16, 2009 Im getting an error when using this script:$WndClass = "test" $WndTitle = "Testing" $xAxis = 100 $yAxis = 456 $COLOR = DllCall("ColorDll.dll", _ ; Don't forget to point the path to .dll if needed "dword:cdecl", "_WinGetPixColor", _ ; Don't edit this line "str", $WndClass, _ ; Your window class here "str", $WndTitle, _ ; Your window title here "ushort", $xAxis, _ ; xAxis to get color from "ushort", $yAxis) ; yAxis to get color from MsgBox(0,"The pixel color is",& $COLOR[0])Error:
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now