مشكلة مع sendmessage.
-
19-09-2019 - |
سؤال
أقوم بتطوير تطبيق باستخدام 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
ل الكل التطبيقات. وهذا هو السبب في أنني سألت لماذا تريد أن تفعل ذلك؟
يرجى الاطلاع على هذا المنشور الأشياء القديمة الجديدة بلوق فيما يتعلق بث الرسائل.