你的应用不必这么麻烦,你只要使用RegisterHotKey就解决了。

解决方案 »

  1.   

    不好意思,看SDK像看一头雾水一样
      

  2.   

    你的程序完全好使,我已经试过了,我改了一下你的运行文件,改为我自己任选的一个可执行文件,是不是你的可执行文件mp.exe有问题.
      

  3.   

    legerwu(Leger) ,多谢了!!
     你一定要找出错误的原因啊!!
      

  4.   

    我觉得用RegisterHotKey好多啦。何必呢。程序的速度也好慢些哦,
      

  5.   

    参考我曾经写的dll代码:///////////////////////
    #include "windows.h"#pragma data_seg("Shared")
    static UINT g_uMessage=NULL;
    static HWND g_hWnd=NULL;
    #pragma data_seg() 
    #pragma comment(linker,"/section:Shared,rws")HINSTANCE g_hinstDll = NULL;
    HHOOK g_hhook      = NULL;LRESULT WINAPI KeyboardHook_HookProc (
       int nCode,
       WPARAM wParam, 
       LPARAM lParam) 
    {
    if(nCode==HC_ACTION)
    {
    if (IsWindow(g_hWnd))
    {
    ::SendMessage(g_hWnd,g_uMessage,wParam,lParam);
    return 0;
    }

    }
    return CallNextHookEx(g_hhook,nCode,wParam,lParam);
    }void StartHook(HWND h,UINT uMessage) 
    {
    g_uMessage=uMessage;
    g_hWnd=h;
    g_hhook=SetWindowsHookEx(WH_KEYBOARD,
    KeyboardHook_HookProc,g_hinstDll,0); if (g_hhook==NULL)
    MessageBox(0,"start err","",MB_OK);
    }void ReleaseHook() 
    {
       if (g_hhook != NULL) 
       {
          UnhookWindowsHookEx(g_hhook);
          g_hhook = NULL;
       }
    }
    BOOL WINAPI DllMain (HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved) 
    {
       switch (fdwReason) 
       {
          case DLL_PROCESS_ATTACH:
             g_hinstDll = hinstDll;
             break;
       }
       return(TRUE);
    }
      

  6.   

    我帮你找到了,失去焦点就不行的原因就是你的这行:
    MouseglhHook=SetWindowsHookEx(WH_MOUSE,MouseProc,glhInstance,0);glhInstance应该传入的是 dll本身的instance,
    即DllMain里的 hInstance,请参考我上面的代码。。(其中要运用一些编译选项,目的是保存dll中的全局变量)
      

  7.   

    我跟踪了一下,发现你的程序确实没有问题,问题出在WinExec函数上,如果你把该行语句改为其他,如:MessageBox则没有任何问题,按键消息任然可以得到,我想这是因为当主程序失去焦点时,WinExec因为无法继承主程序的资源,所以无法启动.
      

  8.   

    哦,不用编译选项也可以就是,
    用一个全局变量保存 DllMain的 hInstance,
    然后在set hook mouse 或者 hook keybd 时传入
    ----------------------
    搞定了记得加我分哦~~~
      

  9.   

    nne998兄:    我使用了你的方法,仍然不行!    你说的编译选项,是指哪些?
      

  10.   

    所以,你的dll可以这样修改://加入一个全局变量
    HINSTANCE g_hinstDll = NULL;  
    //dllmain里这样
    int WINAPI DllMain(HINSTANCE hInstance,DWORD fdwReason,PVOID pvReserved)
    {
        switch (fdwReason) 
       {
          case DLL_PROCESS_ATTACH:
             g_hinstDll = hInstance;
             break;
       }
       return(TRUE);
    }
    //sethook就没必要要第二个参数了
    VOID SetHook(UINT handletype)
    {
        if (handletype==0)
        {
            UnhookWindowsHookEx (KeyboardglhHook);
            UnhookWindowsHookEx (MouseglhHook);
        }
        else if (handletype==1)
        {
            KeyboardglhHook=SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, g_hinstDll, 0);
            MouseglhHook=SetWindowsHookEx(WH_MOUSE,MouseProc,g_hinstDll,0);
        }
    }
    //搞定咯。。
      

  11.   

    nne998的方法还是不行,问题仍然是出在WinExec无法启动新的进程,我建议eEric(Paranoia)采用其他启动可执行文件的方法,如CreateProcess().
      

  12.   

    痛快,痛快!我极少上CSDN网站,今天才知道确实有几个高手,彼此讨论,真是痛快.
      

  13.   

    我已经测试成功了!
    改了一些地方,下面是原程序:///////////////////////////程序:
    #include "windows.h"
    //==================================================================
    static char szAppName[]="ONOWinMain";
    static HINSTANCE hinstDLL; 
    typedef void (* SETHOOK)(UINT iType);  //此地方改动过
    SETHOOK SetHookAlias=NULL;
    BOOL flag=FALSE;
    //=====================================================================
    LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
    ATOM MyRegisterClass(HINSTANCE hInstance);
    BOOL InitInstance(HINSTANCE, int);
    BOOL SetHook(UINT handletype);
    //=====================================================================
    int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
    {
        MSG         msg ;
        MyRegisterClass(hInstance);    
        if(!InitInstance(hInstance,iCmdShow))
        {
            return FALSE;
        } 
        while (GetMessage (&msg, NULL, 0, 0))
        {
            TranslateMessage (&msg) ;
            DispatchMessage (&msg) ;
        }
        return msg.wParam ;
    }
    ATOM MyRegisterClass(HINSTANCE hInstance)
    {
        WNDCLASSEX  wndclass ;
        wndclass.cbSize = sizeof (wndclass) ;
        wndclass.style = CS_HREDRAW | CS_VREDRAW ;
        wndclass.lpfnWndProc = WndProc ;
        wndclass.cbClsExtra = 0 ;
        wndclass.cbWndExtra = 0 ;
        wndclass.hInstance = hInstance ;
        wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
        wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
        wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
        wndclass.lpszMenuName = NULL ;
        wndclass.lpszClassName = szAppName ;
        wndclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION) ;
        return RegisterClassEx (&wndclass) ;
    }
    BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
    {
        HWND        hwnd ;
        hwnd = CreateWindow (szAppName, "Project",
                              WS_OVERLAPPEDWINDOW,
                              CW_USEDEFAULT, CW_USEDEFAULT,
                              CW_USEDEFAULT, CW_USEDEFAULT,
                              NULL, NULL, hInstance, NULL) ;
        if(!hwnd)
        {
            return FALSE;
        }
        ShowWindow (hwnd, SW_MINIMIZE) ;
        UpdateWindow (hwnd) ;
        hinstDLL = LoadLibrary((LPCTSTR) "Pdll.dll");
        if (hinstDLL)
        {
            flag=TRUE;
            SetHookAlias=(SETHOOK)GetProcAddress(hinstDLL,"SetHook");
            if (SetHookAlias)
            {
                SetHookAlias(1);    //此地方改动过
            }
    else
    {
    MessageBox(hwnd,"error getting function \"SetHook\"","Error!",0);
    }
        }
        else
            MessageBox(hwnd,"can't fint the dll!","Error!",0);
        return TRUE;
    }
    LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
    {
        switch (iMsg)
        {
            case WM_CREATE :
                break;
            case WM_DESTROY :
                if(flag)
                    SetHookAlias(0);    //此地方改动过
                PostQuitMessage (0) ;
                return 0 ;
        }
        return DefWindowProc (hwnd, iMsg, wParam, lParam) ;
    }
    /////////////////////////// dll代码:
    #include<windows.h>HHOOK KeyboardglhHook,MouseglhHook;
    VOID SetHook(UINT handletype,HINSTANCE glhInstance);
    LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);
    LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam);HINSTANCE g_hinstDll = NULL;   //此地方改动过int WINAPI DllMain(HINSTANCE hInstance,DWORD fdwReason,PVOID pvReserved)
    {
        //此地方改动过
        switch (fdwReason)    
       {
          case DLL_PROCESS_ATTACH:
             g_hinstDll = hInstance;
             break;
       }
    return true;
    }void SetHook(UINT handletype)
    {
        if (handletype==0)
        {
            UnhookWindowsHookEx (KeyboardglhHook);
            UnhookWindowsHookEx (MouseglhHook);
        }
        else if (handletype==1)
        {
            //此地方改动过
            KeyboardglhHook=SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, g_hinstDll, 0);
            MouseglhHook=SetWindowsHookEx(WH_MOUSE,MouseProc,g_hinstDll,0);
        }
    }
    LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) 

    if(nCode==HC_ACTION)
    {
                      //此地方改动过,用了MessageBox测试
    if (wParam ==VK_UP)
    MessageBox(0,"sdfsfsd","df",MB_OK); 
    //return 0;
    }
        
        return CallNextHookEx(KeyboardglhHook, nCode, wParam, lParam); 

    LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam) 

        if (nCode < 0)
            return CallNextHookEx(MouseglhHook, nCode, wParam, lParam); 
        return CallNextHookEx(MouseglhHook, nCode, wParam, lParam); 
    }
    ---------------------
    //OK!!!!!!!!!!!!!
      

  14.   

    如果用WinExec也行吗?用消息框我早已经解决问题了.
      

  15.   

    WinExec当然行了。就像我前几贴所说的他原来的代码是很有问题。。
    没对比过我改过的地方吗??现在就算失去焦点也行了我测试过了。
      

  16.   

    好吧,再贴上最后修改的代码附上详细一点的注释///////////////////////////程序:
    #include "windows.h"
    //==================================================================
    static char szAppName[]="ONOWinMain";
    static HINSTANCE hinstDLL; //修改前:typedef VOID (* SETHOOK)(int,HINSTANCE);
    //修改后: SetHook的参数变为一个
    typedef void (* SETHOOK)(UINT iType);  SETHOOK SetHookAlias=NULL;
    BOOL flag=FALSE;
    //=====================================================================
    LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
    ATOM MyRegisterClass(HINSTANCE hInstance);
    BOOL InitInstance(HINSTANCE, int);
    //BOOL SetHook(UINT handletype); //这行没用,注释掉
    //=====================================================================
    int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
    {
        MSG         msg ;
        MyRegisterClass(hInstance);    
        if(!InitInstance(hInstance,iCmdShow))
        {
            return FALSE;
        } 
        while (GetMessage (&msg, NULL, 0, 0))
        {
            TranslateMessage (&msg) ;
            DispatchMessage (&msg) ;
        }
        return msg.wParam ;
    }
    ATOM MyRegisterClass(HINSTANCE hInstance)
    {
        WNDCLASSEX  wndclass ;
        wndclass.cbSize = sizeof (wndclass) ;
        wndclass.style = CS_HREDRAW | CS_VREDRAW ;
        wndclass.lpfnWndProc = WndProc ;
        wndclass.cbClsExtra = 0 ;
        wndclass.cbWndExtra = 0 ;
        wndclass.hInstance = hInstance ;
        wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
        wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
        wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
        wndclass.lpszMenuName = NULL ;
        wndclass.lpszClassName = szAppName ;
        wndclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION) ;
        return RegisterClassEx (&wndclass) ;
    }
    BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
    {
        HWND        hwnd ;
        hwnd = CreateWindow (szAppName, "Project",
                              WS_OVERLAPPEDWINDOW,
                              CW_USEDEFAULT, CW_USEDEFAULT,
                              CW_USEDEFAULT, CW_USEDEFAULT,
                              NULL, NULL, hInstance, NULL) ;
        if(!hwnd)
        {
            return FALSE;
        }
        ShowWindow (hwnd, SW_MINIMIZE) ;
        UpdateWindow (hwnd) ;
        hinstDLL = LoadLibrary((LPCTSTR) "Pdll.dll");
        if (hinstDLL)
        {
            flag=TRUE;
            SetHookAlias=(SETHOOK)GetProcAddress(hinstDLL,"SetHook");
            if (SetHookAlias)
            {
                //这里。修改前:SetHookAlias(1,hinstDLL);
                SetHookAlias(1); 
            }
            else
            {
                //如果取调用函数失败。。
                MessageBox(hwnd,"error getting function \"SetHook\"","Error!",0);
            }
        }
        else
            MessageBox(hwnd,"can't fint the dll!","Error!",0);
        return TRUE;
    }
    LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
    {
        switch (iMsg)
        {
            case WM_CREATE :
                break;
            case WM_DESTROY :
                if(flag)
                    SetHookAlias(0);    //还有这里啦。。
                PostQuitMessage (0) ;
                return 0 ;
        }
        return DefWindowProc (hwnd, iMsg, wParam, lParam) ;
    }
    /////////////////////////// dll代码:
    #include<windows.h>HHOOK KeyboardglhHook,MouseglhHook;
    VOID SetHook(UINT handletype,HINSTANCE glhInstance);
    LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);
    LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam);//加入全局变量,保存dll本身的instance,
    //用来传入SetWindowHookEx第三个参数
    HINSTANCE g_hinstDll = NULL;   int WINAPI DllMain(HINSTANCE hInstance,DWORD fdwReason,PVOID pvReserved)
    {
        //修改前:return TRUE;    //修改后:注意以下几行
        switch (fdwReason)    
        {
            case DLL_PROCESS_ATTACH:
                g_hinstDll = hInstance;  // g_hinstDll
                break;
        }
        return true;
    }//修改前:VOID SetHook(UINT handletype,HINSTANCE glhInstance)
    //改过后的SetHook、、、、、
    void SetHook(UINT handletype) 
    {
        if (handletype==0)
        {
            UnhookWindowsHookEx (KeyboardglhHook);
            UnhookWindowsHookEx (MouseglhHook);
        }
        else if (handletype==1)
        {
            //修改前传入的是 LoadLibrary的返回值
            //现在传入的 g_hinstDll 是DllMain中的 hInstance、、、、
            KeyboardglhHook=SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, g_hinstDll, 0);
            MouseglhHook=SetWindowsHookEx(WH_MOUSE,MouseProc,g_hinstDll,0);
        }
    }LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) 

        //修改前:if (nCode < 0)
        //修改后:我想下面这样比较规范吧
        if(nCode==HC_ACTION)
        {
            //此地方改动过,用了MessageBox测试
            if (wParam ==VK_UP)
            {
                //可以先用messagebox测试。
                MessageBox(0,"sdfsfsd","df",MB_OK); 
                
                //原来的这行肯定行啦。
                WinExec("MP.EXE",SW_SHOW);
                
                //截断消息,如果return 0 别的程序就收不到咯
                //return 0;  
            }
        }
        
        return CallNextHookEx(KeyboardglhHook, nCode, wParam, lParam); 
    } LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam) 

        //这样吧。。
        if(nCode==HC_ACTION)
        {
            ;
        }
        return CallNextHookEx(MouseglhHook, nCode, wParam, lParam); 
    }
    ---------------------
    //OK啦!!!!!!!!!!!!!
      

  17.   

    哦,上面一个地方搞错了要修改:>>>>>>>>>>>>>>>>>>>>>>>>
    //截断消息,如果return 0 别的程序就收不到咯
    //return 0;  
    >>>>>>>>>>>>>>>>>>>>>>改为:
    //截断消息,如果return 1 别的程序就收不到咯
    //return 1;  
            
    return 1 就可以截断了。
      

  18.   

    我说兄弟,你不是在耍我吧!明明不行,你偏说可以.你自己用WinExec()试过吗?这种精神,可实在不值得发扬啊!
      

  19.   

    nne998:  你可以自己用一个其他的可执行文件,用WinExec()来试一下,看看行不行.  你的代码确实经过了一些优化,但没有解决根本的问题.
      

  20.   

    。。
    legerwu(Leger) 兄,
    不要再跟我争了,,,我快被你气死了
    我 hook mouse、keyboard、、vc、delpih已经做过n次了.....你说呢?还是让楼主eEric (Paranoia)他试吧
      

  21.   

    我刚才又实际试了一遍,在使用WinExec()时,确实不行,难道是我的工程设置有问题吗?nne998兄,实在很抱歉,我们都不用再争了,让楼主自己试验一下,如果他认为你的办法可行,就采用你的办法,如果问题确实出在WinExec()无法启动上,那采用其他办法来启动可执行文件就是一个新的问题了,如果你有兴趣,我们可以再一起探讨.
      

  22.   

    我把我编译出来的 exe和dll打包了
    大家试试吧http://61.140.78.114/fjj/aaa.zip        (24k)按 VK_UP就会运行"记事本notepad.exe"。。
      

  23.   

    源码打包:
    http://61.140.78.114/fjj/aaa_src.zip(54k)
      

  24.   

    我已经找到问题的所在,因为我在启动该可执行文件时,将可执行文件放在当前目录下,但在动态库中没有设定它的全部路径,现在加上了它的全部路径,问题得到了解决.nne998兄,对你的执著精神,我表示非常的赞赏.