为什么截获不了TAB键?

nightfallrove 2003-05-13 02:05:06
我在日志钩子中处理键盘和鼠标消息时写了这样的代码:
h1=GetActiveWindow();
GetcursorPos(&pos);
current=WindowFromPoint(pos);
if(current!=pre)
{
Memo1->lines->append(buffer);
pre=current;
}
else
{
SendMessage(current,WM_GETTEXT,1024,buffer);
}
我是想在Memo1里面显示用户的所有输入可是在一个有两个输入框的
窗口里,而且用户一回车就会关闭,如果用户用鼠标切换输入
框则可以得到输入的内容,但是如果用户用TAB键切换则无法得到输入的
内容而且输入框的句柄current,光标的位置pos都没有更新,怎样才能
截获TAB键并得到任何时候获得拥有光标的输入框的句柄呢?







...全文
54 8 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
jishiping 2003-05-20
  • 打赏
  • 举报
回复
我试了一下,用WH_CBT也不行,最后还是用WH_CALLWNDPROC解决了。
------------DLL部分----------------
HHOOK hHook=NULL;
HINSTANCE hInst=NULL;
extern "C" __declspec(dllexport)
BOOL _stdcall EnableHook(HWND, BOOL);

int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*)
{
if (reason==DLL_PROCESS_ATTACH)
hInst = hinst;
else if(reason==DLL_PROCESS_DETACH)
EnableHook(NULL, FALSE);
return 1;
}
//---------------------------------------------------------------------------
#define ATOM_NAME "HOOKWND"
#define WM_HOOKMSG (WM_APP+1)
BOOL CALLBACK EnumProc(HWND hwnd, LPARAM lParam)
{
if (GetProp(hwnd,ATOM_NAME)==hwnd) {
*(HWND*)lParam = hwnd; return 0;
}
return TRUE;
}

long CALLBACK HookFun(int nCode, WPARAM wParam,
LPARAM lParam)
{
if (nCode < 0)
return CallNextHookEx(hHook, nCode,
wParam, lParam);
CWPSTRUCT* pMsg = (CWPSTRUCT*)lParam;
HWND hWnd = NULL;
if (pMsg->message==WM_ACTIVATE) {
WORD fActive = LOWORD(pMsg->
wParam);
if (fActive==WA_INACTIVE)
hWnd = (HWND)pMsg->hwnd;
}
else if(pMsg->message==WM_KILLFOCUS)
hWnd = (HWND)pMsg->hwnd;

HWND hMain = NULL;
EnumWindows((FARPROC)EnumProc, (long)
&hMain);
if (hMain!=NULL && hWnd!=NULL)
SendMessage(hMain, WM_HOOKMSG, 0,
(long)hWnd);
return 0; //这儿必须返回 0
}

BOOL _stdcall EnableHook(HWND MainWnd, BOOL enable)
{
static HWND hMain=NULL;

if (enable) {
if (MainWnd==NULL) return FALSE;
if (MainWnd != hMain) {
if (hMain != NULL)
RemoveProp(hMain, ATOM_NAME);
SetProp(MainWnd, ATOM_NAME,
(HANDLE)MainWnd);
hMain = MainWnd;
}
if (hHook == NULL)
hHook = SetWindowsHookEx(WH_CALLWNDPROC,
(HOOKPROC)HookFun, hInst, 0);
return hHook != NULL;
}
else {
if (hMain != NULL) {
RemoveProp(hMain, ATOM_NAME);
hMain = NULL;
}
if (hHook != NULL) {
if (UnhookWindowsHookEx(hHook))
hHook = NULL;
}
return hHook == NULL;
}
}


----------EXE部分---------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TButton *Button1;
TButton *Button2;
TMemo *Memo1;
TButton *Button3;
void __fastcall Button1Click(TObject *Sender);
void __fastcall Button2Click(TObject *Sender);
void __fastcall Button3Click(TObject *Sender);
private: // User declarations
void __fastcall OnHookMsg(TMessage&);
public: // User declarations
__fastcall TForm1(TComponent* Owner);
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_HOOKMSG, TMessage, OnHookMsg)
END_MESSAGE_MAP(TForm)
};

extern "C" BOOL _stdcall EnableHook(HWND, BOOL);
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
EnableHook(Handle, TRUE);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
EnableHook(Handle, FALSE);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
Memo1->Clear();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::OnHookMsg(TMessage& Msg)
{
char buffer[2048];

HWND hWnd = (HWND)Msg.LParam;
SendMessage(hWnd, WM_GETTEXT, 2048,
(long)buffer);
Memo1->Lines->Add(buffer);
}
nightfallrove 2003-05-19
  • 打赏
  • 举报
回复
WH_CBT没用过,
季老大有例子不?
谢了,,,,,
jishiping 2003-05-18
  • 打赏
  • 举报
回复
如果使用WH_JOURNALRECORD钩子的话,我也没有办法。实际上,你只是想在一个窗口失去焦点时,记录这个窗口的文字及ClassName之类的信息。我认为可以用WH_CBT钩子来实现。不过
这需要做成DLL才行。在WH_CBT钩子的回调函数里,拦截nCode==HCBT_ACTIVATE的情形。
nightfallrove 2003-05-18
  • 打赏
  • 举报
回复
如果我要得到按tab后得到焦点的控件的句柄该怎么办呢
不能用WindowFromPoint()了,用什么呢?》
谢谢
jishiping 2003-05-18
  • 打赏
  • 举报
回复
我看了(也试了)你的代码,不是拦截不到TAB键,而是你的程序的问题。对于鼠标单击没有
什么问题,但是对于按键处理却有问题。在按键处理时,你也是使用WindowFromPoint(pos);
这是不对的。当用户按键时,接收输入的窗口和鼠标下面的窗口,根本就是2个不同的窗口。
当用户按TAB键切换窗口时,鼠标没有动,所以你用WindowFromPoint(pos);得到的窗口自然
还是之前用WindowFromPoint(pos);得到的窗口。执行下面的if(cchild!=pchild)时,条件
当然不成立,结果当然不会向TMemo里添加文字了。
nightfallrove 2003-05-18
  • 打赏
  • 举报
回复
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop
#include <mem.h>
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
HHOOK RecordHook=NULL;
HWND window=NULL;//当前活动窗口
HWND pchild=NULL;//前一个获得焦点的子控件
HWND cchild=NULL;//当前获得焦点的子控件
POINT pos;//鼠标点击的位置
char buffer[2048];//用来保存截到的输入数据
char title[512];//窗口标题
char cname[256];//子控件类名
HOOKPROC RecordProc(int code,WPARAM wp,LPARAM lp)//钩子
{
if(code<0)
return (HOOKPROC)CallNextHookEx(RecordHook,code,wp,lp);
if(code!=HC_ACTION)
return (HOOKPROC)CallNextHookEx(RecordHook,code,wp,lp);
//window=GetActiveWindow();
EVENTMSG *pEvent=(EVENTMSG*)lp;
if((pEvent->message==WM_KEYDOWN)||(pEvent->message==WM_KEYUP)
||(pEvent->message==WM_LBUTTONDOWN)
||(pEvent->message==WM_RBUTTONDOWN))
{
int vkey=(BYTE)(pEvent->paramL);
if((keywindow<0)&&(vkey==VK_F12))
Form1->Close();
GetCursorPos(&pos);//显示鼠标位置
Form1->Label2->Caption=IntToStr(pos.x)+" , "+IntToStr(pos.y);
cchild=WindowFromPoint(pos);//得到子控件句柄,类型
GetClassName(cchild,cname,256);
Form1->Label4->Caption=cname;
if(cchild!=pchild)//text是一个memo组件,我用来显示用户的输入数据
{
Form1->text->Lines->Append(strcat(strcat(title,": "),buffer));
memset(buffer,0,2048);
memset(title,0,512);
pchild=cchild;
SendMessage(cchild,WM_GETTEXT, 2048,(long)buffer);
}
else
{
window=GetActiveWindow();
GetWindowText(window,title,512);
SendMessage(cchild,WM_GETTEXT, 2048,(long)buffer);
}
}
return (HOOKPROC)CallNextHookEx(RecordHook,code,wp,lp);
}

void __fastcall TForm1::Button1Click(TObject *Sender)//安装HOOK
{
if(RecordHook==NULL)
RecordHook=SetWindowsHookEx(
WH_JOURNALRECORD,
(HOOKPROC)RecordProc,
HInstance,
NULL);
Form1->Button1->Enabled=false;
Form1->FormStyle=fsStayOnTop;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)//卸下HOOK
{
if(RecordHook)
{
UnhookWindowsHookEx(RecordHook);
Form1->Button1->Enabled=true;
RecordHook=NULL;
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
if(RecordHook)
{
UnhookWindowsHookEx(RecordHook);
RecordHook=NULL;
}
}

//---------------------------------------------------------------------------

//清屏
void __fastcall TForm1::Button3Click(TObject *Sender)
{
Form1->text->Lines->Clear();
}
//---------------------------------------------------------------------------

jishiping 2003-05-17
  • 打赏
  • 举报
回复
“如果用户用鼠标切换输入框则可以得到输入的内容,但是如果用户用TAB键切换则无法得到
输入的内容”

这说明,用户按Tab键时,你的钩子函数没有拦截到。你的代码怎么写的,需要将调用函数
SetWindowsHookEx的代码以及回调函数的相关代码都贴出来,才知道错在哪儿。
Lewolf 2003-05-15
  • 打赏
  • 举报
回复
看一看WantTab属性,有一些Edit类的控件可以自己获取Tab,而不是转移焦点的。

1,222

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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