2017-02-23 55 views
0

中获取字符串我想解码从qCollector返回的消息。如何从已注册的窗口消息的lParam

http://www.mechtrading.com/developers/QCollectorDeveloperGuide_2.1.htm

在我的WndProc似乎收到了应有的lParam为一个字符串的消息,但它看起来像一个整数。也许它是一个指针?

我试过使用Marshal.PtrToStringAnsi(m.LParam))(见下面)但它没有任何变化给我一个非空的字符串。

Output: 
50483: QCOLLECTOR_CLIENT_PORTFOLIO_LIST_REQUEST 
50484: QCOLLECTOR_PORTFOLIO_LIST_REQUEST_COMPLETE 
50485: QCOLLECTOR_CLIENT_DATA_REQUEST 
50486: QCOLLECTOR_DATA_REQUEST_COMPLETE 
50487: QCOLLECTOR_CLIENT_REALTIME_SYMBOL_LIST_REQUEST 
50488: QCOLLECTOR_REALTIME_SYMBOL_LIST_REQUEST_COMPLETE 
50489: QCOLLECTOR_CLIENT_PORTFOLIO_ITEMS_REQUEST 
50490: QCOLLECTOR_PORTFOLIO_ITEMS_REQUEST_COMPLETE 
50491: QCOLLECTOR_CLIENT_REMOVE_REALTIME_SYMBOL_REQUEST 
50492: QCOLLECTOR_CLIENT_CLEAR_REALTIME_SYMBOLS 
50493: QCOLLECTOR_LAST_RECORD_UPDATE 
50494: QCOLLECTOR_REGISTER_FOR_LAST_RECORD_UPDATE 
50495: QCOLLECTOR_UNREGISTER_FOR_LAST_RECORD_UPDATE 
50496: QCOLLECTOR_FILE_UPDATE 
50497: QCOLLECTOR_ALL_FILES_UPDATED 
50498: QCOLLECTOR_REGISTER_FOR_FILE_UPDATES 
50499: QCOLLECTOR_UNREGISTER_FOR_FILE_UPDATES 
50501: QCOLLECTOR_DELETE_PORTFOLIO_ITEM 

SENT to: 13381044 From: 2438012 2438012 
Ans: 1 

Message: 
HWnd: 2438012 
LParam: 49440 
WParam: 0 
Msg: 50484 
String: 

如果您创建一个简单的表单应用程序有一个按钮,然后使用此代码:

using System; 
using System.Collections.Generic; 
using System.Data; 
using System.Diagnostics; 
using System.Linq; 
using System.Runtime.InteropServices; 
using System.Windows.Forms; 

namespace ApiMessageTest2 
{ 
    public partial class Form1 : Form 
    { 


     [DllImport("user32.dll", EntryPoint = "FindWindow")] 
     private static extern int FindWindow(string sClass, string sWindow); 

     [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] 
     static extern uint RegisterWindowMessage(string lpString); 

     [DllImport("user32.dll", CharSet = CharSet.Auto)] 
     static extern int SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam); 

     [DllImport("user32.dll")] 
     static extern bool PostMessage(IntPtr hWnd, uint Msg, int wParam, int lParam); 

     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      TestQC(); 
     } 

     int nWinHandle; 
     bool msgSent = false; 

     List<string> AtomsList = new List<string> { 
      "QCOLLECTOR_CLIENT_DATA_REQUEST", 
      "QCOLLECTOR_CLIENT_PORTFOLIO_LIST_REQUEST", 
      "QCOLLECTOR_PORTFOLIO_LIST_REQUEST_COMPLETE", 
      "QCOLLECTOR_CLIENT_PORTFOLIO_ITEMS_REQUEST", 
      "QCOLLECTOR_PORTFOLIO_ITEMS_REQUEST_COMPLETE", 
      "QCOLLECTOR_CLIENT_REALTIME_SYMBOL_LIST_REQUEST", 
      "QCOLLECTOR_REALTIME_SYMBOL_LIST_REQUEST_COMPLETE", 
      "QCOLLECTOR_DATA_REQUEST_COMPLETE", 
      "QCOLLECTOR_CLIENT_REMOVE_REALTIME_SYMBOL_REQUEST", 
      "QCOLLECTOR_DELETE_PORTFOLIO_ITEM", 
      "QCOLLECTOR_CLIENT_CLEAR_REALTIME_SYMBOLS", 
      "QCOLLECTOR_REGISTER_FOR_FILE_UPDATES", 
      "QCOLLECTOR_UNREGISTER_FOR_FILE_UPDATES", 
      "QCOLLECTOR_FILE_UPDATE", 
      "QCOLLECTOR_ALL_FILES_UPDATED", 
      "QCOLLECTOR_REGISTER_FOR_LAST_RECORD_UPDATE", 
      "QCOLLECTOR_UNREGISTER_FOR_LAST_RECORD_UPDATE", 
      "QCOLLECTOR_LAST_RECORD_UPDATE"}; 

     Dictionary<string, uint> Atoms = new Dictionary<string, uint>(); 

     public void RegisterAtoms() 
     { 
      foreach (var atom in AtomsList) 
      { 
       Atoms.Add(atom, RegisterWindowMessage(atom)); 
      } 

     } 

     public void ShowAtoms() 
     { 
      var sortedAtoms = Atoms.OrderBy(x => x.Value); 

      foreach (var pair in sortedAtoms) 
      { 
       Console.WriteLine(pair.Value.ToString() + ": " + pair.Key); 
      } 
     } 

     public void TestQC() 
     { 

      RegisterAtoms(); 
      ShowAtoms(); 
      System.Diagnostics.Process proc = Process.GetCurrentProcess(); 

      try 
      { 
       nWinHandle = FindWindow("QCDataInterfaceWndClass", null); 
      } 
      catch (Exception err) 
      { 
       throw; 
      } 

      if (nWinHandle == 0) 
      { 
       throw new Exception("Duff"); 
      } 


      msgSent = true; 
      int ans = SendMessage((IntPtr)nWinHandle, Atoms["QCOLLECTOR_CLIENT_PORTFOLIO_LIST_REQUEST"], IntPtr.Zero, this.Handle); 
      Console.WriteLine("SENT to: " + nWinHandle + " From: " + proc.MainWindowHandle + " " + this.Handle); 
      Console.WriteLine("Ans: "+ans); 
     } 

     protected override void WndProc(ref Message m) 
     { 
      if (msgSent) 
      { 

       if (Atoms.ContainsValue((uint)m.Msg) || m.LParam == new IntPtr(nWinHandle)) 
       { 
        Console.WriteLine("HWnd: " + m.HWnd.ToString()); 
        Console.WriteLine("LParam: " + m.LParam.ToString()); 
        Console.WriteLine("WParam: " + m.WParam.ToString()); 
        Console.WriteLine("Msg: " + m.Msg.ToString()); 
        Console.WriteLine("String: " + Marshal.PtrToStringAnsi(m.LParam)); 

       } 
      } 
      base.WndProc(ref m); 
     } 
    } 
} 
+0

哪个消息具体? – IInspectable

+0

@IInspectable我会将它添加到问题 – ManInMoon

+0

是的,它是一个整数,一个* atom *。你必须[捏住这个](http:// pinvoke。net/default.aspx/kernel32/GlobalGetAtomName.html)来获取与之关联的字符串。 –

回答

0

documentation you linked to

的QCollector数据接口依赖于Windows消息Windows Global Atom Table接受命令并与客户端程序交换信息。 原子是由Windows管理的文本字符串的引用,它可以被Windows程序用于共享信息。

...

QCOLLECTOR_PORTFOLIO_LIST_REQUEST_COMPLETE - QCollector节省投资组合列表到一个临时文件后,将会将发送该消息到请求该投资组合列表中的HWND。 lParam是一个Atom,它包含一个字符串值,它是组合列表文件的完整路径和文件名。 当SendMessage返回时,QCollector删除Atom。收到此消息后,客户端应用程序可以读取该文件以获取QCollector中当前投资组合的列表。

...

QCOLLECTOR_PORTFOLIO_ITEMS_REQUEST_COMPLETE - QCollector将这个消息发送给请求的投资组合项目列表窗口句柄。 lParam是一个持有一个字符串值的原子 - 由QCollector创建的投资组合项目列表文本文件的完整路径和文件名。 当SendMessage返回时,QCollector删除Atom。

...

QCOLLECTOR_REALTIME_SYMBOL_LIST_REQUEST_COMPLETE - QCollector将这个消息发送给请求列表窗口句柄。 lParam是一个Atom,它包含一个字符串值 - 列表文本文件的完整路径和文件名。 当SendMessage返回时,QCollector删除Atom。收到此消息后,您的应用程序可以读取该文件以获取有关QCollector定时更新列表中所有项目的信息。

对于您的应用程序收到的所有其他消息,以回复数据请求等等。

每MSDN文档:

About Atom Tables

字符串原子

当应用程序通过空终止字符串到GlobalAddAtomAddAtomGlobalFindAtom,和FindAtom功能,它们接收串原子(返回16位整数)。字符串原子具有以下属性:

  • 字符串原子的值在0xC000(MAXINTATOM)到0xFFFF的范围内。

  • 在搜索原子表中的原子名称时,情况并不重要。此外,整个字符串必须在搜索操作中匹配;没有子字符串匹配被执行。

  • 与字符串原子关联的字符串的大小不能超过255个字节。这个限制适用于所有原子功能。

  • 引用计数与每个原子名称相关联。每次将原子名称添加到表格中时计数都会增加,并且每次从原子名称中删除原子名称时递减。这可以防止相同字符串原子的不同用户破坏对方的原子名称。当原子名称的引用计数等于零时,系统将从表格中删除原子和原子名称。

...

原子表查询

应用程序可以确定一个特定的字符串是否已经在一个原子表通过使用FindAtomGlobalFindAtom或功能。这些函数在原子表中搜索指定的字符串,如果字符串在那里,则返回相应的原子。

应用程序可以使用的GetAtomNameGlobalGetAtomName函数从原子表中检索的原子名字符串,所提供的应用程序具有所寻求对应于串的原子。这两个函数都将指定原子的atom-name字符串复制到缓冲区,并返回被复制的字符串的长度。 GetAtomName从本地原子表中检索原子名称字符串,并且GlobalGetAtomName从全局原子表中检索原子名称字符串。

所以,你的情况,考虑到原子手柄在lParam值传递,您可以使用GlobalGetAtomName()检索字符串值:

检索与指定对应的字符串的副本全球原子。

例如:

using System; 
using System.Collections.Generic; 
using System.Data; 
using System.Diagnostics; 
using System.Linq; 
using System.Runtime.InteropServices; 
using System.Windows.Forms; 

namespace ApiMessageTest2 
{ 
    public partial class Form1 : Form 
    { 
     [DllImport("user32.dll", CharSet = CharSet.Auto)] 
     private static extern IntPtr FindWindow(string sClass, string sWindow); 

     [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] 
     static extern uint RegisterWindowMessage(string lpString); 

     [DllImport("user32.dll", CharSet = CharSet.Auto)] 
     static extern int SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam); 

     [DllImport("user32.dll")] 
     static extern bool PostMessage(IntPtr hWnd, uint Msg, int wParam, int lParam); 

     [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] 
     static extern uint GlobalGetAtomName(ushort nAtom, StringBuilder lpBuffer, int nSize); 

     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      TestQC(); 
     } 

     IntPtr nWinHandle; 

     Dictionary<string, uint> CommandMsgs = new Dictionary<string, uint>(); 
     Dictionary<uint, string> NotificationMsgs = new Dictionary<uint, string>(); 

     public void RegisterMessages() 
     { 
      List<string> Commands = new List<string> { 
       "QCOLLECTOR_CLIENT_DATA_REQUEST", 
       "QCOLLECTOR_CLIENT_PORTFOLIO_LIST_REQUEST", 
       "QCOLLECTOR_CLIENT_PORTFOLIO_ITEMS_REQUEST", 
       "QCOLLECTOR_CLIENT_REALTIME_SYMBOL_LIST_REQUEST", 
       "QCOLLECTOR_CLIENT_REMOVE_REALTIME_SYMBOL_REQUEST", 
       "QCOLLECTOR_DELETE_PORTFOLIO_ITEM", 
       "QCOLLECTOR_CLIENT_CLEAR_REALTIME_SYMBOLS", 
       "QCOLLECTOR_REGISTER_FOR_FILE_UPDATES", 
       "QCOLLECTOR_UNREGISTER_FOR_FILE_UPDATES", 
       "QCOLLECTOR_REGISTER_FOR_LAST_RECORD_UPDATE", 
       "QCOLLECTOR_UNREGISTER_FOR_LAST_RECORD_UPDATE"}; 

      foreach (var MsgName in Commands) 
      { 
       uint msg = RegisterWindowMessage(MsgName); 
       if (msg != 0) 
        CommandMsgs.Add(MsgName, msg); 
      } 

      List<string> Notifications = new List<string> { 
       "QCOLLECTOR_PORTFOLIO_LIST_REQUEST_COMPLETE", 
       "QCOLLECTOR_PORTFOLIO_ITEMS_REQUEST_COMPLETE", 
       "QCOLLECTOR_REALTIME_SYMBOL_LIST_REQUEST_COMPLETE", 
       "QCOLLECTOR_DATA_REQUEST_COMPLETE", 
       "QCOLLECTOR_FILE_UPDATE", 
       "QCOLLECTOR_ALL_FILES_UPDATED", 
       "QCOLLECTOR_LAST_RECORD_UPDATE"}; 

      foreach (var MsgName in Notifications) 
      { 
       uint msg = RegisterWindowMessage(MsgName); 
       if (msg != 0) 
        NotificationMsgs.Add(msg, MsgName); 
      } 
     } 

     public void ShowMessages() 
     { 
      var sortedCommands = CommandMsgs.OrderBy(x => x.Value); 

      foreach (var pair in sortedCommands) 
      { 
       Console.WriteLine($"{pair.Key}: {pair.Value}"); 
      } 

      var sortedNotifications = NotificationMsgs.OrderBy(x => x.Key); 

      foreach (var pair in sortedNotifications) 
      { 
       Console.WriteLine($"{pair.Value}: {pair.Key}"); 
      } 
     } 

     public void TestQC() 
     {  
      RegisterMessages(); 
      ShowMessages(); 

      System.Diagnostics.Process proc = Process.GetCurrentProcess(); 

      try 
      { 
       nWinHandle = FindWindow("QCDataInterfaceWndClass", null); 
      } 
      catch (Exception err) 
      { 
       throw; 
      } 

      if (nWinHandle == IntPtr.Zero) 
      { 
       throw new Exception("Duff"); 
      } 

      int ans = SendMessage(nWinHandle, CommandMsgs["QCOLLECTOR_CLIENT_PORTFOLIO_LIST_REQUEST"], IntPtr.Zero, this.Handle); 
      Console.WriteLine($"SENT to: {nWinHandle} From: {proc.MainWindowHandle} {this.Handle}"); 
      Console.WriteLine($"Ans: {ans}"); 
     } 

     protected override void WndProc(ref Message m) 
     { 
      string MsgName; 
      if (NotificationMsgs.TryGetValue((uint)m.Msg, MsgName)) 
      { 
       Console.WriteLine($"HWnd: {m.HWnd}"); 
       Console.WriteLine($"Msg: {m.Msg} ({MsgName})"); 
       Console.WriteLine($"WParam: {m.WParam}"); 
       Console.WriteLine($"LParam: {m.LParam}"); 

       if ((MsgName == "QCOLLECTOR_PORTFOLIO_LIST_REQUEST_COMPLETE") || 
        (MsgName == "QCOLLECTOR_PORTFOLIO_ITEMS_REQUEST_COMPLETE") || 
        (MsgName == "QCOLLECTOR_REALTIME_SYMBOL_LIST_REQUEST_COMPLETE") || 
        (MsgName == "QCOLLECTOR_DATA_REQUEST_COMPLETE") || 
        (MsgName == "QCOLLECTOR_FILE_UPDATE") || 
        (MsgName == "QCOLLECTOR_LAST_RECORD_UPDATE")) 
       { 
        StringBuilder sb = new StringBuilder(514); 
        GlobalGetAtomName((ushort)Msg.LParam, sb, sb.Capacity); 
        Console.WriteLine($"String: {sb.ToString()}");  
       } 
       else if (MsgName == "QCOLLECTOR_ALL_FILES_UPDATED") 
       { 
        Console.WriteLine($"# Updated: {Msg.LParam}");  
       } 
      } 
      base.WndProc(ref m); 
     } 
    } 
} 
相关问题