各位老大与WINDOWS底层编程高手请进,关于任务栏的时间!
小弟想在自已的的程序启动后不在任务栏里显示,也不想显示为任务栏脚下的小图标,而是希望在双击任务栏里的Windows时钟后显示自已的程序;
问题是我们要怎样得到和控制Windows任务栏的时钟块的全局句柄.并响应自已的事件和接收这些消息!
如果分不够,小弟可以另贴送分,这里我只能是100分了.谢谢!
问题点数:100、回复次数:92Top
1 楼NowCan(城市浪人)回复于 2002-12-30 16:45:36 得分 1
问问BCB_FANS这个牛人。
Top
2 楼copy_paste(木石三)回复于 2002-12-30 16:53:08 得分 1
问问BCB_FANS这个牛人。Top
3 楼copy_paste(木石三)回复于 2002-12-30 16:53:30 得分 0
再问BCB_FANS这个牛人。Top
4 楼copy_paste(木石三)回复于 2002-12-30 16:54:03 得分 0
嗯,还是问BCB_FANS这个牛人吧。:)Top
5 楼Adayuer(饭碗饭碗饭碗你在哪里?)回复于 2002-12-30 17:00:21 得分 0
问问BCB_FANS这个牛人。Top
6 楼Adayuer(饭碗饭碗饭碗你在哪里?)回复于 2002-12-30 17:00:36 得分 0
再问BCB_FANS这个牛人。Top
7 楼Adayuer(饭碗饭碗饭碗你在哪里?)回复于 2002-12-30 17:01:02 得分 0
嗯,还是问BCB_FANS这个牛人吧。:)
Top
8 楼xt_nibin(野人小子)回复于 2002-12-30 17:06:27 得分 0
多谢NowCan(能量、激情、雨水、彩虹——雷雨云)copy_paste(木石三)Adayuer([±0℃])Top
9 楼binbin(破坏分子)回复于 2002-12-30 17:16:22 得分 1
问问BCB_FANS这个牛人。Top
10 楼binbin(破坏分子)回复于 2002-12-30 17:17:00 得分 0
问问BCB_FANS这个牛人。Top
11 楼favorit(九天剑舞·曾几何时,醉里挑灯看剑)回复于 2002-12-30 17:18:54 得分 1
问问BCB_FANS这个牛人:)Top
12 楼binbin(破坏分子)回复于 2002-12-30 17:24:11 得分 0
还是问问BCB_FANS这个牛人吧。Top
13 楼cmsoft(韦小宝是我的老乡)(草根在路上)回复于 2002-12-30 17:25:41 得分 0
既然大家都说去找BCB_FANS,一定找他是没错的了
Top
14 楼invalid(空心菜(Python是个好东东,大家多用用!))回复于 2002-12-30 17:28:00 得分 1
问问BCB_FANS这个牛人。
Top
15 楼binbin(破坏分子)回复于 2002-12-30 17:34:40 得分 0
嗯,有了!!!!
去问问BCB_FANS这个牛人。Top
16 楼xt_nibin(野人小子)回复于 2002-12-30 17:36:12 得分 0
兄弟BCB_FANS这个牛人到底在那里呀!这么没看到他出来呀!Top
17 楼NowCan(城市浪人)回复于 2002-12-30 17:39:22 得分 0
是啊,放假了?Top
18 楼xt_nibin(野人小子)回复于 2002-12-30 17:40:59 得分 0
他是那里的呀!今天就放假了,元旦还要两天呢?TR老大知道吗?帮帮忙呀!Top
19 楼binbin(破坏分子)回复于 2002-12-30 17:42:38 得分 0
BCB_FANS这个牛人,你在哪里啊?Top
20 楼favorit(九天剑舞·曾几何时,醉里挑灯看剑)回复于 2002-12-30 18:37:30 得分 0
等待BCB_FANS这个牛人呀…………Top
21 楼kingcom_xu(冷羽)回复于 2002-12-30 18:49:55 得分 0
去问问BCB_FANS这个牛人。
Top
22 楼kingcom_xu(冷羽)回复于 2002-12-30 18:51:26 得分 0
子类化Top
23 楼dxgxk(郁冬)回复于 2002-12-30 18:56:08 得分 0
再问BCB_FANS这个牛人。Top
24 楼binbin(破坏分子)回复于 2002-12-30 19:07:37 得分 0
子类化???
注入DLL???
Hook???
......
BCB_FANS这个牛人,你在哪里?Top
25 楼slwqw(四大名捕之追杀令)回复于 2002-12-30 19:49:24 得分 0
昨天重装Windows 2000,今天忙着重装软件。
先研究研究.......Top
26 楼invalid(空心菜(Python是个好东东,大家多用用!))回复于 2002-12-30 20:02:58 得分 0
研究研究,来抽烟,来喝酒...Top
27 楼cmsoft(韦小宝是我的老乡)(草根在路上)回复于 2002-12-30 20:20:48 得分 0
拿个凳子坐下来,那个笔记本来听老师上课Top
28 楼favorit(九天剑舞·曾几何时,醉里挑灯看剑)回复于 2002-12-30 20:33:08 得分 0
别跟我抢第一个位,我又耳背又近视,怕学不好
cmsoft让着我点儿:)Top
29 楼kingfish(工作很忙,很少来csdn...)回复于 2002-12-30 20:34:23 得分 0
占个地方学习Top
30 楼jishiping(JSP 季世平)回复于 2002-12-30 21:04:35 得分 0
用全局鼠标钩子才可以。Top
31 楼lichway(lichway)回复于 2002-12-30 21:11:59 得分 0
窗口名:
Shell_TrayWnd 任务栏整条
TrayNotifyWnd 任务栏右下角区域
TraClockWClass 任务栏右下角区域的小时钟
Shell_defview 桌面图标
..Top
32 楼binbin(破坏分子)回复于 2002-12-30 22:32:56 得分 0
用全局鼠标钩子才可以,检测鼠标双击的位置.
对多显示器有没有关系?没用过多头显示,不知道任务栏是什么样的.Top
33 楼cker(〖烟波浩淼三千里、人鬼殊途五百年〗)回复于 2002-12-30 23:48:53 得分 0
啊哈哈,终于看见BCB_FANS这个牛人啊....:)
坐下来听课!Top
34 楼slwqw(四大名捕之追杀令)回复于 2002-12-31 00:15:32 得分 0
给出E-Mail,我发给你例子。Top
35 楼copy_paste(木石三)回复于 2002-12-31 00:24:01 得分 0
靠,严重抗议,FANS没看到大家等你的程序等的脖子都长了。。。
俺刚才试了几次,烦了,就没试了。
你把主要的代码贴一下吧。。。
我用了Mouse Hook都不行,俺也不知错那了。。。Top
36 楼copy_paste(木石三)回复于 2002-12-31 00:27:53 得分 0
HHOOK ClockHook = 0;
HANDLE ClockHandle = NULL;
int CALLBACK GetMsgProc(int code, WPARAM wParam, LPARAM lParam)
{
TMsg *msg = (TMsg*)lParam;
if ((msg->hwnd == ClockHandle) && (msg->message == WM_LBUTTONDOWN))
{
MessageBox(NULL, "Hello", "Hello", MB_ICONINFORMATION);
}
if (code < 0)
return ::CallNextHookEx(0, code, wParam, lParam);
else
return 0;
}
bool __stdcall InstallHook()
{
static const String ShellTray = "Shell_TrayWnd";
static const String TrayNotify = "TrayNotifyWnd";
static const String ClockClass = "TrayClockWClass";
HANDLE tray = FindWindow(ShellTray.c_str(), NULL);
if (NULL == tray) return false;
HANDLE notify = FindWindowEx(tray, NULL, TrayNotify.c_str(), NULL);
if (NULL == notify) return false;
ClockHandle = FindWindowEx(notify, NULL, ClockClass.c_str(), NULL);
if (NULL == ClockHandle) return false;
ClockHook = SetWindowsHookEx(WH_GETMESSAGE, (FARPROC)&GetMsgProc, HInstance, NULL);
if (NULL == ClockHook) return false; else return true;
}
void __stdcall UnInstallHook()
{
if (NULL != ClockHook)
{
UnhookWindowsHookEx(ClockHook);
ClockHook = NULL;
}
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
if (!InstallHook())
Caption = SysErrorMessage(GetLastError());
}
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
UnInstallHook();
}
那回调GetMsgProc死活不听话,打他PP又打不着。FANS看看错那了。
用了Mouse Hook,还是那个样,本来想转成DLL,可不知怎么导入函数来,得,又跑到D(D真是可爱啊。。。)Top
37 楼slwqw(四大名捕之追杀令)回复于 2002-12-31 00:32:47 得分 30
DLL部分=======================================================
DLL部分=======================================================
DLL部分=======================================================
//---------------------------------------------------------------------------
#include <vcl.h>
#include <windows.h>
#include <sysutils.hpp>
#pragma hdrstop
#pragma argsused
#define _DLL_
#include "HookSys.h"
const DWORD WM_TRIGGERCLOCKWND = WM_USER + 1234;
//---------------------------------------------------------------------------
AnsiString HookClassName="THookSysMsgForm";
HWND HookWindowHandle;
HINSTANCE hInst;
//---------------------------------------------------------------------------
FARPROC FOldProc;
HWND hShellTrayWnd = NULL;
TRect FClockWinRect;
LRESULT CALLBACK ShellTrayWindowProc(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
);
//---------------------------------------------------------------------------
// 本来使用全局Mouse Hook也是可以解决问题的,不过我在测试时发现这种方法有Bug,所
// 以采用替换窗口过程的方式。
//
// HHOOK MouseHookID=NULL;
// LRESULT CALLBACK MouseHook(int nCode,WPARAM wParam,LPARAM lParam);
HHOOK hCallWndProcHook = NULL;
LRESULT CALLBACK CallWndProcHook(int nCode,WPARAM wParam,LPARAM lParam);
//---------------------------------------------------------------------------
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
if(reason == DLL_PROCESS_ATTACH)
{
char ModBuf[256];
ZeroMemory(ModBuf,sizeof(ModBuf));
GetModuleFileName(NULL,ModBuf,sizeof(ModBuf));
if(AnsiString(ModBuf).LowerCase().Pos("explorer") > 0)
{
hShellTrayWnd = FindWindow("Shell_TrayWnd",NULL);
if(hShellTrayWnd != NULL)
{
// 替换Shell_TrayWnd窗口的窗口过程
FOldProc = (FARPROC)SetWindowLong(hShellTrayWnd,GWL_WNDPROC,long(ShellTrayWindowProc));
// 保存时钟窗口的窗口位置
HWND hClockWnd;
hClockWnd = FindWindowEx(hShellTrayWnd,0,"TrayNotifyWnd",NULL);
hClockWnd = FindWindowEx(hClockWnd,0,"TrayClockWClass",NULL);
if(hClockWnd != NULL)
{
GetWindowRect(hClockWnd,&FClockWinRect);
}
}
}
hInst = hinst;
//=============
HookWindowHandle = FindWindow(HookClassName.c_str(),NULL);
}
else if(reason == DLL_PROCESS_DETACH)
{
char ModBuf[256];
ZeroMemory(ModBuf,sizeof(ModBuf));
GetModuleFileName(NULL,ModBuf,sizeof(ModBuf));
if(AnsiString(ModBuf).LowerCase().Pos("explorer") > 0)
{
SetWindowLong(hShellTrayWnd,GWL_WNDPROC,long(FOldProc));
}
}
return 1;
}
//---------------------------------------------------------------------------
int DLL_EXP_IMP SetShow(bool IsShow)
{
return false;
}
//---------------------------------------------------------------------------
int DLL_EXP_IMP Hook()
{
hCallWndProcHook = SetWindowsHookEx(WH_CALLWNDPROC,(HOOKPROC)CallWndProcHook,hInst,0);
return 1;
}
//---------------------------------------------------------------------------
int DLL_EXP_IMP Unhook()
{
UnhookWindowsHookEx(hCallWndProcHook);
return 1;
}
//---------------------------------------------------------------------------
// 这个Hook不做任何事,目的只是为了加载DLL到Explorer.Exe进程。
LRESULT CALLBACK CallWndProcHook(int nCode,WPARAM wParam,LPARAM lParam)
{
if(nCode < 0)
return CallNextHookEx(hCallWndProcHook,nCode,wParam,lParam);
return 0;
}
//---------------------------------------------------------------------------
LRESULT CALLBACK ShellTrayWindowProc(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
if(uMsg == WM_NCLBUTTONDBLCLK)
{
TPoint P;
GetCursorPos(&P);
if(PtInRect(&FClockWinRect,P))
{
SendMessage(HookWindowHandle,WM_TRIGGERCLOCKWND,0,0);
return 0;
}
}
return CallWindowProc((FARPROC)FOldProc,hwnd,uMsg,wParam,lParam);
}
//---------------------------------------------------------------------------
主程序部分=======================================================
主程序部分=======================================================
主程序部分=======================================================
void __fastcall THookSysMsgForm::WndProc(Messages::TMessage &Message)
{
TForm::WndProc(Message);
if(Message.Msg == WM_TRIGGERCLOCKWND)
{
Application->Restore();
ShowWindow(Application->Handle,SW_HIDE);
this->Visible = true;
// 强制把窗口显示到最前面
SetWindowPos(this->Handle,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTDOWN,this->Left+20,this->Top+10,0,0);
Sleep(10);
mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTUP,this->Left+20,this->Top+10,0,0);
SetWindowPos(this->Handle,HWND_NOTOPMOST,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
SetForegroundWindow(this->Handle);
}
else if(Message.Msg == WM_SIZE)
{
ShowWindow(Application->Handle,SW_HIDE);
}
}
当然,主程序部分还有其它事情要做,比如如何隐藏图标等。Top
38 楼copy_paste(木石三)回复于 2002-12-31 00:48:04 得分 0
哦,原来如此,明白
牛哥不多写点教导教导俺们。。。
偶原来想的是替换ClockHandle的窗体,你为什么替换的是Shell_Tray的?Top
39 楼binbin(破坏分子)回复于 2002-12-31 00:58:18 得分 0
牛人,就是牛人.Top
40 楼slwqw(四大名捕之追杀令)回复于 2002-12-31 00:59:21 得分 0
“偶原来想的是替换ClockHandle的窗体,你为什么替换的是Shell_Tray的?”
因为那个时钟窗口变态,它不接受任何鼠标消息,就算替换了,你也截获不到任何有用的消息!!!
因此只好对它的爷爷下手(它的老爸TrayNotifyWnd也同样不接受鼠标消息)^_^
Top
41 楼copy_paste(木石三)回复于 2002-12-31 01:04:48 得分 0
口合~~~口合~~~口合~~~
他爷爷下手你也下手。。。
口合~~~口合~~~口合~~~Top
42 楼slwqw(四大名捕之追杀令)回复于 2002-12-31 01:12:19 得分 0
:)Top
43 楼mustang_zr()回复于 2002-12-31 08:45:00 得分 0
TO BCB_FANS:
老大,我看了你写的程序,感觉就是窗口的子类化啊
那为何还要用到钩子呢?是否一定要将DLL注入到Exeplore.exe进程的
地址空间内才能够完成呢?
期待你的回答
Top
44 楼binbin(破坏分子)回复于 2002-12-31 09:30:02 得分 0
To mustang_zr() :
跨进程了啊!不同进程间的内存是独立的,不能把一个进程中的过程地址传到另一个进程中作窗口过程,在另一进程中这个地址根本不是你进程里相同地址的内容.Top
45 楼binbin(破坏分子)回复于 2002-12-31 09:30:46 得分 0
只有注入了DLL,这个dll才能和Explorer.exe在同一进程空间,才能子类化啊.Top
46 楼mustang_zr()回复于 2002-12-31 09:33:27 得分 0
TO binbin
多谢!
不好意思,基础知识不牢.见笑 补课ing.....Top
47 楼jishiping(JSP 季世平)回复于 2002-12-31 11:05:40 得分 35
昨天睡觉前,想到一个很简单的法子,根本不用钩子这么复杂(毕竟使用钩子会使系统性能降低)。办法就是取得时钟窗口,用自己的一个窗口代替时钟窗口,这样所有的操作都是针对自己的窗口。原理简单吧。下面的代码,Form1是主窗口,Form2是代替始终的窗口,Form2为自动创建的。
class TForm1 : public TForm
{
__published: // IDE-managed Components
void __fastcall FormShow(TObject *Sender);
private: // User declarations
protected:
void __fastcall WndProc(TMessage& Msg);
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------
void __fastcall TForm1::WndProc(TMessage& Msg)
{
if (Msg.Msg==WM_SYSCOMMAND && (Msg.WParam
&0xFFF0)==SC_ICON) {
//拦截主窗口的最小化消息,使它隐藏
Msg.Result = 0; Visible = false;
Form2->Show(); //显示自己的时钟窗口
}
else
TForm::WndProc(Msg);
}
//---------------------------------------------------------------
void __fastcall TForm1::FormShow(TObject *Sender)
{
//隐藏任务栏上的程序按钮
ShowWindow(Application->Handle, SW_HIDE);
}
class TForm2 : public TForm
{
__published: // IDE-managed Components
TPanel *Panel1; //用来显示时钟文字
TTimer *Timer1;
void __fastcall FormShow(TObject *Sender);
void __fastcall Timer1Timer(TObject *Sender);
void __fastcall Panel1DblClick(TObject *Sender);
private: // User declarations
HWND hClock;
public: // User declarations
__fastcall TForm2(TComponent* Owner);
};
__fastcall TForm2::TForm2(TComponent* Owner)
: TForm(Owner), hClock(NULL)
{
char* ClassName[3] = {"Shell_TrayWnd",
"TrayNotifyWnd", "TrayClockWClass"};
BorderStyle = bsNone;
Panel1->Align = alClient;
Panel1->BevelInner = bvNone;
Panel1->BevelOuter = bvNone;
for(int n=0; n<3; n++) {
hClock = FindWindowEx(n?hClock
:0, 0, ClassName[n], NULL);
if (hClock==NULL) break;
}
if (hClock != NULL) {
int hFont = SendMessage(hClock,
WM_GETFONT, 0, 0);
Panel1->Font->Handle = hFont!=0
? (HANDLE)hFont : Screen->
IconFont->Handle;
}
}
//---------------------------------------------------------------------------
void __fastcall TForm2::FormShow(TObject *Sender)
{
TRect Rect;
Timer1Timer(Timer1);
GetWindowRect(hClock, &Rect);
SetBounds(Rect.left, Rect.top,
Rect.Width(), Rect.Height());
}
//---------------------------------------------------------------------------
void __fastcall TForm2::Timer1Timer(TObject *Sender)
{
Panel1->Caption = Now().FormatString("hh:nn");
}
//---------------------------------------------------------------------------
void __fastcall TForm2::Panel1DblClick(TObject *Sender)
{
Form1->Show(); Visible = false; //这儿你可以不隐藏时钟窗口
}Top
48 楼xt_nibin(野人小子)回复于 2002-12-31 15:27:13 得分 0
首先多谢各位,小弟家里没上网,今早又有点事没来;
BCB_FANS和JSP等各位大侠你们给了小弟这么多的代码,让小弟感动的真是快说不出话了,只是小弟水平太那个了,我还没看懂这些代码!
BCB_FANS大侠我的EM是“xt_nibin@163.net”,劳你把有DEMO的工程发给小弟!再一次谢谢!Top
49 楼slwqw(四大名捕之追杀令)回复于 2002-12-31 16:27:25 得分 0
已经发送,注意查收!Top
50 楼cker(〖烟波浩淼三千里、人鬼殊途五百年〗)回复于 2002-12-31 19:51:21 得分 0
哈哈,好好的一个任务栏,被你们弄得乌七八糟,,,,:)
老比生气中,,,,.....:(Top
51 楼lluunn007(书生)回复于 2002-12-31 20:11:44 得分 0
看完收工。
受益非浅。
谢了各位。
新年快乐。Top
52 楼passion2002(黑侠)回复于 2002-12-31 20:27:25 得分 0
牛人真是多呀!
佩服,佩服!
学习,学习!Top
53 楼binbin(破坏分子)回复于 2003-01-01 00:23:18 得分 0
俺发现,用鼠标钩子钩不住这个时钟窗口!?
必须用低级鼠标钩子,这样就得自己判断双击了.
而且用了低级鼠标钩子,也吃不掉这个消息,双击时我的程序捕捉到,时钟程序也同时跳出来.
俺的代码,请指正:
//DLL文件
#include <windows.h>
#define DllExport __declspec (dllexport)
HHOOK hMouseHook = NULL;
HINSTANCE hInst=NULL;
DllExport void WINAPI Hook();
DllExport void WINAPI UnHook();
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
hInst=hinst;
return 1;
}
//---------------------------------------------------------------------------
LRESULT CALLBACK MouseProc(int nCode,WPARAM wParam,LPARAM lParam)
{
if (HC_ACTION==nCode && WM_LBUTTONDOWN==wParam)
{
static unsigned long lastclick(0);
if (GetDoubleClickTime()>((LPMSLLHOOKSTRUCT)lParam)->time - lastclick)
{
char ClockClass[255];
GetClassName(WindowFromPoint(((LPMSLLHOOKSTRUCT)lParam)->pt),ClockClass,255);
if (0==strcmp(ClockClass,"TrayClockWClass"))
{
MessageBox(NULL,ClockClass,"Capture",MB_OK);
return 1;//此句吃不掉???
}
}
lastclick = ((LPMSLLHOOKSTRUCT)lParam)->time;
}
LRESULT Result=CallNextHookEx(hMouseHook,nCode,wParam,lParam);
return Result;
}
void WINAPI Hook()
{
hMouseHook = SetWindowsHookEx(WH_MOUSE_LL,(HOOKPROC)MouseProc,hInst,0);
}
//---------------------------------------------------------------------------
void WINAPI UnHook()
{
UnhookWindowsHookEx(hMouseHook);
}
//===============================================================
//调用文件
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
void WINAPI Hook();
void WINAPI UnHook();
#include "appUnit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Hook();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
UnHook();
}
//---------------------------------------------------------------------------
Top
54 楼binbin(破坏分子)回复于 2003-01-01 00:32:53 得分 0
牛人 BCB_FANS 在不在,解释一下鼠标钩子问题好不好?
这是不是你说的鼠标钩子的bug?Top
55 楼slwqw(四大名捕之追杀令)回复于 2003-01-01 16:50:01 得分 0
没有必要使用低级鼠标沟子,使用普通的鼠标沟子就可以了。而且我也没有使用过低级鼠标沟子,无法解释你的那个问题。
LRESULT CALLBACK MouseHook(int nCode,WPARAM wParam,LPARAM lParam)
{
if(nCode < 0)
return CallNextHookEx(MouseHookID,nCode,wParam,lParam);
if((int)wParam == WM_NCLBUTTONDBLCLK)
{
TPoint P;
GetCursorPos(&P);
if(PtInRect(&FClockWinRect,P))
{
SendMessage(HookWindowHandle,WM_TRIGGERCLOCKWND,0,0);
return 1; // 阻止鼠标消息继续传递
}
}
return 0;
}
//---------------------------------------------------------------------------
我所说的Bug,是指:只要在双击的过程中鼠标略为移动,任务栏就跑到右边去了。那晚我试了,好多次都这样!(也有可能是我的光电鼠标引起的,因为这种鼠标的毛病就是容易不自主地发抖!)
=====================
为什么“http://www.csdn.net/expert”一直打不开,从昨天到现在现!!!(可是我却在这里回复,是不是很奇怪???我也觉得很奇怪!!!见鬼了!)。
Top
56 楼bcbsoft(苍之雪)回复于 2003-01-01 17:26:22 得分 0
BCB版的高手多!Top
57 楼binbin(破坏分子)回复于 2003-01-01 19:39:31 得分 0
CSDN论坛今天一天都打不开!
俺的MouseProc中也是return 1;了啊,看俺上面的代码.
俺的普通钩子就是钩不住啊.其他窗口可以,就是在时钟上没反应!
俺是Win2K当SP3,打过最新的补丁,前几天才windows update过.Top
58 楼slwqw(四大名捕之追杀令)回复于 2003-01-01 20:33:15 得分 0
char ClockClass[255];
GetClassName(WindowFromPoint(((LPMSLLHOOKSTRUCT)lParam)->pt),ClockClass,255);
if (0==strcmp(ClockClass,"TrayClockWClass"))
=============
是这里的问题。虽然你在时钟窗口上面单击鼠标,但是我在上面已经说了,这个时钟窗口变态,它不接受任何鼠标消息(以及它的Parent),因此上面得到的类名实际上是“Shell_TrayWnd”,而不是“TrayClockWClass”。Top
59 楼slwqw(四大名捕之追杀令)回复于 2003-01-01 20:47:37 得分 0
所以必须使用PtInRect()方法。Top
60 楼binbin(破坏分子)回复于 2003-01-01 23:10:12 得分 0
但是,在俺这里明确地得到了"TrayClockWClass",截取也成功了--俺的MessageBox弹出来了,但时钟设置也同时弹出来,难道不同版本的w2k不一样?Top
61 楼binbin(破坏分子)回复于 2003-01-01 23:37:07 得分 0
你们到ms的windows update站上升级一下,看看是不是一样.Top
62 楼iec(bcbtovs)回复于 2003-01-02 08:54:38 得分 0
占个位置Top
63 楼slwqw(四大名捕之追杀令)回复于 2003-01-02 09:36:49 得分 0
奇怪,下面是我的代码。双击时钟窗口时,显示的类名的确是“Shell_TrayWnd”。
难道低级鼠标沟子不一样???我试试先。
=================================
LRESULT CALLBACK MouseHook(int nCode,WPARAM wParam,LPARAM lParam)
{
if(nCode < 0)
{
return CallNextHookEx(MouseHookID,nCode,wParam,lParam);
}
if((int)wParam == WM_NCLBUTTONDBLCLK)
{
TPoint P;
char ClassName[16];
HWND hCurrentWnd;
GetCursorPos(&P);
hCurrentWnd = WindowFromPoint(P);
ZeroMemory(ClassName,sizeof(ClassName));
GetClassName(hCurrentWnd,ClassName,sizeof(ClassName));
SendMessage(HookWindowHandle,WM_SETTEXT,0,(LPARAM)AnsiString(ClassName).c_str());
if(AnsiString(ClassName) == "TrayClockWClass")
{
SendMessage(HookWindowHandle,WM_SETTEXT,0,(LPARAM)"Clock Click now.");
}
// return 1; // 阻止弹出时钟窗口
}
return 0;
}
//---------------------------------------------------------------------------
Top
64 楼penu(懒猫·子在川上之再上征程·杀人无心之寓怒于静)回复于 2003-01-02 09:50:46 得分 0
学习!学习!!Top
65 楼slwqw(四大名捕之追杀令)回复于 2003-01-02 10:22:00 得分 20
低级鼠标沟子果然不一样,可以得到正确的类名。不过就算是低级鼠标沟子也同样可以Hook。下面是我的代码,可以屏蔽时钟窗口地弹出。
LRESULT CALLBACK MouseHookLL(int nCode,WPARAM wParam,LPARAM lParam)
{
if(nCode < 0)
{
return CallNextHookEx(MouseHookID,nCode,wParam,lParam);
}
static int LastTick = -1;
if((int)wParam == WM_LBUTTONDOWN))
{
int ThisTick = GetTickCount();
int DeltaTick = ThisTick - LastTick;
LastTick = ThisTick;
///
TPoint P;
char ClassName[16];
HWND hCurrentWnd;
GetCursorPos(&P);
hCurrentWnd = WindowFromPoint(P);
ZeroMemory(ClassName,sizeof(ClassName));
GetClassName(hCurrentWnd,ClassName,sizeof(ClassName));
SendMessage(HookWindowHandle,WM_SETTEXT,0,(LPARAM)AnsiString(ClassName).c_str());
if(AnsiString(ClassName) == "TrayClockWClass" && DeltaTick < 519)
{
SendMessage(HookWindowHandle,WM_SETTEXT,0,
(LPARAM)AnsiString("Hook Now..." + IntToStr(DeltaTick)).c_str());
return 1;
}
}
return 0;
}
其中那个519是双击的时间间隔。在我的电脑上是这个值,实际应用时应该从注册中读取。它位于HKEY_CURRENT_USER\Control Panel\Mouse下面的“DoubleClickSpeed”值。
===========
又收获不少,感谢楼主提这个问题 :)Top
66 楼binbin(破坏分子)回复于 2003-01-02 11:32:29 得分 0
BCB_FANS根本没仔细看俺的代码!;(
俺是这样双击判断的:
if (GetDoubleClickTime()>((LPMSLLHOOKSTRUCT)lParam)->time - lastclick)
有个GetDoubleClickTime()函数的,不用读注册表
(LPMSLLHOOKSTRUCT)lParam)->time保存了鼠标事件发生的时间不用GetTickCountTop
67 楼binbin(破坏分子)回复于 2003-01-02 11:35:52 得分 0
为什么俺的return 1;就不行呢?Top
68 楼xzgyb(老达摩)回复于 2003-01-02 12:07:02 得分 0
学习Top
69 楼slwqw(四大名捕之追杀令)回复于 2003-01-02 12:09:46 得分 0
你的代码在我这里同样可以屏蔽那个时钟窗口!!!!我也想不出你哪里有问题 :(。
我的平台:Windows 2000 Pro中文版 + SP3
=====
Top
70 楼binbin(破坏分子)回复于 2003-01-02 12:18:21 得分 0
xzgyb(老达摩):
向你学习,上次俺那个inherted和DefaultHandler的问题多谢你的研究!Top
71 楼binbin(破坏分子)回复于 2003-01-02 12:49:08 得分 0
俺试了XP,也是一样,唉...Top
72 楼xt_nibin(野人小子)回复于 2003-01-02 13:25:01 得分 0
首先在新的一个中祝各位新年快乐!
BCB_FANS老大,你的钩窗口代码?小弟先研后试,能通过Buil,但就是无法达到想要的效果,也就是说这个HOOK好象没起作用,我的平台是XP中文版,加过SP1的。
具体是我在主FROM的Create事件中调用Hook的,并在Close事件Unhook,但是我单击那个变态的时钟时不能让我的主FROM显示,反而是盖子头的那个时钟出来了。另你发给我的EM我没有收到,不知是为什么?????Top
73 楼binbin(破坏分子)回复于 2003-01-02 13:36:21 得分 0
俺的代码在w2K,XP上都可以,就是时钟消不掉啊!Top
74 楼binbin(破坏分子)回复于 2003-01-02 13:38:33 得分 0
实在不行, 俺就FindWindow+WM_DESTROY.
俺去试试了Top
75 楼xzgyb(老达摩)回复于 2003-01-02 13:40:59 得分 0
binbin:
想了半天
想起来了
呵呵
互相学习
不谢
Top
76 楼binbin(破坏分子)回复于 2003-01-02 13:53:05 得分 5
奇怪的事情发生了,俺给程序稍作改动就好了.
俺的程序如下:
//DLL部分:
#include <windows.h>
#define DllExport __declspec (dllexport)
HHOOK hMouseHook = NULL;
HINSTANCE hInst=NULL;
DllExport void WINAPI Hook();
DllExport void WINAPI UnHook();
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
hInst=hinst;
return 1;
}
//---------------------------------------------------------------------------
LRESULT CALLBACK MouseProc(int nCode,WPARAM wParam,LPARAM lParam)
{
if (HC_ACTION==nCode && WM_LBUTTONDOWN==wParam)
{
static unsigned long lastclick(0);
if (GetDoubleClickTime()>((LPMSLLHOOKSTRUCT)lParam)->time - lastclick)
{
char ClockClass[255];
GetClassName(WindowFromPoint(((LPMSLLHOOKSTRUCT)lParam)->pt),ClockClass,255);
if (0==strcmp(ClockClass,"TrayClockWClass"))
{
HWND mywnd=FindWindow("TForm1","myWindow");
ShowWindow(mywnd,SW_SHOW);
HWND tmphwnd=GetForegroundWindow();//将进程与前台进程挂接以对窗口操作,否则Windows阻止跨进程的窗口Z-order操作
if(AttachThreadInput(GetWindowThreadProcessId(mywnd,NULL),GetWindowThreadProcessId(tmphwnd,NULL),1)){
SetActiveWindow((HWND)mywnd);
AttachThreadInput(GetWindowThreadProcessId(mywnd,NULL),(DWORD)tmphwnd,0);
}
return 1;//此句吃不掉???
}
}
lastclick = ((LPMSLLHOOKSTRUCT)lParam)->time;
}
LRESULT Result=CallNextHookEx(hMouseHook,nCode,wParam,lParam);
return Result;
}
void WINAPI Hook()
{
hMouseHook = SetWindowsHookEx(WH_MOUSE_LL,(HOOKPROC)MouseProc,hInst,0);
}
//---------------------------------------------------------------------------
void WINAPI UnHook()
{
UnhookWindowsHookEx(hMouseHook);
}
//应用程序:
#include <vcl.h>
#pragma hdrstop
void WINAPI Hook();
void WINAPI UnHook();
#include "appUnit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
Hook();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
UnHook();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Hide();
}
//---------------------------------------------------------------------------
Top
77 楼binbin(破坏分子)回复于 2003-01-02 13:54:56 得分 0
return 1;那句的注释忘了去掉了.现在工作正常,
俺去XP上试试.Top
78 楼binbin(破坏分子)回复于 2003-01-02 14:16:04 得分 0
俺发现窗口隐藏用Hide不行,看来API与VCL之间还是有一点兼容问题,Hide方法还涉及到Application的窗口,真烦人.
干脆不要任务栏按钮了.
应用程序修改:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
void WINAPI Hook();
void WINAPI UnHook();
#include "appUnit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{ ShowWindow(Application->Handle,SW_HIDE);
Hook();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
UnHook();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
ShowWindow(Handle,SW_HIDE);//直接用API,不用VCL Hide方法.对应Dll中的ShowWindow API
}
//---------------------------------------------------------------------------
Top
79 楼slwqw(四大名捕之追杀令)回复于 2003-01-02 14:43:08 得分 0
To : binbin(BCB水王(不提倡大家向俺学习))
邪门!看不出改动之后的代码对阻止消息传递有什么作用?
To : xt_nibin
我这里没有XP,无法帮你测试,建议使用SPY++自己跟踪一下(比如窗口结构是否还跟2000一样等)。
奇怪,我明明发了E-Mail啊。再发......Top
80 楼xt_nibin(野人小子)回复于 2003-01-02 15:09:46 得分 0
你好老大,我想可能是163.net有问题吧!这次已经收到!而且你的DEMO工程在我这台WIN2K+SP3上工作正常!我回去再试WINXP!
还有小弟想请教我在DOS里常可接管中断的,如时钟中断,在WINDOWS里有同样的方法吗?小弟有一个程序是用C++ Builder的定时器完成的,但总感觉消耗系统的资源过多,小弟是想接管WINDOWS的时间,到了定义的时间时就发一个消息到一个自已的程序,我看了MSDN的钩子部分,好象钩子没办法钩住时钟,能和你单独谈谈吗?我的QQ是24917896。谢谢!Top
81 楼slwqw(四大名捕之追杀令)回复于 2003-01-02 15:36:58 得分 0
接管时钟中断?不知道。Top
82 楼pazee(耙子)(今年过年不收礼,收礼只收尿不湿)回复于 2003-01-03 12:09:00 得分 0
BCB_FANS真是个牛人!Top
83 楼pazee(耙子)(今年过年不收礼,收礼只收尿不湿)回复于 2003-01-03 12:10:44 得分 0
DOS 那种接管时钟中断 Int 8, Int 1CH的办法在window nt下面是断然行不通的了。
和他类似的方法就是季头说的钩子。Top
84 楼RomanticProgrammer() 兰企鹅||南极俺最帅 ()回复于 2003-01-03 14:48:54 得分 0
牛人都到齐了啊..
听课...
Top
85 楼RomanticProgrammer() 兰企鹅||南极俺最帅 ()回复于 2003-01-03 14:49:30 得分 0
BCB_FANS真是个牛人!Top
86 楼RomanticProgrammer() 兰企鹅||南极俺最帅 ()回复于 2003-01-03 14:50:04 得分 0
吃草否?
:)Top
87 楼xt_nibin(野人小子)回复于 2003-01-03 16:47:12 得分 0
好了,在CDSN里真是感到温馨,这么多高人特别是BCB_FANS等都对小弟这样的照顾,小弟的问题已经解决!请允许小弟在这里再一次说声谢谢!
另小弟想对这个问题的最终解决方案作一些补充;对BCB_FANS和另一些大哥使用不管是MOUSE钩子还是WndProc钩子都基本上可以达到这个效果,但我想各位可能都没想过WINDOWS的任务栏一但拖动到左边或别的地方,程序就将无法正常工作了,这主要是在开始时就把Clock的位置保存了,而拖动后Clock的位置就变了,所以……,我想各位可能会说这只要再钩Shell_Tray,在他发出WM_SIZE事件时通知程序重新获得Clock的区域,这办法很好,小弟的程序也是这样做的,但各位想过没有,这样在系统里就会有一个以上的钩子,本来钩子就对系统的性能就有影响,更别说多个了,我想这样不是很好的;而对于JSP大哥的方法我看一直都没有哪位对其再研究和讨论了,其实小弟认为JSP大哥的方法用自已窗口代替原WINDOWS时钟窗口是一个比较好的办法,因为我想我们花这么大的工夫来钩这么一个Clock一定不只是为了他的双击事件,而是要处理很多事件的,如MOVE等,而如果一味的使用钩子发自定义消息,我想不管是这个.dll 还是主程序都是过于麻烦的,甚至只要一想做点特别的工作就又需要重写并编译.DLL的和全部的工程,但对自已的窗口就不同了,你什么都可以干,这个我想小弟不需要再哆嗦了吧!但JSP大哥你说的使用钩子麻烦这也是不可避勉的,因为如我以上所说,我们需要用钩子来钩住Shell_Tray一但他WM_SIZE或是重画时就通知主程序重新定位那个替代窗口的位置和大小。我不知道我这样做各位老大是否有什么意见?
以上小弟只是针对小弟想完成的功能;由于代码部分与以上各位高人的大同小异,所以在这里就不贴出来了。Top
88 楼slwqw(四大名捕之追杀令)回复于 2003-01-03 17:26:43 得分 5
实际上对原来的代码略为更改一下就可以了。说白了就是动态查询时钟窗口的位置,而不是一开始就保存。
=========================
if(uMsg == WM_NCLBUTTONDBLCLK)
{
TPoint P;
TRect FClockWinRect;
GetCursorPos(&P);
GetWindowRect(hClockWnd,&FClockWinRect); // hClockWnd在DLL的初始化部分保存。
if(PtInRect(&FClockWinRect,P))
{
SendMessage(HookWindowHandle,WM_TRIGGERCLOCKWND,0,0);
return 0;
}
}
Top
89 楼binbin(破坏分子)回复于 2003-01-03 17:50:51 得分 0
俺 的代码没有保存啊.是实时检测的.Top
90 楼xt_nibin(野人小子)回复于 2003-01-04 11:02:42 得分 0
老大就是老大,我怎么就没想到实时检测呢!但是老大实时检测虽然可能解决任务栏拖动的问题,但是我如想要TrayClockWClass的WM_NCMOUSEMOVE,WM_NCRBUTTONDBLCLK等怎么办,我的代码里一用到这些,WINDOWS里的属性POPUP菜单就会出来,是不是要用你们上面谈的底级MOUSE钩子。还有如果我想在MOUSE一移到CLOCK时就显示一个Hint有什么好办法!Top
91 楼slwqw(四大名捕之追杀令)回复于 2003-01-04 11:32:30 得分 0
老兄,你总得自己挖掘一下吧?Top
92 楼xt_nibin(野人小子)回复于 2003-01-04 14:23:35 得分 0
我看我还是用窗口替代算了吧!Top





