|
-
Dec 8th, 2004, 04:59 AM
#1
Thread Starter
New Member
send info between apps
How can I send data (strings) between 2 standalone apps?
-
Dec 8th, 2004, 07:05 AM
#2
Frenzied Member
Re: send info between apps
Need to elaborate a bit on your problem. You want to send text to another application from your app? Or send text/data using a connection such as winsock to a server side app.
:::`DISCLAIMER`:::
Do NOT take anything i have posted to be truthful in any way, shape or form.
Thank You!
--------------------------------
"Never heard about "hiking" poles. I usualy just grab a stick from the nature, and use that as a pole." - NoteMe
"Finaly I can look as gay as I want..." - NoteMe
Languages: VB6, BASIC, Java, C#. C++
-
Dec 8th, 2004, 02:09 PM
#3
Re: send info between apps
Also, do you have the ability to alter both programs. If so, you would probably get quicker answers in a different forum, since the solution would probably be winsock rather than API.
My usual boring signature: Nothing
 
-
Dec 8th, 2004, 08:12 PM
#4
Software Eng.
Re: send info between apps
If they're on the same machine, send a WM_USER + X message. You can pass the string in the lParam parameter.
Then subclass the receiving app, and check for the WM_USER + X message.
-
Dec 8th, 2004, 08:13 PM
#5
Hyperactive Member
Re: send info between apps
Look at CreateFileMapping API. Passing it a null for the name of a file will let windows know you want share memory. You give the shared mem a name when creating and another app can open using that name.
packetvb
-
Dec 15th, 2004, 02:31 AM
#6
New Member
Re: send info between apps
Hi Megatron,
I am facing a similar issue. i appreciate that u can elaborate on WM_USER + X message. even better if u have sample code.
Thank you very much
-
Dec 15th, 2004, 01:53 PM
#7
Lively Member
Re: send info between apps
Named pipe's and Mailslots are capable of communicating between apps
-
Dec 21st, 2004, 09:26 PM
#8
Member
Re: send info between apps
Megatron, I am not sure what you mean by "subclass the receiving app", but I doubt that it is easy.
A WM_USER message would work only for very short strings. The first suggestion should be the WM_COPYDATA message, which can be used for much larger strings. The WM_COPYDATA message will do a CreateFileMapping for you. There is very little to be concerned about when using the WM_COPYDATA message except the receiving application must copy the string (and/or other data) when the message is processed; that is, before the message processing function returns.
The WM_COPYDATA message can be very useful and very easy to use. If the requirement is more complex than what can be done using the WM_COPYDATA message, then there are other possibilities. Look at "Interprocess Communication" (IPC) in the Platform SDK. An ActiveX Component is relatively easy for VB programmers and can be a very useful solution that many people might not think about.
Last edited by Sam Hobbs; Dec 21st, 2004 at 09:31 PM.
-
Dec 22nd, 2004, 12:20 AM
#9
Software Eng.
Re: send info between apps
Megatron, I am not sure what you mean by "subclass the receiving app", but I doubt that it is easy.
Subclassing is a means of accessing the window procedure from VB. Generically speaking it replaces the default window procedure with a custom one. It's definetly not a difficult task, as window procedures are essential for programming in Windows.
A WM_USER message would work only for very short strings
Well, sure, if you're passing a mystery novel through a window message, then yes; you're going to run into problems. Maybe quaso can fill us in on the length of strings he wants to pass.
The WM_COPYDATA message can be very useful and very easy to use
As opposed to what? WM_USER?
They're both window messages, and are subject to the same constraints. Anything that can be done with WM_COPYDATA can also be done with WM_USER.
More over, WM_COPYDATA is a custom message. This means that there is no default action for it, and it's up to the user to process this message (if at all). And how do we do it? You guessed it: Subclassing.
-
Dec 22nd, 2004, 02:35 AM
#10
Member
Re: send info between apps
 Originally Posted by Megatron
Subclassing is a means of accessing the window procedure from VB.
Yes, I am familiar with subclassing windows. However you said "subclass the receiving app", and that is what I am not sure of. If you meant "subclass the receiving application's window" or something such as that, then that I understand.
 Originally Posted by Megatron
Generically speaking it replaces the default window procedure with a custom one. It's definetly not a difficult task, as window procedures are essential for programming in Windows.
Subclassing a window for an application that is within the same address space is relatively easy, at least for C and C++ programs. I assume there are enough existing samples of doing that in VB too. However when using VB some messages will be more difficult than others to process.
In this context, the requirement is to subclass a window in another address space, which is much more complex. I assure you it is not easy for a beginner to write all the code themselves to do that, and it should not be easy for a beginner to simply copy a sample if the beginner needs to modify the code. When crossing address spaces, there are too many things that a person could make a small mistake with and mess up the system.
 Originally Posted by Megatron
Well, sure, if you're passing a mystery novel through a window message, then yes; you're going to run into problems. Maybe quaso can fill us in on the length of strings he wants to pass.
It is not possible to put a pointer in most Windows messages, including none of the WM_USER messages, and then send the message accross address spaces. The pointer would be totally meaningless in another address space. Therefore, without pointers, it is possible to send a maximum of four (16-bit) Unicode characters or a maximum of eight ASCII (8-bit) characters.
 Originally Posted by Megatron
As opposed to what? WM_USER?
They're both window messages, and are subject to the same constraints. Anything that can be done with WM_COPYDATA can also be done with WM_USER.
There is definitely a difference. The WM_COPYDATA message is provided to overcome the limitations of the other messages. Just search the MSDN for what it says about the WM_COPYDATA message.
 Originally Posted by Megatron
More over, WM_COPYDATA is a custom message. This means that there is no default action for it, and it's up to the user to process this message (if at all). And how do we do it? You guessed it: Subclassing.
If the WM_COPYDATA message is more difficult to process than WM_USER messages, then that is unfortunate, since the WM_COPYDATA message is so useful and eliminates most or all of the technicalities that might be a hassle for VB. However I really doubt that there are not any samples of processing the WM_COPYDATA message using VB.
As I indicated, subclassing within an address space is easier than across address spaces, so if the WM_COPYDATA message must be processed by subclassing a window, then that I assume is easy, since Microsoft tries to make things as easy as possible for VB programmers.
Note that the Platform SDK warns against using messages with message ids in the WM_USER range; it is better to use the range WM_APP through 0xBFFF. The WM_USER range is usually safe but it is just as easy to use WM_APP instead of WM_USER. Even better than WM_APP is to use the RegisterWindowMessage function to retrieve a message id. However none of those will allow you to send a pointer in the message that is valid in another address space.
-
Dec 22nd, 2004, 02:05 PM
#11
Software Eng.
Re: send info between apps
Yes, I am familiar with subclassing windows. However you said "subclass the receiving app", and that is what I am not sure of. If you meant "subclass the receiving application's window" or something such as that, then that I understand.
If you want me to be specific: "Replace the receiving appliation's window procedure with a custom procedure of your own."
Subclassing a window for an application that is within the same address space is relatively easy, at least for C and C++ programs. I assume there are enough existing samples of doing that in VB too. However when using VB some messages will be more difficult than others to process.
You're confusing "subclassing" with direct access to a window procedure. Subclassing a window procedure is just as easy in VB, as it is in C or C++. Both require the exact same API's. Processing messages is no different either. Think Win32, not VB vs C vs C++.
In this context, the requirement is to subclass a window in another address space, which is much more complex. I assure you it is not easy for a beginner to write all the code themselves to do that, and it should not be easy for a beginner to simply copy a sample if the beginner needs to modify the code. When crossing address spaces, there are too many things that a person could make a small mistake with and mess up the system.
You're assuming that the receiving app is pre-compiled (i.e. he is not making it)
And in which case, if two way communication is required, then you need to subclass the external process (Replace the receiving appliation's window procedure with a custom procedure of your own). You cannot just send your custom message to another application because it will not know what to do with it. In order to make something happen, subclassing is required.
If, on the other hand, you simply need to send data to a specific address location in this external process (one-way communication) then WriteProcessMemory will do the trick.
It is not possible to put a pointer in most Windows messages, including none of the WM_USER messages, and then send the message accross address spaces. The pointer would be totally meaningless in another address space. Therefore, without pointers, it is possible to send a maximum of four (16-bit) Unicode characters or a maximum of eight ASCII (8-bit) characters.
What's impossible about that? A pointer is simply a number, just like 123 or 456. It represents a specific location of memory in the current address space. If you pass this pointer through SendMessage, you can read it from an external address space via the ReadProcessMemory function for example.
There is definitely a difference. The WM_COPYDATA message is provided to overcome the limitations of the other messages. Just search the MSDN for what it says about the WM_COPYDATA message.
WM_COPYDATA is a window message. It's no more special than WM_LBUTTONDOWN, or WM_CLOSE or any other message. What you're probably referring to as "special" is it takes care of copying the data into the receiving process's address space, though there's really no magic to it.
If the WM_COPYDATA message is more difficult to process than WM_USER messages, then that is unfortunate, since the WM_COPYDATA message is so useful and eliminates most or all of the technicalities that might be a hassle for VB. However I really doubt that there are not any samples of processing the WM_COPYDATA message using VB.
Whether WM_COPYDATA is easier to process than a customized WM_USER message is a subjective question.
As I indicated, subclassing within an address space is easier than across address spaces, so if the WM_COPYDATA message must be processed by subclassing a window, then that I assume is easy, since Microsoft tries to make things as easy as possible for VB programmers.
No easier or harder than any other window message.
Note that the Platform SDK warns against using messages with message ids in the WM_USER range; it is better to use the range WM_APP through 0xBFFF. The WM_USER range is usually safe but it is just as easy to use WM_APP instead of WM_USER.
WM_APP isn't "better" than WM_USER, nor is it the other way around. Granted, Microsoft generally uses WM_USER in controls, rather than main appliation windows, but so long as you have control of both window procedures, it really doesn't matter what range of values you use (either WM_USER or WM_APP).
Even better than WM_APP is to use the RegisterWindowMessage function to retrieve a message id. However none of those will allow you to send a pointer in the message that is valid in another address space.
RegisterWindowMessage creates a new message identifier in the message table, and it stays there for the duration of your windows session. There's nothing wrong with using this, though it offers no significant advantage over WM_USER if you are writing both applications and are in charge of handling the message. It does come in handy when you need to send to HWND_BROADCAST for example (but that's not the issue here).
Bottom line? Pick your favourite, and use it. Neither offers significant advantages over the others.
-
Dec 22nd, 2004, 04:50 PM
#12
Member
Re: send info between apps
 Originally Posted by Megatron
You're confusing "subclassing" with direct access to a window procedure.
No. I know what window subclassing is. See the second paragraph of Safe Subclassing in Win32 in which it says:
an application cannot subclass a window or class that belongs to another process
You probably think that is not accurate, eventhough it is in the MSDN Technical Article on the subject. So I won't try to convince you otherwise, but I hope I am saving other people's time.
 Originally Posted by Megatron
If, on the other hand, you simply need to send data to a specific address location in this external process (one-way communication) then WriteProcessMemory will do the trick.
ReadProcessMemory and WriteProcessMemory are debugging functions. They are not listed in the IPC APIs. I certainly recommend not to use functions such as them in production applications, but you can if you want to. When suggesting for others solutions that require ReadProcessMemory and/or WriteProcessMemory, they should be told that the solution requires use of a debugging API. People should not allow application software to use debugging APIs for any other purpose than debugging, since hackers and viruses and worms could use them to get total control of our systems. People should be warned about use of ReadProcessMemory and WriteProcessMemory. You can use them in your software but when advising others you really need to warn them.
 Originally Posted by Megatron
WM_COPYDATA is a window message. It's no more special than WM_LBUTTONDOWN, or WM_CLOSE or any other message. What you're probably referring to as "special" is it takes care of copying the data into the receiving process's address space, though there's really no magic to it.
I did not say it is magical. Yes, as far as I know, it does nothing we can't do ourselves. However it does do a lot. It does not use ReadProcessMemory and/or WriteProcessMemory or anything like that. It does do the same things that we would normally transfer data across address spaces. The fact that it does that makes it special, since it is different from the other messages.
 Originally Posted by Megatron
Whether WM_COPYDATA is easier to process than a customized WM_USER message is a subjective question.
No easier or harder than any other window message.
Note that I did not say that WM_COPYDATA is easier to process; you indicated that it is not easier.
 Originally Posted by Megatron
WM_APP isn't "better" than WM_USER, nor is it the other way around. Granted, Microsoft generally uses WM_USER in controls, rather than main appliation windows, but so long as you have control of both window procedures, it really doesn't matter what range of values you use (either WM_USER or WM_APP).
It is just as easy to suggest use of WM_APP as it is to suggest use of WM_USER, so it is better to suggest to others that they use WM_APP. There is no reason not to suggest to others that they use WM_APP instead of suggesting use of WM_USER.
 Originally Posted by Megatron
RegisterWindowMessage creates a new message identifier in the message table, and it stays there for the duration of your windows session. There's nothing wrong with using this, though it offers no significant advantage over WM_USER if you are writing both applications and are in charge of handling the message. It does come in handy when you need to send to HWND_BROADCAST for example (but that's not the issue here).
Message table? What message table? Does VB have a message table? If VB has a message table, then RegisterWindowMessage could not update it, since RegisterWindowMessage is a SDK function that knows nothing about VB.
Most experienced software developers understand the value of flexible solutions such as RegisterWindowMessage. I understand that you don't see the value, but many others do. My guess is that most developers of commercial software require use of RegisterWindowMessage when messages are sent across applications.
-
Dec 22nd, 2004, 08:09 PM
#13
Software Eng.
Re: send info between apps
 Originally Posted by Sam Hobbs
No. I know what window subclassing is. See the second paragraph of Safe Subclassing in Win32 in which it says: an application cannot subclass a window or class that belongs to another process.
You sure you read the full article?
2 paragraph's down from that that, he also states:
"However, there are ways you can add subclassing functionality to every process."
So subclassing a window in an external process is possible so long as the window procedure is mapped into its address space. This can be acheived by having your window procedure in a stanard DLL. See my post in the codebank.
General rule of thumb: You shouldn't always take Microsoft's words as engraved in stone.
ReadProcessMemory and WriteProcessMemory are debugging functions. They are not listed in the IPC APIs. I certainly recommend not to use functions such as them in production applications, but you can if you want to.
Granted, they are advanced functions, and you need to know what you're doing when working with them, but your argument of "just because they're debugging functions" really doesn't have any justification.
When suggesting for others solutions that require ReadProcessMemory and/or WriteProcessMemory, they should be told that the solution requires use of a debugging API.
The fact that they're listed under the debug API's in the platform SDK is irrelevent, and does not degrade their functionality; they're still part of the kernerl32 library.
People should be warned about use of ReadProcessMemory and WriteProcessMemory. You can use them in your software but when advising others you really need to warn them.
So by your logic, should I warn someone that they're using GDI API when I suggest BitBlt?
People should not allow application software to use debugging APIs for any other purpose than debugging, since hackers and viruses and worms could use them to get total control of our systems.
I don't follow: How does the use of Read/WriteProcessMemory in my or your application allow a 3rd party hacker to take total control of the system?
(If he's that sophisticated, he can write his own application. No need to tamper with ours)
Yes, as far as I know, it does nothing we can't do ourselves
My point exactly. WM_COPYDATA is just like any other window message.
Note that I did not say that WM_COPYDATA is easier to process; you indicated that it is not easier.
Nor did I say it was more difficult. Window messages are window messages.
It is just as easy to suggest use of WM_APP as it is to suggest use of WM_USER, so it is better to suggest to others that they use WM_APP. There is no reason not to suggest to others that they use WM_APP instead of suggesting use of WM_USER.
I'm going to be repeating myself, but WM_USER is no "better" than WM_APP. Microsoft may use WM_USER for controls, and WM_APP for inter-application communication, but it's really a matter of preference.
Re-read my previous posts, as I would be repeating myself again.
Message table? What message table? Does VB have a message table? If VB has a message table, then RegisterWindowMessage could not update it, since RegisterWindowMessage is a SDK function that knows nothing about VB.
The system message table. When you call RegisterWindowMessage, a new value is added to this internal table (system-wide).
Most experienced software developers understand the value of flexible solutions such as RegisterWindowMessage.
Like I said, as long as you have control of both window procedures, it does not matter which method you use. Those "experienced software developers" can verify this.
We can keep going in circles here, but the underlying facts are:
1. WM_USER, WM_APP or RegisterWindowMessage are ways of creating a custom window message to communicate between applications.
2. To process these messages, you need direct access to the window procedure of the receiving window. In C, you already have access to it, whereas in VB you have to subclass. If it's an external process, you'll have to subclass in either case (using a DLL to map the procedure in the receiver's address space)
3. WM_COPYDATA is a generic message for sending data, and needs to be processed in the same way as any other message.
4. There are other means of transferring data, if you so desire, such as pipes, file mapping etc.
-
Dec 22nd, 2004, 10:13 PM
#14
Member
Re: send info between apps
 Originally Posted by Megatron
You sure you read the full article?
2 paragraph's down from that that, he also states:
"However, there are ways you can add subclassing functionality to every process."
So subclassing a window in an external process is possible so long as the window procedure is mapped into its address space. This can be acheived by having your window procedure in a stanard DLL. See my post in the codebank.
The solution you are talking about does not subclass a window in another process. The subclassing is done in the DLL that is in the same address space as the window. The solution uses a hook, which makes it possible for the subclassing to be controlled by another application, but the subclassing is done within the subclassed window's address space.
Also, your solution uses C++, which proves my point that it is not easy to do in VB.
 Originally Posted by Megatron
General rule of thumb: You shouldn't always take Microsoft's words as engraved in stone.
I knew you would say that the quote I provided was not accurate. However if that quote and the quote you provided are interpreted in context, other people will understand that in 32-bit Windows, a process cannot subclass a window belonging to another process.
 Originally Posted by Megatron
Granted, they are advanced functions, and you need to know what you're doing when working with them, but your argument of "just because they're debugging functions" really doesn't have any justification.
I am concerned that people will be misled into believing that a solution is easier and more typical than they realy are.
 Originally Posted by Megatron
My point exactly. WM_COPYDATA is just like any other window message.
 Originally Posted by Megatron
4. There are other means of transferring data, if you so desire, such as pipes, file mapping etc.
You are one of those people that will never admit a mistake. You will continue to insist you are right until someome tells us to stop. So unless someone else can contribute to this discussion in a factual manner, I will let you say whatever you want to say.
I hope I have made my point for the benefit of others that WM_COPYDATA is a likely solution to the requirement in this thread and if it is a solution it is very easy to use.
-
Dec 22nd, 2004, 10:24 PM
#15
Frenzied Member
Re: send info between apps
Fact - Who said it wasn't a solution? I believe Megatron was insisting that is is not necessarily the ONLY solution nor the best to use in the thread starters situation.
I don't mean to interrupt the bout' , so i'll let round 3 begin as soon as Megatron has replied.
- commentary by: me
:::`DISCLAIMER`:::
Do NOT take anything i have posted to be truthful in any way, shape or form.
Thank You!
--------------------------------
"Never heard about "hiking" poles. I usualy just grab a stick from the nature, and use that as a pole." - NoteMe
"Finaly I can look as gay as I want..." - NoteMe
Languages: VB6, BASIC, Java, C#. C++
-
Dec 22nd, 2004, 11:31 PM
#16
Software Eng.
Re: send info between apps
 Originally Posted by Sam Hobbs
The solution you are talking about does not subclass a window in another process. The subclassing is done in the DLL that is in the same address space as the window. The solution uses a hook, which makes it possible for the subclassing to be controlled by another application, but the subclassing is done within the subclassed window's address space.
And thus you have a method to subclass a window in an external process.
Also, your solution uses C++, which proves my point that it is not easy to do in VB.
We were never debating C vs VB.
I knew you would say that the quote I provided was not accurate. However if that quote and the quote you provided are interpreted in context, other people will understand that in 32-bit Windows, a process cannot subclass a window belonging to another process.
Not sure what you're trying to prove here.
Yes strictly speaking, a process cannot directly subclass a window in another process; that's already a known fact. But for all intents and purposes, the aid of a standard DLL makes it possible to achieve the same effect.
I am concerned that people will be misled into believing that a solution is easier and more typical than they realy are.
You keep making reference to "easy" and "difficult" concepts. If a solution is optimal, then the relative difficultly to implement it should be the least of our worries.
What if our car manufacturers followed the same philosophy?
(Though in this case neither is significantly more optimal than the other, but I thought I would point that out.)
You are one of those people that will never admit a mistake.
Have a look here.
.
Last edited by Megatron; Dec 22nd, 2004 at 11:34 PM.
-
Dec 22nd, 2004, 11:43 PM
#17
Member
Re: send info between apps
 Originally Posted by Megatron
We were never debating C vs VB.
I will leave that for others to judge for themselves.
 Originally Posted by Megatron
Yes strictly speaking, a process cannot directly subclass a window in another process; that's already a known fact. But for all intents and purposes, the aid of a standard DLL makes it possible to achieve the same effect.
That is all I was saying. If you had said this from the beginning, then there would have been nothing more for me to say on the subject of subclassing.
So I was wrong when I said that you will never say you have made a mistake, sorry. I hope you do here too.
Last edited by Sam Hobbs; Dec 22nd, 2004 at 11:47 PM.
-
Dec 22nd, 2004, 11:59 PM
#18
Software Eng.
Re: send info between apps
 Originally Posted by Sam Hobbs
That is all I was saying. If you had said this from the beginning, then there would have been nothing more for me to say on the subject of subclassing.
Actually, as I understood, you were originally debating the relative difficulty of subclassing a window in an external process (2nd/3rd paragraph of your 2nd post)
But I'll let it go, as this issue has been run over more than enough times now.
So I was wrong when I said that you will never say you have made a mistake, sorry. I hope you do here too.
Gladly; if you can point it out for me? (For the benefit of the readers of the thread, of course)
As far as I can see, both you and I are merely pointing out different methods to achieve the same goal.
-
Dec 23rd, 2004, 01:22 AM
#19
Frenzied Member
Re: send info between apps
VB Code:
'************************************************************************************************
'* Name Function SubClass
'*
'* Author
'*
'* Purpose This function instructs Windows to redirect the Window Procedure of a
'* given control to a custom procedure.
'*
'* The function creates (sets) a property of the given Wnd called 'OldWndProc'
'* This ensures that the window retains it's own state with regard to its
'* original Window Procedure.
'*
'* Parameters --> hWnd LONG The handle of the window to be subclassed
'* --> lpfnNew LONG Address of function of which to redirect the
'* the standard WndProc too.
'*
'* Version 14/02/2002 Created
'*
'************************************************************************************************
Public Function SubClass(hwnd As Long, lpfnNew As Long) As Boolean
Dim lpfnOld As Long
Dim fSuccess As Boolean
'*************************************************************
'* If we haven't set the property for this window before . . .
'*************************************************************
If (GetProp(hwnd, OLDWNDPROC) = 0) Then
'*****************************************
'* Redirect Windows Proc to New Proc . . .
'*****************************************
lpfnOld = SetWindowLong(hwnd, GWL_WNDPROC, lpfnNew)
'**********************************************************
'* Set Old Proc Address to the property of the window . . .
'**********************************************************
If lpfnOld Then
fSuccess = SetProp(hwnd, OLDWNDPROC, lpfnOld)
End If
End If
'*************************************
'* Did we subclass successfully . . .
'*************************************
If fSuccess Then
SubClass = True
Else
'*************************************************
'* If we have the old proc address,
'* and still have failed, remove redirection . . .
'*************************************************
If lpfnOld Then
Call UnSubClass(hwnd)
End If
'* Oh **** !!
MsgBox "Unable to successfully subclass " & hwnd, vbCritical
End If
End Function
'************************************************************************************************
'* Name Function UnSubClass
'*
'* Author
'*
'* Purpose This function removes the OldWndProc property of the hWnd, and resets the
'* Window Procedure back to the original.
'*
'* See Function SubClass
'*
'* Parameters --> hWnd LONG The handle of the window to be subclassed
'*
'* Version 14/02/2002 Created
'*
'************************************************************************************************
Public Function UnSubClass(hwnd As Long) As Boolean
Dim lpfnOld As Long
'**********************************
'* Can we get Window property . . .
'**********************************
lpfnOld = GetProp(hwnd, OLDWNDPROC)
'*************************************************************
'* If we have property, remove it, and return Window Proc to
'* original . . .
'*************************************************************
If lpfnOld Then
If RemoveProp(hwnd, OLDWNDPROC) Then
UnSubClass = SetWindowLong(hwnd, GWL_WNDPROC, lpfnOld)
End If
End If
End Function
'************************************************************************************************
'* Name Function GridWndProc
'*
'* Author
'*
'* Purpose SubClass function for Windows Procedure redirection. Use only for the
'* FlexGrid.
'*
'* See Function SubClass
'*
'* Parameters --> See MSDN Documentation
'*
'* Version 14/02/2002 Created
'*
'************************************************************************************************
Public Function NewWndProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Dim uCDS As COPYDATASTRUCT
Dim uData() As Byte
Dim oPb As PropertyBag
Select Case uMsg
Case WM_COPYDATA
'*************************************
'* Retrieve Copy Data Structure . . .
'*************************************
CopyMemory uCDS, ByVal lParam, Len(uCDS)
ReDim uData(uCDS.cbData)
CopyMemory uData(0), ByVal uCDS.lpData, uCDS.cbData
Set oPb = New PropertyBag
oPb.Contents = uData
Select Case uCDS.dwData
Case BM_CURRENCY
gEnv.CurrencyCode = oPb.ReadProperty("Code")
gEnv.CurrencyExchange = oPb.ReadProperty("ExchangeRate")
End Select
Set oPb = Nothing
End Select
'************************************************************
'* Carry on processing in the original Window Procedure . . .
'************************************************************
NewWndProc = CallWindowProc(GetProp(hwnd, OLDWNDPROC), hwnd, uMsg, wParam, lParam)
End Function
and an example of how to send . . .
VB Code:
Private Sub SendCurrency(lHWnd As Long, uCurrency As CURRENCY_EX)
On Error GoTo ERR_SendCurrency
Dim oPacket As PropertyBag
Dim uCopyData As COPYDATASTRUCT
Dim Stream() As Byte
Set oPacket = New PropertyBag
With oPacket
.WriteProperty ("Code"), uCurrency.Code
.WriteProperty ("Description"), uCurrency.Description
.WriteProperty ("ExchangeRate"), uCurrency.ExchangeRate
.WriteProperty ("Format"), uCurrency.Format
.WriteProperty ("IsValid"), uCurrency.IsValid
Stream = .Contents
End With
With uCopyData
.dwData = BM_CURRENCY
.cbData = UBound(Stream) - LBound(Stream) + 1
.lpData = VarPtr(Stream(LBound(Stream)))
End With
SendMessageA lHWnd, WM_COPYDATA, 0&, uCopyData
Set oPacket = Nothing
Exit Sub
ERR_SendCurrency:
Set oPacket = Nothing
End Sub
-
Dec 23rd, 2004, 03:32 AM
#20
Member
Re: send info between apps
Thank you, yrwyddfa.
It is unfortunate that it is necessary to do all that to use the WM_COPYDATA message in VB. I suppose most of the code is for the message process and once it is done that adding other messages to be received would be easy and correspondingly it would be relatively easy to add processing of WM_COPYDATA to a program with a message loop.
I found another sample; see How To Pass String Data Between Applications Using SendMessage.
-
Dec 23rd, 2004, 04:10 AM
#21
Frenzied Member
Re: send info between apps
Yeah - they could've made it easier . . .
Most of the awkward looking API stuff here is for serialising/deserialising the message stream and putting it in and out of property bags.
-
Dec 23rd, 2004, 08:28 AM
#22
Re: send info between apps
If you take a look at my VB6 multithreading example, it has code there which allows you to send VERY LARGE structured data between 2 apps, using the send, or post, message API functions.
The DLL that does this is called vbGatewayy.dll that I wrote.
Take a look.
Not sure if that's relevant 
Woka
-
Dec 23rd, 2004, 09:24 AM
#23
Member
Re: send info between apps
Woka, I assume your sample is useful. For those applications that require something more complicated than what WM_COPYDATA is capable of, I assume it is worth evaluating. Note that the WM_COPYDATA message does automatically a lot of things that a program such as yours must do.
Since the WM_COPYDATA message is not as easy to process in VB as other messages are, and since VB makes COM objects so easy, it is probably practical to use a COM object. I am not sure of the terminology but I hope most people understand. Probably I mean an ActiveX component, but the term ActiveX is not clearly defined.
-
Jan 6th, 2005, 07:17 PM
#24
Re: send info between apps
Summary
It's funny that the original poster has not posted anything here after the original post to clarify the problem. The ensuing discussion however was rather informative so I have compiled what I think is an accurate summary of the conversation. Please correct me if I erred.
As I see it there are two possible scenarios.
1. Both applications are "owned" by the poster (i.e. he has access to the source code of both.)
2. He does not have access to the source code of one of the applications.
Solution for case 1:
Subclass a window in each app to receive messages (yrwyddfa shows how to do that) and use WM_USER, WM_APP or WM_COPYDATA to pass messages back and forth (yrwyddfa again with an example).
Solution for case 2:
Subclass a window in your app to receive messages and hook the other app. The hook will have to point to a routine that resides in a WIN32 DLL which cannot be done with VB (I use VC++ for this). The "owned" app can then communicate with the DLL and hence the other app using the same technique as in case 1.
Notes:
1. Standard windows messages sent between processes, such as WM_SETTEXT and WM_COPYDATA, can contain pointers since the OS knows about these messages and handles the marshalling. If user defined messages such as WM_USER and WM_APP contain pointers, the pointers will only be valid in the address space from which they are sent. One way to handle pointers between processes in user defined messages is to use ReadProcessMemory to retrieve the data.
2. To make sure that your message is not being used by another application, you can register it with the OS with RegisterWindowMessage. It is probably safer to use the WM_APP range because some predefined window classes have already defined values in the WM_USER range.
3. WM_COPYDATA is great for sending text strings or data structures as long as the data structure does not have a pointer in it. If it does, you'll have to use ReadProcessMemory to get that data just like you would with WM_APP.
4. Take a look at Wokawidget's code if you want to see how complex it can get sending code between two applications. Warning: this code is not for beginners especially since it contains no comments. What’s up with that Woka?
-
Jan 7th, 2005, 03:52 AM
#25
-
Jan 9th, 2005, 09:23 AM
#26
New Member
Re: send info between apps
This might help (my apologies if someone has already posted this, I couldn't be bothered reading the entire thread )http://www.thescarms.com/vbasic/PassString.asp
-
Jan 9th, 2005, 09:54 AM
#27
Member
Re: send info between apps
Thank you, moeur. I know you are trying to help.
 Originally Posted by moeur
It's funny that the original poster has not posted anything here after the original post to clarify the problem.
It is more common than it should be. I usually avoid guessing and therefore just ask for clarification before proceeding further. For example, ice_531 asked
" You want to send text to another application from your app? Or send text/data using a connection such as winsock to a server side app."
and Shaggy Hiker asked
" Also, do you have the ability to alter both programs."
I think the issue should have been left there, until clarification was provided.
My experience has been (in the CodeGuru forums) that when a vague question is asked and not clarified, it is common for it to explode into a lengthy discussion. That happens because there is not a topic specific enough to adequately limit discussion, and the vague nature of the subject likely results in differing understandings and points of views. For example Megatron posted comments with a couple or more mistakes.
One of the mistakes was "subclass the receiving app". Applications aren't subclassed; windows are. It was a simple mistake, and I realize that most people would understand what he meant. Note that I tried to be subtle and reasonable in my comment about it. However instead of clarifying what he said, he tried to defend it.
Megatron also said that it is possible to "pass the string in the lParam parameter" of a "WM_USER + X message", which is not possible. If Megatron meant that the string could be put into a lParam parameter, then it is possible to send only a few characters, not enough to be considered a string. If Megatron meant that the string could be sent by using memory outside the message and passing just a pointer in the lParam parameter, then it is necessary to also say that custom marshalling is required.
 Originally Posted by moeur
The ensuing discussion however was rather informative so I have compiled what I think is an accurate summary of the conversation. Please correct me if I erred.
What would help the most is to verify what we have said, before summarizing. Since you have created your summary using inaccurate information, it contributes to the problem, not the solution.
I do understand that you meant well, and I hope I have not discouraged you from helping in the future. The way you could help the most is, as I said, correct any mistakes that we have made. It does not need to be personal and should not be personal, but it is entirely possible to state facts without being personal. Just stating the facts I think is a mature solution.
 Originally Posted by moeur
Solution for case 1:
Subclass a window in each app to receive messages (yrwyddfa shows how to do that) and use WM_USER, WM_APP or WM_COPYDATA to pass messages back and forth (yrwyddfa again with an example).
No; the WM_COPYDATA does not need custom marshalling, but WM_USER and WM_APP messages do. Look at the documentation of the BroadcastSystemMessage, SendMessageTimeout, SendMessage, BroadcastSystemMessageEx, PostMessage, PostThreadMessage, SendNotifyMessage and SendMessageCallback message functions.
 Originally Posted by moeur
Solution for case 2:
Subclass a window in your app to receive messages and hook the other app. The hook will have to point to a routine that resides in a WIN32 DLL which cannot be done with VB (I use VC++ for this). The "owned" app can then communicate with the DLL and hence the other app using the same technique as in case 1.
Receiving messages in another application that cannot be by modified at the source code level is one thing, but how to process them in that other application is a more critical problem, and likely more difficult than simply receiving the messages. Therefore I think it is best to assume that this is not a requirement until it is stated explicitly that it is.
 Originally Posted by moeur
1. Standard windows messages sent between processes, such as WM_SETTEXT and WM_COPYDATA, can contain pointers since the OS knows about these messages and handles the marshalling. If user defined messages such as WM_USER and WM_APP contain pointers, the pointers will only be valid in the address space from which they are sent. One way to handle pointers between processes in user defined messages is to use ReadProcessMemory to retrieve the data.
As far as I know, what you are saying here is accurate, or at least close enough to being accurate. Except it should be stated that it is best to avoid use of ReadProcessMemory, at least in programs being developed for use by other people. I am working on getting some authoritative references on the subject.
 Originally Posted by moeur
2. To make sure that your message is not being used by another application, you can register it with the OS with RegisterWindowMessage. It is probably safer to use the WM_APP range because some predefined window classes have already defined values in the WM_USER range.
I think that what you meant is accurate, but not what you actually said. What you said seems to be saying that is probably safer to use the WM_APP range for message ids instead of message ids obtained using RegisterWindowMessage.
 Originally Posted by moeur
3. WM_COPYDATA is great for sending text strings or data structures as long as the data structure does not have a pointer in it. If it does, you'll have to use ReadProcessMemory to get that data just like you would with WM_APP.
No, use of ReadProcessMemory and WriteProcessMemory are not required. It might be possible to easily convert the data such that pointers are not used. If that is not possible and/or the data is large, then memory-mapped files are more efficient and safer than ReadProcessMemory and/or WriteProcessMemory.
-
Jan 9th, 2005, 12:03 PM
#28
Re: send info between apps
Memory mapped files?
Woka
-
Jan 9th, 2005, 01:44 PM
#29
Member
Re: send info between apps
 Originally Posted by Wokawidget
Memory mapped files?
Woka
I might be using incorrect terminology but it is correct to the extent that this is a common use of the term. I don't know how familiar you are with Memory mapped files, so I should try to define them assuming you know very little. If I don't do that well enough, then say so.
Memory mapped files is a common way for processes to share data; perhaps the most common. It does seem to be an indirect solution, and it probably is, at least somewhat. A Unix system, for example, has more direct functions for sharing memory; at least if my memory is accurate.
When a file is mapped to memory, a portion of memory in each process's address space is mapped to a common portion of virtual memory. The memory can be paged in and out, but that is not done unless physical memory is used to the extent that pages need to be swapped, whether they are part of a memory-mapped file or not. Data in a memory-mapped file can be accessed as efficiently as normal memory in an address space. In terms of efficiency, the memory is the same as the rest of memory for the process. ReadProcessMemory and/or WriteProcessMemory are very inefficient in comparison.
A memory-mapped file can be backed by the pagefile(s), for which the file becomes just a way to share memory. Believe me, that is a solution that is very, very common.
-
Jan 9th, 2005, 05:20 PM
#30
Re: send info between apps
Any exmaples of code? 
Woka
-
Jan 9th, 2005, 06:06 PM
#31
Member
Re: send info between apps
 Originally Posted by Wokawidget
Any exmaples of code?
Woka
How did you search? Whatever you are using to search is no good, since there should be many to be found. As soon as I get through doing things such as checking ther weather, I will look for samples using VB, and hopefully we can help you in knowing how to search.
-
Jan 9th, 2005, 07:52 PM
#32
Re: send info between apps
Hahaha. You sarcastic sod Hahaha.
OK. I will search. I was just wondering if you had any small samples to hand. Not actively looking for this code as I have no need.
Woof
-
Jan 9th, 2005, 09:30 PM
#33
Member
Re: send info between apps
I did not know of any samples, expecially not VB samples. There are many more samples that use the C/C++ languages but the following are two that use VB:
Visual Basic Samples by Karl E. Peterson (MapFile.zip)
Binaryworld - Sharing Data Between Processes Using Memory-Mapped Files ... [ VB -> Memory ]
Also, the MSDN previously contained an online copy of Hardcore Visual Basic, in which there is an article called "Shared Memory Through Memory-Mapped Files".
-
Jan 10th, 2005, 03:49 AM
#34
Re: send info between apps
Cheers for that.
Just got to work. Will check out those link.
Much appreciated 
Woka
-
Jan 13th, 2005, 04:09 PM
#35
Software Eng.
Re: send info between apps
 Originally Posted by Sam Hobbs
One of the mistakes was "subclass the receiving app"
A grave mistake, that was.
Megatron also said that it is possible to "pass the string in the lParam parameter" of a "WM_USER + X message" which is not possible. If Megatron meant that the string could be put into a lParam parameter, then it is possible to send only a few characters, not enough to be considered a string
Do you see the irony in me finger-pointing this insignificant "mistake" you made?
Life's too short to buy green bananas.
No; the WM_COPYDATA does not need custom marshalling, but WM_USER and WM_APP messages do.
No. If the data structure you're passing with WM_COPYDATA contains pointers to other locations of memory, you'll need to improvise a different approach (i.e. remove the pointers).
Receiving messages in another application that cannot be by modified at the source code level is one thing, but how to process them in that other application is a more critical problem, and likely more difficult than simply receiving the messages. Therefore I think it is best to assume that this is not a requirement until it is stated explicitly that it is.
If you're sending strings between two applications, what good is it to only be notified when a string is received? The sole reason you are sending the message (string) is so the other application can make use of it (process it). You can process the messages in that external process by subclassing. Since you have already installed a hook (the callback is already mapped into the address space of that process) you're already half-way there.
To say it's more "difficult" is subjective. Yes, there's more typing involved, but I wouldn't consider that difficult.
avoid use of ReadProcessMemory, at least in programs being developed for use by other people. I am working on getting some authoritative references on the subject.
So long as the memory locations are not modifiable by the user, it does not present a security risk. If you are not confident with your own ability to harness these functions, then don't use them.
-
Jan 13th, 2005, 05:27 PM
#36
Member
Re: send info between apps
 Originally Posted by Megatron
Do you see the irony in me finger-pointing this insignificant "mistake" you made?
I don't know what you are referring to.
 Originally Posted by Megatron
Life's too short to buy green bananas.
That is a subject for the chit-chat forum, but when the closest store that sells ripe bananas is far away, life is to short not to buy green bananas.
 Originally Posted by Megatron
No. If the data structure you're passing with WM_COPYDATA contains pointers to other locations of memory, you'll need to improvise a different approach (i.e. remove the pointers).
Of course. If we had to specify all exceptions such as that (such as WM_COPYDATA works except to send pointers) then we would never get anything done. It's like wasting time driving around in search of ripe bananas.
 Originally Posted by Megatron
If you're sending strings between two applications, what good is it to only be notified when a string is received? The sole reason you are sending the message (string) is so the other application can make use of it (process it). You can process the messages in that external process by subclassing. Since you have already installed a hook (the callback is already mapped into the address space of that process) you're already half-way there.
It depends on what is needed. Yes, if it is simply a matter of processing a message sent to/from a window, then that is as easy as you describe. However if there is something that needs to be done with the data differently than what the other application does, then it can be a lot of work.
For example, if the requirement is to draw text on an image in another application's window, then that might be quite easy. If the image can be resized (zoomed) by the other application, and if the text needs to be correspondingly resized, then that is more work. And it is likely to be more work than someone might think initially, since the text would potentially need to be redrawn after each paint message. If however the requirement is to draw the text in the bitmap that is shown in a window, then that might be significantly more difficult. When I say bitmap here, I mean it might be a bitmap drawn in memory (a memory device context?) that potentially could be written to disk, and the requirement is that the additional text be included in the image when it is written to disk.
Then there are millions of other possible requirements, such as a requirement to alter text that is being processed from/to a database.
 Originally Posted by Megatron
So long as the memory locations are not modifiable by the user, it does not present a security risk. If you are not confident with your own ability to harness these functions, then don't use them.
I am talking more from the point of view of the user of the software. It is my understanding that security specialists would object to use of ReadProcessMemory and WriteProcessMemory. ReadProcessMemory can be a problem when used to get passwords and such. A security specialist has reason to be concerned about allowing use of ReadProcessMemory, since when it is allowed, it has access to all of a process's memory. Also, if a person does not understand Windows adequately, a user might allow use of ReadProcessMemory for an account (theirs or another account) in such a manner that allows all other applications that execute under that user's authority (including unintentional applications such as viruses) to have that access.
Programmers essentially need to have a userid that allows general use of ReadProcessMemory and WriteProcessMemory, right? So for programmers, it might be an insignificant problem. If an application is to be used in a relatively more secure environment, then ReadProcessMemory and WriteProcessMemory would be an important consideration. I am not familiar with Windows security enough to clear about details, but I am attempting to get help from security specialists.
Last edited by Sam Hobbs; Jan 13th, 2005 at 05:33 PM.
-
Jan 13th, 2005, 07:58 PM
#37
Software Eng.
Re: send info between apps
 Originally Posted by Sam Hobbs
I don't know what you are referring to.
Read the red. You contradicted yourself.
(But like I said: That's green banana's)
 Originally Posted by Sam Hobbs
If we had to specify all exceptions such as that (such as WM_COPYDATA works except to send pointers) then we would never get anything done.
The fact that pointers cannot be used needs to be mentioned, as many data structures do work with pointers.
Little things like an integer only stores 16-bits can be left out.
It depends on what is needed. Yes, if it is simply a matter of processing a message sent to/from a window, then that is as easy as you describe. However if there is something that needs to be done with the data differently than what the other application does, then it can be a lot of work.
As I stated earlier, we cannot explicity state it's more difficult.
 Originally Posted by Sam Hobbs
I am talking more from the point of view of the user of the software. It is my understanding that security specialists would object to use of ReadProcessMemory and WriteProcessMemory.
I don't doubt the possibility that some "specialists" will object to the use of these functions.
I also don't doubt that some "specialists" will approve of these functions.
 Originally Posted by Sam Hobbs
ReadProcessMemory can be a problem when used to get passwords and such.
By this logic, we should also disallow the use of WM_GETTEXT, since it can also be used to retrieve passwords.
Also, if a person does not understand Windows adequately, a user might allow use of ReadProcessMemory for an account (theirs or another account) in such a manner that allows all other applications that execute under that user's authority (including unintentional applications such as viruses) to have that access.
Yes, an inexperienced user is prone to harmful attacks committed with deliberate misuse of WriteProcessMemory, but there are just as much -- if not more -- viruses that utilize other methods. The registry, for instance. Point being, if WriteProcessMemory viruses can slip by this user, what's to stop registry viruses (or other types) from doing the same?
-
Jan 13th, 2005, 09:03 PM
#38
Member
Re: send info between apps
 Originally Posted by Megatron
Read the red. You contradicted yourself.
(But like I said: That's green banana's)
Yes, it is a minor issue, but I did not contradict myself; at worst, I was just not clear. I did not write that (for the benefit of others: it is the quote above with the red) as well as I could have, so you just misunderstood it.
 Originally Posted by Megatron
As I stated earlier, we cannot explicity state it's more difficult.
You probably meant to say something such as "definitively" rather than "explicity". I did not say it is definitely more difficult; I was just saying that there is a good chance it could be, depending on requirements. I just was saying that until trying to answer the original question, the question from Shaggy Hiker asking if the other program can be modified should be answered, since the answer is potentially so much more complicated if the other program cannot be modified.
 Originally Posted by Megatron
I don't doubt the possibility that some "specialists" will object to the use of these functions.
I also don't doubt that some "specialists" will approve of these functions.
I hope and expect to get comments from the most definitive and respectable specialists on the subject; however I know of someone else that is more adamant than you are that WriteProcessMemory and ReadProcessMemory are valid for use as IPC. (Brad Jones knows who I am talking about.) If you know of any more specialists that consider WriteProcessMemory and ReadProcessMemory to be valid for use as IPC, then please tell us; I am very interested in knowing about them. The more people there are, the more justification I have to get a response form the specialists that will insist that WriteProcessMemory and ReadProcessMemory should not be used for IPC.
 Originally Posted by Megatron
By this logic, we should also disallow the use of WM_GETTEXT, since it can also be used to retrieve passwords.
Yes, that problem should be solved. Obviously it can't be solved easily, at least not as easily as simply disallowing use of WM_GETTEXT. However use of WriteProcessMemory and ReadProcessMemory can easily be avoided.
 Originally Posted by Megatron
Yes, an inexperienced user is prone to harmful attacks committed with deliberate misuse of WriteProcessMemory, but there are just as much -- if not more -- viruses that utilize other methods. The registry, for instance. Point being, if WriteProcessMemory viruses can slip by this user, what's to stop registry viruses (or other types) from doing the same?
I have said what needs to be said in response to that, so I have nothing more to say except (for the benefit of others) that I have nothing more to say.
Last edited by Sam Hobbs; Jan 13th, 2005 at 09:27 PM.
-
Jan 15th, 2005, 03:00 PM
#39
Software Eng.
Re: send info between apps
 Originally Posted by Sam Hobbs
Yes, it is a minor issue, but I did not contradict myself; at worst, I was just not clear. I did not write that (for the benefit of others: it is the quote above with the red) as well as I could have, so you just misunderstood it.
Precisely; a misunderstanding not even worth mentioning. I merely pointed it out to demonstrate just how fruitless nitpicking insignificant errors are (i.e. "Subclass the app"), rather than focusing on the primary issue.
I hope the irony is apparant, by now.
 Originally Posted by Sam Hobbs
I hope and expect to get comments from the most definitive and respectable specialists on the subject;
I'm going to be repeating myself, but there are specialists both in favour, and against the use of these functions. It's the same with any other area. Custom GINA's for instance: Some specialists are opposed to the idea, yet large scale software giants such as Symantec and Cisco continue to use them. You will not be breaking any new grounds by finding a specialist whose belief's coincide with yours, nor will I be breaking new grounds if I locate a specialist whose belief's coincide with mine. Though if it makes you feel any better, by all means ask them, but it will be the same as asking a Honda salesman if Hondas outrank Fords.
In order to gain an true unbiased understanding, you will need to draw conclusions from arguments on both sides of the debate.
-
Jan 15th, 2005, 03:44 PM
#40
Member
Re: send info between apps
 Originally Posted by Megatron
In order to gain an true unbiased understanding, you will need to draw conclusions from arguments on both sides of the debate.
Yes!
Therefore, it is imperative for us to have available to us comments from those in support of your position. I hope to get comments from at least one person more authoritative than Mick, who is a moderator in the CodeGuru forums, and who also recommends use of ReadProcessMemory and WriteProcessMemory, except the comments I am looking for would of course support what I am saying.
Last edited by Sam Hobbs; Jan 15th, 2005 at 03:50 PM.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|