Results 1 to 16 of 16

Thread: Get Object by HWND

  1. #1

    Thread Starter
    Addicted Member
    Join Date
    May 2000
    Location
    Westminster, Md.
    Posts
    163

    Get Object by HWND

    THere's gotta be a way to do this, but even after searching here and on other sites I can't seem to find it. It's probably staring me right in the face too.

    Is there a way to grab onto an object by using it's HWND?

    Ie:

    If I have the handle of a form and I want to access it's properties through that handle.


    Thanks,
    Eiredrake.

  2. #2
    jim mcnamara
    Guest
    Inside your app:
    Code:
    ' from VB forums
    
    Public Function GetControlFromhWnd(hWnd As Long) As Object
    'Parameters: hWnd - Window Handle to object
    'Returns: Object reference to cotrol with the hwnd
    'Note this will not return forms
    
    Dim frm As Form
    Dim ctl As Control
    
    For Each frm In Forms
     For Each ctl In frm.Controls
      If ctl.hWnd = hWnd Then
        Set GetControlFromhWnd = ctl
        Exit Function
      End If
     Next
    Next
    
    End Function

  3. #3
    jim mcnamara
    Guest
    Private Declare Sub AccessibleObjectFromWindow Lib "OLEACC.DLL" (ByVal hwnd As Long, ByVal dwId As Long, ByVal riid As Long, ppvObject As Any)


    This also returns a pointer (objptr) to an window (control) from
    a hWnd - in another app.

  4. #4
    Hyperactive Member
    Join Date
    May 2002
    Location
    Omaha, NE
    Posts
    263

    Jim...I need help...mental help!!!

    Jim (or anyone else who knows),

    I found this post when I was parousing for answers to my post that is gaining much publicity.

    So, I can get the Hwnd (the first parameter for the AccessibleObjectFromWindow sub, but what about the next three parameters?

    So that you don't have to read all of the other post, let me summarize. I am opening an instance of ie, and performing an execWB function to print out the web page. I am opening a printer settings dialog box (on purpose) when I execute the print, and I want to set a reference to the dialog box, and I have the handle.

    Thanks in advance for the help.

  5. #5
    Frenzied Member
    Join Date
    Jul 2002
    Posts
    1,370
    j j -

    I am not getting what your problem is.
    Once the dialog box closes you can't really reference it. ??

    Instead of telling us what what you're doing -- try explaining what you want. (maybe control the dialog box later on?)

  6. #6
    Hyperactive Member
    Join Date
    May 2002
    Location
    Omaha, NE
    Posts
    263

    What I want...

    To quote my previous post:

    I want to set a reference to a printer settings dialog box, for which I have the handle.

  7. #7
    Hyperactive Member
    Join Date
    May 2002
    Location
    Omaha, NE
    Posts
    263

    ...let me expand just a little bit

    Once I set a project reference to prndialog.dll (from Microsoft), I'd like to be able to do this:

    dim prn as PrinterDlg

    set prn = PrinterSettingsDialogBox that is already open.

  8. #8
    Frenzied Member
    Join Date
    Jul 2002
    Posts
    1,370
    That's what I thought.

    You can do it in C++, so it seems like it's possible since it returns an objptr. You just need to be aware that VB expects IDispatch
    back from an objptr.

    Here is the MSDN discussion:
    AccessibleObjectFromWindow
    The AccessibleObjectFromWindow function retrieves the address of the specified interface to the object associated with the given window.

    For more information about COM parameter attributes, allocating memory, and freeing memory, see Definitions of Parameter Attributes.

    STDAPI AccessibleObjectFromWindow(
    HWND hwnd,
    DWORD dwObjectID,
    REFIID riid,
    void** ppvObject
    );
    Parameters
    hwnd
    [in] Specifies the handle of a window for which an object is to be retrieved. To retrieve an interface pointer to the cursor or caret object, specify NULL and use the appropriate object ID in dwObjectID.
    dwObjectID
    [in] Specifies the object ID. This value is one of the standard object identifier constants or a custom object ID such as OBJID_NATIVEOM, which is the object ID for the Microsoft Office native object model. For more information about OBJID_NATIVEOM, see the Remarks section in this topic.
    riid
    [in] Specifies the reference identifier of the requested interface. This value is either IID_IAccessible or IID_IDispatch.
    ppvObject
    [out] Address of a pointer variable that receives the address of the specified interface.
    Return Values
    If successful, returns S_OK.

    If not successful, returns one of the following or another standard COM error code.

    Error Description
    E_INVALIDARG An argument is invalid.
    E_NOINTERFACE The requested interface is not supported.


    Remarks
    Clients call this function to retrieve the address of an object's IAccessible, IDispatch, IEnumVARIANT, IUnknown, or other supported interface pointer.

    As with other IAccessible methods and functions, clients might receive errors for IAccessible interface pointers because of a user action. For more information, see Receiving Errors for IAccessible Interface Pointers.

    Clients use this function to obtain access to the Microsoft Office 2000 native object model. The native object model provides clients with accessibility information about an Office application's document or client area that is not exposed by Active Accessibility.

    To obtain an IDispatch interface pointer to a class supported by the native object model, specify OBJID_NATIVEOM in dwObjectID. When using this object identifier, the hwnd parameter must match the following window class types.

    Office application Window class IDispatch pointer to
    Word _WwG Window
    Excel EXCEL7 Window
    PowerPoint paneClassDC DocumentWindow
    Command Bars MsoCommandBar CommandBar


    Note that the above window classes correspond to the innermost document window or pane window. For more information about the Office object model, see the Microsoft Office/Visual Basic Programmer's Guide.

    Requirements
    Windows NT/2000/XP: Included in Windows 2000 and later.
    Windows 95/98/Me: Included in Windows 98 and later.
    Redistributable: Requires Active Accessibility 1.3 RDK on Windows NT 4.0 SP6 and Windows 95.
    Header: Declared in Oleacc.h.
    Library: Use Oleacc.lib.

    See Also
    IAccessible, AccessibleObjectFromEvent, AccessibleObjectFromPoint, IDispatch Interface
    Also some information about calling this from another language
    which is Basic-like but low-level:
    ' Object events
    '
    ' The system AND apps generate these. The system generates these for
    ' real windows. Apps generate these for objects within their window which
    ' act like a separate control, e.g. an item in a list view.
    '
    ' When the system generate them, dwParam2 is always WMOBJID_SELF. When
    ' apps generate them, apps put the has-meaning-to-the-app-only ID value
    ' in dwParam2.
    ' For all events, if you want detailed accessibility information, callers
    ' should
    ' ' Call AccessibleObjectFromWindow() with the hwnd, idObject parameters
    ' of the event, and IID_IAccessible as the REFIID, to get back an
    ' IAccessible* to talk to
    ' ' Initialize and fill in a VARIANT as VT_I4 with lVal the idChild
    ' parameter of the event.
    ' ' If idChild isn't zero, call get_accChild() in the container to see
    ' if the child is an object in its own right. If so, you will get
    ' back an IDispatch* object for the child. You should release the
    ' parent, and call QueryInterface() on the child object to get its
    ' IAccessible*. Then you talk directly to the child. Otherwise,
    ' if get_accChild() returns you nothing, you should continue to
    ' use the child VARIANT. You will ask the container for the properties
    ' of the child identified by the VARIANT. In other words, the
    ' child in this case is accessible but not a full-blown object.
    ' Like a button on a titlebar which is'small' and has no children.
    '
    ' For all EVENT_OBJECT events,
    ' hwnd is the dude to Send the WM_GETOBJECT message to (unless NULL,
    ' see above for system things)
    ' idObject is the ID of the object that can resolve any queries a
    ' client might have. It's a way to deal with windowless controls,
    ' controls that are just drawn on the screen in some larger parent
    ' window (like SDM), or standard frame elements of a window.
    ' idChild is the piece inside of the object that is affected. This
    ' allows clients to access things that are too small to have full
    ' blown objects in their own right. Like the thumb of a scrollbar.
    ' The hwnd/idObject pair gets you to the container, the dude you
    ' probably want to talk to most of the time anyway. The idChild
    ' can then be passed into the acc properties to get the name/value
    ' of it as needed.
    '
    ' Example #1:
    ' System propagating a listbox selection change
    ' EVENT_OBJECT_SELECTION
    ' hwnd == listbox hwnd
    ' idObject == OBJID_WINDOW
    ' idChild == new selected item, or CHILDID_SELF if
    ' nothing now selected within container.
    ' Word'97 propagating a listbox selection change
    ' hwnd == SDM window
    ' idObject == SDM ID to get at listbox'control'
    ' idChild == new selected item, or CHILDID_SELF if
    ' nothing
    '
    ' Example #2:
    ' System propagating a menu item selection on the menu bar
    ' EVENT_OBJECT_SELECTION
    ' hwnd == top level window
    ' idObject == OBJID_MENU
    ' idChild == ID of child menu bar item selected
    '
    ' Example #3:
    ' System propagating a dropdown coming off of said menu bar item
    ' EVENT_OBJECT_CREATE
    ' hwnd == popup item
    ' idObject == OBJID_WINDOW
    ' idChild == CHILDID_SELF
    '
    ' Example #4:
    '
    ' For EVENT_OBJECT_REORDER, the object referred to by hwnd/idObject is the
    ' PARENT container in which the zorder is occurring. This is because if
    ' one child is zordering, all of them are changing their relative zorder.

  9. #9
    Frenzied Member Shawn N's Avatar
    Join Date
    Dec 2001
    Location
    Houston
    Posts
    1,631

    Re: Get Object by HWND

    Originally posted by Eiredrake
    THere's gotta be a way to do this, but even after searching here and on other sites I can't seem to find it. It's probably staring me right in the face too.

    Is there a way to grab onto an object by using it's HWND?

    Ie:

    If I have the handle of a form and I want to access it's properties through that handle.


    Thanks,
    Eiredrake.
    What you're trying to do is not completely possible. It kind of sounds like you want to be able to reference an object outside of your own project the same way you would reference your own command button or something. This isn't possible.

    If you post what it is you're trying to accomplish it might be a little easier to help you.
    Please rate my post.

  10. #10
    Frenzied Member
    Join Date
    Jul 2002
    Posts
    1,370
    You can reference objects within your process, not outside of it.
    The reason is that address space doesn't map across processes.

    You call SendMessage to control those objects.

  11. #11
    Hyperactive Member
    Join Date
    May 2002
    Location
    Omaha, NE
    Posts
    263

    Tried and failed...

    I think I'm doing something wrong, check my code please:
    Code:
    Private Sub PrintHTML()
        Dim i
        Dim xHwnd As Long
        Dim objIE As InternetExplorer
        Dim prnDialog As PrinterDlg
        Dim varMe
        
        Set objIE = New InternetExplorer
        objIE.Navigate2 "C:\temp\test.html"
        objIE.ExecWB OLECMDID_PRINT, OLECMDEXECOPT_PROMPTUSER ' execute the print statement and bring up the printer settings dialog box
        For i = 0 To 1000 'meaningless loop to wait on dialog box to appear
        Next
        xHwnd = FindWindow(vbNullString,"Print") 'I wish there was a better way to attain this handle
        AccessibleObjectFromWindow xHwnd, 0, 1, varMe 'this line causes vb to crash
    End Sub
    Thanks again!

  12. #12
    Hyperactive Member
    Join Date
    May 2002
    Location
    Omaha, NE
    Posts
    263

    New try, different error...

    Code:
    Private Sub PrintHTML()
        Dim i As Integer
        Dim xHwnd As Long
        Dim objIE As InternetExplorer
        Dim status As Variant
        
        Set objIE = New InternetExplorer
        objIE.Visible = True
        objIE.Navigate2 "C:\temp\test.html"
        objIE.ExecWB OLECMDID_PRINT, OLECMDEXECOPT_PROMPTUSER
        For i = 0 To 1000
        Next
        xHwnd = FindWindow(vbNullString, "Print")
        status = AccessibleObjectFromWindow(xHwnd, 0, 0, VarPtr(varMe))
    End Sub
    I am now getting a runtimer error '49' - Bad DLL Calling Convention. My problem is the third parameter...I am sure of it. I don't know what I need to be passing in for the riid.

  13. #13
    Hyperactive Member
    Join Date
    May 2002
    Location
    Omaha, NE
    Posts
    263

    ...

    P.S. I tried objPtr instead of VarPtr and I get an "Object Required" error.

  14. #14
    Frenzied Member Shawn N's Avatar
    Join Date
    Dec 2001
    Location
    Houston
    Posts
    1,631
    What are you trying to accomplish using "AccessibleObjectFromWindow" on your last line?
    Please rate my post.

  15. #15
    Hyperactive Member
    Join Date
    May 2002
    Location
    Omaha, NE
    Posts
    263
    I was trying to get a pointer to the printer settings dialog box, that I will be able to use to attach onto and manipulate the settings.

  16. #16
    not necessarily true. you can create an object within your context and then write it into thw virtual memory space of the foriegn process. once in the foriegn process' context, you can populate it, with whatever data need be (typically via send message calls)
    then you can read it back to your process' memory space and manipulate it.

    an example of this is obtaining, setting or adding LV_ITEMs or TV_ITEMs from a foriegn process' list of tree view objects. if you search the archives you'll probably dig up a post from by me from several months back (if its still available) as to how to exactly do this. while this doesnt answer the question posted, a similar approach might be capable of accomplishing his control of the printer dialog from the foreign process.

    Originally posted by jim mcnamara
    You can reference objects within your process, not outside of it.
    The reason is that address space doesn't map across processes.

    You call SendMessage to control those objects.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width