CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
花落谁家,你作主! 盛大widget设计大赛英雄榜
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  VB >  API

【问】除了定时查询以外,如何知道改变了当前焦点窗体?(如:从记事本切换到了IE)

楼主VBAHZ(凌云(E文词汇量580))2004-12-01 15:57:53 在 VB / API 提问

 
  问题点数:20、回复次数:8Top

1 楼henry520()回复于 2004-12-13 16:05:50 得分 1

关注Top

2 楼yiway(一味)回复于 2004-12-13 16:08:59 得分 2

关注,  
   
  鄙人愚见:应该可以通过系统调用解决,具体方法学习中Top

3 楼wwqna(york)回复于 2004-12-13 18:02:20 得分 1

没办法,只有查询Top

4 楼VBAHZ(凌云(E文词汇量580))回复于 2004-12-19 14:04:50 得分 0

GZ  
  Top

5 楼myjian(嗷嗷叫的老马--很不顺.....最近.....很不顺.........)回复于 2004-12-19 20:20:00 得分 10

晕,Windows整个都是消息方式来执行的啊,怎么会只能查询啊。  
   
  正好我给一个朋友做了一个网吧管理系统里有这样的功能:记录当前焦点的窗体的句柄,记录切换到了哪个窗体。  
   
  代码摘自网上,如下:  
   
  *******************************************  
   
  '   窗体部分的代码(Form1.frm)  
  Option   Explicit  
  Private   Sub   Form_Load()  
  Dim   tmp   As   Long  
  '   将日志程序的名称从   CTRL+ALT+DEL   列表中清除  
  'tmp   =   RegisterServiceProcess(ByVal   0&,   1)  
  Timer1.Interval   =   60000   '   定时器的作用是每隔一分钟将日志存盘  
  '   定义一个新的系统级的消息类型  
  Msg_ID   =   RegisterWindowMessage("SHELLHOOK")  
  Call   RegisterShellHook(hwnd,   1)   '   调用未公开的函数(进行注册)  
  '   实施拦截:在存储了原入口地址的同时,将新地址指向自定义的函数WindowProc  
  Original   =   SetWindowLong(hwnd,   GWL_WNDPROC,   AddressOf   WindowProc)  
  SetWindowPos   Me.hwnd,   HWND_TOPMOST,   0,   0,   0,   0,   SWP_NOMOVE   Or   SWP_NOSIZE  
  '   将窗口设为总在最前  
   
  End   Sub  
  Private   Sub   Form_Unload(Cancel   As   Integer)  
  Dim   tmp   As   Long  
  Call   RegisterShellHook(hwnd,   0)   '   调用未公开的函数(取消注册)  
  'tmp   =   SetWindowLong(hwnd,   GWL_WNDPROC,   Original)   '   将入口地址还原  
  End   Sub  
   
  **************************  
   
  '   模块部分的代码(模块1.bas)  
  Public   Declare   Function   RegisterShellHook   Lib   "Shell32"   Alias   "#181"   _  
  (ByVal   hwnd   As   Long,   ByVal   nAction   As   Long)   As   Long  
  Public   Declare   Function   RegisterWindowMessage   Lib   "user32"   Alias   _  
  "RegisterWindowMessageA"   (ByVal   lpString   As   String)   As   Long  
  Public   Declare   Function   SetWindowLong   Lib   "user32"   Alias   "SetWindowLongA"   _  
  (ByVal   hwnd   As   Long,   ByVal   nIndex   As   Long,   ByVal   dwNewLong   As   Long)   As   Long  
  Public   Declare   Function   GetWindowText   Lib   "user32"   Alias   "GetWindowTextA"   _  
  (ByVal   hwnd   As   Long,   ByVal   lpString   As   String,   ByVal   cch   As   Long)   As   Long  
  Public   Declare   Function   CallWindowProc   Lib   "user32"   Alias   "CallWindowProcA"   _  
  (ByVal   lpPrevWndFunc   As   Long,   ByVal   hwnd   As   Long,   ByVal   Msg   As   Long,   ByVal   _  
  wParam   As   Long,   ByVal   lParam   As   Long)   As   Long  
  Public   Declare   Function   RegisterServiceProcess   Lib   "kernel32"   _  
  (ByVal   dwProcessID   As   Long,   ByVal   dwType   As   Long)   As   Long  
  Const   HSHELL_WINDOWCREATED   =   1   '   系统级的窗体被创建  
  Const   HSHELL_WINDOWDESTROYED   =   2   '   系统级的窗体即将被关闭  
  'Const   HSHELL_ACTIVATESHELLWINDOW   =   3   '   SHELL   的主窗体将被激活(本例未用)  
  Const   HSHELL_WINDOWACTIVATED   =   4   '   系统级的窗体被激活  
  'Const   HSHELL_GETMINRECT   =   5   '   窗体被最大化或最小化(本例未用)  
  'Const   HSHELL_REDRAW   =   6   '   Windows   任务栏被刷新(本例未用)  
  'Const   HSHELL_TASKMAN   =   7   '   任务列表的内容被选中(本例未用)  
  'Const   HSHELL_LANGUAGE   =   8   '   中英文切换或输入法切换(本例未用)  
  Public   Const   GWL_WNDPROC   =   -4   '   该索引用来创建窗口类的子类  
  Public   Msg_ID   As   Long,   Original   As   Long  
  Public   Function   WindowProc(ByVal   hwnd   As   Long,   ByVal   uMsg   As   Long,   ByVal   _  
  wParam   As   Long,   ByVal   lParam   As   Long)   As   Long   '   回调函数  
  Dim   tmp1   As   String,   tmp2   As   String,   i   As   Long  
  If   uMsg   =   Msg_ID   Then  
  tmp1   =   String(200,   "*")  
  i   =   GetWindowText(lParam,   tmp1,   200)   '   取窗体的标题  
  If   i   >   0   Then   tmp1   =   Left(tmp1,   i)   Else   tmp1   =   "未命名"  
  tmp1   =   tmp1   +   "   "   +   Str(Date)   +   "   "   +   Str(Time)   +   vbCrLf   '   加入日期  
  '   下面对窗体句柄值进行格式化的目的是为了日志文件在视觉上更美观  
  tmp2   =   Format(lParam,   "000000")  
  If   Right(Form1.Text1,   2)   <>   vbCrLf   Then   tmp2   =   vbCrLf   +   tmp2  
  Select   Case   wParam  
  Case   HSHELL_WINDOWCREATED  
  Form1.Text1   =   Form1.Text1   +   tmp2   +   "   创建:"   +   tmp1  
  Case   HSHELL_WINDOWDESTROYED  
  Form1.Text1   =   Form1.Text1   +   tmp2   +   "   关闭:"   +   tmp1  
  Case   HSHELL_WINDOWACTIVATED  
  Form1.Text1   =   Form1.Text1   +   tmp2   +   "   激活:"   +   tmp1  
  '   为了程序简洁,本例仅处理“创建”、“激活”和“关闭”这三个消息,  
  '   其实就生成日志文件的目的,上述三个消息已基本够用。  
  '   Case   ...  
  '   ...  
  End   Select  
  Else  
  '   使用已被存储下来的原入口地址  
  WindowProc   =   CallWindowProc(Original,   hwnd,   uMsg,   wParam,   lParam)  
  End   If  
  End   Function  
   
  ***********************************  
   
  '*************************************************************************  
  '**模   块   名:ModOnTop  
  '**说         明:将窗体放到Z轴最上层  
  '**创   建   人:马云剑  
  '**日         期:2004年10月27日  
  '**修   改   人:  
  '**日         期:  
  '**描         述:  
  '**版         本:V1.0  
  '*************************************************************************  
  Public   Declare   Function   SetWindowPos   Lib   "user32"   (ByVal   hwnd   As   Long,   ByVal   hWndInsertAfter   As   Long,   ByVal   x   As   Long,   ByVal   y   As   Long,   ByVal   cx   As   Long,   ByVal   cy   As   Long,   ByVal   wFlags   As   Long)   As   Long  
  Public   Const   HWND_TOPMOST&   =   -1  
  '   将窗口置于列表顶部,并位于任何最顶部窗口的前面  
  Public   Const   SWP_NOSIZE&   =   &H1  
  '   保持窗口大小  
  Public   Const   SWP_NOMOVE&   =   &H2  
  '   保持窗口位置  
   
   
  '**************  
  '*     使用方法     *  
  '**************  
   
  '在窗体Load事件里加入以下代码:  
   
  'SetWindowPos   Me.hwnd,   HWND_TOPMOST,   0,   0,   0,   0,   SWP_NOMOVE   Or   SWP_NOSIZE  
  '   将窗口设为总在最前  
   
  Top

6 楼myjian(嗷嗷叫的老马--很不顺.....最近.....很不顺.........)回复于 2004-12-19 20:22:20 得分 3

窗体部分还有一个过程忘了帖:  
   
  ***********************************  
   
  Private   Sub   Timer1_Timer()  
  If   Len(Text1.Text)   >   0   Then  
  Open   "C:\SystemLog.Sys"   For   Append   As   #1   '   以“添加”方式打开日志  
  Print   #1,   Text1.Text   '   日志自动存盘  
  Text1.Text   =   ""  
  Close   #1  
  End   If  
  End   Sub  
   
  Top

7 楼myjian(嗷嗷叫的老马--很不顺.....最近.....很不顺.........)回复于 2004-12-19 20:25:29 得分 3

这个代码在运行时,可以显示当前都切换了哪些焦点,以及焦点的标题。  
   
  但这个好像是用的子类,我不懂......  
   
  请大家解释一下什么是子类......  
   
  还有这个代码也请分析一下!!!3Q!Top

8 楼VBAHZ(凌云(E文词汇量580))回复于 2004-12-19 20:57:23 得分 0

就是这个,多谢!  
   
  子类嘛。。。俺也老菜一个,就俺的理解:  
  子类就是把送给窗体的消息,转到自己的代码段(形成了一个子“进程”?“类”?),处理自己想要接收到的信息,并把无关消息再扔给原窗体消息处理(VB的优势,就是封装了这一切细节,编程者无需关心消息过程)  
   
  本例来说,上面的代码是我看到的中文注释最多的一例(好久没这么亲切了,中文真好:),除去API定义外,没有几句了,应该很简单的,但助人为。。那个什么本啊,老兄具体哪里不明白请说,三个臭皮匠凑起来也够亮吧,呵呵    
   
  Top

相关问题

  • 定时关闭窗体的问题
  • 我做的记事本内的查找窗体时"Activeform"出错,我将如何除立?
  • 一个窗体中最多能用多少个定时器?
  • 模态窗体定时关闭问题,高手请进。
  • 如何让窗体过一定时间自动关闭?
  • 急迫:为什么定时器在web窗体中无法起作用?
  • 如何得到一个窗体的句柄,并定时向它发送消息?
  • Meno 2 记事本
  • 用window.open打开一个ie窗体,在此窗体关闭后,怎么刷新主窗体?
  • 奇怪!有一个xml,IE打不开,firefox打开乱码,记事本打开正常(xp下)

关键词

  • 代码
  • 函数
  • 消息
  • 系统
  • 窗体
  • 子类
  • hshell
  • tmp
  • 日志
  • swp

得分解答快速导航

  • 帖主:VBAHZ
  • henry520
  • yiway
  • wwqna
  • myjian
  • myjian
  • myjian

相关链接

  • Visual Basic类图书
  • Visual Basic类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo