C ++ SendMessage пытается получить строку

Работая с C ++, я потратил много часов, пытаясь понять это. Этот код взят из работающей программы, я переписываю его на C #, но происходят некоторые вещи, которые я не понимаю.

Приведенный ниже код — именно то, что запускается, когда я нажимаю «Step Into». Как это происходит от :: SendMessage (…) до :: OnCopyData (..) с pCopyDataStruct, содержащим данные сейчас?

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;
}
}

Любая помощь очень ценится, я просмотрел все документы MSDN, которые я могу сегодня вечером, просто кажется, что я где-то упускаю что-то простое. Думал, что это может быть обратный вызов, но это не так.

1

Решение

Код отправляет сообщение (33508) в конкретное окно. Видимо, получающее окно обрабатывает это сообщение, отправляя WM_COPYDATA сообщение для HWND ты прошел в WPARAM в оригинале SendMessage() вызов. По сути, он реализует механизм обратного вызова.

Исходный номер сообщения (33508) не является одним из стандартных сообщений Win32 (по крайней мере, я его не узнаю), поэтому, скорее всего, это пользовательское сообщение. Кроме того, тот факт, что он использует WM_COPYDATA Чтобы ответить, можно предположить, что окно получения находится в другом процессе (т. е. не принадлежит вашему приложению).

2

Другие решения

Хорошо, понял это сейчас. С помощью эта страница а также Вот. Ниже то, что я сейчас использую для C #. Это ни в коем случае не законченный код, но он работает и хорош для целей обучения.

Нажмите кнопку рассчитать,

    [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);

Затем происходит обратный вызов и активируется WndProc (см. Сообщение 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);
}

Спасибо большое всем, кто ответил! Я уверен, что я бы сдался, если бы не ваша помощь. 🙂

1

По вопросам рекламы [email protected]