Получение сообщений от другого процесса - PullRequest
0 голосов
/ 20 сентября 2019

Кажется, что я упускаю что-то фундаментальное из моего приложения, обновленного с VB6.Все, что я хочу сделать - это получить SendMessage сообщений от другого приложения .

Старое приложение VB6 работает, однако я обнаружил, что в .Networld, переопределение метода WndProc (ref Message m) не работает.Обратите внимание, я вижу сообщения, приходящие из одного и того же приложения, например, если я перемещаю мышь внутри окна.

Я попытался имитировать то, что сделал VB6, то есть, используя SetWindowLong , CallWindowProc и т. Д. ... и тоже не работает.

Я редко читал о внедрении DLL ( P / Invoking SetWindowLong и CallWindowProc в управляемом коде (компактная структура) ) но не могу двигаться дальше.

Возможно ли это в .Net?Я надеюсь, что кто-то может указать мне правильное направление.

ОБНОВЛЕНИЕ: В MSDN есть тема по этому поводу.Вот ссылка: https://docs.microsoft.com/en-us/windows/win32/dataxchg/using-data-copy

Но это на C ++.Мне интересно, возможно ли это в .NET

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsAppMessage
{
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        //HandleCreated += Form1_HandleCreated;
    }


    protected override void WndProc(ref Message m)
    {
        Console.WriteLine(m.ToString());

        // Listen for operating system messages or from other applications
        base.WndProc(ref m);
    }

/*
    private void Form1_HandleCreated(object sender, EventArgs e)
    {
        _handle = this.Handle;
        Attach();
    }


    [DllImport("user32.dll", SetLastError = true)]
    private static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong);

    [DllImport("user32.dll")]
    public static extern int CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hWnd, int Msg, int wParam, int lParam);

    private delegate int WindowProc(IntPtr hWnd, int Msg, int wParam, int lParam);
    private const int GWL_WNDPROC = -4;

    private IntPtr _handle;
    private IntPtr _oldCallback;
    private WindowProc _newCallback;


    public void Attach()
    {
        _newCallback = WndProc; // Pins WndProc - will not be garbage collected.
        _oldCallback = SetWindowLong(_handle, GWL_WNDPROC,
            Marshal.GetFunctionPointerForDelegate(_newCallback));

        // Just to be sure...
        if (_oldCallback == IntPtr.Zero)
            throw new Win32Exception(Marshal.GetLastWin32Error());
    }

    public void Detach()
    {
        if (_newCallback == null || _oldCallback == null)
            return;

        SetWindowLong(_handle, GWL_WNDPROC, _oldCallback);
        _newCallback = null;
    }

    private int WndProc(IntPtr hWnd, int Msg, int wParam, int lParam)
    {

        Console.WriteLine(Msg.ToString());

        // Forward the message to the original WndProc function.
        return CallWindowProc(_oldCallback, hWnd, Msg, wParam, lParam);
    }

}
*/

}

1 Ответ

0 голосов
/ 24 сентября 2019

Просто к вашему сведению, я решил эту проблему.Главное, чего мне не хватало, - это программным образом разрешить получение сообщений из «другого приложения».

Тема для поиска - Изоляция привилегий пользовательского интерфейса (UIPI), поэтому возникает необходимость явного вызова ChangeWindowMessageFilterEx API.

Например:

 ChangeWindowMessageFilterEx(this.Handle, Constants.WM_COPYDATA, ChangeWindowMessageFilterExAction.Allow, ref filterStatus);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...