请教关于钩子回放WH_JOURNALPLAYBACK

raylin 2008-06-04 11:47:23
我用WH_JOURNALRECORD记录键盘操作,然后用WH_JOURNALPLAYBACK回放,但回放的时候所有的鼠标和键盘都被屏蔽,我想在回放过程中可以进行回放终止操作,请问各位专家有没有办法可以解决?
...全文
398 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
乐小仙 2012-04-22
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 的回复:]
我用WH_JOURNALRECORD记录键盘操作,然后用WH_JOURNALPLAYBACK回放,但回放的时候所有的鼠标和键盘都被屏蔽,我想在回放过程中可以进行回放终止操作(例如能否让鼠标不被屏蔽?,或者某个键不被屏蔽?),请问各位专家有没有办法可以解决?
我的本意是在回放过程中,能够点击"停止回放"按钮来达到取消回放的功能。
[/Quote]
我也正在研究这个问题,请问您的问题解决了吗?怎么解决的?求指教~
raylin 2008-06-05
  • 打赏
  • 举报
回复
我用WH_JOURNALRECORD记录键盘操作,然后用WH_JOURNALPLAYBACK回放,但回放的时候所有的鼠标和键盘都被屏蔽,我想在回放过程中可以进行回放终止操作(例如能否让鼠标不被屏蔽?,或者某个键不被屏蔽?),请问各位专家有没有办法可以解决?
我的本意是在回放过程中,能够点击"停止回放"按钮来达到取消回放的功能。
raylin 2008-06-04
  • 打赏
  • 举报
回复
谢谢上面兄弟的代码,但我找不到可以在回放过程中,可以终止回放操作,返回到原来界面的代码,能否指出是哪段代码? 谢谢了
laolaoliu2002 2008-06-04
  • 打赏
  • 举报
回复
http://blog.csdn.net/BigFanOfCpp/archive/2005/03/27/332159.aspx
laolaoliu2002 2008-06-04
  • 打赏
  • 举报
回复
/*****************MessageTipDlg.cpp***********************/

// MessageTipDlg.cpp : 实现文件
//
#include "stdafx.h"

#include "MessageTip.h"
#include "MessageTipDlg.h"

#include "HOOKService.h"
#include ".\messagetipdlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CMessageTipDlg 对话框

CMessageTipDlg::CMessageTipDlg(CWnd* pParent /*=NULL*/)
: CDialog(CMessageTipDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CMessageTipDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LIST_MSGTIP, m_ListCtrl_MsgTip);
}

BEGIN_MESSAGE_MAP(CMessageTipDlg, CDialog)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_BN_CLICKED(ID_BUTTON_START, OnBnClickedButtonStart)
ON_BN_CLICKED(ID_BUTTON_DISPLAY, OnBnClickedButtonDisplay)
ON_BN_CLICKED(ID_BUTTON_EXIT, OnBnClickedButtonExit)
ON_MESSAGE(WM_PASSDATA,OnPassData)
// ON_WM_SIZE()
ON_BN_CLICKED(ID_BUTTON_OPENRECORD, OnBnClickedButtonOpenrecord)
ON_BN_CLICKED(ID_BUTTON_SAVERECORD, OnBnClickedButtonSaverecord)
END_MESSAGE_MAP()


// CMessageTipDlg 消息处理程序

BOOL CMessageTipDlg::OnInitDialog()
{
CDialog::OnInitDialog();

// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, TRUE); // 设置小图标

// TODO: 在此添加额外的初始化代码
EnableDisplayFunction(FALSE);

m_ImageList.Create(16,16,ILC_COLOR32,1,1);
// m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_MSGNAME));
// m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_MSGTIME));
// m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_MSGPARAM));
m_ImageList.Add(m_hIcon);

InitListCtrl();

return TRUE; // 除非设置了控件的焦点,否则返回 TRUE
}

// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。

void CMessageTipDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文

SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

// 使图标在工作矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;

// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}

//当用户拖动最小化窗口时系统调用此函数取得光标显示。
HCURSOR CMessageTipDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}

void CMessageTipDlg::OnBnClickedButtonStart()
{
// TODO: Add your control notification handler code here
CFileDialog CommonFileDlg(FALSE,_T("hook"),_T("消息保存文件"));
if (m_FileOut.m_hFile == INVALID_HANDLE_VALUE)
{
if (CommonFileDlg.DoModal() != IDOK)
{
AfxMessageBox("请选择消息保存位置^_^");
return ;
}
CFileFind FindFind;
if (FindFind.FindFile((LPCTSTR)CommonFileDlg.GetPathName(),0))
m_FileOut.Open((LPCTSTR)CommonFileDlg.GetPathName(),CFile::modeReadWrite);
else
m_FileOut.Open((LPCTSTR)CommonFileDlg.GetPathName(),CFile::modeCreate|CFile::modeReadWrite);
}
else
m_FileOut.SeekToBegin();

ULONGLONG ulFileLength = m_FileOut.GetLength();
if (ulFileLength > 0xffff)
{
m_FileOut.Close();
CString cstrNewFile(_T(""));
cstrNewFile.Format("%s%I64d",CommonFileDlg.GetPathName(),rand() % ulFileLength);
CFileFind FindFind;
if (FindFind.FindFile((LPCTSTR)cstrNewFile,0))
m_FileOut.Open((LPCTSTR)cstrNewFile,CFile::modeReadWrite);
else
m_FileOut.Open((LPCTSTR)cstrNewFile,CFile::modeCreate|CFile::modeReadWrite);
}

if (!InstallOperationsHook(m_hWnd,
AfxGetApp()->m_hInstance))
{
AfxMessageBox("安装系统钩子失败!");
}

EnableStartRecordFunction(FALSE);
EnableDisplayFunction();
}

void CMessageTipDlg::OnBnClickedButtonDisplay()
{
// TODO: Add your control notification handler code here
if (!InstallOperationsDisplayHook(m_hWnd,
AfxGetApp()->m_hInstance))
{
AfxMessageBox("安装系统钩子失败!");
}

EnableStartRecordFunction();
EnableDisplayFunction(FALSE);
}

void CMessageTipDlg::OnBnClickedButtonExit()
{
// TODO: Add your control notification handler code here
FreeMsgList();
UnInstallOperationsHook();
UnInstallOperationsDisplayHook();
CDialog::OnOK();
}

void CMessageTipDlg::OnOK()
{
return ;
}

void CMessageTipDlg::OnCancel()
{
return ;
}

void CMessageTipDlg::OnClose()
{
return ;
}

void CMessageTipDlg::EnableDisplayFunction(BOOL IsEnable/* = TRUE */)
{
((CButton*)GetDlgItem(ID_BUTTON_DISPLAY))->EnableWindow(IsEnable);
}

void CMessageTipDlg::EnableStartRecordFunction(BOOL IsEnable/* = TRUE */)
{
((CButton*)GetDlgItem(ID_BUTTON_START))->EnableWindow(IsEnable);
}


void CMessageTipDlg::InitListCtrl()
{
g_AppInstance = AfxGetApp()->m_hInstance;

m_ListCtrl_MsgTip.SetImageList(&m_ImageList,LVSIL_SMALL);
LVCOLUMN col;
col.mask = LVCF_FMT|LVCF_IMAGE|LVCF_SUBITEM|LVCF_TEXT|LVCF_WIDTH;
col.fmt = LVCFMT_CENTER|LVCFMT_IMAGE;
col.iImage = 0;
col.cchTextMax = ::lstrlen("消息名称")+1;
col.pszText = "消息名称";
col.iSubItem = 0;
CRect rect(0,0,0,0);
m_ListCtrl_MsgTip.GetWindowRect(&rect);
col.cx = 120;
m_ListCtrl_MsgTip.InsertColumn(0,&col);

col.cx = 120;
col.cchTextMax = ::lstrlen("消息值")+1;
col.pszText = "消息值";
m_ListCtrl_MsgTip.InsertColumn(1,&col);

col.cx = rect.Width();
col.cchTextMax = ::lstrlen("消息时间")+1;
col.pszText = "消息时间";
m_ListCtrl_MsgTip.InsertColumn(2,&col);
}

LRESULT CMessageTipDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
// TODO: Add your specialized code here and/or call the base class
return CDialog::WindowProc(message, wParam, lParam);
}

BOOL CMessageTipDlg::PreTranslateMessage(MSG* pMsg)
{
// TODO: Add your specialized code here and/or call the base class
return CDialog::PreTranslateMessage(pMsg);
}

LRESULT CMessageTipDlg::OnPassData(WPARAM wParam,LPARAM lParam)
{
LPEVENTMSG lpEventMsg = (LPEVENTMSG)lParam;
CString cstrMsg(_T(""));
TCHAR TargetWindowName[MAX_PATH] = { '\0' };
::GetWindowText(::GetActiveWindow(),TargetWindowName,MAX_PATH);
COleDateTime cdt(COleDateTime::GetCurrentTime());
CString cstrMsgName(GetMsgName(lpEventMsg->message));
cstrMsg.Format("消息名称:%s\r\n消息目标窗体:%s\r\n消息发送时间:%s\r\n---------------------------------------------\r\n",
cstrMsgName,TargetWindowName,
cdt.Format("%Y年%m月%d日%H时%M分%S秒"));
m_FileOut.Write((LPCTSTR)cstrMsg,cstrMsg.GetLength());
m_ListCtrl_MsgTip.DeleteAllItems();
m_ListCtrl_MsgTip.InsertItem(0,(LPCTSTR)cstrMsgName,0);
m_ListCtrl_MsgTip.SetItemText(0,1,(LPCTSTR)TargetWindowName);
m_ListCtrl_MsgTip.SetItemText(0,2,(LPCTSTR)cdt.Format("%Y年%m月%d日%H时%M分%S秒"));
return 0;
}

BOOL CMessageTipDlg::DestroyWindow()
{
// TODO: Add your specialized code here and/or call the base class
if (m_FileOut.m_hFile != INVALID_HANDLE_VALUE)
m_FileOut.Close();
return CDialog::DestroyWindow();
}

void CMessageTipDlg::OnBnClickedButtonOpenrecord()
{
// TODO: Add your control notification handler code here
}

void CMessageTipDlg::OnBnClickedButtonSaverecord()
{
// TODO: Add your control notification handler code here
}


/*****************MessageTipDlg.cpp***********************/
laolaoliu2002 2008-06-04
  • 打赏
  • 举报
回复
/*****************stdafx.h***********************/
#pragma once

#ifndef VC_EXTRALEAN
#define VC_EXTRALEAN // 从 Windows 标头中排除不常使用的资料
#endif

// 如果您必须使用下列所指定的平台之前的平台,则修改下面的定义。
// 有关不同平台的相应值的最新信息,请参考 MSDN。
#ifndef WINVER //允许使用 Windows 95 和 Windows NT 4 或更高版本的特定功能。
#define WINVER 0x0400 //为 Windows98 和 Windows 2000 及更新版本改变为适当的值。
#endif

#ifndef _WIN32_WINNT // 允许使用 Windows NT 4 或更高版本的特定功能。
#define _WIN32_WINNT 0x0400 //为 Windows98 和 Windows 2000 及更新版本改变为适当的值。
#endif

#ifndef _WIN32_WINDOWS // 允许使用 Windows 98 或更高版本的特定功能。
#define _WIN32_WINDOWS 0x0410 //为 Windows Me 及更新版本改变为适当的值。
#endif

#ifndef _WIN32_IE //允许使用 IE 4.0 或更高版本的特定功能。
#define _WIN32_IE 0x0400 //为 IE 5.0 及更新版本改变为适当的值。
#endif

#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // 某些 CString 构造函数将是显式的
....
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h>// Windows 公共控件的 MFC 支持
#endif // _AFX_NO_AFXCMN_SUPPORT
#define WM_PASSDATA WM_USER+1982
#include <vector>
using namespace std;
#include <windowsx.h>
#include <winable.h>

struct MsgStruct
{
UINT nCode;
LPCTSTR pszText;
};

struct MsgList
{
public:
MsgList()
{
memset(&Event,0,sizeof(EVENTMSG));
lpNext = NULL;
}
~MsgList()
{
if (lpNext && !::IsBadReadPtr(lpNext,sizeof(MsgList)))
delete lpNext;
memset(&Event,0,sizeof(EVENTMSG));
lpNext = NULL;
}
EVENTMSG Event;
MsgList *lpNext;
};
static HHOOK g_hHookOperationsRecord = NULL;
static HHOOK g_hHookOperationsDisplay = NULL;
static HINSTANCE g_AppInstance = NULL;
static MsgList* g_pMsgMovePtr = NULL;
static MsgList* g_pMsgListHeader = NULL;
static MsgList* g_pMsgListLast = NULL;
static MsgList* g_pMsgListPrev = NULL;
static HWND g_Dlg_Hwnd = NULL;
static DWORD RetTime = 0;
static MsgStruct messages[] = {
...};
/*****************stdafx.h***********************/

/*****************MessageTipDlg.h***********************/
#pragma once
#include "afxcmn.h"

// CMessageTipDlg 对话框
class CMessageTipDlg : public CDialog
{
// 构造
public:
CMessageTipDlg(CWnd* pParent = NULL); // 标准构造函数

// 对话框数据
enum { IDD = IDD_MESSAGETIP_DIALOG };

protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
HICON m_hIcon;

// 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnClickedButtonStart();
afx_msg void OnBnClickedButtonDisplay();
afx_msg void OnBnClickedButtonExit();
afx_msg void OnOK();
afx_msg void OnCancel();
afx_msg void OnClose();
afx_msg LRESULT OnPassData(WPARAM,LPARAM);
private:
void EnableDisplayFunction(BOOL = TRUE);
void EnableStartRecordFunction(BOOL = TRUE);
CListCtrl m_ListCtrl_MsgTip;
CImageList m_ImageList;
CFile m_FileOut;
void InitListCtrl();
protected:
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
public:
virtual BOOL PreTranslateMessage(MSG* pMsg);
virtual BOOL DestroyWindow();
afx_msg void OnBnClickedButtonOpenrecord();
afx_msg void OnBnClickedButtonSaverecord();
};
/*****************MessageTipDlg.h***********************/
laolaoliu2002 2008-06-04
  • 打赏
  • 举报
回复
/*****************HOOKService.cpp***********************/

#include "stdafx.h"

#include "HOOKService.h"

BOOL InstallOperationsHook(HWND hWnd,HINSTANCE hInst)
{
if (!UnInstallOperationsDisplayHook())
return FALSE;

if (CheckOperationsRecordHookHandle())
return TRUE;

g_AppInstance = hInst;

g_Dlg_Hwnd = hWnd;

FreeMsgList();

g_hHookOperationsRecord = ::SetWindowsHookEx(WH_JOURNALRECORD,
JournalRecordProc,
g_AppInstance,
0);

return g_hHookOperationsRecord ? TRUE : FALSE;
}

BOOL InstallOperationsDisplayHook(HWND hWnd,HINSTANCE hInst)
{
if (!UnInstallOperationsHook())
return FALSE;

if (CheckOperationsDisplayHookHandle())
return TRUE;

g_AppInstance = hInst;

g_Dlg_Hwnd = hWnd;

g_pMsgListPrev = g_pMsgMovePtr = g_pMsgListLast = NULL;

RetTime = 0;

g_hHookOperationsDisplay = ::SetWindowsHookEx(WH_JOURNALPLAYBACK,
JournalPlaybackProc,
g_AppInstance,
0);

return g_hHookOperationsDisplay ? TRUE : FALSE;
}

LRESULT CALLBACK JournalRecordProc(int nCode,WPARAM wParam,LPARAM lParam)
{
if (nCode < 0)
return ::CallNextHookEx(g_hHookOperationsRecord,nCode,wParam,lParam);
if (nCode == HC_ACTION)
{
MsgList* pTmpMsgList = new MsgList;
pTmpMsgList->Event.hwnd = ((LPEVENTMSG)lParam)->hwnd;
pTmpMsgList->Event.message = ((LPEVENTMSG)lParam)->message;
pTmpMsgList->Event.paramH = ((LPEVENTMSG)lParam)->paramH;
pTmpMsgList->Event.paramL = ((LPEVENTMSG)lParam)->paramL;
pTmpMsgList->Event.time = ((LPEVENTMSG)lParam)->time;
if (!g_pMsgMovePtr)
{
if (!g_pMsgListHeader)
g_pMsgListPrev = g_pMsgListHeader = g_pMsgMovePtr = pTmpMsgList;
}
else
{
g_pMsgListLast = pTmpMsgList;/*将新消息作为最后的消息*/
g_pMsgListPrev = g_pMsgMovePtr;/*保存上次的消息*/
g_pMsgMovePtr->lpNext = pTmpMsgList;/*将新消息挂到消息列表*/
g_pMsgMovePtr = pTmpMsgList;/*将实时指针指向最后的消息*/
}
::PostMessage(g_Dlg_Hwnd,WM_PASSDATA,wParam,(LPARAM)pTmpMsgList);
}

return ::CallNextHookEx(g_hHookOperationsRecord,nCode,wParam,lParam);
}

LRESULT CALLBACK JournalPlaybackProc(int nCode,WPARAM wParam,LPARAM lParam)
{
if (nCode < 0)
return ::CallNextHookEx(g_hHookOperationsDisplay,nCode,wParam,lParam);

if (!g_pMsgMovePtr)
{
if (!g_pMsgListHeader)
{
return UnInstallOperationsDisplayHook();
}
g_pMsgMovePtr = g_pMsgListHeader;
g_pMsgListPrev = g_pMsgListHeader;
}

switch (nCode)
{
case HC_GETNEXT:
/*********************************************************************
*The hook procedure must copy the current mouse or keyboard message *
*to the EVENTMSG structure pointed to by the lParam parameter. *
*********************************************************************/
{
LPEVENTMSG lpEvent = (LPEVENTMSG)lParam;
if (g_pMsgMovePtr && g_pMsgListPrev && lpEvent)
{
lpEvent->message = g_pMsgListPrev->Event.message;
lpEvent->paramL = g_pMsgListPrev->Event.paramL;
lpEvent->paramH = g_pMsgListPrev->Event.paramH;
lpEvent->time = g_pMsgListPrev->Event.time;
lpEvent->hwnd = g_pMsgListPrev->Event.hwnd;
RetTime = g_pMsgMovePtr->Event.time - g_pMsgListPrev->Event.time;

if (g_pMsgMovePtr != g_pMsgListPrev)
{
g_pMsgListPrev = g_pMsgMovePtr;
}

}
if (RetTime < 0)
RetTime = 1;
return RetTime;
}
case HC_SKIP:
/*****************************************************************************
*The hook procedure must prepare to copy the next mouse or keyboard message *
*to the EVENTMSG structure pointed to by lParam. *
*Upon receiving the HC_GETNEXT code, *
*the hook procedure must copy the message to the structure. *
*****************************************************************************/
{
if (!g_pMsgMovePtr->lpNext)
{
return UnInstallOperationsDisplayHook();
}

if (g_pMsgListPrev != g_pMsgMovePtr)
g_pMsgListPrev = g_pMsgMovePtr;

g_pMsgMovePtr = g_pMsgMovePtr->lpNext;
return 0;
}
default:
break;
}
return ::CallNextHookEx(g_hHookOperationsDisplay,nCode,wParam,lParam);
}

BOOL CheckOperationsRecordHookHandle()
{
return g_hHookOperationsRecord ? TRUE : FALSE;
}

BOOL CheckOperationsDisplayHookHandle()
{
return g_hHookOperationsDisplay ? TRUE : FALSE;
}

BOOL UnInstallOperationsHook()
{
if (!g_hHookOperationsRecord)
return TRUE;

BOOL IsUnInstallSuccess = ::UnhookWindowsHookEx(g_hHookOperationsRecord);

g_hHookOperationsRecord = NULL;

return IsUnInstallSuccess;
}

BOOL UnInstallOperationsDisplayHook()
{
if (!g_hHookOperationsDisplay)
return TRUE;

BOOL IsUnInstallSuccess = ::UnhookWindowsHookEx(g_hHookOperationsDisplay);

g_hHookOperationsDisplay = NULL;

return IsUnInstallSuccess;
}

LPCTSTR GetMsgName(UINT nCode)
{
for(int i=0,nCount=sizeof(messages)/sizeof(MsgStruct);i<nCount;++i)
{
if(messages[i].nCode == nCode)
return messages[i].pszText;
}
return "Sorry,I Don't Know.";
}

void FreeMsgList()
{
delete g_pMsgListHeader;
g_pMsgMovePtr = NULL;
g_pMsgListHeader = NULL;
g_pMsgListLast = NULL;
g_pMsgListPrev = NULL;
RetTime = 0;
}

/*****************HOOKService.cpp***********************/
laolaoliu2002 2008-06-04
  • 打赏
  • 举报
回复
/*****************HOOKService.h***********************/

BOOL InstallOperationsHook(HWND,HINSTANCE);
BOOL InstallOperationsDisplayHook(HWND,HINSTANCE);
BOOL UnInstallOperationsHook();
BOOL UnInstallOperationsDisplayHook();
BOOL CheckOperationsRecordHookHandle();
BOOL CheckOperationsDisplayHookHandle();
LRESULT CALLBACK JournalPlaybackProc(int,WPARAM,LPARAM);
LRESULT CALLBACK JournalRecordProc(int,WPARAM,LPARAM);
LPCTSTR GetMsgName(UINT);
void FreeMsgList();

/*****************HOOKService.h***********************/

raylin 2008-06-04
  • 打赏
  • 举报
回复
自己顶一下.

2,641

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 硬件/系统
社区管理员
  • 硬件/系统社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧