叶帆工作室

嵌入式开发爱好者(十年开发经验,精通C/C++/VC/VB/C#...)

刘洪峰ID:yefanqiu
521372次访问,排名81好友0人,关注者169
微软MVP / CSDN 2008十大MVB/MSDN中文技术论坛版主
yefanqiu的文章
原创 216 篇
翻译 0 篇
转载 3 篇
评论 1088 篇
叶帆的公告
本博客原创文章,作者保留一切权利,需经作者同意后方可转载,转载时 请注明[叶帆工作室]及文章链接。yefan@vip.sina.com
【简介】叶帆[微软MVP]
【文章】叶帆文章列表
【软件】叶帆共享软件列表
最近评论
jacle169:峰哥, micro Framework3.0 beta出了,我已经装到vs08里了,但是你的sdk不能注册到vs08里,你帮帮忙改个vs08 里能用的sdk吧,谢谢.
赵广涛:高手帮帮忙,VB画有两个Y轴的曲线图怎么画?
sfweb2008:老兄:
你真厉害!
你有VB Api函数功能及用法详解吗?我有好多这方面的问题不是很明白!还请指教,谢谢!

我的邮箱xsdjxx@tom.com
xweil:谢谢你的推荐,享用受益中
changesway:很有收获!谢谢
文章分类
收藏
    相册
    叶帆照片
    【叶帆软件】
    [01]VB源码之友(V2.1.548)
    [02]API浏览器.net(V5.0)
    [03]叶帆成语词典(V2.0.8)
    [04]叶帆密码库(V1.2.8)
    【叶帆资源】
    DAO 2.0引擎
    叶帆快速通道
    Windows Embedded 专题
    中文MSDN
    叶帆圈子--工业自动化
    叶帆工作室(博客园)
    叶帆工控--工业自动化
    叶帆群组--工业应用开发
    微软中文技术论坛
    瑞康社区论坛
    叶帆友情链接
    张欣
    枕善居
    莫依
    葛涵涛
    郑建
    陈辉
    马宁
    马骐
    魏涛序
    黎波
    存档
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    原创 获取Windows 外壳信息通知(VB源程序)收藏

    新一篇: 要想做真正的编程高手,还是应该踏实些,告别浮躁 | 旧一篇: [转]大量正版软件下载链接

            从网上看了一篇《分享windows的秘密-外壳通知消息》的文章,感觉很不错,可是它是delphi的程序,和VB相差很大,API在VB中没有对应的声明,并且一些结构体在VB中没有现成的定义,所以很是研究了一番,优盘的插入、拔出,光盘的插入、取出都有了相应的通知,效果不错。

          可以接收的消息如下:

      SHCNE_ASSOCCHANGED  一个文件关联被改变了
      SHCNE_ATTRIBUTES   
    一个项目或文件夹的属性被改变了
      SHCNE_CREATE       
    文件夹的外壳成员被创建了
      SHCNE_DELETE        
    非文件夹的外壳成员被删除了
      SHCNE_DRIVEADD     
    添加了一个驱动器
      SHCNE_DRIVEADDGUI  
    通过外壳添加的驱动器
      SHCNE_DRIVEREMOVED  
    一个驱动器被删除了
      SHCNE_EXTENDED_EVENT  
    未被使用
      SHCNE_FREESPACE    
    驱动器的自由空间数有了变化
      SHCNE_MEDIAINSERTED  
    存储介质被插入到驱动器中
      SHCNE_MEDIAREMOVED  
    存储介质从驱动器中被删除
      SHCNE_MKDIR        
    一个目录被创建
      SHCNE_NETSHARE     
    本地的目录被共享
      SHCNE_NETUNSHARE   
    本地目录被取消共享
      SHCNE_RENAMEFOLDER  
    文件夹名称被改变
      SHCNE_RENAMEITEM   
    非文件的外壳对象的名称被改变
      SHCNE_RMDIR        
    一个文件夹被删除
      SHCNE_SERVERDISCONNECT  
    计算机被服务器断开
      SHCNE_UPDATEDIR    
    一个文件夹中的内容被改变
      SHCNE_UPDATEIMAGE  
    系统图像列表中的一个图像被改变
      SHCNE_UPDATEITEM    
    一个非文件夹外壳对象的名称被改变

    运行后的截图:

      

    关键源码:

    '*************************************************************************
    '**函 数 名:WindowProc
    '**输    入:ByVal hwnd(Long)   -
    '**        :ByVal uMsg(Long)   -
    '**        :ByVal wParam(Long) -
    '**        :ByVal lParam(Long) -
    '**输    出:(Long) -
    '**功能描述:子类函数
    '**全局变量:
    '**调用模块:
    '**作    者:叶帆
    '**日    期:2005年12月23日
    '**修 改 人:
    '**日    期:
    '**版    本:V1.0
    '*************************************************************************
    Private Function WindowProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
        '-------------------------------
        Dim i As Long
        If uMsg = WM_YFSYSMSG Then
            For i = 0 To 20
                If (lParam And lngFlag(i)) > 0 Then
                    frmSysmsg.lstMsg.AddItem Format(Now, "HH:MM:SS") & " " & strFlag(i)
                End If
            Next
            Exit Function
        End If
       
        '-------------------------------
        WindowProc = CallWindowProc(lngPreWinProc, hwnd, uMsg, wParam, lParam)
    End Function

    '*************************************************************************
    '**函 数 名:ISubProc
    '**输    入:hwnd(Long) - 窗口句柄
    '**输    出:无
    '**功能描述:
    '**全局变量:
    '**调用模块:安装子类
    '**作    者:叶帆
    '**日    期:2005-12-23 11:41:37
    '**修 改 人:
    '**日    期:
    '**版    本:V1.0.0
    '*************************************************************************
    Public Sub ISubProc(hwnd As Long)
        '记录原本的Window Procedure的位址
        lngPreWinProc = GetWindowLong(hwnd, GWL_WNDPROC)
        Call SetWindowLong(hwnd, GWL_WNDPROC, AddressOf WindowProc)
    End Sub

    '*************************************************************************
    '**函 数 名:UnISubProc
    '**输    入:hwnd(Long) - 窗口句柄
    '**输    出:无
    '**功能描述:卸载子类
    '**全局变量:
    '**调用模块:
    '**作    者:叶帆
    '**日    期:2005-12-23 11:43:53
    '**修 改 人:
    '**日    期:
    '**版    本:V1.0.0
    '*************************************************************************
    Public Sub UnISubProc(hwnd As Long)
        '取消Message的截取,而使之又只送往原来的Window Procedure
        Call SetWindowLong(hwnd, GWL_WNDPROC, lngPreWinProc)
    End Sub

    '*************************************************************************
    '**函 数 名:SysMsgRegister
    '**输    入:无
    '**输    出:无
    '**功能描述:消息注册
    '**全局变量:
    '**调用模块:
    '**作    者:叶帆
    '**日    期:2005-12-23 13:18:02
    '**修 改 人:
    '**日    期:
    '**版    本:V1.0.0
    '*************************************************************************
    Public Sub SysMsgRegister(hwnd As Long)
        Dim nr As NotifyRegister

        lngFlag = Array(SHCNE_ASSOCCHANGED, _
                  SHCNE_ATTRIBUTES, _
                  SHCNE_CREATE, _
                  SHCNE_DELETE, _
                  SHCNE_DRIVEADD, _
                  SHCNE_DRIVEADDGUI, _
                  SHCNE_DRIVEREMOVED, _
                  SHCNE_EXTENDED_EVENT, _
                  SHCNE_FREESPACE, _
                  SHCNE_MEDIAINSERTED, _
                  SHCNE_MEDIAREMOVED, _
                  SHCNE_MKDIR, _
                  SHCNE_NETSHARE, _
                  SHCNE_NETUNSHARE, _
                  SHCNE_RENAMEFOLDER, _
                  SHCNE_RENAMEITEM, _
                  SHCNE_RMDIR, _
                  SHCNE_SERVERDISCONNECT, _
                  SHCNE_UPDATEDIR, _
                  SHCNE_UPDATEIMAGE, _
                  SHCNE_UPDATEITEM)

        strFlag = Array("文件关联被改变", _
                  "文件夹属性被改变", _
                  "文件夹外壳成员被创建", _
                  "非文件夹外壳成员被删除", _
                  "添加了一个驱动器", _
                  "通过外壳添加的驱动器", _
                  "一个驱动器被删除了", _
                  "未使用", _
                  "驱动器自由空间发生变化", _
                  "存储介质插入驱动器", _
                  "存储介质被移除", _
                  "一个目录被创建", _
                  "本地目录被共享", _
                  "本地目录被取消共享", _
                  "文件夹名称被改变", _
                  "非文件的外壳对象名称被改变", _
                  "一个文件夹被删除", _
                  "计算机被服务器断开", _
                  "一个文件夹的内容被改变", _
                  "系统图像列表中的一个图像被改变", _
                  "一个非文件夹外壳对象的名称被改变")

        lngHandle = SHChangeNotifyRegister(hwnd, SHCNF_ACCEPT_INTERRUPTS Or SHCNF_ACCEPT_NON_INTERRUPTS, SHCNE_ALLEVENTS, WM_YFSYSMSG, 1, nr)
        If lngHandle > 0 Then
            frmSysmsg.picFlag.BackColor = RGB(0, 200, 0)
        Else
            frmSysmsg.picFlag.BackColor = RGB(255, 0, 0)
        End If
    End Sub

    '*************************************************************************
    '**函 数 名:UnSysMsgRegister
    '**输    入:无
    '**输    出:无
    '**功能描述:取消注册
    '**全局变量:
    '**调用模块:
    '**作    者:叶帆
    '**日    期:2005-12-23 13:19:06
    '**修 改 人:
    '**日    期:
    '**版    本:V1.0.0
    '*************************************************************************
    Public Sub UnSysMsgRegister()
        If lngHandle > 0 Then
            SHChangeNotifyDeregister lngHandle
        End If
    End Sub

    在Windows XP / VB 6.0环境下测试成功。
    源代码下载地址:http://www.sky-walker.com.cn/YeFan/SourceCode/yfsysmsg.rar

    发表于 @ 2005年12月23日 15:02:00|评论(loading...)|编辑

    新一篇: 要想做真正的编程高手,还是应该踏实些,告别浮躁 | 旧一篇: [转]大量正版软件下载链接

    评论

    #叶帆 发表于2005-12-24 01:27:00  IP: 221.217.159.*
    不错,不过它这程序里只能设定监控特定的目录,好像没有实现指定目录的监控。

    我目前可以实现,对特定目录的监控了
    (要进行Unicode转换)
    '监视指定的目录
    If Len(WatchPath) > 0 Then
    nr.pidlPath = SHSimpleIDListFromPath(StrConv(WatchPath, vbUnicode))
    nr.bWatchSubtree = IIf(bFlag, 1, 0)
    End If
    #yefan 发表于2005-12-24 01:37:00  IP: 221.217.159.*
    to Sunlight
    能简要介绍你吗?
    #Sunlight 发表于2005-12-24 08:14:00  IP: 61.6.90.*
    I'm am electrical Engineer of Samling company ,Malaysia.
    By the way,there are wide usages of Radiation measurement system,moisure meter and Radar Level sensor in wood industry like Fiber board (MDF).
    #Sunlight 发表于2005-12-24 08:19:00  IP: 61.6.90.*
    I'm an electrical Engineer of Samling company ,Malaysia.
    By the way,there are wide usages of Radiation measurement system,moisture meter and Radar Level sensor in wood industry like Fiber board (MDF).
    #Sunlight 发表于2005-12-23 23:25:00  IP: 61.6.90.*
    SHChangeNotifyRegister 实现文件目录操作即时监视程序
    http://members.aol.com/btmtz/vb
    http://www.mvps.org/ccrp

    download it at:
    http://www.supercss.com/code/1658.htm
    #Sunlight 发表于2005-12-23 17:07:00  IP: 61.6.90.*
    Excellent!
    #莫取网名 发表于2005-12-31 17:03:00  IP: 218.64.101.*
    你好。可以问你另一个问题吗?那就是关于控件注册的问题。
    问题说明网址链接:

    http://community.csdn.net/Expert/TopicView.asp?id=4476317

    我发这个贴子发了好久了,可是却没有人知道。希望大虾赐教!
    #Sunlight 发表于2006-01-01 09:04:00  IP: 61.6.90.*

    '=================================================================================
    ' Name: RegServe
    ' Usage: (un)registers ActiveX-Dll's
    ' Arguments: Path - path to file
    ' Mode -
    ' Returns: False - function fails
    ' True - success
    ' Filename: modRegister.bas
    ' Author: Sunlight
    ' Date: 18 Dec 2004
    ' '=================================================================================
    Public Function RegServe(ByVal Path$, Mode As Boolean) As Boolean

    Dim insthLib&, lpLibAdr&, hThd&, lpExCode&
    Dim procName$, Result&, okFlag As Boolean

    '### Load DLL into the memory

    insthLib = LoadLibrary(Path)
    '### Select action
    If insthLib Then
    If Mode Then
    procName = "DllRegisterServer"
    Else
    procName = "DllUnregisterServer"
    End If
    '### address of the DLL in the memory
    lpLibAdr = GetProcAddress(insthLib, procName)
    If lpLibAdr <> 0 Then
    '### action start
    hThd = CreateThread(ByVal 0, 0, ByVal lpLibAdr, ByVal 0&, 0&, 0&)
    If hThd Then
    '### wait for loading maximum 5 sec
    Result = WaitForSingleObject(hThd, 5000)
    If Result = STATUS_WAIT_0 Then
    '###
    #Sunlight 发表于2006-01-01 11:49:00  IP: 61.6.90.*
    'The following code isn't written by ME.
    'I just revised a little bit.I haven't yet tested it.

    'Another Method

    VERSION 1.0 CLASS
    BEGIN
    MultiUse = -1 'True
    Persistable = 0 'NotPersistable
    DataBindingBehavior = 0 'vbNone
    DataSourceBehavior = 0 'vbNone
    MTSTransactionMode = 0 'NotAnMTSObject
    END
    Attribute VB_Name = "clsCOMRegisterDLL"
    Attribute VB_GlobalNameSpace = False
    Attribute VB_Creatable = True
    Attribute VB_PredeclaredId = False
    Attribute VB_Exposed = True

    'make two References to : ISA helper COM component 1.0 type library and TypeLib Information
    Option Explicit

    Public Type GUID
    Data1 As Long
    Data2 As Integer
    Data3 As Integer
    Data4(0 To 7) As Byte
    End Type

    Public Enum eSYSKIND
    SYS_WIN16 = 0&
    SYS_WIN32 = 1&
    SYS_MAC = 2&
    End Enum

    Private Declare Function LoadTypeLib Lib "oleaut32.dll" (pFileName As Byte, pptlib As Object) As Long
    Private Declare Function RegisterTypeLib Lib "oleaut32.dll" (ByVal ptlib As Object, szFullPath As Byte, szHelpFile As Byte) As Long
    Private Declare Function UnRegisterTypeLib Lib "oleaut32.dll" (libID As GUID, ByVal wVerMajor As Integer, ByVal wVerMinor As Integer, ByVal lCID As Long, ByVal tSysKind As eSYSKIND) As Long
    Private Declare Function CLSIDFromString Lib "ole32.dll" (lpsz As Byte,
    #yefan 发表于2006-01-01 17:57:00  IP: 221.217.145.*
    其实没有这么麻烦,把控件与可执行程序放在同一个目录,它会自动注册的。

    此外检测注册我是这样作的,引用该控件的一个方法或属性,如果报错说明有错误,在出错处理的地方调用一个函数(不要直接写注册代码),里面注册即可。
    #莫取网名 发表于2006-01-01 15:10:00  IP: 218.64.106.*
    你好。谢谢你的答复。可是我希望采用的是对注册表进行信息检测,查看所需控件是否已经注册。如果没有注册。则可利用shell语句进行注册的!
    再次表示感谢,更希望得到再次答复!
    #yefan 发表于2006-01-02 21:11:00  IP: 221.217.144.*
    此外检测注册我是这样作的,引用该控件的一个方法或属性,如果报错说明有错误,在出错处理的地方调用一个函数(不要直接写注册代码),里面注册即可。
    --已经说了
    #莫取网名 发表于2006-01-02 21:16:00  IP: 61.180.93.*
    那请问你可以给个例子吗?
    #莫取网名 发表于2006-01-02 15:40:00  IP: 218.64.109.*
    你好,其实我想表达的是这样的问题:
    网址连接如下:
    http://community.csdn.net/Expert/TopicView.asp?id=4476317

    麻烦你进去看一下好吗?
    #yefan 发表于2006-01-03 13:10:00  IP: 221.217.129.*
    '*************************************************************************
    '**函 数 名:Form_Load
    '**输 入:无
    '**输 出:无
    '**功能描述:初始化
    '**全局变量:
    '**调用模块:
    '**作 者:叶帆
    '**日 期:2005-09-14 12:54:34
    '**修 改 人:
    '**日 期:
    '**版 本:V1.0.0
    '*************************************************************************
    Private Sub Form_Load()
    On Error GoTo ToExit '打开错误陷阱
    '------------------------------------------------
    OCX1.tag = 1

    '------------------------------------------------
    Exit Sub
    '----------------
    ToExit:
    If Err.Number = 429 Then
    RegVoice '自动注册组件
    End If

    End Sub

    '*************************************************************************
    '**函 数 名:RegVoice
    '**输 入:无
    '**输 出:无
    '**功能描述:
    '**全局变量:
    '**调用模块:
    '**作 者:叶帆
    '**日 期:2005-09-14 14:52:45
    '**修 改 人:
    '**日 期:
    '**版 本:V1.0.0
    '*************************************************************************
    Private Sub RegVoice()
    On Error GoTo ToExit '打开错误陷阱
    '------------------------------------------------
    Shell "RegSvr32 /S OCX1.ocx"

    DoEvents

    OCX1.tag = 1

    '------------------------------------------------
    Exit Sub
    '----------------
    ToExit:
    MsgBox "组件无法注册,找不到OCX1.ocx!", vbCritical, "测试"
    #莫取网名 发表于2006-01-03 16:01:00  IP: 218.64.109.*
    谢谢你的热心帮助。可是在下还是搞不明白这个原理,问题如下:
    OCX1.tag = 1是在程序启动时就执行,然后就Exit Sub 退出form_load事件了,那岂不是永远都不会调用RegVoice函数进行控件(组件)注册吗?顺便请问Err.Number = 429中的429是代表哪一种错误?还有RegVoice函数中的移交控制权DoEvents有什么作用呢?tag属性好像也没有起到作用吧?怒在下愚钝,还望高手见笑!
    #yefan 发表于2006-01-03 17:10:00  IP: 221.217.141.*
    如果控件没有注册,执行该语句OCX1.tag = 1就会出错,否则注册语句不用重复执行了。

    有些东西,最好自己试试。
    #hpygzhx520 发表于2007-08-18 22:55:14  IP: 221.3.203.*
    老大,问个问题,我想实现IShellExecuteHook接口,但TLB自动生成的是:
    Private Sub IShellExecuteHookW_Execute(pei As OLElib.SHELLEXECUTEINFO)
    '
    End Sub
    这是过程而不是函数,无法返回值以确认是否让当前HOOK到的通过,怎么办呢?
    谢谢
    #yefanqiu 发表于2007-08-19 12:36:39  IP: 221.217.134.*
    不大明白你的意思
    #hpygzhx520 发表于2007-08-19 14:33:25  IP: 221.213.72.*
    感谢回复
    我需要实现IShellExecuteHook接口,引用了OLElib.tlb
    这个接口可以HOOK到ShellExecute这个动作
    但是引用OLElib.tlb后,用
    Implements IShellExecuteHookW
    来实现这个接口,于是看到IShellExecuteHookW的一个方法
    Private Sub IShellExecuteHookW_Execute(pei As OLElib.SHELLEXECUTEINFO)
    '
    End Sub
    假设我HOOK到对calc.exe的调用,我得处理是否让其通过.资料上说,返回S_OK就是让其通过,也就是启动calc.exe,否则就是阻止对calc.exe的启动.
    但这是一个Sub,而不是一个Function.我没办法让其返回S_OK,请问怎么办?
    谢谢
    #yefanqiu 发表于2007-08-20 18:35:08  IP: 221.217.142.*
    你可以看看这篇文章是不是有参考价值。
    http://blog.csdn.net/startsoft/archive/2002/12/30/13417.aspx
    我按你的方法并没有截获calc.exe的调用,我不知道是否要特殊处理,如果方便,你可以把目前实现的代码发到我的邮箱(yefanqiu@sohu.com),有时间我可以研究一下。
    #hpygzhx520 发表于2007-08-21 10:11:39  IP: 220.165.193.*
    谢谢
    代码现在不在我现在用的计算机上,等我晚上回去发
    Implements IShellExecuteHookW

    Private Sub IShellExecuteHookW_Execute(pei As OLElib.SHELLEXECUTEINFO)
    msgbox pei.lpfile
    End Sub

    这样得到的是当前HOOK到的程序名称的指针,想办法取得字符串就可以看得出了.假设现在某个程序调用calc.exe,则上述得到calc
    #hpygzhx520 发表于2007-08-21 10:13:43  IP: 220.165.193.*
    忘记说了,在HKLM\Software\Microsoft\Windows\CurrentVersion\Explorer\ShellExecuteHooks项下新建一个字符串值,其名为这个DLL的GUID
    #yefanqiu 发表于2007-08-22 00:09:52  IP: 221.217.142.*
    '必须用以下的方法,才能实现返回指定的值,我已经测试,可达到预定目的。(不过我获取的字符串,总有问题)
    Implements IShellExecuteHookW
    Private m_pOldIShellExecuteHookW As Long

    Private Sub Class_Initialize()
    Dim pShellExecuteHookW As IShellExecuteHookW
    Set pShellExecuteHookW = Me
    m_pOldIShellExecuteHookW = SwapVtableEntry(ObjPtr(pShellExecuteHookW), 4, AddressOf Execute)
    End Sub

    Public Sub IShellExecuteHookW_Execute(pei As olelib.SHELLEXECUTEINFO)
    End Sub
    --------------------------
    ‘模块
    Public Function Execute(pei As olelib.SHELLEXECUTEINFO) As HRESULTS
    MsgBox pei.lpDirectory
    Execute = S_FALSE
    End Function

    ‘此外还需要一个模块,比较大主要实现SwapVtableEntry等函数
    #hpygzhx520 发表于2007-08-22 10:47:41  IP: 220.165.216.*
    有些奇怪,AddressOf好象不能在类模块使用吧?能把你那个模块发给我吗?谢谢
    hpygzhx520@163.com
    #hpygzhx520 发表于2007-08-22 16:31:00  IP: 220.165.216.*
    代码已经收到,不胜感激!
    #yefanqiu 发表于2007-08-22 16:34:21  IP: 222.130.246.*
    可以使用,不过AddressOf 指向的函数要在模块中写
    程序已发
    #HY 发表于2008-04-03 19:09:02  IP: 121.12.233.*
    这个代码对我很有用,我主要是用来检测存储介质被插拨到驱动器中的情况,请问有VB.NET版的吗?
    发表评论  


    登录
    Csdn Blog version 3.1a
    Copyright © 叶帆