发送消息的问题

发布于 2024-08-17 03:09:23 字数 4385 浏览 4 评论 0原文

我正在使用 C# 开发一个应用程序,具有与 Windows 中类似的复制、粘贴功能。 我添加了菜单项并与相应的应用程序链接。

请查看下图以获得更多想法。

添加到 shell 菜单的项目 http://softwaregenius.net/myimages/menu.jpg

像我们一样在 Windows 资源管理器中选择多个项目,您需要选择多个文件和/或文件夹,然后选择 OS Util->FastCopy。打开一个表单,如下所示

FastCopy 上显示的表单 http://softwaregenius.net/myimages/fastcopy1.jpg

该应用程序运行良好。这里的主要问题是,选择文件后,所有这些文件都会在相应的软件中打开。也就是说,如果我选择了 Word 文档,则文件名将添加到 FastCopy 表单中,但也会在 Word 中打开。

当我调查时,我发现这个问题是由于SendMessage造成的。我必须使用 PostMessage 而不是 SendMessage。但是当我这样做时,应用程序无法运行。

下面是我在 C# 2005 中的 Main 函数编码

static class Program
{
    static Mutex mutex = new Mutex(true, "{8F6F0AC4-B9A1-45fd-A8CF-72F04E6BDE92}");
    [STAThread]
    static void Main(string[] args)
    {
        string fileName = "";
        if (args.Length > 0)
        {
            fileName = args[0];
        }
        if (mutex.WaitOne(TimeSpan.Zero, true))
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            frmFastCopy frm = new frmFastCopy();
            frm.AddItemToList(fileName);
            Application.Run(frm);

        }
        else
        {
            //The following message is sent just to show up the form
            NativeMethods.PostMessage(
                    (IntPtr)NativeMethods.HWND_BROADCAST,
                    NativeMethods.WM_SHOWME,
                    IntPtr.Zero,
                    IntPtr.Zero);

            //Send the filename
            SendFileName(fileName);
        }
    }

    static void SendFileName(string s)
    {
        Win32.CopyDataStruct cds = new Win32.CopyDataStruct();

        cds.cbData = (s.Length + 1) * 2;
        cds.lpData = Win32.LocalAlloc(0x40, cds.cbData);
        Marshal.Copy(s.ToCharArray(), 0, cds.lpData, s.Length);
        cds.dwData = (IntPtr)1;
        Win32.SendMessage((IntPtr)NativeMethods.HWND_BROADCAST, Win32.WM_COPYDATA, IntPtr.Zero, ref cds);
        //NativeMethods.PostMessage((IntPtr)NativeMethods.HWND_BROADCAST, Win32.WM_COPYDATA, cds.lpData, IntPtr.Zero);
    }
}

}


下面是 WndProc 的副本以及 Form

公共分部类 frmFastCopy 中的其他代码: { 委托无效 AddItemToListDelegate(string itm);

    public frmFastCopy()
    {
        InitializeComponent();
    }

    public void AddItemToList(string itm)
    {
        if (lvFilesAndFolders.InvokeRequired)
        {
            AddItemToListDelegate m = new AddItemToListDelegate(AddItemToList);
            this.Invoke(m, new object[] { itm });
        }
        else
        {
            lvFilesAndFolders.Items.Add(itm);
        }
    }
    protected override void WndProc(ref Message m)
    {
        if (m.Msg==NativeMethods.WM_SHOWME)
        {
                ShowMe();
        }
        if (m.Msg==Win32.WM_COPYDATA)
        {
                //string s = Marshal.PtrToStringUni(m.LParam);
                MessageBox.Show("Got message");

                Win32.CopyDataStruct st = (Win32.CopyDataStruct)Marshal.PtrToStructure(m.LParam, typeof(Win32.CopyDataStruct));
                string strData = Marshal.PtrToStringUni(st.lpData);
                AddItemToList(strData);
        }
        base.WndProc(ref m);
    }
    private void ShowMe()
    {
        this.Show();
        if (WindowState == FormWindowState.Minimized)
        {
            WindowState = FormWindowState.Normal;
        }
        // get our current "TopMost" value (ours will always be false though)
        bool top = TopMost;
        // make our form jump to the top of everything
        TopMost = true;
        // set it back to whatever it was
        TopMost = top;
    }

这是 NativeCode 类,

internal class NativeMethods
{
    public const int HWND_BROADCAST = 0xffff;
    public static readonly int WM_SHOWME = RegisterWindowMessage("WM_SHOWME");
    [DllImport("user32")]
    public static extern bool PostMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam);
    [DllImport("user32")]
    public static extern int RegisterWindowMessage(string message);

}

我知道你们都是天才。有人可以告诉我应该在哪里进行更改以打开所选文件,或者我应该如何使用 postmessage。

感谢您分享您的宝贵时间。

问候

伊尔凡

I am developing an application using C# having similar functionality of copy,paste as in Windows.
I have added menu items and linked with respective applications.

Please look at the following image for getting more idea.

Items added to shell menu http://softwaregenius.net/myimages/menu.jpg

Like we select multiple items in windows explorer, you need to select multiple files and/or folders and then select OS Util->FastCopy. A form is opened as shown below

Form shown on FastCopy http://softwaregenius.net/myimages/fastcopy1.jpg

The application is working perfectly. The major problem here is that after selecting the files all these files are opening up within there respective softwares. That is if i selected word document then the filename is added to FastCopy form but the is also opening up within Word also.

When i investigate i found that this problem is due to SendMessage. I have to use PostMessage instead of SendMessage. But when i do so the application is not working.

Below is my Main function coding in C# 2005

static class Program
{
    static Mutex mutex = new Mutex(true, "{8F6F0AC4-B9A1-45fd-A8CF-72F04E6BDE92}");
    [STAThread]
    static void Main(string[] args)
    {
        string fileName = "";
        if (args.Length > 0)
        {
            fileName = args[0];
        }
        if (mutex.WaitOne(TimeSpan.Zero, true))
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            frmFastCopy frm = new frmFastCopy();
            frm.AddItemToList(fileName);
            Application.Run(frm);

        }
        else
        {
            //The following message is sent just to show up the form
            NativeMethods.PostMessage(
                    (IntPtr)NativeMethods.HWND_BROADCAST,
                    NativeMethods.WM_SHOWME,
                    IntPtr.Zero,
                    IntPtr.Zero);

            //Send the filename
            SendFileName(fileName);
        }
    }

    static void SendFileName(string s)
    {
        Win32.CopyDataStruct cds = new Win32.CopyDataStruct();

        cds.cbData = (s.Length + 1) * 2;
        cds.lpData = Win32.LocalAlloc(0x40, cds.cbData);
        Marshal.Copy(s.ToCharArray(), 0, cds.lpData, s.Length);
        cds.dwData = (IntPtr)1;
        Win32.SendMessage((IntPtr)NativeMethods.HWND_BROADCAST, Win32.WM_COPYDATA, IntPtr.Zero, ref cds);
        //NativeMethods.PostMessage((IntPtr)NativeMethods.HWND_BROADCAST, Win32.WM_COPYDATA, cds.lpData, IntPtr.Zero);
    }
}

}


Below is the copy for WndProc and other code from within the Form

public partial class frmFastCopy : Form
{
delegate void AddItemToListDelegate(string itm);

    public frmFastCopy()
    {
        InitializeComponent();
    }

    public void AddItemToList(string itm)
    {
        if (lvFilesAndFolders.InvokeRequired)
        {
            AddItemToListDelegate m = new AddItemToListDelegate(AddItemToList);
            this.Invoke(m, new object[] { itm });
        }
        else
        {
            lvFilesAndFolders.Items.Add(itm);
        }
    }
    protected override void WndProc(ref Message m)
    {
        if (m.Msg==NativeMethods.WM_SHOWME)
        {
                ShowMe();
        }
        if (m.Msg==Win32.WM_COPYDATA)
        {
                //string s = Marshal.PtrToStringUni(m.LParam);
                MessageBox.Show("Got message");

                Win32.CopyDataStruct st = (Win32.CopyDataStruct)Marshal.PtrToStructure(m.LParam, typeof(Win32.CopyDataStruct));
                string strData = Marshal.PtrToStringUni(st.lpData);
                AddItemToList(strData);
        }
        base.WndProc(ref m);
    }
    private void ShowMe()
    {
        this.Show();
        if (WindowState == FormWindowState.Minimized)
        {
            WindowState = FormWindowState.Normal;
        }
        // get our current "TopMost" value (ours will always be false though)
        bool top = TopMost;
        // make our form jump to the top of everything
        TopMost = true;
        // set it back to whatever it was
        TopMost = top;
    }

Here is the NativeCode class

internal class NativeMethods
{
    public const int HWND_BROADCAST = 0xffff;
    public static readonly int WM_SHOWME = RegisterWindowMessage("WM_SHOWME");
    [DllImport("user32")]
    public static extern bool PostMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam);
    [DllImport("user32")]
    public static extern int RegisterWindowMessage(string message);

}

I know you guys are genius. Could someone tell me where should i make changes to that the selected files should be opened or rather how i should use postmessage.

Thanks for sharing your valuable time.

Regards

Irfan

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

美人迟暮 2024-08-24 03:09:23

请看我的评论(我想知道为什么你不在这里使用 Clipboard 类)。但忽略这一点:你为什么要广播这条消息?

您能否找到您的应用程序(通过名称、窗口类等)并仅将消息发送到您自己的应用程序


详细说明消息处理:
您在下面的评论中提到了关于 HWND_BROADCAST 的内容:

这只是全局句柄
我的应用程序。

不,不是。它是一个特殊值,告诉 Windows“此消息适用于所有应用程序”。您正在向所有应用程序发送WM_SHOWME。这就是为什么我问你为什么要这样做?

请参阅旧新事物博客上的这篇文章关于消息广播。

Please look at my comment (I wonder why you don't use the Clipboard class here). But ignoring that: Why do you broadcast the message?

Can you locate your application (by name, window class, whatever) and only send the message to your own application?


To elaborate on the message handling:
You say regarding HWND_BROADCAST in the comments below:

Thats nothing but the global handle to
my application.

No, it's not. It is a special value that tells Windows "this message is for all applications". You are sending a WM_SHOWME to all applications. Which is why I asked why you would want to do that?

Please see this post on the old new things blog regarding message broadcasts.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文