首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SendMessage问题

SendMessage问题
EN

Stack Overflow用户
提问于 2010-01-07 18:37:02
回答 1查看 3.4K关注 0票数 0

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

请看下面的图片,以获得更多的想法。

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

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

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

这个应用程序运行得很好。这里的主要问题是,在选择文件之后,所有这些文件都在各自的软件中打开。也就是说,如果我选择了word文档,那么文件名就会添加到FastCopy表单中,但是Word中也会打开文件名。

当我调查时,我发现这个问题是由SendMessage引起的。我必须使用PostMessage而不是SendMessage。但是当我这样做的时候,应用程序就不能工作了。

以下是我在C# 2005中的主要功能编码

代码语言:javascript
复制
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和其他代码的副本

公共部分类frmFastCopy :表单{委托无效AddItemToListDelegate(string );

代码语言:javascript
复制
    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类

代码语言:javascript
复制
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。

谢谢你分享宝贵的时间。

问候

埃尔凡

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2010-01-07 18:54:20

请看我的评论(我想知道为什么这里不使用剪贴板类)。但忽略了这一点:你为什么要广播这个信息?

您能否定位您的应用程序(按名称、窗口类等),并且只将消息发送给您自己的应用程序?

要详细说明消息处理:在下面的注释中提到关于HWND_BROADCAST的内容:

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

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

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2022694

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档