سؤال

أقوم بتطوير تطبيق باستخدام C # له وظيفة مماثلة للنسخ واللصق كما هو الحال في Windows. لقد أضفت عناصر قائمة ورتبطة بالتطبيقات المعنية.

يرجى إلقاء نظرة على الصورة التالية للحصول على المزيد من الفكرة.

البنود المضافة إلى القائمة Shell http://softwaregenius.net/myimages/menu.jpg

مثل تحديد عناصر متعددة في مستكشف Windows، تحتاج إلى تحديد ملفات و / أو مجلدات متعددة ثم حدد OS UTIL-> FastCopy. يتم فتح نموذج كما هو موضح أدناه

النموذج الموضح في FastCopy http://softwaregyius.net/myimages/fastcopy1.jpg

التطبيق يعمل تماما. المشكلة الرئيسية هنا هي أنه بعد تحديد الملفات يتم فتح جميع هذه الملفات داخل البرامج المعنية. هذا إذا قمت بتحديد مستند Word، فسيتم إضافة اسم الملف إلى FastCopy نموذج ولكن يفتح أيضا داخل Word أيضا.

عندما التحقق في أنني وجدت أن هذه المشكلة ترجع إلى sendmessage. لا بد لي من استخدام postmessage بدلا من sendmessage. ولكن عندما أفعل ذلك، فإن التطبيق لا يعمل.

أدناه هو ترميز وظيفتي الرئيسية في 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 وعن رمز آخر من داخل النموذج

الفئة الجزئية العامة Frmeftcopy: النموذج {مندوب باطلة additemtoleistdelegate (سلسلة 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.

شكرا لتقاسم وقتك الثمين.

يعتبر

عرفان

هل كانت مفيدة؟

المحلول

يرجى إلقاء نظرة على تعليقي (أتساءل لماذا لا تستخدم فئة الحافظة هنا). ولكن تجاهل ذلك: لماذا تبث الرسالة؟

يمكنك تحديد موقع التطبيق الخاص بك (حسب الاسم، فئة النافذة، أيا كان) وترسل فقط الرسالة إلى طلبك الخاص?


لتوضيح التعامل مع الرسالة: تقول فيما يتعلق ب HWND_Broadcast في التعليقات أدناه:

هذا ليس سوى المقبض العالمي لتطبيقي.

لا ليس كذلك. إنها قيمة خاصة تحكي Windows "هذه الرسالة مخصصة لجميع التطبيقات". أنت ترسل WM_SHOWME ل الكل التطبيقات. وهذا هو السبب في أنني سألت لماذا تريد أن تفعل ذلك؟

يرجى الاطلاع على هذا المنشور الأشياء القديمة الجديدة بلوق فيما يتعلق بث الرسائل.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top