2013-05-18 101 views
1

使用C++,我花了很多時間已經嘗試解決這個問題。這段代碼來自一個工作程序,我用C#重寫了它,但是有些事情我不明白。C++ SendMessage嘗試接收字符串

下面的代碼正是我按「Step Into」時運行的代碼。它是如何從:: SendMessage(...)到:: OnCopyData(..)與pCopyDataStruct現在包含數據?

的main.cpp

void COTP::main() 
{ 
    //string will be returned using WM_COPYDATA message 
    ::SendMessage(hWnd, 33508, (WPARAM)GetSafeHwnd(), 11); 

    // WPARAM is a typedef for UINT_PTR which is an unsigned int. 
} 

afxwin2.inl

_AFXWIN_INLINE HWND CWnd::GetSafeHwnd() const 
    { return this == NULL ? NULL : m_hWnd; } 

的main.cpp

BOOL COTP::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct) 
{ 
    CString str, str2; 

    switch (pCopyDataStruct->dwData) 
    { 
     case JRC_COPYDATA_ID_TRACK_FILENAME: 
      str = (LPCTSTR)pCopyDataStruct->lpData; 
      break; 
    } 
} 

任何幫助超級讚賞,我已經看過直通所有MSDN文檔,我可以今晚,它看起來像我在某處丟失了簡單的東西。認爲這可能是一個回調,但這似乎並不正確。

+0

當您在調試器中的OnCopyData中時,您的堆棧看起來像什麼? –

+0

您需要了解Windows消息泵(SendMessage將打入Windows的呼叫,並且最終的功能取決於泵在應用程序中的連接方式)以及MFC如何設計使用它們。 「未記錄的MFC」一書很好地解釋了這一點。 –

+0

調用堆棧是我所需要的,謝謝。 LRESULT CALLBACK是第一個:)。這部分看起來可能需要一段時間才能轉換爲C#。 – Drew

回答

1

好吧現在想通了。在this pagehere的幫助下。以下是我目前用於C#的內容。這絕不是完成的代碼,但這確實起作用,並且對於學習目的而言是有益的。

點擊計算按鈕,

[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] 
    public static extern IntPtr GetActiveWindow(); 

    private void btnCalculate_Click(object sender, EventArgs e) 
    { 
     int hwnd = 0; 
     hwnd = Win32.FindWindow("The App pulling from", "Window"); 

     int s = (int)GetActiveWindow(); 
     int s3 = Win32.SendMessage(hwnd, 33508, s, 11); 

那麼什麼情況是出現回調,並激活的WndProc(參考消息M),

protected override void WndProc(ref Message m) 
    { 
     // Prevents error creating window handle message. 
     base.WndProc(ref m); 

     // WM_COPYDATA 
     // m.Msg = 0x4a 
     //msg=0x4a (WM_COPYDATA) hwnd=0x251e62 wparam=0x69063e lparam=0x1c42cca0 result=0x0 
     if (m.Msg == 0x4a) 
     { 
      Console.WriteLine(m); 
      WndProc(m.HWnd, m.Msg, m.WParam, m.LParam); 
     } 
    } 

    public struct CopyDataStruct : IDisposable 
    { 
     public IntPtr dwData; 
     public int cbData; 
     public IntPtr lpData; 

     public void Dispose() 
     { 
      if (this.lpData != IntPtr.Zero) 
      { 
       LocalFree(this.lpData); 
       this.lpData = IntPtr.Zero; 
      } 
     } 
    } 

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] 
    public unsafe struct DataStruct 
    { 
     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 300)] 
     public string s; 
     public double d; 
     public char c; 
    }; 

    protected void WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam) 
    { 
     CopyDataStruct cps = (CopyDataStruct)Marshal.PtrToStructure(lParam, typeof(CopyDataStruct)); 
     DataStruct data = (DataStruct)Marshal.PtrToStructure(cps.lpData, typeof(DataStruct)); 
     // data.s is what we needed. 
     Console.WriteLine(data.s); 
    } 

非常感謝大家,回答!如果不是你的幫助,我相信我會放棄。 :)

2

該代碼正在向特定窗口發送消息(33508)。顯然,接收窗口通過發送WM_COPYDATA消息來處理該消息,該消息是HWND您在原始SendMessage()調用中通過了WPARAM。它基本上實現了回調機制。

原始消息號(33508)不是標準的Win32消息(至少不是我認識的),所以它可能是一個自定義消息。而且,它使用WM_COPYDATA進行響應的事實表明接收窗口處於不同的進程中(即,不屬於您的應用程序)。