【源码下载地址】:http://210.33.90.250/download/vbsrc/vbwchooker.rar这个类模块通过在VB运行库调用CreateWindowExA之前插入我们的自己的处理过程,从而达到了截获VB窗口的创建,并修改窗口创建信息(如标题、风格、窗口类名等)的效果。这里所说的窗口不是单指VB中的窗体,而是还包括任何具有句柄的控件,比如PictureBox、TextBox等总之,我只是做了这个东西提供给了大家一个可能性,至于大家怎么发挥它的最大功效那就要看大家自己的了 ^_^呼~~~又是一个课题解决了……

解决方案 »

  1.   

    超级绿豆你好!
        我下载了你的东东,确实很好用,我提个想法不知道能不能实现?
    能否把Dll中的窗口变成MDI中的子窗口,还有,就是一旦变成子窗口的话,能否解决ActiveForm的问题(第一次创建子窗口,第二次如果子窗口存在则激活子窗口),如果能解决的话,那用处就更大了。
        我在实际中遇到了这个问题,一直没能解决(呵呵……,别怪我多嘴呀!!!)
      

  2.   

    不是在乎,是無道理,我心情不好的時候,偏要無道理一點最近心情都BT。﹝。。﹝。
    一直向BIAN人來著
      

  3.   

    呵呵,绿豆真牛,
    你怎么不重写一个MSVBVM60.DLL呀,最好能让VB编译标准的DLL,而且还能脱离MSVBVMXX这样的虚拟机运行,等等.....就起名叫的GBVBVM70.DLL,呵呵,那就大快人心了....   :)
      

  4.   

    我越来越觉得脱离MSVBVMXX这样的虚拟机运行不是不可能的了:)研究研究……
      

  5.   

    呵呵,Windows本身就是n多的dll组成,如果不用虚拟机来搞vb,那vb就不是vb了替换的可能性是有的,担这样做就像扔了钢刀用石刀,无甚意义……
      

  6.   

    CSDN,纯技术论坛,非技术类与狗不得回复.....
      

  7.   

    绿豆,有个问题想请教一下,你可不可以用VB内嵌ASM的方法实现位移操作呀? 就是C++中的>>
      

  8.   

    我覺得我tmd夠任你了你自己一男的,我估計你連狗不如我從來不講我淑女,我哥常說要善,我tmd忍到這程度已經溝好了你真tmd是一隻狗,大不了,你投訴我。,我靠
      

  9.   

    你沒用說我,但是我說你,你boyzhang就是一隻狗,這話就是莫依說的怎麼樣,我指著名字就說你是狗
    真的爛人
      

  10.   

    樓上的就是狗,好了,今天罵完了,你要玩,偶不奉陪。樓下各位都看好了今天偶點名字道姓的講他boyzhang就是狗那位投訴就投訴吧。偶哥說:對你這樣的人,實在不應該浪費精神。偶想:是呢?一隻狗就讓他吠吧泡泡泡泡去
      

  11.   

    很感谢绿豆的资源共享csdn是一个讨论技术的地方,但是我们除过技术,还需要一些生活,工作上的讨论
    vb版的人气已经很差了,大家都是有目共睹的。希望大家口下留情,不要因为一些事情而使得人越来越少
      

  12.   

    绿豆,有个问题想请教一下,你可不可以用VB内嵌ASM的方法实现位移操作呀? 就是C++中的>>
      

  13.   

    //你可不可以用VB内嵌ASM的方法实现位移操作呀? 就是C++中的>>Option ExplicitPrivate Sub Form_Load()
        Dim i As Long
        Dim j As Long    i = 8
        j = 2
        
        Debug.Print i; "<<"; j; "="; Shift(i, j, False)
        Debug.Print i; ">>"; j; "="; Shift(i, j, True)End SubPublic Function Shift(ByVal lVal As Long, ByVal bBitsCount As Byte, ByVal fShiftLeft As Boolean) As Long
        Dim oAnyCall As New CVBAnyCall
        Dim sAsm As String
        '17:               push Ecx
        '0040B8E8 51                   push        ecx
        sAsm = "51"
        '18:           cmp dword ptr [esp+10h],0
        '0040B8E9 83 7C 24 0C 00       cmp         dword ptr [esp+10h],0
        sAsm = sAsm & " 83 7C 24 10 00"
        '19:           mov ecx,dword ptr [esp+0Ch]
        '0040B8EE 8B 4C 24 08          mov         ecx,dword ptr [esp+0C]
        sAsm = sAsm & " 8B 4C 24 0C"
        '20:           mov eax,dword ptr [esp+8]
        '0040B8F2 8B 44 24 04          mov         eax,dword ptr [esp+8]
        sAsm = sAsm & " 8B 44 24 08"
        '21:           je sr
        '0040B8F6 74 04                je          sr (0040b8fc)
        sAsm = sAsm & " 74 04"
        '22:           shl Eax, cl
        '0040B8F8 D3 E0                shl         eax,cl
        sAsm = sAsm & " D3 E0"
        '23:           jmp ex
        '0040B8FA EB 02                jmp         ex (0040b8fe)
        sAsm = sAsm & " EB 02"
        '24:   sr:
        '25:           shr Eax, cl
        '0040B8FC D3 E8                shr         eax,cl
        sAsm = sAsm & " D3 E8"
        '26:   ex:
        '27:           pop Ecx
        '0040B8FE 59                   pop         ecx
        sAsm = sAsm & " 59"
        '28:           ret 0Ch
        '0040B8FF C2 0C 00             ret         0Ch
        sAsm = sAsm & " C2 0C 00"
        
        With oAnyCall
            .ThroughVTable = True
            Shift = .CallCodeBytes(sAsm, lVal, bBitsCount, fShiftLeft)
        End With
    End Function
      

  14.   

    绿豆,看一看这里
    //C++代码
    #include<iostream.h>
    void main()
    {
    int i(8),j(8);
    i=i<<2;
    j=j>>2;
    cout<<i<<endl;
    cout<<j<<endl;
    //用于中止程序,以便看结果
    int stop;
    cin>>stop;
    }
    //输出为:
    //32
    //2
    '绿豆的VB代码
    '.......................
        Dim i As Long
        Dim j As Long    i = 8
        j = 2
        
        Debug.Print i; "<<"; j; "="; Shift(i, j, False)
        Debug.Print i; ">>"; j; "="; Shift(i, j, True)
    '输出
    '8 << 2 = 2
    '8 >> 2 = 32
    '........................
    是不是搞反了?   :)
      

  15.   

    呵呵,是写反了,不过你只要把参数名字fShiftLeft改成fShiftRight就好了 ^_^
      

  16.   

    //请问能不能在VB中调用汇编的编译器编译一端汇编程序
    答案是:可以。可以调用外部编译器,如微软的ML来编译生成obj文件,然后连接到自己的程序中……经过这上一个月的倒腾,我觉得VB6越来越可爱,以往在我眼中曾经存在的禁地、界限基本上都消失了,所以我现在很想说一句:用VB,真的没有什么不可能
      

  17.   

    用VB,真的没有什么不可能!
    我最近把一个SDK程序翻译成VB的,我才知道窗口到底是什么东西了。
    建议大家学一门别的语言,再回来看VB就有很大的不同。
      

  18.   

    //答案是:可以。可以调用外部编译器,如微软的ML来编译生成obj文件,然后连接到自己的程序中……恩,可以用偷梁换柱的办法,把C2.EXE替换掉,这样就可以控制编译过程。先预留空模块,编译出OBJ,然后用编译好的汇编代码OBJ替换,最后交给LINK.EXE。//用VB,真的没有什么不可能但是最近又有转Delphi的趋势,许多需要共享内存块的全局钩子没法做。
      

  19.   

    //……需要共享内存块的全局钩子没法做但如果用VB能做真的DLL,那么还会有问题么?:)我在这里先预告一下了,后天我会再贴一个这些天写的一个有关VB编译控制的Add-in,用它我们就可以制作真正的DLL了…… ^_^
      

  20.   

    有了哟,我都用了好久了,不过是用的老外做的,编译出来的是DLL,不过不是标准的....:|曾在网上看过一篇文章,讲的就是这个....就是Hook到编译的过程,在编译时加几个参数,VB的编译器和VC的差不多......
      

  21.   

    //...不过是用的老外做的,编译出来的是DLL,不过不是标准
    呵呵,正是和那个差不多的,原理也差不多,只是我和老外勾的地方不一样……不过生成的应该是标准的DLL了,因为偶已经用偶Add-in生成的DLL实现了全局钩子……
      

  22.   

    关于在VB中如何DLL注入!!http://expert.csdn.net/Expert/topic/2739/2739860.xml?temp=.4273645'---------------------------------
    原来的一个贴,大家争的面红耳赤的.......
    里面有我提到的一个VB+DLL做的线程注入和一个VB+DLL做的全局HOOK,可以改成纯VB的了?对了,线程注入的我找了好久,只有一个ASM的例子可以调试通过,不知道你有没有研究过这方面的问题?
      

  23.   

    //答案是:可以。可以调用外部编译器,如微软的ML来编译生成obj文件,然后连接到自己的程序中……//恩,可以用偷梁换柱的办法,把C2.EXE替换掉,这样就可以控制编译过程。先预留空模块,编译出OBJ,然后用编译好的汇编代码OBJ替换,最后交给LINK.EXE。请说详细一点可以吗,我不大明白
      

  24.   

    拿C2.EXE举例,所谓偷梁换柱就是自己写个exe,命名为C2.EXE,然后把VB目录下的C2.EXE改为其他名字,比如C21.EXE。这样当你编译工程的时候,VB会调用名称为C2.EXE的程序来编译工程,而这时候调用的C2.EXE是你写的那个,于是你就可以通过Command$来获得编译的命令行参数,然后做进一步处理后,再用Shell之类的函数调用真正的C2.EXE来继续编译……
    对于LINK.EXE也是同理……obj文件的处理就相对复杂一点点了,现在乌漆抹黑的,脑子有点糊,等我清醒了再说了…… :)
      

  25.   

    学习 !由于VB.NET与VB60完全不兼容,并且VB.NET失去了VB60那一种简洁明快的美感,VB。NET不兼容WIN98,对硬件的要求也非常高,使我对VB.NET极其抵触,可VB60又没有后继版本了,我感到万分的痛苦。现在微软的.net推广的并不如意,B/S结构的产品的实际应用中遇到了很多局限,C/S结构的产品又卷土重来。在这种情况下,我真希望有哪家实力雄厚的公司能推出VB60的后继版本,使他完全兼容VB60,WIN98,并且对硬件要求不高,同时对internet的开发加强,那该多好啊,这样我的程序员生命不至于现在就终结。
      

  26.   

    //我想问的是在VB中调用汇编的编译器编译汇编语言的程序,并返回编译后的信息
    那么,用那种能够读取DOS程序信息的方法试试看,例子这里找找,前几天还看到一个的
      

  27.   

    //读取DOS程序信息的方法,你要的是这个吗?我找不着原帖了,只好帖出来。 
    回复人: MSTOP(陈建华(东莞立晨企资)) ( ) 信誉:111  2004-4-1 17:26:50  得分:0  
      
      
    ‘**窗体代码。'DOSOutpus
    'Capture the outputs of a DOS command
    'Author: Marco Pipino
    '[email protected]
    '28/02/2002
    Option ExplicitPrivate WithEvents objDOS As DOSOutputsPrivate Sub cmdExecute_Click()
        On Error GoTo errore
        objDOS.CommandLine = txtCommand.Text
        objDOS.ExecuteCommand
        Exit Sub
    errore:
        MsgBox (Err.Description & " - " & Err.Source & " - " & CStr(Err.Number))
    End SubPrivate Sub cmdExit_Click()
        Set objDOS = Nothing
        End
    End SubPrivate Sub Form_Load()
        Set objDOS = New DOSOutputs
    End SubPrivate Sub objDOS_ReceiveOutputs(CommandOutputs As String)
        txtOutputs.Text = txtOutputs.Text & CommandOutputs
    End SubPrivate Sub txtOutputs_Change()
        txtOutputs.SelStart = Len(txtOutputs.Text)
    End Sub'********************************************
    '**类(DOSOutputs)代码Option Explicit'The CreatePipe function creates an anonymous pipe,
    'and returns handles to the read and write ends of the pipe.
    Private Declare Function CreatePipe Lib "kernel32" ( _
        phReadPipe As Long, _
        phWritePipe As Long, _
        lpPipeAttributes As Any, _
        ByVal nSize As Long) As Long'Used to read the the pipe filled by the process create
    'with the CretaProcessA function
    Private Declare Function ReadFile Lib "kernel32" ( _
        ByVal hFile As Long, _
        ByVal lpBuffer As String, _
        ByVal nNumberOfBytesToRead As Long, _
        lpNumberOfBytesRead As Long, _
        ByVal lpOverlapped As Any) As Long'Structure used by the CreateProcessA function
    Private Type SECURITY_ATTRIBUTES
        nLength As Long
        lpSecurityDescriptor As Long
        bInheritHandle As Long
    End Type'Structure used by the CreateProcessA function
    Private Type STARTUPINFO
        cb As Long
        lpReserved As Long
        lpDesktop As Long
        lpTitle As Long
        dwX As Long
        dwY As Long
        dwXSize As Long
        dwYSize As Long
        dwXCountChars As Long
        dwYCountChars As Long
        dwFillAttribute As Long
        dwFlags As Long
        wShowWindow As Integer
        cbReserved2 As Integer
        lpReserved2 As Long
        hStdInput As Long
        hStdOutput As Long
        hStdError As Long
    End Type'Structure used by the CreateProcessA function
    Private Type PROCESS_INFORMATION
        hProcess As Long
        hThread As Long
        dwProcessID As Long
        dwThreadID As Long
    End Type'This function launch the the commend and return the relative process
    'into the PRECESS_INFORMATION structure
    Private Declare Function CreateProcessA Lib "kernel32" ( _
        ByVal lpApplicationName As Long, _
        ByVal lpCommandLine As String, _
        lpProcessAttributes As SECURITY_ATTRIBUTES, _
        lpThreadAttributes As SECURITY_ATTRIBUTES, _
        ByVal bInheritHandles As Long, _
        ByVal dwCreationFlags As Long, _
        ByVal lpEnvironment As Long, _
        ByVal lpCurrentDirectory As Long, _
        lpStartupInfo As STARTUPINFO, _
        lpProcessInformation As PROCESS_INFORMATION) As Long'Close opened handle
    Private Declare Function CloseHandle Lib "kernel32" ( _
        ByVal hHandle As Long) As Long'Consts for the above functions
    Private Const NORMAL_PRIORITY_CLASS = &H20&
    Private Const STARTF_USESTDHANDLES = &H100&
    Private Const STARTF_USESHOWWINDOW = &H1
    Private mCommand As String          'Private variable for the CommandLine property
    Private mOutputs As String          'Private variable for the ReadOnly Outputs property'Event that notify the temporary buffer to the object
    Public Event ReceiveOutputs(CommandOutputs As String)'This property set and get the DOS command line
    'It's possible to set this property directly from the
    'parameter of the ExecuteCommand method
    Public Property Let CommandLine(DOSCommand As String)
        mCommand = DOSCommand
    End PropertyPublic Property Get CommandLine() As String
        CommandLine = mCommand
    End Property'This property ReadOnly get the complete output after
    'a command execution
    Public Property Get Outputs()
        Outputs = mOutputs
    End PropertyPublic Function ExecuteCommand(Optional CommandLine As String) As String
        Dim proc As PROCESS_INFORMATION     'Process info filled by CreateProcessA
        Dim ret As Long                     'long variable for get the return value of the
                                            'API functions
        Dim start As STARTUPINFO            'StartUp Info passed to the CreateProceeeA
                                            'function
        Dim sa As SECURITY_ATTRIBUTES       'Security Attributes passeed to the
                                            'CreateProcessA function
        Dim hReadPipe As Long               'Read Pipe handle created by CreatePipe
        Dim hWritePipe As Long              'Write Pite handle created by CreatePipe
        Dim lngBytesread As Long            'Amount of byte read from the Read Pipe handle
        Dim strBuff As String * 256         'String buffer reading the Pipe    'if the parameter is not empty update the CommandLine property
        If Len(CommandLine) > 0 Then
            mCommand = CommandLine
        End If
        
        'if the command line is empty then exit whit a error message
        If Len(mCommand) = 0 Then
            MsgBox "Command Line empty", vbCritical
            Exit Function
        End If
        
        'Create the Pipe
        sa.nLength = Len(sa)
        sa.bInheritHandle = 1&
        sa.lpSecurityDescriptor = 0&
        ret = CreatePipe(hReadPipe, hWritePipe, sa, 0)
        
        If ret = 0 Then
            'If an error occur during the Pipe creation exit
            MsgBox "CreatePipe failed. Error: " & Err.LastDllError, vbCritical
            Exit Function
        End If
        
        'Launch the command line application
        start.cb = Len(start)
        start.dwFlags = STARTF_USESTDHANDLES Or STARTF_USESHOWWINDOW
        'set the StdOutput and the StdError output to the same Write Pipe handle
        start.hStdOutput = hWritePipe
        start.hStdError = hWritePipe
        'Execute the command
        ret& = CreateProcessA(0&, mCommand, sa, sa, 1&, _
            NORMAL_PRIORITY_CLASS, 0&, 0&, start, proc)
            
        If ret <> 1 Then
            'if the command is not found ....
            MsgBox "File or command not found", vbCritical
            Exit Function
        End If
        
        'Now We can ... must close the hWritePipe
        ret = CloseHandle(hWritePipe)
        mOutputs = ""
        
        'Read the ReadPipe handle
        Do
            ret = ReadFile(hReadPipe, strBuff, 256, lngBytesread, 0&)
            mOutputs = mOutputs & Left(strBuff, lngBytesread)
            'Send data to the object via ReceiveOutputs event
            RaiseEvent ReceiveOutputs(Left(strBuff, lngBytesread))
        Loop While ret <> 0
        
        'Close the opened handles
        ret = CloseHandle(proc.hProcess)
        ret = CloseHandle(proc.hThread)
        ret = CloseHandle(hReadPipe)
        
        'Return the Outputs property with the entire DOS output
        ExecuteCommand = mOutputs
    End Function
      

  28.   

    //但如果用VB能做真的DLL,那么还会有问题么?:)大概是个人的心理因素——觉得不可靠(做出“真”的DLL,到底有没有问题?其中VB的数据类型的兼容问题,还有这种特殊的DLL的内存分配问题,都不清楚啊;我是个倾向于实用主义的人,所以觉得用Delphi反而简单、安全。
      

  29.   

    你说的没有错,比如VB中很多函数都涉及到线程存储空间,实在是不大安全。不过就我个人来说,这么做更多的意义是在于追求技术实现的本身,呵呵还有……这做出来的DLL的确还有点问题,我还在继续研究中……我嘴巴一快就说自己做出了全局钩子,其实……呵呵,各位观众,不好意思,我道歉、道歉!
      

  30.   

    那VB的DLL和标准的DLL还有那些差别呢?我用的那个老外的也写不好全局HOOK....
      

  31.   

    //我想问的是在VB中调用汇编的编译器编译汇编语言的程序,并返回编译后的信息
    //那么,用那种能够读取DOS程序信息的方法试试看,例子这里找找,前几天还看到一个的如果用读DOS信息,那编译器是不是用MASM的汇编编译器,能返回出错的信息吗