2017-12-27 3 views
-1

현재 프로세스 인 뷰어를 설정했으며 메시지를 수신하려고합니다. WM_DRAWCLIPBOARD.WinApi C#에서 클립 보드 이벤트를 구독하는 방법?

[DllImport("User32.dll", CharSet = CharSet.Auto)] 
public static extern IntPtr SetClipboardViewer(IntPtr hWndNewViewer); 

var result = WinapiClipboard.SetClipboardViewer(Process.GetCurrentProcess().Handle); 

그것은 내가 그 메시지를 구문 분석하는 애플리케이션 정의 함수를 사용해야하는 right here 말한다. 그러나 결코 함수/메소드에 영향을 미치지 않습니다.

private static IntPtr WndProc(IntPtr hWnd, uint message, IntPtr wParam, IntPtr lParam) 
    { 
     var hdc = Process.GetCurrentProcess().Handle; 
     var clipboard = new WinClipboard(); 

     switch (message) 
     { 
      case WinapiClipboard.WM_DRAWCLIPBOARD: 
       var result = clipboard.GetUnicodeTextAsync().Result; 


       return IntPtr.Zero; 
      default: 
       break; 
     } 
     return WinapiClipboard.DefWindowProc(hWnd, message, wParam, lParam); 
    } 

어떻게해야합니까? 나는 심지어 정확하게 구독하고 있는가?

UPDATE :

내가 윈폼/WPF 또는 그 .NET 고전적인 프레임 워크의 기능 중 하나를 사용하고 있지 않다. 내가 가진 모든 .net 표준 2.0 또는 .net 코어.

+1

는 [SetClipboardViewer] (https://msdn.microsoft.com/en-us/library/windows/desktop/ms649052.aspx)는 ** 창 ** 핸들,하지를 기대 ** 프로세스 ** 처리. 창 핸들이없는 경우 유일한 목적으로 [메시지 전용 창] (https://msdn.microsoft.com/en-us/library/windows/desktop/ms632599.aspx#message_only)을 만듭니다. 클립 보드 메시지를 수신 중입니다. – IInspectable

+1

이것은 항상 전체 프레임 워크를 사용할 수있는 종류의 기계에서만 작동합니다. 따라서 .netcore/standard를 목표로하는 것은 무의미한 방법으로 여러분의 삶을 복잡하게 만듭니다. 음, 우리. –

답변

0

이 윈폼 응용 프로그램에서 모든 꽤 똑바로 앞을 향해 열린 길을 건너입니다

: 당신은

를 선언 (어떤 쉽게) 콘솔 응용 프로그램에서이 작업을 수행하지 못할

[DllImport("User32.dll", CharSet=CharSet.Auto)] 
public static extern IntPtr SetClipboardViewer(IntPtr hWndNewViewer); 
양식 생성자에서 63,210

그런 다음 폼에서의 WndProc

재정 의하여 양식의 WM_DRAWCLIPBOARD 메시지를받을

// this.handle is your forms handle 
_ClipboardViewerNext = SetClipboardViewer(this.Handle); 

protected override void WndProc(ref Message m) 
{ 
    switch ((Win32.Msgs)m.Msg) 
    { 
     case Win32.Msgs.WM_DRAWCLIPBOARD: 
     // Handle clipboard changed 
     break; 
     // ... 
    } 

    // we call this so we to pass the message along 
    base.WndProc(ref m); 
} 


Anothe 연구 방법은

은 양식 생성자에서이

public const int WM_CLIPBOARDUPDATE = 0x031D; 
public static IntPtr HWND_MESSAGE = new IntPtr(-3); 

[DllImport("user32.dll", SetLastError = true)] 
[return: MarshalAs(UnmanagedType.Bool)] 
public static extern bool AddClipboardFormatListener(IntPtr hwnd); 

[DllImport("user32.dll", SetLastError = true)] 
public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent); 

선언이를하고 어쩌면 더 현대적인 접근 양식에

SetParent(Handle, HWND_MESSAGE); 
AddClipboardFormatListener(Handle); 

protected override void WndProc(ref Message m) 
{ 
    if (m.Msg == WM_CLIPBOARDUPDATE) 
    { 
     // handle message 
    } 
    base.WndProc(ref m); 
} 
당신은 클래스 라이브러리를 사용하는 경우

당신은이 숨겨 생성하고 액션이나 이벤트를 다시 전달해야합니다

private class HiddenForm : Form 
{ 
    public HiddenForm() 
    { 
     SetParent(Handle, HWND_MESSAGE); 
     AddClipboardFormatListener(Handle); 
    } 

    protected override void WndProc(ref Message m) 
    { 
     if (m.Msg == WM_CLIPBOARDUPDATE) 
     { 
      // do stuff here like call event 
     } 
     base.WndProc(ref m); 
    } 
} 

:이 중에 있지만 테스트되지는

을 시작한다

업데이트 1

SetClipboardViewer은 프로세스 핸들이 아닌 창 핸들을 필요로합니다. 에 IInspectable

업데이트 2

이 의지를 감사 - 당신이 창 핸들이없는 경우, 클립 보드 메시지 수신의 목적을위한 메시지 전용 창을 만들 항상 전체 프레임 워크를 사용할 수있는 종류의 기계에서만 작동합니다.- 감사 한스 옆모습에

+0

그래, 그게 문제 야 - 표준 2.0 클래스 라이브러리 인 winforms 프로젝트를 사용하고 있지 않다. –

+0

@DThr. 자신 만의 숨겨진 양식을 만들 수 있습니다. –

+0

흠. 그게 효과가있다. 그러나 어떤 형식도없이 그것을 할 수는 없습니까? –

0

winforms 프로젝트를 수행 할 때 정적이 아닌 기존 Control.WndProc를 재정의합니다.

protected override void WndProc(ref Message m) 
{ 
if(WM_DRAWCLIPBOARD == msg.Msg) 
{ ... } 
else 
    base.WndProc(ref msg); 
} 
+0

winforms 프로젝트를 사용하고 있지 않습니다. 표준 2.0 클래스 라이브러리입니다. –