Sign in to follow this  
Followers 0
DoctorLechter

Problems Calling Dll Function

6 posts in this topic

#1 ·  Posted (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 by DoctorLechter

Share this post


Link to post
Share on other sites



#2 ·  Posted (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 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.

Share this post


Link to post
Share on other sites

#3 ·  Posted (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 by DoctorLechter

Share this post


Link to post
Share on other sites

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 from

Second:

- 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

Share this post


Link to post
Share on other sites

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:

Posted Image

Share this post


Link to post
Share on other sites

I also have a similar error,anybody help me

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0