Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion GroupsVB SyntaxEnterprise DevelopmentDatabase AccessControlsCOMWin APICrystal ReportDeploymentGeneralGeneral 2
Related Topics
VB.NET / ASP.NETMS SQL ServerMS AccessOther Database ProductsMore Topics ...

VB Forum / COM / September 2007



Tip: Looking for answers? Try searching our database.

VB6: WM_COPYDATA, SendMessage and custom messages

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Anonymous - 07 Sep 2007 14:55 GMT
I am attempting to write a demo C app that will send custom data to a VB
app. I am using SendMessageTimeout, and WM_COPY.

This is the C structure that I am sending from the C code:

typedef struct
{
    GUID        guid ;
    UnsignedInt    version ;
    SourceType    srcId ;
    EventType    eventId ;
    char         msg[MSG_MAX_MSG_LEN+1] ;
} ConsoleMsgStruct ;

I am able to receive the message in my VB6 WindowProc callback. However,
the problem is retreiving the fields from the received message.

Here are the types I am using in VB:

Private Type GUID
  Data1 As Long         '4 bytes
  Data2 As Long         '4 bytes
  Data3 As Long         '4 bytes
  Data4(8) As Byte      '8 bytes
End Type

Private Type ConsoleMsg
    the_guid    As GUID         '20 bytes
    version     As Integer      '2 bytes
    srcId       As Integer      '2 bytes
    eventId     As Integer      '2 bytes
    msg         As String * 128 '128 bytes
End Type

Private Type COPYDATASTRUCT
    dwData As Long
    cbData As Long
    lpData As Long
End Type

This is my VB callback (WindowProc)

Public Function ListenerWindowProcCallback(ByVal hwnd As Long, _
                              ByVal wMsg As Long, ByVal wParam As Long, _
                              ByVal lParam As Long) As Long

    Dim recvd       As ConsoleMsg
    Dim cdata       As COPYDATASTRUCT
    Dim pBytes      As Long

    If wMsg = WM_COPYDATA Then
        Debug.Print "Custom msg received. wParam is: " & wParam

    //Note: I am not sure if these are necessary or being used correctly
here ...
        CopyMemory cdata, lParam, Len(cdata)
        pBytes = VarPtr(cdata.lpData)

    'FIXME: This does not seem to work. The data I get is corrupted
        CopyMemory recvd, pBytes, 152

    Else
        '\\Pass the message to the previous
        ListenerWindowProcCallback = CallWindowProc(hOldProc, hwnd,
wMsg, wParam, lParam)
    End If

End Function

Does anyone Know how I may fix the above code, so that the variable
recvd is correctly populated?
Karl E. Peterson - 07 Sep 2007 17:57 GMT
> I am attempting to write a demo C app that will send custom data to a VB
> app. I am using SendMessageTimeout, and WM_COPY.
<snip>
> //Note: I am not sure if these are necessary or being used correctly
> here ...
>         CopyMemory cdata, lParam, Len(cdata)
                          ^
Missing a ByVal on the Source pointer (lParam).  Without that, this call will copy
the memory that begins at VarPtr(lParam).

>         pBytes = VarPtr(cdata.lpData)

The pointer to your structure *is* cdata.lpData -- this just obtains a pointer to
this pointer.

> 'FIXME: This does not seem to work. The data I get is corrupted
>         CopyMemory recvd, pBytes, 152

Which would probably work here, but it's easier to just use ByVal cdata.lpData as
the source.

Also, 152 is an incorrect number of bytes, for that structure.  (Are you aware of
VB's DWORD alignment madness?)

>     Else
>         '\\Pass the message to the previous
[quoted text clipped - 6 lines]
> Does anyone Know how I may fix the above code, so that the variable
> recvd is correctly populated?

You may need to take additional steps, depending on whether the passed string is
ANSI or Unicode, as well.  But first you just need to get the right memory
addressed, and the above should put you on the right track there.
Signature

.NET: It's About Trust!
http://vfred.mvps.org

Anonymous - 07 Sep 2007 19:13 GMT
>>I am attempting to write a demo C app that will send custom data to a VB
>>app. I am using SendMessageTimeout, and WM_COPY.
[quoted text clipped - 37 lines]
> ANSI or Unicode, as well.  But first you just need to get the right memory
> addressed, and the above should put you on the right track there.

thanks, I actually spotted all of the errors above after trawling the
web and ngs for articles etc (hence the cancelled post).

BTW, are you the same Karl Peterson who maintains a VB website/blog?. A
lot of my answers actually came from your website ! :)

Whilst I'm here, I have another question. This is to do with events and
asymchronous processing. My assumption is that if an object raises an
event and passes data in the event, it does not need to wait for all the
event sinks to finish processing before it continues does it?

The reason I ask is that I am receiving data at quite a high rate of
output. what I want to do is is receive the data, UNmarshal the data and
raise an event and return immediately - so the sender does not have to
wait - am I correct in this assumption?
Karl E. Peterson - 07 Sep 2007 20:22 GMT
> thanks, I actually spotted all of the errors above after trawling the
> web and ngs for articles etc (hence the cancelled post).

Cool.  (This server doesn't recognize cancels, though.)

> BTW, are you the same Karl Peterson who maintains a VB website/blog?.

Website, yep.  Blog, never! <g>

> A lot of my answers actually came from your website ! :)

Very cool.  :-)

> Whilst I'm here, I have another question. This is to do with events and
> asymchronous processing. My assumption is that if an object raises an
> event and passes data in the event, it does not need to wait for all the
> event sinks to finish processing before it continues does it?

Uh, yeah.  Not that it really has any choice in the matter.  You could demonstrate
this fairly easily by rigging it up something like this:

 Debug.Print Now
 RaiseEvent MyEvent
 Debug.Print Now

Then sticking a Sleep(5000) call in the event sink(s).  Just for kicks, try it with
and without a DoEvents right before the Sleep.

> The reason I ask is that I am receiving data at quite a high rate of
> output. what I want to do is is receive the data, UNmarshal the data and
> raise an event and return immediately - so the sender does not have to
> wait - am I correct in this assumption?

When you recieve the data, set a very short duration timer and return.  Raise your
event when the timer fires.
Signature

.NET: It's About Trust!
http://vfred.mvps.org

 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.