| 发表于:2007-11-26 16:53:29 楼主 |
程序的功能目的很简单,如果程序窗口被其他程序挡住,按ctrl+z能把程序窗口切换到最前面来(成为当前窗口)。 实现的方式是:用一个键盘钩子监视ctrl+z,当这两个键被按下时,把程序窗口最大化,并置为topmost窗口。 出现问题的地方是,有时候切换几次后,再把程序关掉,会出现explorer.exe出错的提示,点确定后桌面消失,过一会儿才会出来。 键盘钩子写在一个dll里,代码是改自网上找来的一个键盘钩子的代码 dll代码: library hook; uses hookunit in 'hookunit.pas'; exports enablehotkeyhook, disablehotkeyhook; {$r *.res} begin hnexthookproc := 0; procsaveexit := exitproc; exitproc := @hotkeyhookexit; end. hookunit.pas代码: unit hookunit; interface uses windows, messages,dialogs,sysutils,inifiles,forms; var hnexthookproc: hhook;//保存setwindowshookex的返回值 procsaveexit: pointer; function keyboardhookhandler(icode: integer;wparam: wparam;lparam: lparam): lresult; stdcall; export; function enablehotkeyhook: bool; export;//安装钩子 function disablehotkeyhook: bool; export;//卸载钩子 procedure hotkeyhookexit; far; implementation function keyboardhookhandler(icode: integer;wparam: wparam;lparam: lparam): lresult; stdcall; export; const _keypressmask=$80000000;//键盘掩码常量 var myhandle,otherhandle:cardinal; ini:tinifile; s:string; scr_w,scr_h:integer; begin result:=0; if icode < 0 then //根据sdk说明,若icode小于0,调用callnexthookex并返回 begin result:=callnexthookex(hnexthookproc, icode, wparam, lparam); exit; end; // 监测是否按下了ctrl+z, if ((lparam and _keypressmask) = 0) and(getkeystate(vk_control) <0) and ((wparam = ord('z')) )then begin //以下是我自己改的部分 scr_h:=getdevicecaps(getwindowdc(getdesktopwindow),vertres);//高 scr_w:=getdevicecaps(getwindowdc(getdesktopwindow),horzres);//宽 s:=extractfilepath(application.exename)+'pic\button.ini'; ini:=tinifile.create(s); //从配置文件中读取程序的标题名 s:=ini.readstring('buttons','title',''); //找到程序窗口的句柄 myhandle:=findwindow(nil,pchar(s)); //最大化窗口 postmessage(myhandle,wm_syscommand,sc_maximize,0); //设置为topmost窗口 setwindowpos(myhandle,hwnd_topmost,0, 0,scr_w,scr_h, swp_nosize); //修改结束 result:=1; exit; end; end; function enablehotkeyhook: bool; export; begin result := false;//初始化返回值 if hnexthookproc <> 0 then//如果已经注册,直接退出 exit; //挂上键盘钩子,同时传回值必须保留下来,免得hook呼叫链结断掉 hnexthookproc:=setwindowshookex(wh_keyboard,keyboardhookhandler,hinstance,0); //注册hook result:=hnexthookproc <> 0;//通过返回值确定是否注册成功 end; function disablehotkeyhook: bool; export; begin if hnexthookproc <> 0 then begin unhookwindowshookex(hnexthookproc);//解除keyboard hook hnexthookproc:=0;//恢复标志 end; result:=hnexthookproc=0;//返回是否注销成功 end; procedure hotkeyhookexit; begin if hnexthookproc <> 0 then disablehotkeyhook;//如果忘了解除hook,自动代理解除动作 exitproc:=procsaveexit; end; end. 在主程序里调用这个钩子 在主窗体的onformcreate事件中调用loadhook加载钩子 procedure tform1.loadhook; var path:string; begin if hookhandle=0 then begin path:=extractfilepath(application.exename)+'hook.dll'; hookhandle:=loadlibrary(pchar(path)); if hookhandle> 0 then begin @enablehook:=getprocaddress(hookhandle,'enablehotkeyhook'); @disablehook:=getprocaddress(hookhandle,'disablehotkeyhook'); if @enablehook <> nil then enablehook; end; end; end; 在主窗体的onclose事件中调用unloadhook卸载钩子 procedure tform1.unloadhook; begin if @disablehook <> nil then begin disablehook; //if disablehook then // showmessage('注销钩子成功'); end; if hookhandle <> 0 then begin freelibrary(hookhandle); end; end; 请各位大哥帮我看看,有哪里写得不好导致程序不稳定 |
|
|
|
|