|
|
Comments and Discussions
|
|
 |

|
The code has a bug, and it is so annoying in a way that it doesn't happen all the time, and when it happens, it doesn't give you any details. It just crashes the VB6 app.
After spending some time, I came to the same finding as somebody noted below "Very Important Note". If I can reach the author, I would do so to make the good code to be correct and more beneficial to others... Wanted to leave a stronger comment so that other people read it before moving on.
|
|
|
|
|

|
The example given has a slight error which only occurs under certain circumstances:
Private Function ProcessWindowMessages(ByVal hwnd As Long, ByVal wMsg As Long, _
ByVal wParam As Long, ByVal lParam As Long) As Long
The last parameter should be a long, not an int. If you lock your workstation with this set as an int, a negative value is shown which blows out the app with a win32 exception. Taken me months to track it down!
|
|
|
|

|
You can download it from the following link:
Just type the link in the browser and download it
Download link: http://w17.easy-share.com/1700679295.html
Delete link: http://w17.easy-share.com/1700679295/del_6dkt4bvbdlua2o4n
|
|
|
|

|
Does this work in Vista? I thought Vista dropped some stuff (of course later they added some stuff back in).
|
|
|
|

|
hay this is the best IPC thing i've ever read !!
But ,....
can i pass anything other than this with windows message . like a parameter..etc
wndproc does have parameters like wparam and lparam . how can i pass any string from first application to second using this IPC ?
is there any scope of using WM_COPYDATA or something simillar (please describe it.)
Kedar
|
|
|
|
|

|
thats really fine.
I'd like to send a structure{no,name} as a parameter .
how to do that using WM_COPYDATA ?
"You can do any thing you set to your mind" - theGhost_k8
|
|
|
|

|
I have not had to copy a structure through the method I used (so long ago), so have not used WM_COPYDATA method. This page seems to have a good code listing
http://www.codeguru.com/forum/printthread.php?t=231750
I also thought you could use a comma-delimited string, or something along those lines to transfer a heap of strings. I guess there would be a size limitation on the parameters of the SendMessage function though..
Hope that helps!!!
Angus
3 out of every 4 people make up 75% of the worlds' population
-- modified at 23:48 Wednesday 21st June, 2006
|
|
|
|

|
hi ! glad to see your immediate reply to the post.
Now about the problem.
Yes ! The real reson of passing a structure is not to pass a string but an object. As u've suggested about comma-delimited string, thats of no use in that case. Check what i've tried here is:- pass a structure like
Structure PT
Dim x As Integer
Dim y As Char
Dim xy As String
End Structure
Dim MyVariable As PT
MyVariable.X = 125
MyVariable.y = "c"
MyVariable.xy = "String is here"
Dim MyPointer As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(MyVariable))
Marshal.StructureToPtr(MyVariable, data.lpData, True)
and then used sendMessage to pass this structure. and on the other side at wndProc i listen to WM_COPYDATA unmarshall this and get this structure like this:
Dim MyPoint As PT
MyPoint = Marshal.PtrToStructure(CType(m.GetLParam(GetType(CopyData)), CopyData).lpData, GetType(PT))
MsgBox("->" & MyPoint.y & "<--->" & MyPoint.x & "<----->" & MyPoint.xy & "<-")
NOW THE PROBLEM !! :- i'm not able to get all values of the structure , only the first parameter. i.e. x. remaining vaules are "junk-values".. so i think this may be a marshalling problem. If u want i can mail you the code.
-------------------------------xxxxxx--------------------------------
-------:FYI:-----
WHAT I AM DOING ??
While i click on "Save" button of any office-document i want to save it using my application.. not using windows-save-dialogbox..
I HAVE FAILED TO DO:-
capture the event of "Save_Button" of "Word" AND call my_dialogbox to save. and pass this doc.'s object by applicationObject. But Cant get handle to that "save" button of "File" menu or track event of that click...
SO WHAT WAY I'M FOLLOWING??
I've created an addin to word. [VB.NET]
By clickin that addin-button i want to pass this word's object to my application (My_Save_dlgBox) to save this word.
HOPE:- ONLY YOU
- Thank You Very Much
[Kedar V]
Least I aspect:- any thoughts/Ideas from your side that i may have missed-out..
"You can do any thing you set to your mind" - theGhost_k8
|
|
|
|

|
Hmm, after some googling I think the following link may help you, assuming add-in and receiving application are both in .Net. It deals with serialising objects and then passing them through WM_COPYDATA, but with a wrap-around class. It has some samples there so hope that helps.
http://www.vbaccelerator.com/home/NET/Code/Libraries/Windows_Messages/Simple_Interprocess_Communication/article.asp
I must admit I have not gone any further with inter-process communication than this article, and am not actually using that code any more. Everything has been converted across to VB.Net now.
Angus.
Angus
3 out of every 4 people make up 75% of the worlds' population
-- modified at 3:33 Saturday 1st July, 2006
|
|
|
|

|
how do you pass paramters as part of the windows message?
ex.I want to send a message from a VB app to a VB.NEt app but LOAD_CUSTOMER with a customer number 12345
|
|
|
|

|
You can pass integers through window messaging using the wParam and lParam parameters. Note the new MessageBox in VB.Net to show the wParam value. Also note the new "12345" value in the VB6 code to pass through the value. This should help you on your way.
Example below:
VB.Net (clsWindowMessaging.vb)
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
Select Case m.Msg
Case VB6_TO_VBNET_MessageId().ToInt32
MessageBox.Show("Windows Message from VB6 Environment", "VBNETMessaging")
MessageBox.Show(m.WParam.ToString)
Case CSHARP_TO_VBNET_MessageId().ToInt32
MessageBox.Show("Windows Message from C# Environment", "VBNETMessaging")
MessageBox.Show(m.WParam.ToString)
End Select
MyBase.WndProc(m)
End Sub
VB6 (modMessaging.bas)
Public Function SendMessageToVBNET()
Dim hwndTarget As Long
Dim MessageId As Long
If WindowMessagingInitialised = False Then
InitWindowMessaging
End If
hwndTarget = VBNET_WindowHandle
MessageId = VB6_TO_VBNET_MessageId
If hwndTarget <> 0 Then
Call PostMessage(hwndTarget, MessageId, 12345, 0)
End If
End Function
Angus
3 out of every 4 people make up 75% of the worlds' population
|
|
|
|

|
HWND_BROADCAST not working for u?
All your source are belong to us!
|
|
|
|

|
Hi Guys,
Great Tutorial. I like it and I like the code.
I have one question though. How can you make this work to pass messages from one VB6 application on a PC to another VB6 application on another PC. I have to place a small VB app on the server that triggers a refresh on the client side everytime the database is updated.
I appreciate any help on the subject.
Thanks
Salim
|
|
|
|

|
What you need to be looking for is client-server communications in VB6. Having never done this (ewww), I can't really be much help besides googling some results for you.
-> http://www.vbip.com/winsock/winsock_control_ssahmed_01.asp
-> http://www.codeproject.com/Purgatory/winsock.asp
Book from Amazon: http://www.amazon.com/gp/product/1571691545/103-0165782-9268656?v=glance&n=283155
Hope they start you on a road to a solution.
Angus
3 out of every 4 people make up 75% of the worlds' population
|
|
|
|

|
Thanks minja. I have already looked up these pages myself and I am working on it. Hope this leads to where I want to be.
I will try to use winsock along with windows messaging for a better result but then again I might just stick to winsock.
Thanks again,
Salim
|
|
|
|

|
Hi,
first at all thanks for this how-to. It is realy nice.
Going to the point, I'm trying to send a string through the LParam argument of the message. After doing some search in google, I found that you can even pass objects if you want; the trick is that instead of passing a string to the PostMessage function, you have to call it with a pointer to a memory address (IntPtr in other words) and change the declaration of PostMessage to reflect this.
I have tried several things, but it seams that either the contents of the memory address are deleted after doing the PostMessage or I'm doing something wrong in the other side of the comunication. Have you ever tried to do this?
Before posting my code here, I have to explain that I have two applications coded in C#: a server and a client which send messages each other (If you are interested, I could send the complete source to you). I modify your code a little bit to do a C# Server to C# Client communication and viceversa; messages are received, but the string in the memory address is lost. So here is the code:
[DllImport("user32.dll")]
//I replaced the lParameter type by an IntPtr
//in order to be able to pass a pointer to a
//string as a message. I found some messages
//in google, which says that you can do that
public static extern IntPtr PostMessage (IntPtr hwnd,
IntPtr wMsg, Int32 wParam, IntPtr lParam);
protected override void WndProc(ref Message m)
{
if (m.Msg == CSHARP_SERVER_TO_CLIENT_MessageId.ToInt32())
{
MessageBox.Show("Windows Message from Server environment", "C#ClientMessaging");
//Here I will try to get the contents of the memory
//address referenced by m.LParam. I checked this value
//in both: the client and the server and it has the same
//value, but the string returned by PtrToStringAuto is
//either empty or has garbage on it.
string test = Marshal.PtrToStringAuto(m.LParam);
MessageBox.Show(test);
}
base.WndProc(ref m);
}
public void SendMessageToServer()
{
IntPtr hwndTarget;
IntPtr MessageId;
//This is a pointer to a memory address I
//create to store a string
IntPtr messagePointer;
//The local variable to assign the string
string msgStr;
hwndTarget = this.SERVER_WindowHandle;
MessageId = CSHARP_CLIENT_TO_SERVER_MessageId;
//Assign some message to send
msgStr = "test";
//Allocate memory to the string and store it somewhere
//on the heap. messagePointer will get the memory
//address, where the string was stored
messagePointer = Marshal.StringToHGlobalAuto(msgStr);
//As a test, I read the string from the memory address
//on another variable and it works, I get "test"
string test = Marshal.PtrToStringAuto(messagePointer);
MessageBox.Show(test);
if (!System.IntPtr.Zero.Equals(hwndTarget))
{
//messagePointer is used as LParam for the PostMessage function
PostMessage(hwndTarget, MessageId, 0, messagePointer);
}
}
The client application is almost the same, the only thing that changes are the method and variable names.
I even tried to test it with your example by modifying the VB.Net and C# examples but it didn't work as well. Do you know how to solve it?
Thanks in advanced,
Josef Meile
|
|
|
|

|
Ah, by the way, before I found your code, I was trying to get it working with the WM_COPYDATA how to you mention in the "Confused... " thread, the problem here is that I'm working with Excel and Visio COM Objects and they can't be accessed from the WM_COPYDATA handler, I get:
An outgoing call cannot be made since the application is dispatching an input-synchronous call.
So, I search on google and found a delphi message, where the solution was to send a message with PostMessage and not *SendMessage*, which will throw the same exception as well. Unfortunatelly, all the messages I have found, not many, suggest diferent things, but none of them have a complete solution to the problem.
Regards,
Josef
|
|
|
|

|
Ok, I found the answer to my question:
It seems like I can't do what I want with PostMessage. As I have read, the difference with SendMessage is that the later sends a message to a window inmediately and waits for an answer; while PostMessage sends the message to the forms' message queue and exits. So, the memory location I stored in my SendMessageToServer method will be lost because it is local. To solve this problem I found that I could used something called FileMap, which creates a memory that can be shared between different processes. I guess it will work, but something more direct would have being better
The other issue I had with the COM Objects is that they only can be used by the thread that originated then, so, there will be problems with the How-To you mentioned: WM_COPYDATA because it uses SendMessage, which creates a new thread whenever a new message arrives. Here I also tried the Invoke and BeginInvoke functions of DotNet, but I had the same error messages
Thanks anyway,
Josef
|
|
|
|
|
|

|
cool, just as I was about to try to answer your question.
yep, that is a nice way to combine. The way we were using it was just as a notifier between VB.Net app and VB6 app when a certain process finished. We didn't need any data, just needed to know that something had finished.
maybe you should write up an extension article to mine!!
Angus
3 out of every 4 people make up 75% of the worlds' population
|
|
|
|

|
Due to a reader request, I have now updated source and demos to include VB6 to VB6 communication. There are plenty of demos of this around the web, but it was a 5 minute job because I have everything setup already.
Angus
3 out of every 4 people make up 75% of the Worlds' population
|
|
|
|

|
I am experimenting with your code and seem to have gotten myself into the jam you describe below.
Now, when I run a VB6 project that initiates messaging, it blows out of VB as soon as I click on any other window. How can I undo the damage?
VB6: One thing to note that is VITALLY IMPORTANT is that you need to disconnect your custom Message Handler before the application closes, otherwise it starts to handle messages in the VB IDE. It was quite hard to track this problem down because it would work nicely when I ran the executable, but once inside the IDE, it would crash VB.
|
|
|
|

|
Is it crashing when you start the VB app, and then click on another window? If so, then I am guessing you have a mistake in the modMessaging.ProcessWindowMessages function. Make sure that if the Window Message is not one of your custom messages, then it is handed back down to the default message handler via the CallWindowProc Win32 function.
If it is passing to this, then I guessing that the address of the original handler has been set incorrectly.
If it is crashing when you quit the VB app back to VB6 and then click on another app, then your custom Window handling is never being set back to the original handler. Call the modMessaging.StopWindowMessaging function to reset the handler back to the original (usually MainForm).
Try these and if it does not work, get back to me. Do the compiled app's work for you?
Angus
3 out of every 4 people make up 75% of the Worlds' population
|
|
|
|

|
Thanks for getting back. Yes, that's exactly what happens. I start a VB app, then click on another window and the Vb app gets blown away. In fact, now when I start your VBMessaging VB app and click another window, it gets blown away. That's even after rebooting and having started no other applications. Some gremlin is living in my machine and has taken control.
|
|
|
|

|
Hmm, maybe this is low level stuff like OS or vb runtime problems. What OS and runtime are you running under?
I haven't had any problems yet, but am running XP Pro on both machines. Not sure what vb runtime I have at home. Will check tonight.
I can also do up two VB apps which message each other to see if that helps at all. Are you running the prog's in debug mode. Can you tell me what lines it is crashing on? Any debug info?
Angus
3 out of every 4 people make up 75% of the Worlds' population
|
|
|
|

|
Hey minja,
Thanks for your responsiveness to my problem, but as it so often turns out, this is one of my own creation. I dropped the "e" in the "else" in the ProcessWindowsMessages function somehow when I added the modmessaging module to my project. Any windows message then blew out my app because of a syntax error. So now I can resume testing. And thanks for the link to the tutorial. It explains things slightly differently than you do, and between the two demos I now have an understanding of a very useful function.
Joe
|
|
|
|

|
You can say "explained it better than you did" if you like.
Because I was coding at work, and doing research at work/home I lost track of a few links. I am going to put that link the in the "referenced" links section.
Hopefully your problems are solved. Good luck!!
Angus
3 out of every 4 people make up 75% of the Worlds' population
|
|
|
|
|
 |
|
|
General News Suggestion Question Bug Answer Joke Rant Admin
|
Article outlining methods for communicating between VB6, VB.NET, and C# apps using Window Messaging.
| Type | Article |
| Licence | |
| First Posted | 3 May 2004 |
| Views | 156,061 |
| Bookmarked | 54 times |
|
|