Author |
|
onhiatus Senior Member
Joined: May 12 2004 Location: United States
Online Status: Offline Posts: 279
|
Posted: January 28 2005 at 22:20 | IP Logged
|
|
|
So I've written this nifty VB program to control my IOM142A (actually just reads the temperature sensors at this point). Now I'd like to be able to act upon this data with PowerHome.
I'd like to do this with Windows Messaging.
I've found one of [the other] Tony's examples that shows how PH could pole my VB app via windows messages (see WinAmp Status). However, I'd rather have some way of pushing the data to PH from my VB app. Actually I'd need to go both ways - for example, so that PH could toggle a relay.
Are there any examples of how to do this? Or could someone point me at some documentation?
Thanks, Tony (no No)
|
Back to Top |
|
|
TonyNo Moderator Group
Joined: December 05 2001 Location: United States
Online Status: Offline Posts: 2889
|
Posted: January 28 2005 at 23:02 | IP Logged
|
|
|
Tony,
Part of my old VB CID app is what you want. Dave gave me some code to send messages from my VB app to PH. I can't find the email right now, but, maybe Dave can. If not, I should be able to get you the chunks of code to do the job.
Tony (the other one)
|
Back to Top |
|
|
TonyNo Moderator Group
Joined: December 05 2001 Location: United States
Online Status: Offline Posts: 2889
|
Posted: January 29 2005 at 15:35 | IP Logged
|
|
|
Here is the code. It is set up to send a single string.
Declarations
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function SendMessageCDS Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByRef lParam As Any) As Long
Private Type COPYDATASTRUCT
dwData As Long
cbData As Long
lpData As String
End Type
Dim hPwrHome As Long
Dim cds As COPYDATASTRUCT
Form Load (if you use PH to launch the program, you can pass the handle with this, ph_run( "your_app " + string(ph_handle()) ))
args = Command()
If Len(args) <> 0 Then
hPwrHome = CLng(args) ' Get handle passed by PH
End If
Here is the code that actually sends the string (Var) to PH...
cds.dwData = 11
cds.cbData = Len(Var) + 1
cds.lpData = LCase(Var)
SendMessageCDS hPwrHome, 74, 0, cds
In PH, setup a trigger to call your macro on a WM_COPYDATA trigger type, and a Trigger ID of Data. The data from the VB app will be put into the [TEMP5] system variable.
Tony
|
Back to Top |
|
|
onhiatus Senior Member
Joined: May 12 2004 Location: United States
Online Status: Offline Posts: 279
|
Posted: January 29 2005 at 18:17 | IP Logged
|
|
|
This is almost what I want. It should also be possible to get the PH handle if my app was not launched through PH, right? Any suggestions on how to get that handle?
I am sooooo close
-Tony
|
Back to Top |
|
|
TonyNo Moderator Group
Joined: December 05 2001 Location: United States
Online Status: Offline Posts: 2889
|
Posted: January 29 2005 at 21:14 | IP Logged
|
|
|
I believe you could also use ph_findwindow. I think there were issues with that, though; I can't remember for sure.
Tony
|
Back to Top |
|
|
onhiatus Senior Member
Joined: May 12 2004 Location: United States
Online Status: Offline Posts: 279
|
Posted: January 29 2005 at 21:39 | IP Logged
|
|
|
Actually trying to find a way to get the powerhome handle from the VB app when it wasn't launched from powerhome.
What is the equivalent VB function to ph_findwindow?
|
Back to Top |
|
|
TonyNo Moderator Group
Joined: December 05 2001 Location: United States
Online Status: Offline Posts: 2889
|
Posted: January 30 2005 at 10:08 | IP Logged
|
|
|
Doh!
That would be findwindow(). I found this code example. It looks for a window class of "WindowClassName"...
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As Long) As Long
Sub GetWindowHandle()
Dim hwnd As Long
' Call the FindWindow API; this API returns a window handle.
hwnd = FindWindow("WindowClassName", 0&)
' Check if you were able to obtain the Window handle.
If hwnd <> 0 Then
' If hwnd not zero a window handle was obtained.
MsgBox "Successfully obtained Window Handle (HWND) for " _
& "WindowClassName.", vbInformation, "Got Handle"
Else
MsgBox "Could not obtain Window Handle (HWND) for WindowClassName.", _
vbInformation, "Failed To Get Handle"
End If
End Sub
|
Back to Top |
|
|
onhiatus Senior Member
Joined: May 12 2004 Location: United States
Online Status: Offline Posts: 279
|
Posted: January 30 2005 at 17:45 | IP Logged
|
|
|
That's the ticket. Thanks!
Just for anyone trying to follow around at home it looks like PH's window class (for use with the FindWindow API above) is "FNWND390"
So now my code seems to work. Is there an easy way to peek at what values are in power home's temp variables?
|
Back to Top |
|
|
TonyNo Moderator Group
Joined: December 05 2001 Location: United States
Online Status: Offline Posts: 2889
|
Posted: January 30 2005 at 19:35 | IP Logged
|
|
|
For testing, you could use a Message Box to display what is in [TEMP5], or, assign a global with the value of [TEMP5] in the macro.
Tony
|
Back to Top |
|
|
dhoward Admin Group
Joined: June 29 2001 Location: United States
Online Status: Offline Posts: 4447
|
Posted: February 01 2005 at 15:04 | IP Logged
|
|
|
Ok,
Since were talking about Windows Messaging, I'll use this post to document the various messages that PowerHome supports.
As Tony stated above, PowerHome supports message number 74 for the Copy Data Struct message.
The COPYDATASTRUCT structure consists of 3 long integers. The first long is l_dwdata and can contain either 0,1, or 11 and determines how PowerHome will handle the message. The second long is l_cbdata and is the length of the data pointed to by the third long. The third long is l_lpdata and is a pointer to the actual data.
The lparam value of the SendMessage function should point to the COPYDATASTRUCT in memory. The wparam should be either 0 or contain the handle of the application that is sending the message.
If l_dwdata = 0, then l_lpdata should point to a valid PowerHome formula. The formula will then be queued for evaluation. After the formula is evaluated, if wparam is greater than 0 (should point to the handle that originally called), PowerHome will create it's own CDS structure containing the result of the formula. This message will then be sent to the handle in wparam with lparam pointing to the new CDS.
If l_dwdata = 1, then PowerHome will respond in the same manner as l_dwdata = 0, except that a trigger is fired after the formula is queued. The wparam value will be in [TEMP3], l_dwdata will be in [TEMP4], and the formula will be in [TEMP5]. If wparam is greater than 0, then the formula result will be sent in a corresponding CDS message.
If l_dwdata = 11, then l_lpdata should point to a string of data. This data IS NOT evaluated. The appropriate trigger will be fired and this data will be available in [TEMP5].
PowerHome also supports a slew of new Windows messages in addition to the CDS message (74). These are documented below:
If the message number is 1024 to 1028, then PowerHome will fire the appropriate trigger. The wparam value will be available in [TEMP3] and the lparam value will be available in [TEMP4].
If the message number is 1029 to 1033, then PowerHome will fire the appropriate trigger. lparam should point directly to a string of data in memory. wparam will be in [TEMP3], lparam will be in [TEMP4], and the string of data pointed to by lparam will be in [TEMP5]. This will be very similar in functionality to the CDS message with the l_dwdata parameter set to 11 without having to create a COPYDATASTRUCT.
If the message number is 1034 to 1038, then lparam should point to string containing a valid PH formula. The formula will then be added to the execution queue for evaluation. The appropriate trigger will also be fired with wparam in [TEMP3], lparam in [TEMP4], and the formula in [TEMP5].
If the message number is 1039 to 1043, then lparam should point to a PowerHome formula. wparam should be either 0 or contain the memory address to write the formula result to. The formula is immediately evaluated and then the appropriate trigger is fired. wparam will be [TEMP3], lparam in [TEMP4], the formula in [TEMP5], and the formula result in [TEMP10]. If wparam is greater than 0, then the result will be copied to the memory location pointed to by wparam.
If the message number is 1044 to 1048, then lparam should point to a valid PH formula. wparam should be either 0 or contain the handle to have the result of the formula within a windows message sent to. The formula is queued for evaluation. The appropriate trigger is fired. wparam is in [TEMP3], lparam in [TEMP4], the formula in [TEMP5]. After the formula is evaluated, if wparam is greater than 0, then PH will generate a windows message sent to the handle contained in wparam. The message number will be the same as the original message, the wparam parameter will contain the handle of PH and lparam will point to the result of the formula in memory.
Message number 1049: lparam points to a PH formula in memory. The formula is queued for evaluation. NO TRIGGER is fire.
Message number 1050: lparam points to a PH formula. The formula is evaluated immediately. NO TRIGGER
Message number 1051: Same as 1039 to 1043 except no trigger is fired.
Message number 1052: Same as 1044 to 1048 except no trigger is fired.
Dave.
|
Back to Top |
|
|
dhoward Admin Group
Joined: June 29 2001 Location: United States
Online Status: Offline Posts: 4447
|
Posted: February 01 2005 at 15:09 | IP Logged
|
|
|
One other note, when using the FindWindow API to get the PH handle, you may rather search on the Window Title rather than the Class name. The class name for all PowerBuilder 9 applications will be FNWND390 so may not adequately limit itself to PowerHome.
To use the Window Title syntax, use:
hwnd = FindWindow(0&, " PowerHome ")
The title of the main PowerHome frame is a single space followed by "PowerHome" folled by two spaces.
HTH,
Dave.
|
Back to Top |
|
|
TonyNo Moderator Group
Joined: December 05 2001 Location: United States
Online Status: Offline Posts: 2889
|
Posted: February 01 2005 at 19:22 | IP Logged
|
|
|
Which one...
" PowerHome "
or
a single space followed by "PowerHome" followed by two spaces
|
Back to Top |
|
|
dhoward Admin Group
Joined: June 29 2001 Location: United States
Online Status: Offline Posts: 4447
|
Posted: February 01 2005 at 22:24 | IP Logged
|
|
|
Heh, the "single space followed by PowerHome followed by two spaces.
I forgot that HTML will remove multiple spaces .
Dave.
|
Back to Top |
|
|
onhiatus Senior Member
Joined: May 12 2004 Location: United States
Online Status: Offline Posts: 279
|
Posted: February 02 2005 at 21:05 | IP Logged
|
|
|
Dave, I tried to change my code to try using the Window Title instead of the Class Name. However I was unable to get it to work - I even checked (using Spy++) that you were correct about the number of spaces.
From my code:
This works:
hWnd = FindWindow("FNWND390", 0&)
This does not (always returns '0'):
hWnd = FindWindow(" PowerHome ", 0&)
(Note there is one space, then "PowerHome", then two more spaces)
Any thoughts?
Thanks, Tony
Edited by onhiatus
|
Back to Top |
|
|
onhiatus Senior Member
Joined: May 12 2004 Location: United States
Online Status: Offline Posts: 279
|
Posted: February 03 2005 at 00:56 | IP Logged
|
|
|
Argh, I'm pulling my hair out here. Why can't I get a macro to copy [Temp5] to a global variable "MyGlobal"?
Can someone post the formula to do this?
Thanks, Tony
|
Back to Top |
|
|
TonyNo Moderator Group
Joined: December 05 2001 Location: United States
Online Status: Offline Posts: 2889
|
Posted: February 03 2005 at 07:33 | IP Logged
|
|
|
You would use...
Set Global | My Global | "[TEMP5]"
I'm guessing you are missing the quotes? Those are needed for strings.
TonyNo
|
Back to Top |
|
|
dhoward Admin Group
Joined: June 29 2001 Location: United States
Online Status: Offline Posts: 4447
|
Posted: February 03 2005 at 11:34 | IP Logged
|
|
|
Tony,
The formula you posted:
hWnd = FindWindow(" PowerHome ", 0&)
will not find a window title. You need to use:
hWnd = FindWindow(0&, " PowerHome ")
The first parameter is for searching by classname and the second parameter is for searching for window title .
TonyNo posted the proper macro command for copying a system to global variable. You can also use the following formula:
ph_setglobal_s("MY GLOBAL",ph_getvar_s(2,5))
The "ph_getvar_s(2,5)" will get the [TEMP5] variable as a string and assigns it to the "MY GLOBAL" global variable.
You could also sometimes get away with:
ph_setglobal_s("MY GLOBAL","[TEMP5]")
This will work so long as the [TEMP5] variable doesnt contain any double quotes.
If [TEMP5] was numeric, then you could use:
ph_setglobal_a("MY GLOBAL",[TEMP5])
Hope this helps and doesnt add to the confusion .
Dave.
|
Back to Top |
|
|
onhiatus Senior Member
Joined: May 12 2004 Location: United States
Online Status: Offline Posts: 279
|
Posted: February 03 2005 at 16:03 | IP Logged
|
|
|
...
Thanks guys.
|
Back to Top |
|
|
TonyNo Moderator Group
Joined: December 05 2001 Location: United States
Online Status: Offline Posts: 2889
|
Posted: February 03 2005 at 18:04 | IP Logged
|
|
|
Wow. Nice FindWindow catch, Dave! I figured since it was a good looking chunk of code, it would be correct!
Never believe what you read on the web!
|
Back to Top |
|
|
dhoward Admin Group
Joined: June 29 2001 Location: United States
Online Status: Offline Posts: 4447
|
Posted: February 03 2005 at 18:11 | IP Logged
|
|
|
|
Back to Top |
|
|