Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

DllCall. Help, anyone?


  • Please log in to reply
26 replies to this topic
foom
  • Members
  • 386 posts
  • Last active: Jul 04 2007 04:53 PM
  • Joined: 19 Apr 2006
I allways google for these values like this "define A_DEFINED_VALUE"

I have a question regarding the LSB. Does it mean an int 1 does look like this in memory( bytes delimited by |)
00000001|00000000|00000000|00000000
and not like this:
00000000|00000000|00000000|00000001
?

Pil
  • Members
  • 55 posts
  • Last active: Mar 25 2014 05:00 AM
  • Joined: 26 Feb 2006
Hi.
olfen wrote:

WinHex helped me get started with DllCalls and I am still using it to see what actually is happening in the process memory.
It allows you to open the memory of your running ahk script (Alt-F9) and see what data is present at a certain offset (you can get that offset by evaluating &variable).

Interesting.
I downloaded WinHex.
Could you give some more details about how evaluating &variable?
Thanks
Noel

PhiLho
  • Moderators
  • 6850 posts
  • Last active: Jan 02 2012 10:09 PM
  • Joined: 27 Dec 2005
@foom Exactly!
A useful helper function (overkill here, but of general utility for debugging):
a := 1
MsgBox % DumpDWORDs(a, 4)

FormatHexNumber(_value, _digitNb)
{
	local hex, intFormat

	; Save original integer format
	intFormat = %A_FormatInteger%
	; For converting bytes to hex
	SetFormat Integer, Hex

	hex := _value + (1 << 4 * _digitNb)
	StringRight hex, hex, _digitNb
	; I prefer my hex numbers to be in upper case
	StringUpper hex, hex

	; Restore original integer format
	SetFormat Integer, %intFormat%

	Return hex
}

/*
// For debugging, return formatted hex string separating DWORDs
// Idem to Bin2Hex, usable directly in a MsgBox...
// Extended mode: give offsets and Ascii dump.
*/
DumpDWORDs(ByRef @bin, _byteNb, _bExtended=false)
{
	local dataSize, dataAddress, granted, line, dump, hex, ascii
	local dumpWidth, offsetSize, resultSize

	offsetSize = 4	; 4 hex digits (enough for most dumps)
	dumpWidth = 32
	dataAddress := &@bin
	; Make enough room (faster)
	resultSize := _byteNb * 4
	If _bExtended
	{
		dumpWidth = 16 ; Make room for offset and Ascii
		resultSize += offsetSize + 8 + dumpWidth
	}
	granted := VarSetCapacity(dump, resultSize)
	if (granted < resultSize)
	{
		; Cannot allocate enough memory
		ErrorLevel = Mem=%granted%
		Return -1
	}
	If _bExtended
	{
		offset = 0
		line := FormatHexNumber(offset, offsetSize) ": "
	}
	Loop %_byteNb%
	{
		; Get byte in hexa
		hex := FormatHexNumber(*dataAddress, 2)
		If _bExtended
		{
			; Get byte in Ascii
			If (*dataAddress >= 32)	; Not a control char
			{
				ascii := ascii Chr(*dataAddress)
			}
			Else
			{
				ascii := ascii "."
			}
			offset++
		}
		line := line hex A_Space
		If (Mod(A_Index, dumpWidth) = 0)
		{
			; Max dumpWidth bytes per line
			If (_bExtended)
			{
				; Show Ascii dump
				line := line " - " ascii
				ascii =
			}
			dump := dump line "`n"
			line =
			If (_bExtended && A_Index < _byteNb)
			{
				line := FormatHexNumber(offset, offsetSize) ": "
			}
		}
		Else If (Mod(A_Index, 4) = 0)
		{
			; Separate bytes per groups of 4, for readability
			line := line "| "
		}
		dataAddress++	; Next byte
	}
	If (Mod(_byteNb, dumpWidth) != 0)
	{
		If (_bExtended)
		{
			line := line " - " ascii
		}
		dump := dump line "`n"
	}

	Return dump
}
Note it displays 31 00 00 00 because AHK stores integers as Ascii strings.
[EDIT] For a more meaningful result:
VarSetCapacity(buf, 4, 0)
DllCall("RtlFillMemory", "UInt", &buf, "UInt", 1, "UChar", 1)
MsgBox % DumpDWORDs(buf, 4)

Posted Image vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")

MisterW
  • Members
  • 65 posts
  • Last active: Jun 18 2007 11:14 AM
  • Joined: 20 Jul 2005

I might be wrong but I think shimanov (btw. is he still with us?)


I've been wondering that too?

olfen
  • Members
  • 115 posts
  • Last active: Dec 25 2012 09:48 AM
  • Joined: 04 Jun 2005

Hi.
olfen wrote:

WinHex helped me get started with DllCalls and I am still using it to see what actually is happening in the process memory.
It allows you to open the memory of your running ahk script (Alt-F9) and see what data is present at a certain offset (you can get that offset by evaluating &variable).

Interesting.
I downloaded WinHex.
Could you give some more details about how evaluating &variable?
Thanks
Noel


Here's an example to demonstrate it:
var = 1234567890

;copy variables address to clipboard
setformat, integer, hex
offset := &var
stringtrimleft, offset, offset, 2 ;remove 0x for WinHex
clipboard = %offset%

setformat, integer, dec
process, exist
msgbox,
(
Content: %var%
Offset: 0x%offset%

Now start Winhex and go through the following steps:
- Menu: Tools -> Open RAM (Alt+F9)
- Double click "Autohotkey #%errorlevel%"
- Select "Entire Memory" and click OK
- Menu: Postition -> Go To Offset (Alt+G)
- Paste the Offset of the variable (it has already been copied to the clipboard) and click OK
)


neXt
  • Members
  • 549 posts
  • Last active: May 20 2015 02:38 AM
  • Joined: 18 Mar 2007
K, not to create a new topic on Dlls, i'll just raise this one.

I seriously don't get this dllcalls, it's so confusing :? .
I took a simple example from a help file and modified it a bit but i don't get the desired result for some reason.
DllCall("MessageBox", "int", "0", "str", "example", "str", "My First DllCall", "Uint", "MB_YESNO")

return
1) according to http://msdn2.microso...y/ms645505.aspx last parameter is Type, but why do i get just an OK button when i specified YES/NO ?

2) What does Unsigned means ?

3)This is from the first page:
DllCall("kernel32.dll\GlobalMemoryStatus"
       ,"uint",&memoryusage
       ,"uint",&availphys
       ,"unit",&totalpagefile)

msgbox % &memoryusage
msgbox % &availphys
msgbox % &totalpagefile
Were "availphys" & "memoryusage" came from ??? I'm looking on this page http://msdn2.microso...y/Aa366586.aspx and i can't see this parameters :shock: .

Daniel2
  • Guests
  • Last active:
  • Joined: --
Sorry to drudge up an old topic.. but seemed appropriate; i'm new to trying to attempting to use dllcall. I'm trying to help w/ adding functions to corrupt's awesome richedit initiative in part.. but mostly just want to learn how to
harness the power of extending ahk w/ dllcalls. An example function is
EM_GETSELTEXT.

The EM_GETSELTEXT message retrieves the currently selected text in a rich edit control.

lResult = SendMessage( // returns LRESULT in lResult
(HWND) hWndControl, // handle to destination control
(UINT) EM_GETSELTEXT, // message ID
(WPARAM) wParam, // = (WPARAM) () wParam;
(LPARAM) lParam // = (LPARAM) () lParam; );

Parameters

wParam
This parameter is not used; it must be zero. lParam
Pointer to a buffer that receives the selected text. The calling application must
ensure that the buffer is large enough to hold the selected text.
Return Value
This message returns the number of characters copied, not including the
terminating null character.

I am obviously missing some fundamental points on how to get message ID's :(
DllCall("SendMessage"
                  , "UInt", _ctrlID
                  , "UInt", ???
                  , "Str", ""
                  , "Cdecl Str", &_tmp1)
An example function that he already included was for setting EM_SETTEXTEX.
DllCall("SendMessage"
                  , "UInt", _ctrlID
                  , "UInt", 0x461
                  , "Str", ""
                  , "Str", opt1) ; EM_SETTEXTEX
Unless its listed in list of windows messages (in help file..) how is everybody finding these values.? :? Lately there have been tons of new functionality enhancing scripts posted.. & many of the new functions declare these constants included prior to starting function
WS_CHILD           := 

0x40000000
WS_VISIBLE         := 0x10000000
WS_EX_CLIENTEDGE   := 0x200
GWL_HINSTANCE      := -6
WM_USER            := 0x400
Besides using one of the mentioned utilities/api databases.. is there something simple like I am overlooking for getting these messages (like a simple function.. or maybe converting EM_GETSELTEXT to hex..?)
I appriciate any help anyone can give.. & I apologize if this has been covered over & over again-- but there are just too many search results to look through when your not evan completely sure what your looking for :)

neXt
  • Members
  • 549 posts
  • Last active: May 20 2015 02:38 AM
  • Joined: 18 Mar 2007
Is it forbitten to talk about Dlls or something?

PhiLho
  • Moderators
  • 6850 posts
  • Last active: Jan 02 2012 10:09 PM
  • Joined: 27 Dec 2005

Is it forbitten to talk about Dlls or something?

Why do you ask that? I saw nobody screaming on you.
Note that most people aren't present 24h a day on the forum, and lot of them are on a different time zone...

DllCall("MessageBox", "int", "0", "str", "example", "str", "My First DllCall", "Uint", "MB_YESNO")

After "Int", you have to put an integer, so that's 0, not "0". It might make no difference for AHK, but it is cleaner this way.
"MB_YESNO" isn't correct, see this as a variable holding an integer ("UInt"). To have the values of such variables (actually constants, they never change), a tool like ApiViewer is precious.
It shows Const MB_YESNO As Long = &H4&, which is VB code, but can be translated as MB_YESNO := 0x4

An unsigned number is a number (usually integer) without sign symbol, meaning it is always a positive (or null) number.

Were "availphys" & "memoryusage" came from

They are just variables of the script. The & means to provide their address instead of their values, usually because the API function will fill them (or they are binary structure, ie. complex data).

Note that using DllCall without knowing C programming nor Windows programming is at best hazardous, unless you are sticking to using examples found on the forum.
Now, it is doable, Skan managed to use it quite efficiently without prior knowledge.

Daniel2, corrupt prefers to use DllCall to SendMessage, but you can stick to the standard command.
Oh, and the tip on ApiViewer answers your question "how is everybody finding these values.?", another possibility is to download some Windows development tool and look at the provided .h files... But ApiViewer is fast and handy.
Posted Image vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")

neXt
  • Members
  • 549 posts
  • Last active: May 20 2015 02:38 AM
  • Joined: 18 Mar 2007
Sorry, you are right :oops: .
Thanks a lot on your tips!

tank
  • Administrators
  • 4345 posts
  • AutoHotkey Foundation
  • Last active: May 02 2019 09:16 PM
  • Joined: 21 Dec 2007
Sorry i know this is an ancient topic

It shows Const MB_YESNO As Long = &H4&, which is VB code, but can be translated as MB_YESNO := 0x4

OK i give How
Never lose.
WIN or LEARN.

Sivvy
  • Members
  • 726 posts
  • Last active: Apr 23 2010 02:50 PM
  • Joined: 21 Jul 2008

OK i give How

Not sure what your asking... Do you mean "How is 'Const MB_YESNO As Long = &H4&' translated as 'MB_YESNO := 0x4'?"