挑战极限

weiyulin 2009-06-01 04:41:19

问题一,之前发过的贴,如果哪位老师知道的话,随便解决一下:

大家都知道,当我们的程序注册一组热键时,会通知操作系统进行注册
我的想法是 有没有什么方法 可以获取当前系统中所有已注册的热键 并知道哪个热键属于哪个应用程序
反正我是想不到方法,在此请教各位老师? 请大家积极讨论!!!!!!!!!!!!!!!!!!!!!!


问题二,关闭指定包含某些字符的窗口:

如有个窗口标题为 [hao123网址之家] 那么我只需要指定其中一个或多个字符将其找到,并关闭


谢谢
...全文
130 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
weiyulin 2009-06-03
  • 打赏
  • 举报
回复


没人 看来另一个问题 [color=#FF0000] 解决不了了[/color]
lyserver 2009-06-02
  • 打赏
  • 举报
回复
第二个问题:

Option Explicit

Private Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, _
ByVal lpString As String, ByVal cch As Long) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, _
ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Const WM_SYSCOMMAND = &H112
Private Const SC_CLOSE = &HF060&

Sub main()
EnumWindows AddressOf EnumWindowsProc, 0
End Sub

Private Function EnumWindowsProc(ByVal hwnd As Long, ByVal lParam As Long) As Long
Dim strCaption As String

strCaption = String(255, vbNullChar)
GetWindowText hwnd, strCaption, 255 '获得窗口标题
strCaption = Left(strCaption, InStr(strCaption, vbNullChar) - 1)
If InStr(strCaption, "hao123") Then '判断标题中是否包含hao123网址之家
SendMessage hwnd, WM_SYSCOMMAND, SC_CLOSE, 0&
End If
EnumWindowsProc = 1 '继续查找下一个窗口
End Function
chenhui530 2009-06-02
  • 打赏
  • 举报
回复
你先看这段代码是系统在注册热键的函数代码,查找热件通过函数FindHotKey。再看FindHotKey中关键在gphkFirst,其实它是有个系统级全局变量对应结构HOTKEY其中内部成员pti有指向线程内核对象通过线程内核对象就可以知道是什么程序注册的热键的了。下面是部分函数代码和关键结构。以及我用windbg手动分析的一些结果(在我的机器上)。


typedef struct tagHOTKEY {
PTHREADINFO pti;
PWND spwnd;
WORD fsModifiers; // MOD_SHIFT, MOD_ALT, MOD_CONTROL, MOD_WIN
WORD wFlags; // MOD_SAS
UINT vk;
int id;
struct tagHOTKEY *phkNext;
} HOTKEY, *PHOTKEY;

BOOL _RegisterHotKey(
PWND pwnd,
int id,
UINT fsModifiers,
UINT vk)
{
PHOTKEY phk;
BOOL fKeysExist;
PTHREADINFO ptiCurrent;
BOOL bSAS = FALSE;
WORD wFlags;

wFlags = fsModifiers & MOD_SAS;
fsModifiers &= ~MOD_SAS;

ptiCurrent = PtiCurrent();

/*
* Blow it off if the caller is not the windowstation init thread
* and doesn't have the proper access rights
*/
if (PsGetCurrentProcess() != gpepCSRSS) {
if (grpWinStaList && !CheckWinstaWriteAttributesAccess()) {
return FALSE;
}
}

/*
* If VK_PACKET is specified, just bail out, since VK_PACKET is
* not a real keyboard input.
*/
if (vk == VK_PACKET) {
return FALSE;
}

/*
* If this is the SAS check that winlogon is the one registering it.
*/
if (wFlags & MOD_SAS) {
if (PsGetCurrentProcess()->UniqueProcessId == gpidLogon) {
bSAS = TRUE;
}
}

/*
* Can't register hotkey for a window of another queue.
* Return FALSE in this case.
*/
if ((pwnd != PWND_FOCUS) && (pwnd != PWND_INPUTOWNER)) {
if (GETPTI(pwnd) != ptiCurrent) {
RIPERR0(ERROR_WINDOW_OF_OTHER_THREAD, RIP_VERBOSE, "");
return FALSE;
}
}

phk = FindHotKey(ptiCurrent, pwnd, id, fsModifiers, vk, FALSE, &fKeysExist);

/*
* If the keys have already been registered, return FALSE.
*/
if (fKeysExist) {
RIPERR0(ERROR_HOTKEY_ALREADY_REGISTERED, RIP_WARNING, "Hotkey already exists");
return FALSE;
}

if (phk == NULL) {
/*
* This hotkey doesn't exist yet.
*/
phk = (PHOTKEY)UserAllocPool(sizeof(HOTKEY), TAG_HOTKEY);

/*
* If the allocation failed, bail out.
*/
if (phk == NULL) {
return FALSE;
}

phk->pti = ptiCurrent;

if ((pwnd != PWND_FOCUS) && (pwnd != PWND_INPUTOWNER)) {
phk->spwnd = NULL;
Lock(&phk->spwnd, pwnd);
} else {
phk->spwnd = pwnd;
}
phk->fsModifiers = (WORD)fsModifiers;
phk->wFlags = wFlags;

phk->vk = vk;
phk->id = id;

/*
* Link the new hotkey to the front of the list.
*/
phk->phkNext = gphkFirst;
gphkFirst = phk;

} else {

/*
* Hotkey already exists, reset the keys.
*/
phk->fsModifiers = (WORD)fsModifiers;
phk->wFlags = wFlags;
phk->vk = vk;
}

if (bSAS) {
/*
* store the SAS on the terminal.
*/
gvkSAS = vk;
gfsSASModifiers = fsModifiers;
}

return TRUE;
}



PHOTKEY FindHotKey(
PTHREADINFO ptiCurrent,
PWND pwnd,
int id,
UINT fsModifiers,
UINT vk,
BOOL fUnregister,
PBOOL pfKeysExist)
{
PHOTKEY phk, phkRet, phkPrev;

/*
* Initialize out 'return' values.
*/
*pfKeysExist = FALSE;
phkRet = NULL;

phk = gphkFirst;

while (phk) {

/*
* If all this matches up then we've found it.
*/
if ((phk->pti == ptiCurrent) && (phk->spwnd == pwnd) && (phk->id == id)) {
if (fUnregister) {

/*
* Unlink the HOTKEY from the list.
*/
if (phk == gphkFirst) {
gphkFirst = phk->phkNext;
} else {
phkPrev->phkNext = phk->phkNext;
}

if ((pwnd != PWND_FOCUS) && (pwnd != PWND_INPUTOWNER)) {
Unlock(&phk->spwnd);
}
UserFreePool((PVOID)phk);

return((PHOTKEY)1);
}
phkRet = phk;
}

/*
* If the key is already registered, set the exists flag so
* the app knows it can't use this hotkey sequence.
*/
if ((phk->fsModifiers == (WORD)fsModifiers) && (phk->vk == vk)) {

/*
* In the case of PWND_FOCUS, we need to check that the queues
* are the same since PWND_FOCUS is local to the queue it was
* registered under.
*/
if (phk->spwnd == PWND_FOCUS) {
if (phk->pti == ptiCurrent) {
*pfKeysExist = TRUE;
}
} else {
*pfKeysExist = TRUE;
}
}

phkPrev = phk;
phk = phk->phkNext;
}

return phkRet;
}


lkd> dd win32k!gphkFirst
bf9aa114 e21de820 00000000 00000000 00000000 //e21de820就是gphkFirst系统全局变量,其实它就是PHOTKEY
bf9aa124 e11161d8 e4c5d300 00000000 bc6355c0
bf9aa134 00000000 00000000 00000000 00000000
bf9aa144 bc5d1150 00000000 bc5d1170 00000000
bf9aa154 bc5d1190 00000000 bc5d11b0 00000000
bf9aa164 bc5d11d0 0000000a 00000004 00000004
bf9aa174 00000000 00000000 00000000 000927c0
bf9aa184 00000000 00000000 00000000 00000000

再展开结构
e21de820 e27caaa8 bc6388f0 00000003 0000005a //3就是fsModifiers MOD_ALT + MOD_CONTROL,5a就是vk这样在我的机器上就注册了一个Ctrl+Alt+Z的热键,事实证明分析正确因为我确实建立了一个这样的热键。而e20ce1d0指向下一个链表也就是新的元素,就这样一直展开下去就可以枚举到所有注册的系统热键直到指向下一个链表为空为止
e21de830 00000005 e20ce1d0 0c040604 e24e4d43
e21de840 00020001 000172b5 e1484d94 54430003
e21de850 e214ca46 e23272b9 0c1d0604 6e746146
e21de860 0044005c 0063006f 006d0075 006e0065
e21de870 00730074 00610020 0064006e 00530020
e21de880 00740065 00690074 0067006e 005c0073
e21de890 006c0041 0020006c 00730055 00720065
weiyulin 2009-06-02
  • 打赏
  • 举报
回复


明天加分
weiyulin 2009-06-02
  • 打赏
  • 举报
回复

API调用不是我的强项 呵呵 我想要代码 sorry
weiyulin 2009-06-02
  • 打赏
  • 举报
回复
谢谢陈辉老师 的回复 可我根本不懂C 谢谢

第二个问题 感谢江春南

不管第一个问题能否解决,此贴将在3天后结贴


谢谢
lyserver 2009-06-01
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 PctGL 的回复:]

又被我抢到沙发了。,。。
第1个问题,那天没事的时候看了一个外国人做的软件,实现了你说的功能,叫什么给忘了,无意中找到的
我逆了看过之后,实现方法和我说的雷同,只不过我说的方法麻烦了
他直接用 setwindowshook 加载全局钩子,然后把热建全都sendmessage发送测试了一遍,在钩子里面截取并记录就实现了


第2个问题,用枚举窗口 enumwindow 在回调函数中,getwindowtext ,然后做比较就可以实现了
[/Quote]
如上
PctGL 2009-06-01
  • 打赏
  • 举报
回复

又被我抢到沙发了。,。。
第1个问题,那天没事的时候看了一个外国人做的软件,实现了你说的功能,叫什么给忘了,无意中找到的
我逆了看过之后,实现方法和我说的雷同,只不过我说的方法麻烦了
他直接用 setwindowshook 加载全局钩子,然后把热建全都sendmessage发送测试了一遍,在钩子里面截取并记录就实现了


第2个问题,用枚举窗口 enumwindow 在回调函数中,getwindowtext ,然后做比较就可以实现了

1,486

社区成员

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

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