我想让一个程序在后台运行,但是这个程序注册了好几个热键,把他的窗口隐藏了,按键盘那个窗口里还是有反应,查了以前的帖子,说是重复注册热键引起冲突,我试了试,发现无论先启动哪个程序,那个隐藏的窗口还是能接收到按键消息,没法屏蔽掉他的热键,后来我感觉用热键冲突不是很好,因为那个程序有10多个热键,都注册了是不是太。。??后来我看到了关于hook记录键盘事件的文章,我从codeproject上下载了代码加入了我的程序中,然后在键盘钩子程序里去掉了CallNextHookEx,这样就所有的键盘事件都没反映了,然后我的思路是查找当前活动的窗口,向他发送按键消息?不知道这个思路对不对?现在的问题是,我取道的当前活动窗口老是不对,用vs.net编译运行时查找的当前窗口竟然是vs.net ide。。请大家帮我想想办法
private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
{
  IntPtr hwnd = GetForegroundWindow();
// IntPtr hwnd = GetFocus(); 
IntPtr EdithWnd = new IntPtr(0); 
string lpszClass = "Edit";   EdithWnd = FindWindowEx(hwnd,EdithWnd,lpszClass,null);  // it was ok and someone listens to events
if ((nCode >= 0) && (KeyDown!=null || KeyUp!=null || KeyPress!=null))
{
KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct) Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
// raise KeyDown
if ( KeyDown!=null && ( wParam ==WM_KEYDOWN || wParam==WM_SYSKEYDOWN ))
{
Keys keyData=(Keys)MyKeyboardHookStruct.vkCode;
KeyEventArgs e = new KeyEventArgs(keyData);
// KeyDown(this, e);
SendMessage(EdithWnd,WM_KEYDOWN,(IntPtr)keyData,"0");
}

// raise KeyPress
if ( KeyPress!=null &&  wParam ==WM_KEYDOWN )
{
byte[] keyState = new byte[256];
GetKeyboardState(keyState); byte[] inBuffer= new byte[2];
if (ToAscii(MyKeyboardHookStruct.vkCode,
            MyKeyboardHookStruct.scanCode,
            keyState,
            inBuffer,
            MyKeyboardHookStruct.flags)==1) 
            {
             KeyPressEventArgs e = new KeyPressEventArgs((char)inBuffer[0]);
// KeyPress(this, e);
            }
}

// raise KeyUp
if ( KeyUp!=null && ( wParam ==WM_KEYUP || wParam==WM_SYSKEYUP ))
{
Keys keyData=(Keys)MyKeyboardHookStruct.vkCode;
KeyEventArgs e = new KeyEventArgs(keyData);
// KeyUp(this, e);
SendMessage(EdithWnd,WM_KEYUP,(IntPtr)keyData,"0");
} }
return -1;
}

解决方案 »

  1.   

    试试
    BOOL UnregisterHotKey
    (
        HWND hWnd,
        int id
    );
    先找到窗口句柄,然后循环 id 从1-100,应该够了吧,我不知道行不要不 hook  wm_hotkey消息,如果 是hwnd 是指定窗口的就屏蔽
      

  2.   

    刚才有一点进展把发送的消息改成这个,纪事本可以接收到,
    SendMessage(EdithWnd, WM_SETTEXT, (IntPtr)0, e.KeyData.ToString());但是显示的都是大写字符,数字也都带着D,连后退,和删除键都显示成字符了。。back 和 delete是不是edit控件不支持wm_keydown消息?
      

  3.   

    .Net的全局键盘钩子,很可惜只能使用低级键盘钩子来实现但问题在于低级键盘钩子,只能捕获键盘的虚拟键码所以你只能用MapVirtualKeyEx(API)自己转换。。但好像仍然不能控制大小写。。恩恩。。只能自己手动写处理了。
      

  4.   

    大小写应该是有标志为来标志的,好像是在lparam里