Drew
Drew

Reputation: 43

C++ SendMessage trying to receive string

Working with C++, I've spent way to many hours already trying to figure this out. This code is from a working program, I'm rewriting it in C#, but there is some things happening I do not understand.

The below code is exactly what runs when I press "Step Into". How is it going from ::SendMessage(...) to ::OnCopyData(..) with pCopyDataStruct containing data now?

main.cpp

void COTP::main()
{
    //string will be returned using WM_COPYDATA message
    ::SendMessage(hWnd, 33508, (WPARAM)GetSafeHwnd(), 11);

    // WPARAM is a typedef for UINT_PTR which is an unsigned int.
}

afxwin2.inl

_AFXWIN_INLINE HWND CWnd::GetSafeHwnd() const
    { return this == NULL ? NULL : m_hWnd; }

main.cpp

BOOL COTP::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct) 
{
    CString str, str2;

    switch (pCopyDataStruct->dwData)
    {
        case JRC_COPYDATA_ID_TRACK_FILENAME:
            str = (LPCTSTR)pCopyDataStruct->lpData;
            break;
    }
}

Any help super appreciated, I have looked thru all the msdn documents that I can tonight, it just seems like I'm missing something simple somewhere. Thought it might be a callback, but that doesn't seem right.

Upvotes: 1

Views: 1998

Answers (2)

Drew
Drew

Reputation: 43

Alright got it figured out now. With the help of this page and here. Below is what I'm currently using for C#. This is by no means finished code, but this does work and is good for learning purposes.

Click calculate button,

    [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
    public static extern IntPtr GetActiveWindow();

    private void btnCalculate_Click(object sender, EventArgs e)
    {
        int hwnd = 0;
        hwnd = Win32.FindWindow("The App pulling from", "Window");

        int s = (int)GetActiveWindow();
        int s3 = Win32.SendMessage(hwnd, 33508, s, 11);

Then what happens is a callback occurs and activates WndProc(ref Message m),

    protected override void WndProc(ref Message m)
    {
        // Prevents error creating window handle message.
        base.WndProc(ref m);

        // WM_COPYDATA
        // m.Msg = 0x4a
        //msg=0x4a (WM_COPYDATA) hwnd=0x251e62 wparam=0x69063e lparam=0x1c42cca0 result=0x0
        if (m.Msg == 0x4a)
        {
            Console.WriteLine(m);
            WndProc(m.HWnd, m.Msg, m.WParam, m.LParam);
        }
    } 

    public struct CopyDataStruct : IDisposable
    {
        public IntPtr dwData;
        public int cbData;
        public IntPtr lpData;

        public void Dispose()
        {
            if (this.lpData != IntPtr.Zero)
            {
                LocalFree(this.lpData);
                this.lpData = IntPtr.Zero;
            }
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public unsafe struct DataStruct
    {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 300)]
        public string s;
        public double d;
        public char c;
    };

    protected void WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam)
    {
        CopyDataStruct cps = (CopyDataStruct)Marshal.PtrToStructure(lParam, typeof(CopyDataStruct));
        DataStruct data = (DataStruct)Marshal.PtrToStructure(cps.lpData, typeof(DataStruct));
        // data.s is what we needed.
        Console.WriteLine(data.s);
    }

Thank you very much to everyone that replied! I am confident I would have given up if not for your help. :)

Upvotes: 1

cbranch
cbranch

Reputation: 4769

The code is sending a message (33508) to a specific window. Apparently the receiving window processes that message by sending a WM_COPYDATA message to the HWND you passed in the WPARAM in the original SendMessage() call. It's essentially implementing a callback mechanism.

The original message number (33508) is not one the standard Win32 messages (at least not that I recognize), so it's likely a custom message. Also, the fact that it's using WM_COPYDATA to respond would suggest that the receiving window is in a different process (i.e., not owned by your application).

Upvotes: 2

Related Questions