Jump to content
Sign in to follow this  
DoctorLechter

Problems Calling Dll Function

Recommended Posts

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

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

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

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  

×
×
  • Create New...