2012-06-03 34 views
4

我正在創建剪貼板監視器作爲項目,並在剪貼板上更改應用程序,通過調用GetClipboardOwner來檢測哪個程序使用了剪貼板。獲取進程ID時出錯

這是從代碼的摘錄:

protected override void WndProc(ref Message m) 
     { 
      const int WM_DRAWCLIPBOARD = 0x308; 
      const int WM_CHANGECBCHAIN = 0x030D; 

      switch (m.Msg) 
      { 
       case WM_DRAWCLIPBOARD: 
        Debug.Indent(); 
        //Process the clipboard here 
        uint processId; 
        IntPtr ownerHwnd = GetClipboardOwner(); 
        GetWindowThreadProcessId(ownerHwnd, out processId); 
        Process proc = Process.GetProcessById((int)processId); 
        Debug.WriteLine(String.Format("Window Title: {0} Filename: {1}", proc.MainWindowTitle, process.MainModule.FileName)); 
        SendMessage(_NextClipboardViewer, m.Msg, m.WParam, m.LParam); 
        break; 

       case WM_CHANGECBCHAIN: 
        if (m.WParam == _NextClipboardViewer) 
         _NextClipboardViewer = m.LParam; 
        else 
         SendMessage(_NextClipboardViewer, m.Msg, m.WParam, m.LParam); 
        break; 

       default: 
        base.WndProc(ref m); 
        break; 
      } 
     } 

和DLLImports:

[DllImport("User32.dll")] 
     public static extern IntPtr SetClipboardViewer(IntPtr _newviewerhandle); 

[DllImport("User32.dll")] 
     public static extern bool ChangeClipboardChain(IntPtr removehandle, IntPtr nexthandle); 

[DllImport("User32.dll")] 
     public static extern int SendMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam); 

[DllImport("User32.dll")] 
     public static extern IntPtr GetClipboardOwner(); 

[DllImport("kernel32.dll")] 
     public static extern int GetWindowThreadProcessId(IntPtr handle, out uint threadid); 

在異常輸出窗口是 - 發生在東西類型「System.EntryPointNotFoundException」的第一次機會異常.exe

UPDATE 2將「Kernel32」更改爲「User32」後,它可以工作,但對於某些應用程序像Word,Excel,我得到這個例外; System.dll中發生類型'System.ComponentModel.Win32Exception'的第一次機會異常

任何想法?

UPDATE 3上述例外是因爲一個32位處理(我的應用程序)訪問造成一個64位進程的模塊(如Word,Excel等) 更改配置到x64工作。

回答

6

DllImportGetWindowThreadProcessId應該使用user32.dll,不kernel32.dll

每MSDN:http://msdn.microsoft.com/en-us/library/windows/desktop/ms633522(v=vs.85).aspx

或者乾脆使用PInvoke.Net:GetWindowThreadProcessId

+1

+1。爲了節省麻煩PInvoke.net是一個獲得DllImports的地方... –

+0

@AlexeiLevenkov良好的通話。我忘了那個網站:) – jglouie

+0

哇!謝謝。現在,我對此感到無聊和尷尬。 現在,我收到另一個錯誤...更新問題 – vs2010noob