0

Windowsと同様のコピー、貼り付け機能を持つC#を使用してアプリケーションを開発しています。メニュー項目を追加し、それぞれのアプリケーションとリンクしました。

詳細については、次の画像をご覧ください。

シェルメニューに追加されたアイテム http://softwaregenius.net/myimages/menu.jpg

Windows エクスプローラーで複数の項目を選択するように、複数のファイルやフォルダーを選択してから、[OS Util] -> [FastCopy] を選択する必要があります。以下のようにフォームが開きます

FastCopy に表示されるフォーム http://softwaregenius.net/myimages/fastcopy1.jpg

アプリケーションは完全に機能しています。ここでの主な問題は、ファイルを選択した後、これらすべてのファイルがそれぞれのソフトウェア内で開かれることです。つまり、Word 文書を選択すると、ファイル名が FastCopy フォームに追加されますが、Word 内でも開かれます。

調査したところ、この問題は SendMessage が原因であることがわかりました。SendMessage の代わりに PostMessage を使用する必要があります。しかし、そうすると、アプリケーションが機能しません。

以下は、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);
    }
}

}


以下は、フォーム内の WndProc およびその他のコードのコピーです。

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

これが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);

}

私はあなたたちが天才であることを知っています。選択したファイルを開く必要がある場所を変更する必要があるか、またはポストメッセージをどのように使用する必要があるかを誰かに教えてもらえますか。

貴重な時間を共有していただきありがとうございます。

よろしく

イルファン

4

1 に答える 1

1

私のコメントを見てください (なぜここで Clipboard クラスを使用しないのだろうか)。しかし、それを無視して: なぜメッセージをブロードキャストするのですか?

アプリケーションを (名前、ウィンドウ クラスなどで) 見つけて、自分のアプリケーションだけにメッセージ送信できますか?


メッセージ処理について詳しく説明するには: 以下のコメントで HWND_BROADCAST について述べます。

それは私のアプリケーションへのグローバルハンドルに他なりません。

いいえ、ちがいます。Windows に「このメッセージはすべてのアプリケーション用です」と伝える特別な値です。すべてのアプリケーションに を送信しWM_SHOWMEています。なぜそれをしたいのかと聞いたのはなぜですか?

メッセージ ブロードキャストについては、古い新しいものに関するブログのこの投稿を参照してください。

于 2010-01-07T18:54:20.333 に答える