请教一个关于窗体自定义消息(传递消息)的问题(C#语言),请赐教

lpz89 2012-04-17 12:37:36
我先描述一下我的程序,这是一个浏览gif格式图片的查看器,打开gif文件时默认用该查看器查看,当该查看器已经打开的时候,再打开其他的gif格式文件,仍然以原查看器查看,并不是再次打开一个查看器。

起初我是用
public static extern int SendMessage(IntPtr hwnd, uint wMsg, IntPtr wParam, IntPtr lParam);
来传递消息,
我在主窗体中定义了一个方法
LoadImage(string fileName),用于加载目标gif文件,
在program类中定义了一个方法
private static void HandleRunningInstance(Process instance, string[] args)
{
if (args.Length > 0)
{
try
{
IntPtr lp = Marshal.StringToCoTaskMemAnsi(args[0] + "\0\0");
SendMessage(instance.MainWindowHandle, WM_USER + 1, IntPtr.Zero, lp);
//string fileName = Marshal.PtrToStringAnsi(lp);
//Log(lp.ToString() + "--" + fileName);
}
catch (Exception ex)
{
Log(ex.Message);
}
}
}

第一个参数是获取的已经打开的查看器的进程,第二个参数是入口Main(string[] args)方法的参数,args里包括目标Gif文件的文件名,
在主窗体中重写了方法:
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == WM_USER + 1)
{
try
{
string fileName = Marshal.PtrToStringAnsi(m.LParam);
Program.Log("WndProc获取到参数:" + fileName.ToString());
LoadImage(fileName.ToString());
}
catch (Exception ex)
{
Program.Log("error:" + ex.Message);
}
}
}
可是我用这种方法获取到的fileName是空值。。。


然后传递消息的方法改成了
public static extern int SendMessage(IntPtr HWnd, uint Msg, int WParam, ref Msg lParam);
对应代码:
private static void HandleRunningInstance(Process instance, string[] args)
{
if (args.Length > 0)
{
try
{
Msg msg = new Msg();
msg.FileName = args[0];
SendMessage(instance.MainWindowHandle, WM_USER + 1, 0, ref msg);
}
catch (Exception ex)
{
Log(ex.Message);
}
}
}


protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == WM_USER + 1)
{
try
{
Msg msg1 = new Msg();
Program.Log(msg1.GetType().ToString());
Msg msg = (Msg)m.GetLParam(msg1.GetType());
string fileName = msg.FileName;
Program.Log("WndProc获取到参数:" + fileName.ToString());
LoadImage(fileName.ToString());
}
catch (Exception ex)
{
Program.Log("error:" + ex.Message);
}
}
}

可是这样又没有取得msg,


我调试得到了LParam参数,可是参数转换成字符串不行,转换成结构也不行,这是怎么回事,请高手指教。
...全文
123 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
orochiheart 2012-04-18
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]
恭喜了 其实发消息蛮简单的就sendmessage和postmessage
[/Quote]
+1 学习!
wy811007 2012-04-18
  • 打赏
  • 举报
回复
恭喜了 其实发消息蛮简单的就sendmessage和postmessage
orochiheart 2012-04-18
  • 打赏
  • 举报
回复
恭喜!
lpz89 2012-04-18
  • 打赏
  • 举报
回复
问题已经解决:
使用的API函数是
[DllImport("user32.dll", SetLastError = true)]
public static extern int SendMessage(IntPtr HWnd, uint Msg, int WParam, ref COPYDATASTRUCT lParam);
COPYDATASTRUCT 结构的定义如下:
[StructLayout(LayoutKind.Sequential)]
public struct COPYDATASTRUCT
{
public IntPtr dwData;
public int cbData;
public IntPtr lpData;
}

部分代码如下:发送消息:
/// <summary>
/// 通过 SendMessage 向指定句柄发送数据
/// </summary>
/// <param name="hWnd"> 接收方的窗口句柄 </param>
/// <param name="dwData"> 附加数据< /param>
/// <param name="lpdata"> 发送的数据 </param>
public static int SendCopyData(IntPtr hWnd, int dwData, byte[] lpdata)
{
COPYDATASTRUCT cds = new COPYDATASTRUCT();
cds.dwData = (IntPtr)dwData;
cds.cbData = lpdata.Length;
cds.lpData = Marshal.AllocHGlobal(lpdata.Length);
Marshal.Copy(lpdata, 0, cds.lpData, lpdata.Length);
IntPtr lParam = Marshal.AllocHGlobal(Marshal.SizeOf(cds));
Marshal.StructureToPtr(cds, lParam, true);
int result = 0;
try
{
result = WindowsAPI.SendMessage(hWnd, WindowsAPI.WM_COPYDATA, dwData, ref cds);
}
finally
{
Marshal.FreeHGlobal(cds.lpData);
Marshal.DestroyStructure(lParam, typeof(COPYDATASTRUCT));
Marshal.FreeHGlobal(lParam);
}
return result;
}

接收处理消息:
protected override void WndProc(ref Message m)
{
if (m.Msg == WindowsAPI.WM_COPYDATA)
{
COPYDATASTRUCT cds = (COPYDATASTRUCT)Marshal.PtrToStructure(m.LParam, typeof(COPYDATASTRUCT));
int dwData = cds.dwData.ToInt32();
if (dwData == WindowsAPI.WM_OPENNEWFILE)
{
byte[] lpData = new byte[cds.cbData];
Marshal.Copy(cds.lpData, lpData, 0, cds.cbData);
string fileName = Encoding.UTF8.GetString(lpData);
LoadImage(fileName);
}
m.Result = (IntPtr)0;
}
else
{
base.WndProc(ref m);
}
}

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧