用spy++也拿不到,那估计用SendMessage,PostMessage之类的就没有办法了。
只能侵入他的进程,找到地址,接下来你就可以做事情了,

解决方案 »

  1.   

    总不至于Hook窗口VbaWindow的窗口过程吧。
    窗口 VbaWindow 的详细信息:
    =======================================
    Powered by Spy4Win v0.20b
    Author: ccrun(老妖), [email protected]
    =======================================1. 常规信息
    -----------------------------------
    用户数据:0x0A559468 (173380712)
    标识(ID):0x00000000 (0)
    实例句柄:0x65000000 (1694498816)
    客户矩形:(0,0)-(927,502), 927x502
    窗口矩形:(353,477)-(1280,994), 927x517
    窗口标题:立即窗口
    窗口句柄:0x0032038C (3277708)
    窗口过程:0x00000000 (0)
    2. 样式描述
    -----------------------------------
    窗口样式:0x54000000 (1409286144)
    WS_CHILDWINDOW - 子窗口(不能与WS_POPUP合用)
    WS_VISIBLE - 可见状态
    WS_CLIPSIBLINGS - 使窗口排除子窗口之间的相对区域扩展样式:0x00000000 (0)控件样式:0x00000000 (0)
    3. 控件及组件包信息
    -----------------------------------
    控件类名:VbaWindow
    控件描述:无相关信息
    所属组件包名称:无相关信息
    组件包描述:无相关信息
    相关网站:无
    4. 窗口的类信息
    -----------------------------------
    类  名:VbaWindow
    类 原 子:0x0000C26F (49775)
    实例句柄:0x65000000 (1694498816)
    窗口过程:0x6506870D (1694926605)
    菜单句柄:(None)
    图标句柄:(None)
    光标句柄:(None)
    背景画刷:(None)
    小 图 标:(None)
    类样式:0x0000000B (11)
    CS_VREDRAW
    CS_HREDRAW
    CS_DBLCLKS
    5. 窗口状态及关系窗口
    -----------------------------------
    父窗口:0x0025022E - wndclass_desked_gsk
    上一个窗口:0x003D01FC - wndclass_pbrs
    下一个窗口:0x000F0394 - VBSlider
    首个子窗口:0x0019032A - ScrollBar
    所属窗口:(None)
    窗口状态:正常显示
    窗口可见:是
    窗口可用:是
    Unicode窗口:否
    总在最前:否
    窗口只读:否子窗口列表:
    TreeView的项目数: 4
    -------------------------
    |-VbaWindow
    |---ScrollBar
    |---ScrollBar
    |---ScrollBar6. 窗口文本内容
    -----------------------------------
    立即窗口
    7. 窗口所属进程信息
    -----------------------------------
    可执行文件:C:\Program Files\Microsoft Office\OFFICE11\WINWORD.EXE
    进程标识符:0x00000668 (1640)
    线程标识符:0x00000D18 (3352)
    命令行参数:"C:\Program Files\Microsoft Office\OFFICE11\WINWORD.EXE" 
    该文件不是Delphi和BCB生成的或已被加壳。
    8. 生成查找窗口相关代码(C++代码)
    -----------------------------------
    // 查找窗口的代码:
    //---------------------------------
    // 以下是查找窗口 VbaWindow 的代码:
    // 在窗口标题不能确定的情况下可将标题设为NULL
    HWND MyFindWindow()
    {
        const int MyMaxParentWinCount = 2;
        // 父窗口类名数组
        char *A_szClassName[MyMaxParentWinCount] =
        {
            "wndclass_desked_gsk",
            "VbaWindow"
        };
        // 父窗口标题数组
        char *A_szWinName[MyMaxParentWinCount] =
        {
            "Microsoft Visual Basic - Normal - [NewMacros (代码)]",
            "立即窗口"
        };
        // 首先求得顶级父窗口
        HWND hLastWin = FindWindow(A_szClassName[0], A_szWinName[0]);
        // 逐次用FindWindowEx函数求出各级子窗口
        for(int i=1; i<MyMaxParentWinCount; i++)
        {
            hLastWin = FindWindowEx(hLastWin, NULL,
                A_szClassName[i], A_szWinName[i]);
        }
        return hLastWin;
    }
    // 举例: HWND hLastWin = MyFindWindow();
    // 窗口样式的代码:
    //---------------------------------
    HWND hWin = (HWND)3277708; // 0x0032038C
    // 获取和设置该窗口的样式
    long lStyle = GetWindowLong(hWin, GWL_STYLE);
    SetWindowLong(hWin, GWL_STYLE, lStyle);
    // 获取和设置该窗口的扩展样式
    long lExStyle = GetWindowLong(hWin, GWL_EXSTYLE);
    SetWindowLong(hWin, GWL_EXSTYLE, lExStyle);
    // 窗口样式/扩展样式/控件样式参考:
    //---------------------------------
    /* 窗口样式参考列表:
    WS_POPUP - 弹出式窗口(不能与WS_CHILDWINDOW样式同时使用)
    WS_CHILDWINDOW - 子窗口(不能与WS_POPUP合用)
    WS_MINIMIZE - 最小化状态
    WS_VISIBLE - 可见状态
    WS_DISABLED - 不可用状态
    WS_CLIPSIBLINGS - 使窗口排除子窗口之间的相对区域
    WS_CLIPCHILDREN - 当在父窗口内绘图时,排除子窗口区域
    WS_MAXIMIZE - 具有最大化按钮,须指定WS_SYSTEM样式
    WS_CAPTION - 有标题框和边框(和WS_TILED样式相同)
    WS_BORDER - 有单边框
    WS_DLGFRAME - 带对话框边框样式,不带标题框
    WS_VSCROLL - 有垂直滚动条
    WS_HSCROLL - 有水平滚动条
    WS_SYSMENU - 标题框上带有窗口菜单(须指定WS_CAPTION样式)
    WS_THICKFRAME - 有可调边框(与WS_SIZEBOX样式相同)
    WS_GROUP - 组样式,每个组的第一个控件具有WS_TABSTOP样式
    WS_TABSTOP - 可接受TAB键焦点
    WS_MINIMIZEBOX - 有最小化按钮
    WS_MAXIMIZEBOX - 有最大化按钮
    WS_OVERLAPPEDWINDOW - 具有层叠,标题框,系统菜单,可调边框,系统按钮
    WS_POPUPWINDOW - 具有单边框,弹出式,系统菜单样式
    *//* 窗口扩展样式参考列表:
    WS_EX_DLGMODALFRAME - 带双层边框
    WS_EX_NOPARENTNOTIFY - 创建/销毁时不通知父窗口
    WS_EX_TOPMOST - 窗口置顶(停留在所有非最高层窗口的上面)
    WS_EX_ACCEPTFILES - 可接受文件拖放
    WS_EX_TRANSPARENT - 透明样式,在同属窗口已重画时该窗口才可重画
    WS_EX_MDICHILD - MDI子窗口样式
    WS_EX_TOOLWINDOW - 工具条窗口样式
    WS_EX_WINDOWEDGE - 带凸起边缘的边框
    WS_EX_CLIENTEDGE - 带阴影的边缘
    WS_EX_CONTEXTHELP - 有上下文帮助样式,标题栏包含一个问号标志
    WS_EX_RIGHT - 右对齐
    WS_EX_RTLREADING - 窗口文本从右到左显示
    WS_EX_LEFTSCROLLBAR - 垂直滚动条在窗口左边界
    WS_EX_CONTROLPARENT - 允许用户使用TAB键在窗口的子窗口间搜索
    WS_EX_STATICEDGE - 当窗口为不可用状态时创建一个三维边缘
    WS_EX_APPWINDOW - 当窗口可见时将一个顶层窗口放置在任务栏上
    WS_EX_OVERLAPPEDWINDOW - 带凸起边缘的边框,边缘有阴影
    WS_EX_PALETTEWINDOW - 带立体边框,有工具条窗口样式,窗口在顶层
    WS_EX_LAYERED - 分层或透明窗口,该样式可使用混合特效
    WS_EX_NOINHERITLAYOUT - 子控件不继承窗体或控件的布局
    WS_EX_LAYOUTRTL - 窗体或控件将具有从右向左的布局(因而会被镜像)
    WS_EX_COMPOSITED - 用双缓冲从下到上绘制窗口的所有子孙(WinXP以上)
    WS_EX_NOACTIVATE - 处于顶层但不激活
    *//* 控件样式参考列表:
    无相关信息
    */
    =======================================
    2013-12-17 17:01:02
      

  2.   

    你能不能回点有用处的东西呢…………看你猩猩都那么多的了……
    你这些所谓的“信息”,根本就不是我需要的东西嘛!
    先才看了一个贴子,在说你老是回复一些乱七八糟的东西………………
    如果通过 HOOK方式,可以正确的达到我要求的目的,完全可以!
    但你要注意一点,VBA的立即窗口是在VBA代码运行过程中,向它内部输出一些文本信息用的。
    这输出信息并不是只是“追加”的方式,而是光标(即“插入点”)在哪,就从哪开始输出。  这个窗口的内容,仅限于文本(当然也包含一些非显示字符在内,比如回车符、换行符,以及“输出”内容本身就包含的一些非显示字符、控制字符 等)。
      窗口内的总行数好象被它进行了限制,最多只有200行。  我需要的是“现有内容”,包括手工操作输入的内容、代码输出的内容。
      并不是仅指要“截获”代码输出时的内容。
      

  3.   

    方法我已经告诉你了“Hook窗口VbaWindow的窗口过程”
    顺便再告诉你可能要用到的4个API:
    AdjustTokenPrivileges
    VirtualAllocEx
    WriteProcessMemory
    CreateRemoteThread
    恕不远送!
      

  4.   


    赵老师,那你一路走好…………你说的“Hook窗口VbaWindow的窗口过程”,就是HOOK它原来的窗口消息处理过程吧!
    如果是指这个:
    我还是再说一下, VAB代码跟 它的立即窗口,属性同一进程的,直接 SetWindowLong( ) 就可以完成HOOK了!
    用不着再通过你的那几个 API去绕圈子……
      

  5.   

    SetWindowLong
    The SetWindowLong function changes an attribute of the specified window. The function also sets a 32-bit (long) value at the specified offset into the extra window memory of a window. LONG SetWindowLong(
      HWND hWnd,       // handle of window
      int nIndex,      // offset of value to set
      LONG dwNewLong   // new value
    );
     
    Parameters
    hWnd 
    Handle to the window and, indirectly, the class to which the window belongs. 
    nIndex 
    Specifies the zero-based offset to the value to be set. Valid values are in the range zero through the number of bytes of extra window memory, minus 4; for example, if you specified 12 or more bytes of extra memory, a value of 8 would be an index to the third 32-bit integer. To set any other value, specify one of the following values: Value Action 
    GWL_EXSTYLE Sets a new extended window style. 
    GWL_STYLE Sets a new window style. 
    GWL_WNDPROC Sets a new address for the window procedure. 
    GWL_HINSTANCE Sets a new application instance handle. 
    GWL_ID Sets a new identifier of the window. 
    GWL_USERDATA Sets the 32-bit value associated with the window. Each window has a corresponding 32-bit value intended for use by the application that created the window. 
    The following values are also available when the hWnd parameter identifies a dialog box: Value Action 
    DWL_DLGPROC Sets the new address of the dialog box procedure. 
    DWL_MSGRESULT Sets the return value of a message processed in the dialog box procedure. 
    DWL_USER Sets new extra information that is private to the application, such as handles or pointers. dwNewLong 
    Specifies the replacement value. 
    Return Values
    If the function succeeds, the return value is the previous value of the specified 32-bit integer.If the function fails, the return value is zero. To get extended error information, callGetLastError. If the previous value of the specified 32-bit integer is zero, and the function succeeds, the return value is zero, but the function does not clear the last error information. This makes it difficult to determine success or failure. To deal with this, you should clear the last error information by callingSetLastError(0) before calling SetWindowLong. Then, function failure will be indicated by a return value of zero and a GetLastError result that is nonzero.Res
    The SetWindowLong function fails if the window specified by the hWnd parameter does not belong to the same process as the calling thread.Certain window data is cached, so changes you make using SetWindowLong will not take effect until you call the SetWindowPos function.If you use SetWindowLong with the GWL_WNDPROC index to replace the window procedure, the window procedure must conform to the guidelines specified in the description of the WindowProc callback function. If you use SetWindowLong with the DWL_MSGRESULT index to set the return value for a message processed by a dialog procedure, you should return TRUE directly afterwards. Otherwise, if you call any function that results in your dialog procedure receiving a window message, the nested window message could overwrite the return value you set using DWL_MSGRESULT. Calling SetWindowLong with the GWL_WNDPROC index creates a subclass of the window class used to create the window. An application can subclass a system class, but should not subclass a window class created by another process. The SetWindowLong function creates the window subclass by changing the window procedure associated with a particular window class, causing the system to call the new window procedure instead of the previous one. An application must pass any messages not processed by the new window procedure to the previous window procedure by calling CallWindowProc. This allows the application to create a chain of window procedures. Reserve extra window memory by specifying a nonzero value in the cbWndExtra member of the WNDCLASSEX structure used with the RegisterClassEx function. You must not call SetWindowLong with the GWL_HWNDPARENT index to change the parent of a child window. Instead, use the SetParent function. Windows CE: The nIndex parameter must be a multiple of 4 bytes. Unaligned access is not supported. The following nIndex parameter values are not supported: GWL_HINSTANCE GWL_HWNDPARENT GWL_USERDATA Windows CE versions 2.0 and later support the DWL_DLGPROC value in the nIndex parameter, but Windows CE 1.0 does not.QuickInfo
      Windows NT: Requires version 3.1 or later.
      Windows: Requires Windows 95 or later.
      Windows CE: Requires version 1.0 or later.
      Header: Declared in winuser.h.
      Import Library: Use user32.lib.
      Unicode: Implemented as Unicode and ANSI versions on Windows NT.See Also
    Window Classes Overview, Window Class Functions, CallWindowProc, GetWindowLong, RegisterClassEx, SetParent, WindowProc, WNDCLASSEX  不给某些人几个嘴巴,他不服气啊!
      

  6.   

    用同一进程中的VBA代码请帖主移驾VBA论坛。http://bbs.csdn.net/forums/VBA
      

  7.   

    重赏之下必有勇夫!¥10000吧。email:[email protected]
      

  8.   

    其实如果楼主学会编写.ahk脚本(参考http://www.autohotkey.com)的话,就可以省下¥10000给孩子买奶粉了。
      

  9.   

    再给提供一个思路哈:搜“GetWord”
      

  10.   


    我还没那么多可用分呢,
    再说,我的需求已经很清楚的说明了,还要什么EMail呀。
      还有就是重赏也未必能解决的啊。
      

  11.   

    原来你说的RMB 1W啊……
      

  12.   

    窗口过程:0x6506870D 的代码在
    C:\Program Files\Common Files\Microsoft Shared\vba\VBA6\VBE6.DLL
    中,用W32Dasm软件反汇编看看。
      

  13.   

    你这个什么“脚本”能有用吗……!!!
    我用API, SetForegroundWindow,再 ShowWindow(hWnd, SW_SHOW),
        然后模拟键盘 Ctrl 按下、A按下、A放开、C按下、C放开,Ctrl放开,
    结果剪贴板中还是原来的文本,根本不是立即窗口中的内容。但是如果把窗口句柄换成 别的EditBox句柄,直接 SendMessage( ) 就搞定了。
      

  14.   

    用.ahk脚本至少可以清空立即窗口。
      

  15.   

    理论上可以将90%的手动操作改为用.ahk脚本执行。
      

  16.   

    你试过了?在立即窗口隐藏的情况下也能清空?

    隐藏的话,我可以说里面没内容。
    ①你只要一手动让其显示,让我看里面的内容,我就说我在.ahk脚本里面也可以做到让其显示,取其中的内容;你说我再手动隐藏,我也可以让.ahk脚本取完内容后隐藏。你再说人隐藏后是有内容的,你不能显示出来取内容后再隐藏,我坚持说隐藏后其实没内容,转步骤①
      

  17.   

    ①你只要一手动让其显示,让我看里面的内容,我就说我在.ahk脚本里面也可以做到让其显示,取其中的内容;你说我再手动隐藏,我也可以让.ahk脚本取完内容后隐藏。你再说“人隐藏后是有内容的,你不能显示出来取内容后再隐藏”,我坚持说隐藏后其实没内容,转步骤①

    加“”修改一处语病。
      

  18.   

    一大片的汇编代码,我看不出什么明堂出来 …………

    所以要学习.ahk嘛。学.ahk写个脚本完成功能⑴总比分析窗口过程对应的汇编,然后写个C/C++ Hook DLL完成同样功能简单的多吧。
      

  19.   

    你这样的方式,也许我不用你的什么ahk脚本,能通过VBA代码操作VBE来搞呢。
    把VBE激活到前台,模拟键盘Ctrl+G,让立即窗口显示出来。
    获取VBA窗口的大小、位置等参数。
    然后按立即窗口的位置、大小,用模拟“鼠标+键盘”操作,应该也能全部复制和清空内容了。只是我不想走这条路,这个以前就考虑过的了。
      

  20.   

    不必要在我的面前把ahk捧得太高……
      

  21.   

    你只要举一个比ahk更强大的Windows系统级脚本能完成类似ahk支持的功能就行。
      

  22.   

    你这样的方式,也许我不用你的什么ahk脚本,能通过VBA代码操作VBE来搞呢。
    把VBE激活到前台,模拟键盘Ctrl+G,让立即窗口显示出来。
    获取VBA窗口的大小、位置等参数。
    然后按立即窗口的位置、大小,用模拟“鼠标+键盘”操作,应该也能全部复制和清空内容了。只是我不想走这条路,这个以前就考虑过的了。
    个人建议:
    有很多看似可以走通的路摆在你面前,在最终选择走哪条路之前,建议不要把太多精力浪费在挑选走哪条路上,先能用最少的代价走通一次再说。
      

  23.   

    当然有后台操作的方法了。
    ReadProcessMemory
      

  24.   

    你这样的方式,也许我不用你的什么ahk脚本,能通过VBA代码操作VBE来搞呢。
    把VBE激活到前台,模拟键盘Ctrl+G,让立即窗口显示出来。
    获取VBA窗口的大小、位置等参数。
    然后按立即窗口的位置、大小,用模拟“鼠标+键盘”操作,应该也能全部复制和清空内容了。只是我不想走这条路,这个以前就考虑过的了。
    个人建议:
    有很多看似可以走通的路摆在你面前,在最终选择走哪条路之前,建议不要把太多精力浪费在挑选走哪条路上,先能用最少的代价走通一次再说。过来人啊!这怎么变成水帖了?
      

  25.   

    你这样的方式,也许我不用你的什么ahk脚本,能通过VBA代码操作VBE来搞呢。
    把VBE激活到前台,模拟键盘Ctrl+G,让立即窗口显示出来。
    获取VBA窗口的大小、位置等参数。
    然后按立即窗口的位置、大小,用模拟“鼠标+键盘”操作,应该也能全部复制和清空内容了。只是我不想走这条路,这个以前就考虑过的了。
    个人建议:
    有很多看似可以走通的路摆在你面前,在最终选择走哪条路之前,建议不要把太多精力浪费在挑选走哪条路上,先能用最少的代价走通一次再说。过来人啊!这怎么变成水帖了?
    这个贴子中,zhao4zhong1 倒是来回复了不少。
    但这些根本不是我要的东西。
    他是说了些方法、思路,但这仅仅是“理论上”的。这些我又不是不知道,并且实际操作没有实现。
    当然,其中的“ahk脚本”除外,只是“从A脚本去调用B脚本,实现XX功能”,有意思吗?
     那个脚本要实现这些,也得调用系统的API(虽然我完全不了解它,但也可以肯定它并不直接支持底层操作)。
     它要用什么API,我在VBA中照样能调用,何必去绕个圈子!!!想来是没有能解决我需求的方法了,很郁闷。
    因些转水区,当散分了。
      

  26.   

    我发这个贴子,目的是找一个“后台操作”的实现方法。
    把那个窗口“弄到前台来操作”,不是我想要的。

    提供一个思路:在另一个看不见的桌面上把那个窗口“弄到前台来操作”,也可以看作是一种后台操作。
    CreateDesktop
    The CreateDesktop function creates a new desktop on the window station associated with the calling process. It returns a handle that can be used to access the new desktop. The calling process must have an associated window station, either assigned by the system at process creation time or set by SetProcessWindowStation. A desktop is a secure object contained within a window station object. A desktop has a logical display surface and contains windows, menus, and hooks.HDESK CreateDesktop(
      LPCTSTR lpszDesktop,    // name of the new desktop
      LPCTSTR lpszDevice,     // reserved; must be NULL.
      LPDEVMODE pDevMode,     // reserved; must be NULL
      DWORD dwFlags,          // flags to control interaction with other 
                              // applications
      DWORD dwDesiredAccess,  // specifies access of returned handle
      LPSECURITY_ATTRIBUTES lpsa  // specifies security attributes of 
                                  // the desktop
    );
     
    Parameters
    lpszDesktop 
    Pointer to a null-terminated string specifying the name of the desktop to be created. Desktop names are case-insensitive and may not contain backslash characters (\). 
    lpszDevice 
    Reserved; must be NULL. The desktop uses the default display driver loaded at boot time. 
    pDevMode 
    Reserved; must be NULL. 
    dwFlags 
    A bit flag parameter that controls how the calling application will cooperate with other applications on the desktop. This parameter can specify zero or the following value: Value Description 
    DF_ALLOWOTHERACCOUNTHOOK Allows processes running in other accounts on the desktop to set hooks in this process. 
    dwDesiredAccess 
    Specifies the access rights the returned handle has to the desktop. This parameter must include the DESKTOP_CREATEWINDOW flag because internally CreateDesktop uses the handle to create a window. In addition, you can specify any of the standard access rights, such as READ_CONTROL or WRITE_DAC, and a combination of the following desktop-specific access rights. Value Description 
    DESKTOP_CREATEMENU Required to create a menu on the desktop. 
    DESKTOP_CREATEWINDOW Required to create a window on the desktop. 
    DESKTOP_ENUMERATE Required for the desktop to be enumerated. 
    DESKTOP_HOOKCONTROL Required to establish any of the window hooks. 
    DESKTOP_JOURNALPLAYBACK Required to perform journal playback on the desktop. 
    DESKTOP_JOURNALRECORD Required to perform journal recording on the desktop. 
    DESKTOP_READOBJECTS Required to read objects on the desktop. 
    DESKTOP_SWITCHDESKTOP Required to activate the desktop using the SwitchDesktop function. 
    DESKTOP_WRITEOBJECTS Required to write objects on the desktop. 
    lpsa 
    Pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle can be inherited by child processes. If lpsa is NULL, the handle cannot be inherited. 
    The lpSecurityDescriptor member of the structure specifies a security descriptor for the new desktop. If lpsa is NULL, the desktop inherits its security descriptor from the parent window station. Return Values
    If the function succeeds, the return value is a handle to the newly created desktop. If the specified desktop already exists, the function succeeds and returns a handle to the existing desktop. When you are finished using the handle, call the CloseDesktop function to close it.If the function fails, the return value is NULL. To get extended error information, call GetLastError.Res
    The CreateDesktop function returns a handle that can be used to access the desktop.If the dwDesiredAccess parameter specifies the READ_CONTROL, WRITE_DAC, or WRITE_OWNER standard access rights to access the security descriptor of the desktop object, you must also request the DESKTOP_READOBJECTS and DESKTOP_WRITEOBJECTS access rights.QuickInfo
      Windows NT: Requires version 3.51 or later.
      Windows: Unsupported.
      Windows CE: Unsupported.
      Header: Declared in winuser.h.
      Import Library: Use user32.lib.
      Unicode: Implemented as Unicode and ANSI versions on Windows NT.See Also
    Window Stations and Desktops Overview, Window Station and Desktop Functions, CloseDesktop, SECURITY_ATTRIBUTES, SetProcessWindowStation, SwitchDesktop