Jump to content

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

Retrieve AddressBar of Firefox through DDE Message


  • Please log in to reply
55 replies to this topic
Joy2DWorld
  • Members
  • 562 posts
  • Last active: Jun 30 2014 07:48 PM
  • Joined: 04 Dec 2006
@Sean,

thanks for keeping me sane....


here is my attempt at a POKE....

and please.... where has it gone wrong??


Poke_(item) {

	Global  WM_DDE_POKE,ClientHwnd,ServerHwnd, myAnswer
	myAnswer =
	Pitem := "X" . item
	InsertInt(0x0501, Pitem) ; pOffset = 0, pSize = 4)  ;; 0701 ??
	
	HPItem := DllCall("GlobalAlloc"
	, UINT, 0x0000 ;  0x0040 ... 
	, UINT, 256) ; ie, size 
	
	hItem := DllCall("GlobalAddAtom", "str", Item, "Ushort")	

	LPARAM := DllCall("PackDDElParam",  "UINT",  Pitem, "UINT", HPItem ,"UINT" , hItem)


	PostMessage, WM_DDE_POKE, ClientHwnd, LPARAM   ,, ahk_id %ServerHwnd%
	DllCall("DeleteAtom", "Ushort", hItem)	
	

	return Wait(myAnswer)


}


which...

from <!-- m -->http://msdn2.microso...y/ms648997.aspx<!-- m -->


WM_DDE_POKE Notification
A Dynamic Data Exchange (DDE) client application posts a WM_DDE_POKE message to a DDE server application. A client uses this message to request the server to accept an unsolicited data item. The server is expected to reply with a WM_DDE_ACK message indicating whether it accepted the data item.

To post this message, call the PostMessage function with the following parameters.

Syntax

PostMessage(
(HWND) hWnd,
WM_DDE_POKE,
(WPARAM) wParam,
(LPARAM) lParam
);

Parameters

wParam
Handle to the client window posting the message.
lpDdePoke
The low-order word is a handle to a global memory object containing a DDEPOKE structure with the data and additional information.
The high-order word contains a global atom that identifies the data item for which the data or notification is being sent.

Return Value

No return value.
Remarks

Posting

The client application must allocate memory for the global memory object using the GlobalAlloc function. The client application must delete the object if either of the following conditions is true:

The server application responds with a negative WM_DDE_ACK message.
The fRelease member is FALSE, but the server application responds with either a positive or negative WM_DDE_ACK.
The client application must create the atom using the GlobalAddAtom function.

The client application must create or reuse the WM_DDE_POKE lpDdePoke parameter by calling the PackDDElParam function or the ReuseDDElParam function.


Joyce Jamce

Sean
  • Members
  • 2462 posts
  • Last active: Feb 07 2012 04:00 AM
  • Joined: 12 Feb 2007

here is my attempt at a POKE....

Why are you trying to use DDEMessage instead of DDEML?
Anyway, I added DDE_POKE and DDE_EXECUTE in the first post, but, not tested.
Please inform me if meet a problem with it.

Joy2DWorld
  • Members
  • 562 posts
  • Last active: Jun 30 2014 07:48 PM
  • Joined: 04 Dec 2006
hope this doesn't sound too silly, been working on it for MONTHS and MONTHS (and somehow my mind did not want to comprehend!), and very very very very much appreciate your help, and lending of your artful skill!


basic answer:


Speed and the ability to be a server.


AHK has no callback right now. Been working on coding something in machine code that basically accepts the callback and then writes the data after the code (sequentially in memory).


Trying to keep it small, but workable. Idea is: define VAR space large enough for the code & it's memory space. Place code in the Var (either at beginning, or at offset). GIVE THE CODE (& offset) as the callback ...



but, that is going slow,

anyhow,

without callback AHK can only do ASYNC communication with the DDE -->

have to wait for the response before moving on to next request;

but with messaging:

we can send as many requests as server can handle... and deal with them in a syncronous way--> talking and listening at the same time.


(not sure the code is tracking the message ids, ie. puting into var what message the data is being sent in response to; but i'll look and play with that, when have time to tinker more...)


also benchmarks for the requests are ++MUCH++ faster with message than DLL (am not sure why, and maybe it's just my system ???).


anyhow...


wonder if its possible with the messaging calls in AHK to create a DDE SERVER....

for example: notice with the explore possibilities, can register to receive ++EVERY URL VISITED++ and that sure does seem to open up interesting possibilities !


not possible right now with dll (as I understand it), but sure seems possible with messaging...



also with getting notices from excell and Word and such, upon triggers and occurences...

finally, in case helpful, my (thanks to YOU, working!) code for dll poke:


Poke( Item, nTimeOut = 10000, nFormat = 1)   ; CF_TEXT = 1
{
	Global idInst, hConv,nResult, XTYP_POKE
	
	hItem   := DdeCreateStringHandle(idInst, Item  )	
			
	hData := DllCall("DdeClientTransaction", "Uint", &Item, "Uint",strlen(Item)+1 , "Uint", hConv, "Uint", hItem, "Uint", nFormat, "Uint", XTYP_POKE, "Uint", nTimeOut , "UintP", nResult) 
	
	sData := DdeAccessData(hData)
	DdeUnaccessData(hData)
	DdeFreeDataHandle(hData)
	;MsgBox, % sData
	return sData
}

Joyce Jamce

Sean
  • Members
  • 2462 posts
  • Last active: Feb 07 2012 04:00 AM
  • Joined: 12 Feb 2007

not possible right now with dll (as I understand it), but sure seems possible with messaging...

Callback is now possible using callback.dll
<!-- m -->http://www.autohotke...topic19370.html<!-- m -->

Joy2DWorld
  • Members
  • 562 posts
  • Last active: Jun 30 2014 07:48 PM
  • Joined: 04 Dec 2006
yeah, was just looking at that...

very, very interesting...





tried it ?




ie. as DDE server via DDEML.



(although requires still the external DLL)



Am I missing something (quite possible),
but wouldn't DDE be a simple and very
powerful way for AHK scripts to communicate
with eachother ?


(beyond like the WM_COPYDATA approach)
Joyce Jamce

Joy2DWorld
  • Members
  • 562 posts
  • Last active: Jun 30 2014 07:48 PM
  • Joined: 04 Dec 2006
@Sean

Why are you trying to use DDEMessage instead of DDEML?
Anyway, I added DDE_POKE and DDE_EXECUTE in the first post, but, not tested.
Please inform me if meet a problem with it.


There are some interesting interactions with the DDEDM approach and the AHK timer calls...

could possibly be an AHK bug relating to DLL handling ????

the interaction is kind of complex, and have not solidified exactly what and where... but... dde calls via DLL are interefered with by timer 'interrupts' running in the script.

the messaging seems to be immune, as the return data is also a 'interrupt'..

have wrapped the DDE into a function set, and
when get all the kinks out... (ie. more bug free...) will
post... for... FINALLY!!! (and thanks to you, Sean),

a nice DDE AHK function set!

ahhhhh.
Joyce Jamce

Joy2DWorld
  • Members
  • 562 posts
  • Last active: Jun 30 2014 07:48 PM
  • Joined: 04 Dec 2006

Why are you trying to use DDEMessage instead of DDEML?


DDEML allows only 1 connection per physical thread (not AHK psuedo threads)... so...

ONLY ONE PATHWAY IS Useable between a server and AHK script,

but...

with DDEMessages......

you can open upon to 99 (maybe even 100) channels PER server from single script. (have not yet experimented with using control hwnd in place of windows... may allow unlimited #..)


also, allows sending string of requests, and collecting the responses as they come in (like a callback) vs. waiting for responses one by one.
Joyce Jamce

M
  • Guests
  • Last active:
  • Joined: --
This DDE stuff looks complicated. Still I'd like to use it to control the audio player Xmplay. It's DDE commands are described here: http://support.xmpla...ticle.php?id=17

If it is possible, could someone help me out with a function or something similar that I can just input keys from the list on the xmplay page into?

Like this:

DDE_function(512) ; Volume up

Sean
  • Members
  • 2462 posts
  • Last active: Feb 07 2012 04:00 AM
  • Joined: 12 Feb 2007

DDE_function(512) ; Volume up

DDE_EXECUTE() is for commands, so you may use it.

M
  • Guests
  • Last active:
  • Joined: --
Hi Sean
This
DDE_EXECUTE(key512)   ; volume up xmplay

DDE_EXECUTE(sCmd) 
{ 
   Global  WM_DDE_EXECUTE, hWndClient, hWndServer 

   hCmd := DllCall("GlobalAlloc", "Uint", 0x0002, "Uint", StrLen(sCmd)+1) 
   pCmd := DllCall("GlobalLock" , "Uint", hCmd) 
   DllCall("lstrcpy", "Uint", pCmd, "str",sCmd) 
   DllCall("GlobalUnlock", "Uint", hCmd) 

   PostMessage, WM_DDE_EXECUTE, hWndClient, hCmd,, ahk_id %hWndServer% 
   If ErrorLevel 
   DllCall("GlobalFree", "Uint", hCmd) 
}
doesn't work in itself. I suppose I also need some of your code below, but I don't know what parts I need and what I need to update :oops:
(I guess change "Firefox" to "XMplay", the name according to AU3_Spy. But what more?)
sApplication := "Firefox"
sTopic := "WWW_GetWindowInfo" 
sItem  := "0xFFFFFFFF" 

CF_TEXT      := 1 
WM_DDE_INITIATE   := 0x3E0 
WM_DDE_TERMINATE:= 0x3E1 
WM_DDE_ADVISE   := 0x3E2 
WM_DDE_UNADVISE   := 0x3E3 
WM_DDE_ACK   := 0x3E4 
WM_DDE_DATA   := 0x3E5 
WM_DDE_REQUEST   := 0x3E6 
WM_DDE_POKE   := 0x3E7 
WM_DDE_EXECUTE   := 0x3E8 

DetectHiddenWindows, On 

OnMessage(WM_DDE_ACK , "DDE_ACK") 
OnMessage(WM_DDE_DATA, "DDE_DATA") 

nAppli := DllCall("GlobalAddAtom", "str", sApplication, "Ushort") 
nTopic := DllCall("GlobalAddAtom", "str", sTopic, "Ushort") 

Process, Exist 
WinGet, hAHK, ID, ahk_pid %ErrorLevel% 

SendMessage, WM_DDE_INITIATE, hAHK, nAppli | nTopic << 16,, ahk_id 0xFFFF 

DllCall("DeleteAtom", "Ushort", nAppli) 
DllCall("DeleteAtom", "Ushort", nTopic)


Sean
  • Members
  • 2462 posts
  • Last active: Feb 07 2012 04:00 AM
  • Joined: 12 Feb 2007

doesn't work in itself. I suppose I also need some of your code below, but I don't know what parts I need and what I need to update :oops:

If you'll use the DDEMessage, you need to tweak DDE_ACK too.
I recommend using DDEML version.
Replace the autoexecution part with the following code.

sServer := "xmplay"
sTopic  := "xmplay"
sData   := "key512"

idInst  := DdeInitialize()
hServer := DdeCreateStringHandle(idInst, sServer)
hTopic  := DdeCreateStringHandle(idInst, sTopic )
hConv   := DdeConnect(idInst, hServer, hTopic)
hData   := DdeClientTransaction(0x4050, hConv, 0, sData)

DdeFreeStringHandle(idInst, hServer)
DdeFreeStringHandle(idInst, hTopic )
DdeDisconnect(hConv)
DdeUninitialize(idInst)

PS. I updated the DDEML version, so, make sure to use the latest one.

SoggyDog
  • Members
  • 803 posts
  • Last active: Mar 04 2013 06:27 AM
  • Joined: 02 May 2006
Edit: Removed Post and Code.

Worked a little last night and found some answers.

Thanks anyway.

sdg

Joy2DWorld
  • Members
  • 562 posts
  • Last active: Jun 30 2014 07:48 PM
  • Joined: 04 Dec 2006
have just about gotten the bugs out of a fairly complete DDE function set. Ie. will make DDE as easy to use as "ConnectDDE("topic","server")" and "Execute(command,data)".


sorry for the delay... Trying to make it universal & allowing multiple connections, batch processing, including failsafe options, etc. (for complex apps), and AHK had some unexpected hidden tricks/traps for me...
Joyce Jamce

a
  • Guests
  • Last active:
  • Joined: --
Sean,
when I run DDEMessage.ahk I get a msgbox with the url and the window title. How do I get them into variables instead? I've tried changing this line
MsgBox % sInfo      ; "URL", "Title"
into things like
xvariable = %sInfo%
but it does not work (and I have no idea why). Can you help me out? Ideally, I'd like to output URL and title in two separate variables that I can then work with in the rest of my script.

Joy2DWorld
  • Members
  • 562 posts
  • Last active: Jun 30 2014 07:48 PM
  • Joined: 04 Dec 2006
Try the DDE wrapper, here:

<!-- m -->http://www.autohotke... ... hlight=dde<!-- m -->


use:

DDE_Connect("firefox" , "WWW_GetWindowInfo") ; DDE_Connect("NAME_OF_DDE_SERVER","TOPIC_REQUESTED",


and likely,

your_var := DDE_Request("WWW_GetWindowInfo")





[have not played or tested, and have no idea what is return, but based on your post, likely you'll have to 'unpack' the response via regex or other method (substr, etc.).]
Joyce Jamce