BBC BASIC for Windows
« WM_COPYDATA »

Welcome Guest. Please Login or Register.
Apr 5th, 2018, 10:21pm



ATTENTION MEMBERS: Conforums will be closing it doors and discontinuing its service on April 15, 2018.
Ad-Free has been deactivated. Outstanding Ad-Free credits will be reimbursed to respective payment methods.

If you require a dump of the post on your message board, please come to the support board and request it.


Thank you Conforums members.

BBC BASIC for Windows Resources
Online BBC BASIC for Windows documentation
BBC BASIC for Windows Beginners' Tutorial
BBC BASIC Home Page
BBC BASIC on Rosetta Code
BBC BASIC discussion group
BBC BASIC for Windows Programmers' Reference

« Previous Topic | Next Topic »
Pages: 1  Notify Send Topic Print
 thread  Author  Topic: WM_COPYDATA  (Read 2801 times)
Nick
New Member
Image


member is offline

Avatar




PM

Gender: Male
Posts: 33
xx WM_COPYDATA
« Thread started on: Sep 6th, 2011, 10:02pm »

Hi,

Regarding WM_COPYDATA

Do you know of any BBC4W programmes which use this function to move data to/from other apps?

I am presuming that this function copies a given amount of data to the memory heap of the target application. You have to pass to the target a pointer to a COPYDATASTRUCT comprising:

dwData
ULONG_PTR
The data to be passed to the receiving application.

cbData
DWORD
The size, in bytes, of the data pointed to by the lpData member.

lpData
PVOID
The data to be passed to the receiving application. This member can be NULL.


So in BBC4W terms, ULONG_PTR would be set to the start address of the data in memory to be copied, cbData is the number of bytes - but what is lpData?

How can it be simultaneously "The data to be passed..." and "This member can be NULL"?

Thanks

Nick
User IP Logged

admin
Administrator
ImageImageImageImageImage


member is offline

Avatar




PM


Posts: 1145
xx Re: WM_COPYDATA
« Reply #1 on: Sep 7th, 2011, 08:20am »

on Sep 6th, 2011, 10:02pm, Nick wrote:
Regarding WM_COPYDATA, Do you know of any BBC4W programmes which use this function to move data to/from other apps?

Yes, the Module Viewer add-in utility uses it. When you say "other apps" obviously both 'ends' of the link must coöperate - one sending the WM_COPYDATA message and the other receiving it - so you can't use it to transfer data to or from an app you haven't written yourself unless you happen to know it processes that message.

Quote:
what is lpData? How can it be simultaneously "The data to be passed..." and "This member can be NULL"?

It can't be NULL if you're actually passing some data in memory! The situation in which it can be NULL is if you're using WM_COPYDATA only to send (up to) 32 bits of data in cbData.

The big advantage of WM_COPYDATA over rolling your own 'custom' message is that it takes care of marshalling the data between the two independent address spaces of the two processes.

Richard.
User IP Logged

Nick
New Member
Image


member is offline

Avatar




PM

Gender: Male
Posts: 33
xx Re: WM_COPYDATA
« Reply #2 on: Sep 7th, 2011, 09:21am »

on Sep 7th, 2011, 08:20am, Richard Russell wrote:
Yes, the Module Viewer add-in utility uses it.


Is there any chance of getting the source code - at least of the PROC/FN that builds your COPYDATASTRUCT?

Quote:
so you can't use it to transfer data to or from an app you haven't written yourself


Noted - I am writing both sender and receiver apps.

Thanks for the clarification with lpData!

Am I right to assume that if you get a TRUE response to sending a WM_COPYDATA message, it means that windows has managed to understand your DATACOPY struct and has copied the data to the receiver's memory space?

That is the point in my present code where it is not working! I just get a 0 returned from the WM_COPYDATA message.

Thanks again for BBC4W - it is fabulous.

Nick
User IP Logged

admin
Administrator
ImageImageImageImageImage


member is offline

Avatar




PM


Posts: 1145
xx Re: WM_COPYDATA
« Reply #3 on: Sep 7th, 2011, 12:58pm »

on Sep 7th, 2011, 09:21am, Nick wrote:
Is there any chance of getting the source code - at least of the PROC/FN that builds your COPYDATASTRUCT?

Couldn't be simpler, really:

Code:
      DIM cds{dwData%, cbData%, lpData%}
      cds.dwData% = pAddress%
      cds.cbData% = codesize%
      cds.lpData% = code% 

Quote:
Am I right to assume that if you get a TRUE response to sending a WM_COPYDATA message, it means that windows has managed to understand your DATACOPY struct and has copied the data to the receiver's memory space?

That seems unlikely. MSDN implies that it works like any other 'sent' message - the returned value is whatever the receiving application returns.

Quote:
That is the point in my present code where it is not working! I just get a 0 returned from the WM_COPYDATA message.

Does your receiving application see the message, and if so what does it return? Are you using assembler code to handle the receipt of the message, or the SUBCLASS library? Neither is exactly straightforward. :(

Richard.
User IP Logged

Nick
New Member
Image


member is offline

Avatar




PM

Gender: Male
Posts: 33
xx Re: WM_COPYDATA
« Reply #4 on: Sep 8th, 2011, 12:15pm »

on Sep 7th, 2011, 12:58pm, Richard Russell wrote:
[quote]Does your receiving application see the message, and if so what does it return?


Yes, it most definitely does. The wparam indeed points to the SENDER Hwin, and the lparam is non-zero and the @msg% bit is 74 (WM_COPYDATA). The routine returns the value I state when it returns form processing the COPYDATA message. That value is correctly returned to the sender app.

BUT (and this is where i am struggling), I am unsure how to access the pointer to the copied data (the lparam value).

I presume that during the message processing, I have to set up a structure identical to the one sent (ie the COPYDATA structure). Once this is filled it will give me individual access to the three structure components. Then I can get the data, copy it and exit the message processing.

But I can's simply equate the lparam to my (e.g.) RECEIVED_COPIEDDATASTRUCT

How do I pass the 'pointer' contained in the lparam to my structure? Is the lparam value simply the start address in the receivers' memory to the identical DATASTRUCT that was sent? or is it a "pointer" in some other sense?

Sorry to sound lame sad

Nick
User IP Logged

admin
Administrator
ImageImageImageImageImage


member is offline

Avatar




PM


Posts: 1145
xx Re: WM_COPYDATA
« Reply #5 on: Sep 8th, 2011, 1:13pm »

on Sep 8th, 2011, 12:15pm, Nick wrote:
How do I pass the 'pointer' contained in the lparam to my structure?

You have to use this piece of BB4W 'magic':

Code:
      !(^cds{}+4) = lparam% 

What this does is to change the structure's data pointer so that it points to the data in the received message.

Richard.
User IP Logged

Nick
New Member
Image


member is offline

Avatar




PM

Gender: Male
Posts: 33
xx Re: WM_COPYDATA
« Reply #6 on: Sep 8th, 2011, 1:37pm »

on Sep 8th, 2011, 1:13pm, Richard Russell wrote:
You have to use this piece of BB4W 'magic':


That makes a lot of sense now. - thank you.

So like this?:

DEF FN_copydata(m%,w%,l%)
REM This has to be fast - just get the data and return
REM m% is the WM_COPYDATA value (74)
REM w% is sender handle
REM l% points to COPYDATASTRUCT
DIM RECEIVED_COPYDATA{dw%,cb%,lpdata%}
!(^RECEIVED_COPYDATA{}+4) = l%
return_value%=97 REM arbitrary choice!
= return_value%


(this is my FN that handles the subclassed COPYDATA message)

And: will it need similar 'magic' on the sending function?

SYS "SendMessage", target_hwnd%, WM_COPYDATA, @hwnd%, COPYDATASTRUCT {} ?

Nick
« Last Edit: Sep 8th, 2011, 3:09pm by Nick » User IP Logged

admin
Administrator
ImageImageImageImageImage


member is offline

Avatar




PM


Posts: 1145
xx Re: WM_COPYDATA
« Reply #7 on: Sep 8th, 2011, 4:07pm »

on Sep 8th, 2011, 1:37pm, Nick wrote:
So like this?

Bear in mind that, as a rule, any pointers sent in a message are only valid until the receiving end returns. So make sure you do everything you need with the values contained in the COPYDATASTRUCT before the '= return_value%'. Arguably you would be better off making it a LOCAL structure rather than a Global structure, to guarantee this.

Quote:
return_value%=97 REM arbitrary choice!
= return_value%

MSDN says you should return TRUE (=1), so it's not really an "arbitrary choice".

Richard.
User IP Logged

Nick
New Member
Image


member is offline

Avatar




PM

Gender: Male
Posts: 33
xx Re: WM_COPYDATA
« Reply #8 on: Sep 8th, 2011, 4:33pm »

on Sep 8th, 2011, 4:07pm, Richard Russell wrote:
Bear in mind that, as a rule, any pointers sent in a message are only valid until the receiving end returns.


Yes, I was going to add that once the IPC bit of it was working properly.

Unfortunately mine still doesn't work. Does the COPYDATA statement at the sending end need similar 'magic'?

At present:

SYS "SendMessage", target_hwnd%, WM_COPYDATA, @hwnd%, COPYDATASTRUCT {}

Thanks Nick


User IP Logged

admin
Administrator
ImageImageImageImageImage


member is offline

Avatar




PM


Posts: 1145
xx Re: WM_COPYDATA
« Reply #9 on: Sep 8th, 2011, 9:34pm »

on Sep 8th, 2011, 4:33pm, Nick wrote:
At present:
SYS "SendMessage", target_hwnd%, WM_COPYDATA, @hwnd%, COPYDATASTRUCT {}

That looks OK to me (except that there's a space between COPYDATASTRUCT and the opening brace, which isn't allowed). Anyway, you said your receiving application was seeing the message successfully so it must be working.

Incidentally, I presume you realise that COPYDATASTRUCT is the name of the generic structure; typically not of a particular instantiation (of which there could be several in a program). Although there's nothing stopping you calling your structure that, I would normally use a more succinct name such as cds{}.

Richard.
User IP Logged

Nick
New Member
Image


member is offline

Avatar




PM

Gender: Male
Posts: 33
xx Re: WM_COPYDATA
« Reply #10 on: Sep 10th, 2011, 05:30am »

on Sep 8th, 2011, 9:34pm, Richard Russell wrote:
That looks OK to me (except that there's a space between COPYDATASTRUCT and the opening brace, which isn't allowed). Anyway, you said your receiving application was seeing the message successfully so it must be working.


Yes, after some tidying up, it works nicely.

Quote:
Incidentally, I presume you realise that COPYDATASTRUCT is the name of the generic structure; typically not of a particular instantiation


Yes, I did. I have it like this while authoring - it helps me to see more clearly which variable is what.

Thanks again - your help is much appreciated.

Nick
User IP Logged

Pages: 1  Notify Send Topic Print
« Previous Topic | Next Topic »

| |

This forum powered for FREE by Conforums ©
Terms of Service | Privacy Policy | Conforums Support | Parental Controls