|
|
#1 |
|
Junior Member
Join Date: Apr 2002
Posts: 5
|
Anyone get WM_COPYDATA in vb.net to work?
The following does nothing. Anyone see what's happening here when trying to send a copydata structure to winamp?
Public Structure COPYDATASTRUCT Public dwData As Long Public cbData As Long Public lpData As Long End Structure Declare Function CopyDataSendMessage Lib "user32" Alias _ "SendMessageA" (ByVal WndID As Long, ByVal wMsg As Long, _ ByVal wParam As Long, ByRef lParam As COPYDATASTRUCT) As Long Declare Function lstrcpy Lib "kernel32" Alias "lstrcpyA" _ (ByVal lpString1 As String, ByVal lpString2 As String) As Long Dim oCDS As COPYDATASTRUCT Dim lRet As Long oCDS.dwData = IPC_PLAYFILE ' 100 oCDS.lpData = lstrcpy(sFilename, sFilename) oCDS.cbData = Len(sFilename) + 1 lRet = CopyDataSendMessage(m_hwnd, WM_COPYDATA, 0, oCDS) |
|
|
|
|
|
#2 |
|
Junior Member
Join Date: Apr 2002
Posts: 5
|
ouch - still having trouble with this one. Has anyone done this in vb.net?
|
|
|
|
|
|
#3 |
|
Junior Member
Join Date: Jul 2002
Posts: 10
|
Solved: COPYDATASTRUCT in C#
Hey there,I found your posting when searching for a solution for this WM_COPYDATA problem myself. Actually I'm not a really programmer and so first of all, I couldn't figure out, how to get this C/C++ stuff work in C#. Eventually, the clue was to search for some anything related to structs in C#. I partly took code from other C# FAQs that I don't understand entirely, because they seemed really crazy. I remember, it was something about .NET RichTextBox or so ![]() Somehow I managed to put the following code together and have it load my files into a Winamp playlist window that is already open and referenced in my application: [ StructLayout( LayoutKind.Sequential )] private struct FileInfo { [ MarshalAs(UnmanagedType.ByValArray, SizeConst=256 )] public char[] file; // name of mp3 file (max. 255 chars + '\0') public int index; // index in playlist } [ StructLayout( LayoutKind.Sequential )] private struct COPYDATASTRUCT { public uint dwData; public uint cbData; public uint lpData; } public unsafe void addSongToPlaylist (string filename) { FileInfo f = new FileInfo(); f.file = new char[256]; int i; char[]dummy = filename.ToCharArray(); for(i = 0; (i < filename.Length) && (i < 255); i ++) f.file[i] = dummy[i]; f.file[i] = '\0'; f.index = 0; // allocate memory (very C-stylish ) and convert struct into pointerIntPtr fmem = Marshal.AllocCoTaskMem(256 + sizeof (int)); Marshal.StructureToPtr(f, fmem, false); COPYDATASTRUCT cds = new COPYDATASTRUCT(); cds.lpData = (uint)(fmem.ToInt32()); // attach f to cds cds.cbData = (uint)(filename.Length + 1 + sizeof(int)); // +1 is for the '\0' cds.dwData = (uint)(PlaylistMessages.InsertFilename); // = 106 // some hardcore C stuff again IntPtr cdsmem = Marshal.AllocCoTaskMem(3*sizeof(uint)); Marshal.StructureToPtr(cds, cdsmem, false); SendMessage (hWndPlaylist, WM_COPYDATA, 0, cdsmem.ToInt32()); // API call // free allocated memory Marshal.FreeCoTaskMem(cdsmem); Marshal.FreeCoTaskMem(fmem); } (As base class, I use an entirly modificated version of Noah Coad's Winamp C# wrapper class, just for your information.) As I said, it worked in my application, utilizes marshalling stuff (what is this??) and pointers and memory allocation (in c#??). With this "Marshal", it's possible to create a pointer on a C# struct, this looks very useful to me, because other WM_COPYDATA messages seem to use this kind of data structure as well. Pfff, well. Use it for your purposes as you like. It would be great, if somebody looked through the code and thried to optimize it. I mean, copying characters with a loop is rather silly in C#, the reason, why I did it like this is, that it actually works. Greetings from Austria, Barney. For further questions, you can visit my website: http://www.barney.at |
|
|
|
|
|
#4 |
|
Junior Member
Join Date: Apr 2010
Posts: 1
|
WM_COPYDATA in VB.net
I got this to work.
Imports System.Runtime.InteropServices Public Class Form1 Const WM_COPYDATA As Integer = 74 Const SIG_LENGTH As Integer = 36 Const MAX_COPY_LENGTH As Integer = 128 Const SigConnect As String = "F7B82657-BD18-4ee6-B182-78721293821C" Dim CDCount As Integer Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _ (ByVal lpClassName As String, ByVal lpWindowName As String) As Integer Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _ (ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, _ ByVal lParam As IntPtr) As Integer Dim hWndSender As Integer Private Const _messageID As Integer = 10 <StructLayout(LayoutKind.Sequential)> _ Private Structure COPYDATASTRUCT Public dwData As IntPtr Public cbData As Integer Public lpData As IntPtr End Structure Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load Dim s As SubclassHWND = New SubclassHWND() s.AssignHandle(Me.Handle) 's is now peeking into the Windows message pump CDCount = 0 'Count of the number of times I get a WM_COPYDATA message End Sub 'The WndProc in SubclassHWND traps the WM_COPYDATA message and then 'calls this function with the message, m. The wParam is the window 'handle. The lParam has the pointer to the COPYDATASTRUCT Public Sub ProcessWM_COPYDATA(ByRef m As System.Windows.Forms.Message) Dim data As COPYDATASTRUCT Dim Signature As String, SigComp As String Dim message As String Dim mAddr As UInteger, i As Integer ' get the data... data = CType(m.GetLParam(GetType(COPYDATASTRUCT)), COPYDATASTRUCT) hWndSender = m.WParam Signature = Marshal.PtrToStringAnsi(data.lpData, data.cbData + 1) mAddr = data.lpData mAddr = mAddr + 37 message = Marshal.PtrToStringAnsi(mAddr, data.cbData - 37) SigComp = SigConnect 'The GUID string is in indexes 0 to 35 in the String objects. 'String objects are UniCode (2 bytes per character) For i = 0 To 35 If SigComp(i) <> Signature(i) Then MsgBox(i) End If Next CDCount = CDCount + 1 MsgBox("CDCount=" + Format(CDCount, "D")) MsgBox("Signature=" + Signature) MsgBox("Message=" + message) End Sub 'Handler for clicking on the 'Send Data' button. Send data to the other application Private Sub SendWM_COPYDATA_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SendWM_COPYDATA.Click Dim hWnd As IntPtr 'Window handle of the other application Dim Message As String 'Information to be sent to the other application Dim mCopyData As COPYDATASTRUCT 'COPYDATASTRUCT structure 'Find the window that this app will send data to hWnd = FindWindow(Nothing, "FirstApp") If (hWnd <> 0) Then 'Found the other window 'The information to be sent to the other application is the GUID string and contents 'of the text box on the form Message = SigConnect + " " + WMCopyData.Text 'Make a pointer which points to a block of unmanaged memory. The COPYDATASTRUCT structure will 'end up in this block of memory. The pCopyData pointer will work in the SendMessage call Dim pCopyData As IntPtr = Marshal.AllocHGlobal(Message.Length() + 40) ' set up the data... mCopyData.lpData = Marshal.StringToHGlobalAnsi(Message) 'Copy the data to another block of unmanaged memory mCopyData.cbData = Message.Length mCopyData.dwData = _messageID 'Turn the COPYDATASTRUCTURE into a pointer to a COPYDATASTRUCTURE. The data from the 'mCopyData COPYDATASTRUCTURE is copied into the unmanaged memory block created 'in the call to Marshall.AllocHGlobal above. pCopyData then points to that block. Marshal.StructureToPtr(mCopyData, pCopyData, False) ' send the WM_COPYDATA message to the other application SendMessage(hWnd, WM_COPYDATA, Me.Handle, pCopyData) ' free the pointers... Marshal.FreeHGlobal(mCopyData.lpData) Marshal.FreeHGlobal(pCopyData) End If End Sub End Class |
|
|
|
![]() |
|
|||||||
| Thread Tools | Search this Thread |
| Display Modes | |
|
|