2010-07-20 8 views
7

나는 다른 응용 프로그램이 보내는 메시지을 가로 채기해야하는 C# 응용 프로그램을 작성하고 있습니다. 모니터링하는 응용 프로그램을 작성한 회사에서 예제 코드를 보냈지 만 C++에서는 실제로 알지 못합니다. 나는 그들이 다음 코드를 사용하여 가지고 한 C++ 예제 코드에서 특정 응용 프로그램에서 Windows 메시지 캡처

: 나는 그것을이 알고있는 것처럼

UINT uMsg = RegisterWindowMessage(SHOCK_MESSAGE_BROADCAST); 
ON_REGISTERED_MESSAGE(WM_SHOCK_BROADCAST_MESSAGE, OnShockStatusMessage) 
LRESULT OnShockStatusMessage(WPARAM wParam, LPARAM lParam); 

는 우리가 듣고 싶은 특정 메시지에 대한 윈도우에서 ID를 검색합니다. 그런 다음 우리는 ID와 일치하는 메시지가 도청 될 때마다 OnShockStatusMessage으로 C++에 요청합니다. 연구의 조금 나는이 같은 기본적인 일을해야 이해하는 바와 같이한다는 점에서, C#

[DllImport("user32.dll", SetLastError = true)] 
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); 

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

private IntPtr _hWnd; // APS-50 class reference 
private List<IntPtr> _windowsMessages = new List<IntPtr>(); // APS-50 messages 

private const string _className = "www.AuPix.com/SHOCK/MessageWindowClass"; 

// Windows Messages events 
private const string _messageBroadcast = "www.AuPix.com/SHOCK/BROADCAST"; 
private const string _messageCallEvents = "www.AuPix.com/SHOCK/CallEvents"; 
private const string _messageRegistrationEvents = "www.AuPix.com/SHOCK/RegistrationEvents"; 
private const string _messageActions = "www.AuPix.com/SHOCK/Actions"; 

private void DemoProblem() 
{ 
    // Find hidden window handle 
    _hWnd = FindWindow(_className, null); 

    // Register for events 
    _windowsMessages.Add(new IntPtr(RegisterWindowMessage(_messageActions))); 
    _windowsMessages.Add(new IntPtr(RegisterWindowMessage(_messageBroadcast))); 
    _windowsMessages.Add(new IntPtr(RegisterWindowMessage(_messageCallEvents))); 
    _windowsMessages.Add(new IntPtr(RegisterWindowMessage(_messageRegistrationEvents))); 
} 

protected override void WndProc(ref Message m) 
{ 
    base.WndProc(ref m); 

    // Are they registered Windows Messages for the APS-50 application? 
    foreach (IntPtr message in _windowsMessages) 
    { 
     if ((IntPtr)m.Msg == message) 
     { 
      Debug.WriteLine("Message from specified application found!"); 
     } 
    } 

    // Are they coming from the APS-50 application? 
    if (m.HWnd == shock.WindowsHandle) 
    { 
     Debug.WriteLine("Message from specified application found!"); 
    } 

} 

을에서 다음과 같은 조립 한 후에

는 :

  1. 응용 프로그램 I를 찾습니다 모니터하기를 원합니다
  2. 창 메시지를 등록합니다. 가로 채기를 원합니다.
  3. 모든 창 메시지를 확인한 다음, 필요한 메시지를 제거합니다.
  4. 특정 메시지 또는 I 모니터링있어 응용 프로그램에서 모든 메시지의 절편 내 검사의 어느 것도 의 WndProc() 방법의 내 재정에서 그러나

.

내가 들어온 모든 메시지에 대해 Debug.WriteLine 인 경우, 해당 메시지가 모니터링되고 있음을 알 수 있습니다. 그러나 내가 원하는 메시지는 걸러 내 지 않습니다.

C++로 작성된 예제 모니터링 응용 프로그램을 실행하면 해당 Window 메시지가 전송되고 선택되는 것을 볼 수 있습니다. 단지 C# 구현이 동일하지 않습니다.

답변

1

다른 응용 프로그램을 보내려면 PostMessage 내 응용 프로그램에 창 메시지를 보내달라고 요청해야합니다.

PostMessage((int)_hWnd, _windowsMessages[0], SHOCK_REQUEST_ACTIVE_CALLINFO, (int)_thisHandle); 
PostMessage((int)_hWnd, _windowsMessages[0], SHOCK_REQUEST_ALL_REGISTRATIONINFO, (int)_thisHandle); 
PostMessage((int)_hWnd, _windowsMessages[0], SHOCK_REQUEST_CALL_EVENTS, (int)_thisHandle); 
PostMessage((int)_hWnd, _windowsMessages[0], SHOCK_REQUEST_REGISTRATION_EVENTS, (int)_thisHandle); 

하지 꽤 코드,하지만 충분이 내가 지금 필요한 모든 인 작동 증명 :

0

나는 문제가 RegisterWindowMessage()에 대한 P/Invoke 정의에 있다고 생각합니다.

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

차이를해야하는 대신 IntPtr의 반환 값으로 uint 사용 : pinvoke.net는 다음을 사용하여 제안합니다. 일반적으로 반환 값이 핸들 (예 : HWND 또는 HANDLE) 인 경우 IntPtr을 사용하려고하지만 반환 값을 C# 형식으로 직접 변환 할 수 있으면 해당 형식을 사용하는 것이 좋습니다.

+0

당신이 준 예제 코드는 내가 지금 사용하고 무엇을 실제로 :) –

+0

@Peter 아, 그리워. 왜 IntPtr 목록을 만들었습니까? 왜 그냥 그것을 만들지 목록 ? – Andy

+0

다른 웹 사이트에서 [DllImport] 문을 복사하여 차이가 있는지 확인하는 것이 좋겠지 만 각각에 약간의 차이가있었습니다. –

관련 문제