Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate

Allowing Function Pointer in DllCall


  • Please log in to reply
43 replies to this topic
Sean
  • Guests
  • Last active:
  • Joined: --

Sean could you please elaborate where you get the information to build for example the IID_IWebBrowser2 (InterfaceID?)?


I translated it from its string representation {D30C1661-CDAF-11D0-8A3E-00C04FC9E26E}.

There exists a page in MSDN to describe the translation between the two. You may search it there. But, if you compare them carefully, you may figure it out yourself how to do it.

BTW, there exist helper APIs, but I decided to do it this way. Basically, it is:
First convert the string representation to Unicode.
Then, encode it using either CLSIDFromString or IIDFromString.

Sean
  • Guests
  • Last active:
  • Joined: --

I've executed your script/sample and based on the above links, set within the code I've expected to get/see one of those pages loaded within the Gui/Control. But I might be wrong.

Sorry for the inconvenience. Yes, I only tested it on my XPSP2. And machines I can access around me are all XPSP2 too.
I rewrote it replacing direct references with appropriate indrections. Please follow the instructions in MsgBox after executing.

Thx for your effort. Much appreciated. :D

Thanks.
I'm afraid this may be my last post for a while, I've been detracted too much from my current project, so I have to concentrate on it for now.


Gui, Show, w800 h600 Center, WebBrowser

hWnd := WinExist( "WebBrowser" )

sWinName := "Shell.Explorer"		; ProgID of WebBrowser control

VarSetCapacity(IID_IDispatch, 16)

;Encode 128bit IID_IDispatch
EncodeInteger(&IID_IDispatch    , 0x00020400)
EncodeInteger(&IID_IDispatch + 4, 0)
EncodeInteger(&IID_IDispatch + 8, 0xC0)
EncodeInteger(&IID_IDispatch +12, 0x46 << 24)


hModule := DllCall("LoadLibrary", "str", "atl.dll")

DllCall("atl\AtlAxWinInit")

hCtrl := DllCall("CreateWindowEx"
	, "Uint", 0x200				; WS_EX_CLIENTEDGE
	, "str",  "AtlAxWin"			; ClassName
	, "Uint", &sWinName			; WindowName
	, "Uint", 0x10000000 | 0x40000000	; WS_VISIBLE | WS_CHILD
	, "int",  0				; Left
	, "int",  0				; Top
	, "int",  800				; Width
	, "int",  600				; Height
	, "Uint", hWnd
	, "Uint", 0
	, "Uint", 0
	, "Uint", 0)

; Obtain IUnknown Interface
DllCall("atl\AtlAxGetControl", "Uint", hCtrl, "UintP", ppunk)

; Obtain IDispatch Interface
DllCall(DecodeInteger(DecodeInteger(ppunk) + 4*0)    ; QueryInterface
	, "Uint", ppunk
	, "Uint", &IID_IDispatch
	, "UintP", ppwb)

DllCall(DecodeInteger(DecodeInteger(ppunk) + 4*2)    ; Release
	, "Uint", ppunk)


If !ppwb
{
	MsgBox, We're Failed. Now Exit the app.
	ExitApp
}
Else
	MsgBox, We're ready for the test after pressing OK!


sUrl := "http://www.autohotkey.com/"
VarSetCapacity(wUrl, StrLen(sUrl) * 2 + 2)
Unicode(sUrl, wUrl)

sUrl1 := "http://www.autohotkey.com/forum/"
VarSetCapacity(wUrl1, StrLen(sUrl1) * 2 + 2)
Unicode(sUrl1, wUrl1)


DllCall(DecodeInteger(DecodeInteger(ppwb) + 4*11)    ; Navigate
	, "Uint", ppwb
	, "Uint", &wUrl
	, "Uint", 0
	, "Uint", 0
	, "Uint", 0
	, "Uint", 0)

MsgBox, Wait for "LOADING" AHK site completed, then press OK

DllCall(DecodeInteger(DecodeInteger(ppwb) + 4*11)    ; Navigate
	, "Uint", ppwb
	, "Uint", &wUrl1
	, "Uint", 0
	, "Uint", 0
	, "Uint", 0
	, "Uint", 0)

MsgBox, Wait for "LOADING" AHK Forum completed, then press OK

DllCall(DecodeInteger(DecodeInteger(ppwb) + 4*7)     ; GoBack
	, "Uint", ppwb)

MsgBox, Wait until "GO BACK" done, then press OK

DllCall(DecodeInteger(DecodeInteger(ppwb) + 4*8)     ; GoForward
	, "Uint", ppwb)

MsgBox, Wait until "GO FORWARD" done, then all test DONE!

DllCall(DecodeInteger(DecodeInteger(ppwb) + 4*2)     ; Release
	, "Uint", ppwb)

DllCall("FreeLibary", "Uint", hModule)


Unicode(ByRef sString, ByRef wString)
{
    DllCall("MultiByteToWideChar"
	, "Uint", 0
	, "Uint", 0
	, "Uint", &sString
	, "int",  -1
	, "Uint", &wString
	, "int",  StrLen(sString) + 1)
}

DecodeInteger(ref)
{
    DllCall("ntdll\RtlMoveMemory", "UintP", val, "Uint", ref, "Uint", 4)
    Return val
}

EncodeInteger(ref, val)
{
    DllCall("ntdll\RtlFillMemoryUlong", "Uint", ref, "Uint", 4, "Uint", val)
}



BoBo
  • Guests
  • Last active:
  • Joined: --

Please follow the instructions in MsgBox after executing.

Well, I ended up with this ..

We're Failed. Now Exit the app.


XPPro/SP2
AHK 1.0.46.07
IE 6.0.2900.x

:(

majkinetor
  • Moderators
  • 4512 posts
  • Last active: May 20 2019 07:41 AM
  • Joined: 24 May 2006
lol...
Posted Image

majkinetor
  • Moderators
  • 4512 posts
  • Last active: May 20 2019 07:41 AM
  • Joined: 24 May 2006
I made a little helper function, pandan to C DEFINE_GUID macro:

DEFINE_GUID( ByRef pVarName, pGuid ) {
	local a,, start = 1, splitAt = 8,4,4,2,2,2,2,2,2,2,2

	StringReplace,  pGuid, pGuid, {, , A
	StringReplace,  pGuid, pGuid, -, , A

	loop, parse, splitAt,`,
	{
		  a%A_Index% := "0x" SubStr( pGuid, start, A_LoopField )
		  start += A_LoopField
	}

	VarSetCapacity(pVarName, 16)
    DllCall("ntdll\RtlFillMemoryUlong", "Uint", &pVarName, "Uint", 4, "Uint", a1) 
    DllCall("ntdll\RtlFillMemoryUlong", "Uint", &pVarName, "Uint", 4, "Uint", a2 | a3 << 16) 
    DllCall("ntdll\RtlFillMemoryUlong", "Uint", &pVarName, "Uint", 4, "Uint", a4 | a5 << 8 | a6 << 16 | a7 << 24) 
    DllCall("ntdll\RtlFillMemoryUlong", "Uint", &pVarName, "Uint", 4, "Uint", a8 | a9 << 8 | a10 << 16 | a11 << 24) 
}

So, you can write now:
DEFINE_GUID(IID_IWebBrowser2, "{8856F961-340A-11D0-A96B-00C04FD705A2}")

Posted Image

foom
  • Members
  • 386 posts
  • Last active: Jul 04 2007 04:53 PM
  • Joined: 19 Apr 2006
IIDFromString(s, ByRef IID){
    Unicode(s,w)
    VarsetCapacity(IID,16)
    return DllCall("ole32\IIDFromString", "str", w, "str", IID)
}

CLSIDFromString(s, ByRef CLSID){
    Unicode(s,w)
    VarsetCapacity(CLSID,16)
    return DllCall("ole32\CLSIDFromString", "str", w, "str", CLSID)
}

Unicode(ByRef sString, ByRef wString)
{
    VarSetCapacity(wString, StrLen(sString) * 2 + 2)
    DllCall("MultiByteToWideChar", "Uint", 0, "Uint", 0
            , "Uint", &sString, "int",  -1
            , "Uint", &wString, "int",  StrLen(sString) + 1)
}

Does someone know where to get the IID for ISpVoice? I have the CLSID from the registry but i cant find the freakin IDD for SpVoice. :x

Sean
  • Guests
  • Last active:
  • Joined: --

XPPro/SP2
AHK 1.0.46.07
IE 6.0.2900.x

Have you used this test build?

(Edit by moderator: Link dead, so use the current release from http://www.autohotkey.com/download/ because it has this feature now.)

Sean
  • Guests
  • Last active:
  • Joined: --

So, you can write now:

DEFINE_GUID(IID_IWebBrowser2, "{8856F961-340A-11D0-A96B-00C04FD705A2}")

Good, I'll use either this one or helper APIs from next time.

Sean
  • Guests
  • Last active:
  • Joined: --

Does someone know where to get the IID for ISpVoice? I have the CLSID from the registry but i cant find the freakin IDD for SpVoice. :x

I think I have to explain a little how to use oleview.exe or tlb.exe to get informations from TypeLib for IDispatch type objects before leaving a while. As oleview.exe might be too overwhelming at first use, I recommend playing with tlb.exe for a while.

OK, in this SpVoice case, the TypeLib resides in sapi.dll according to the registry. So, trigger tlb.exe and locate sapi.dll there, then double click it. Voila, all you need are there, IID_ISpVoice, IID_ISpeechVoice, etc. BTW, according to it, IID_ISpeechVoice, not IID_ISpVoice, is the default interface.

majkinetor
  • Moderators
  • 4512 posts
  • Last active: May 20 2019 07:41 AM
  • Joined: 24 May 2006
Thx foom for better wrappers.

I knew such functions do exist but several fast searches failed... :)

BUT, I think there is no difference between IID and CLSID functions. In .h files for sample I read I have:

// IExample2 type library's GUID
// {E1124082-5FCD-4a66-82A6-755E4D45A9FC}
DEFINE_GUID(CLSID_TypeLib, 0xe1124082, 0x5fcd, 0x4a66, 0x82, 0xa6, 0x75, 0x5e, 0x4d, 0x45, 0xa9, 0xfc);

// IExample2 object's GUID
// {520F4CFD-61C6-4eed-8004-C26D514D3D19}
DEFINE_GUID(CLSID_IExample2, 0x520f4cfd, 0x61c6, 0x4eed, 0x80, 0x4, 0xc2, 0x6d, 0x51, 0x4d, 0x3d, 0x19);

// IExample2 VTable's GUID (interface)
// {B6127C55-AC5F-4ba0-AFF6-7220C95EEF4D}
DEFINE_GUID(IID_IExample2, 0xb6127c55, 0xac5f, 0x4ba0, 0xaf, 0xf6, 0x72, 0x20, 0xc9, 0x5e, 0xef, 0x4d);

So, they are all calculated with the same C macro...
Posted Image

foom
  • Members
  • 386 posts
  • Last active: Jul 04 2007 04:53 PM
  • Joined: 19 Apr 2006
First of all thanks Sean for giving me some startup help.

Now its time for a little TTS fun.
#SingleInstance Force
#NoEnv
;SetBatchLines -1
sCLSID_SpVoice:="{96749377-3391-11D2-9EE3-00C04F797396}"
sIID_ISpeechVoice:="{269316D8-57BD-11D2-9EEE-00C04F797396}"

;some errorcodes
E_INVALIDARG            = 0x80070057
NOERROR                 = 0x00000000 
CO_E_CLASSSTRING        = 0x800401F3 
REGDB_E_CLASSNOTREG     = 0x80040154 
REGDB_E_READREGDB       = 0x80040150 
CLASS_E_NOAGGREGATION   = 0x80040110 
E_NOINTERFACE           = 0x80004002
E_POINTER               = 0x80004003
E_HANDLE                = 0x80070006
E_ABORT                 = 0x80004004
E_FAIL                  = 0x80004005
E_ACCESSDENIED          = 0x80070005
E_PENDING               = 0x8000000A


if ret := hex(IIDFromString(sIID_ISpeechVoice, IID_ISpeechVoice)) or ret2 := CLSIDFromString(sCLSID_SpVoice,CLSID_SpVoice)
{
msgbox Optaining I/CLS-ID from string failed. Exiting! %ret% %ret2%
exitapp
}

if ret := DllCall("ole32\CoInitialize", "Uint", 0)
msgbox, % "Init COM: " ret


if ret := DllCall("ole32\CoCreateInstance"
            , "Uint", &CLSID_SpVoice
            , "Uint", 0
            , "Uint", 1
            , "Uint", &IID_ISpeechVoice
            , "UintP", ppSpVoice, "cdecl uint")
msgbox, % "CoCreateInstance()`nReturned: " hex(ret)

if not pSpVoice := DecodeInteger(ppSpVoice)
msgbox, % "pSpVoice = " pSpVoice

TTS=
(C
<xml version="1.0">
    <SAPI>
        Stephen <PRON SYM="eh aw k iy n g"/> said, <SILENCE MSEC="500"/> not!<SILENCE MSEC="500"/>
        Some people think that,
        if you put a <PRON SYM="b eh r l iy 1 n eh r"> Berliner</PRON>
        into a <PRON SYM="k aa - n 2 ow  - n eh"> Kanone </PRON>,
        you get a <PRON SYM="t ay l ch 2 eh n b eh sh l oy n iy g eh r"> Teilchenbeschleuniger </PRON>!
    </SAPI>
</xml>
)
wTTS=
unicode(TTS,wTTS)   
if ret := DllCall(DecodeInteger(pSpVoice + 4*28)
            , "Uint", ppSpVoice
            , "str" , wTTS
            , "Uint", 0    ;SPF_DEFAULT = 0. If the fist character of text is "<" input will be parsed as xml.
            , "Uint", 0)
msgbox, % "pSpVoice->Speak()`nErrorlevel: "  errorlevel "`nReturned: " hex(ULong(ret))

DllCall("ole32\CoUninitialize")

hex(n)
{
    old=%A_FormatInteger%
    SetFormat, integer, hex
    n+=0
    SetFormat, integer, %old%
    return n
}

IIDFromString(s, ByRef IID){
    Unicode(s,w)
    VarSetCapacity(IID, 16)
    return DllCall("ole32\IIDFromString", "str", w, "str", IID, "cdecl uint")
}

CLSIDFromString(s, ByRef CLSID){
    Unicode(s,w)
    VarSetCapacity(CLSID, 16)
    return DllCall("ole32\CLSIDFromString", "str", w, "str", CLSID, "cdecl uint")
}


Unicode(ByRef sString, ByRef wString) ;Convert ansi to unicode. Returns (strlen+\0)*2, e.g. the buffersize
{
	outlen := VarSetCapacity(wString, StrLen(sString) * 2 + 2, 0)
	return DllCall("MultiByteToWideChar"
                         , "UInt", 0, "UInt", 0
        			     , "Str", sString, "Int", -1
        			     , "UInt", &wString, "Int", outlen) * 2
}

DecodeInteger(ref)
{
    DllCall("ntdll\RtlMoveMemory", "UintP", val, "Uint", ref, "Uint", 4)
    Return val
}

EncodeInteger(ref, val)
{
    DllCall("ntdll\RtlFillMemoryUlong", "Uint", ref, "Uint", 4, "Uint", val)
}

ULong(n){
    DllCall("ntdll\RtlFillMemoryUlong", "UintP", out, "Uint", 4, "Uint", n)
    return out
}


AHKnow*
  • Guests
  • Last active:
  • Joined: --
I was looking at information on the Windows API when I came across this link- http://www.relisoft....win32/index.htm

They have a COM/OLE section that goes more into using C++ to implement COM/OLE.

AHKnow
  • Members
  • 121 posts
  • Last active: May 17 2009 09:11 PM
  • Joined: 03 Jul 2004
A really good tool to help understand what is going here is COMView, located at-

<!-- m -->http://www.japheth.de/<!-- m -->

<!-- m -->http://www.japheth.de/COMView.html<!-- m -->

<!-- m -->http://www.japheth.d...oad/COMView.ZIP<!-- m -->

You can get the CLSID and IID, in addition to other info.

Also, Comwizard

<!-- m -->http://home.pacbell..../comwizard.html<!-- m -->

djdeeno31
  • Members
  • 1 posts
  • Last active: Jan 24 2008 03:56 PM
  • Joined: 24 Jan 2008
How can i put this webbrowser in to a exist Gui?



Gui, Show, w800 h600 Center, WebBrowser

hWnd := WinExist( "WebBrowser" )

sWinName := "Shell.Explorer"		; ProgID of WebBrowser control

VarSetCapacity(IID_IDispatch, 16)

;Encode 128bit IID_IDispatch
EncodeInteger(&IID_IDispatch    , 0x00020400)
EncodeInteger(&IID_IDispatch + 4, 0)
EncodeInteger(&IID_IDispatch + 8, 0xC0)
EncodeInteger(&IID_IDispatch +12, 0x46 << 24)


hModule := DllCall("LoadLibrary", "str", "atl.dll")

DllCall("atl\AtlAxWinInit")

hCtrl := DllCall("CreateWindowEx"
	, "Uint", 0x200				; WS_EX_CLIENTEDGE
	, "str",  "AtlAxWin"			; ClassName
	, "Uint", &sWinName			; WindowName
	, "Uint", 0x10000000 | 0x40000000	; WS_VISIBLE | WS_CHILD
	, "int",  0				; Left
	, "int",  0				; Top
	, "int",  800				; Width
	, "int",  600				; Height
	, "Uint", hWnd
	, "Uint", 0
	, "Uint", 0
	, "Uint", 0)

; Obtain IUnknown Interface
DllCall("atl\AtlAxGetControl", "Uint", hCtrl, "UintP", ppunk)

; Obtain IDispatch Interface
DllCall(DecodeInteger(DecodeInteger(ppunk) + 4*0)    ; QueryInterface
	, "Uint", ppunk
	, "Uint", &IID_IDispatch
	, "UintP", ppwb)

DllCall(DecodeInteger(DecodeInteger(ppunk) + 4*2)    ; Release
	, "Uint", ppunk)


If !ppwb
{
	MsgBox, We're Failed. Now Exit the app.
	ExitApp
}
Else
	MsgBox, We're ready for the test after pressing OK!


sUrl := "http://www.autohotkey.com/"
VarSetCapacity(wUrl, StrLen(sUrl) * 2 + 2)
Unicode(sUrl, wUrl)

sUrl1 := "http://www.autohotkey.com/forum/"
VarSetCapacity(wUrl1, StrLen(sUrl1) * 2 + 2)
Unicode(sUrl1, wUrl1)


DllCall(DecodeInteger(DecodeInteger(ppwb) + 4*11)    ; Navigate
	, "Uint", ppwb
	, "Uint", &wUrl
	, "Uint", 0
	, "Uint", 0
	, "Uint", 0
	, "Uint", 0)

MsgBox, Wait for "LOADING" AHK site completed, then press OK

DllCall(DecodeInteger(DecodeInteger(ppwb) + 4*11)    ; Navigate
	, "Uint", ppwb
	, "Uint", &wUrl1
	, "Uint", 0
	, "Uint", 0
	, "Uint", 0
	, "Uint", 0)

MsgBox, Wait for "LOADING" AHK Forum completed, then press OK

DllCall(DecodeInteger(DecodeInteger(ppwb) + 4*7)     ; GoBack
	, "Uint", ppwb)

MsgBox, Wait until "GO BACK" done, then press OK

DllCall(DecodeInteger(DecodeInteger(ppwb) + 4*8)     ; GoForward
	, "Uint", ppwb)

MsgBox, Wait until "GO FORWARD" done, then all test DONE!

DllCall(DecodeInteger(DecodeInteger(ppwb) + 4*2)     ; Release
	, "Uint", ppwb)

DllCall("FreeLibary", "Uint", hModule)


Unicode(ByRef sString, ByRef wString)
{
    DllCall("MultiByteToWideChar"
	, "Uint", 0
	, "Uint", 0
	, "Uint", &sString
	, "int",  -1
	, "Uint", &wString
	, "int",  StrLen(sString) + 1)
}

DecodeInteger(ref)
{
    DllCall("ntdll\RtlMoveMemory", "UintP", val, "Uint", ref, "Uint", 4)
    Return val
}

EncodeInteger(ref, val)
{
    DllCall("ntdll\RtlFillMemoryUlong", "Uint", ref, "Uint", 4, "Uint", val)
}

[/quote]