Results 1 to 5 of 5
  1. #1
    5 Star Lounger
    Join Date
    Feb 2001
    Location
    Youngstown, Ohio, USA
    Posts
    705
    Thanks
    1
    Thanked 0 Times in 0 Posts

    Send Object / Express ClickYes (2000 SR1)

    Somewhere in these forums not too long ago someone provided a link to ExpressSoft to get their Express ClickYes program to automate emailing from Access. For the most part, it works superbly, but there are a couple of technical hitches that I'm wondering if they can be ironed out. (Product background - it sits in the system tray, waiting for the Outlook security prompt, automatically clicking 'Yes', without the 5-second delay otherwise required.)

    I'm not interested in having ClickYes always running, so I set up my macros to start it with RunApp where required, but I havn't found any way to automate shutting it down once it is no longer required. There doesn't seem to be any 'unload' function programmed into ClickYes, so is there a VBA option that might work instead? The web site has some sample VB/VBA code, but it's not all that clear to me how to incorporate it.

    A solution to this would probably also help with the other little glitch that I've encountered - multiple instances of ClickYes running in the System Tray. For the sake of redundancy I've set most of my object-sending databases up with their own ClickYes RunApp code, so each can function in a stand-alone mode. For now though this has left me with multiple instances of ClickYes running when I run multiple databases in sequence. If the program can't be closed automatically, can I at least check to see if it is running before starting a second, third, or so on, instance?

  2. #2
    Plutonium Lounger
    Join Date
    Mar 2002
    Posts
    84,353
    Thanks
    0
    Thanked 29 Times in 29 Posts

    Re: Send Object / Express ClickYes (2000 SR1)

    You can use the FindWindow API function to determine if ClickYes is running. Put the following declaration in a general module:

    Public Declare Function FindWindow Lib "user32" _
    Alias "FindWindowA" (ByVal lpClassName As Any, _
    ByVal lpWindowName As Any) As Long

    From the website, you can learn that the window name is "EXCLICKYES_WND". FindWindow("EXCLICKYES_WND", 0&) will return a non-zero number (the window handle) if ClickYes is running, and 0 if it isn't. So you can use code like:

    If FindWindow("EXCLICKYES_WND", 0&) = 0 Then
    ' Insert code to start ClickYes here
    End If

    There may be a message you can send to ClickYes to unload itself, but I can't help you with that.

  3. #3
    Bronze Lounger
    Join Date
    Nov 2001
    Location
    Arlington, Virginia, USA
    Posts
    1,394
    Thanks
    0
    Thanked 3 Times in 3 Posts

    Re: Send Object / Express ClickYes (2000 SR1)

    Once you get the application's window handle using FindWindow API you can close app using Windows PostMessage API to send it a message to close. Example:

    Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" _
    (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long

    Function apiCloseWindow(ByVal hwnd As Long)

    Const WM_CLOSE = &H10

    apiCloseWindow = PostMessage(hwnd, WM_CLOSE, 0, vbNullString)

    End Function

    The only tricky part about FindWindow is figuring out the app's Window class name - these are somewhat arbitrary.... If you have multiple instances of the app running you'll have to loop thru them and close each - FindWindow will return the hwnd of the first instance of a given class it happens to find.

    HTH

  4. #4
    Plutonium Lounger
    Join Date
    Mar 2002
    Posts
    84,353
    Thanks
    0
    Thanked 29 Times in 29 Posts

    Re: Send Object / Express ClickYes (2000 SR1)

    Thanks, Mark. This should solve the original poster's problem, since the makers of ClickYes have revealed the window class name "EXCLICKYES_WND".

  5. #5
    Bronze Lounger
    Join Date
    Nov 2001
    Location
    Arlington, Virginia, USA
    Posts
    1,394
    Thanks
    0
    Thanked 3 Times in 3 Posts

    Re: Send Object / Express ClickYes (2000 SR1)

    Suppose you have an application and do not know its Class Name and can't find it listed somewhere? It's a little convoluted, but you can use the application's window caption (the text that appears in app title bar) to get the app window's Hwnd & Class Name, using some API functions as shown:

    Option Compare Database
    Option Explicit

    Declare Function apiGetDesktopWindow Lib "user32" Alias "GetDesktopWindow" () As Long

    Declare Function apiGetWindow Lib "user32" Alias "GetWindow" _
    (ByVal hWnd As Long, ByVal wCmd As Long) As Long

    Declare Function apiGetWindowText Lib "user32" Alias "GetWindowTextA" _
    (ByVal hWnd As Long, ByVal lpString As String, ByVal aint As Long) As Long

    Declare Function apiGetClassName Lib "user32" Alias "GetClassNameA" _
    (ByVal hWnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long

    Public Const GW_CHILD = 5
    Public Const GW_HWNDNEXT = 2
    Public Const MAX_LEN = 128

    Use these two similar functions return text string from the API's:

    Public Function GetCaption(hWnd As Long)

    Dim strBuffer As String
    Dim intLen As Integer

    If hWnd <> 0 Then
    strBuffer = Space(MAX_LEN)
    intLen = apiGetWindowText(hWnd, strBuffer, MAX_LEN)
    GetCaption = Left(strBuffer, intLen)
    End If

    End Function

    Public Function GetClassName(ByVal hWnd As Long)

    Dim strBuffer As String
    Dim intLen As Integer

    If hWnd <> 0 Then
    strBuffer = Space(MAX_LEN)
    intLen = apiGetClassName(hWnd, strBuffer, MAX_LEN)
    GetClassName = Left(strBuffer, intLen)
    End If

    End Function

    Use these to get Class Name and Hwnd for a specified application window caption:

    Sub TestGetHwndAndClassName(ByVal strAppCaption As String)

    Dim strClassName As String
    Dim n As Long

    strClassName = ""
    n = GetHwnd(strAppCaption, strClassName)

    Debug.Print "Hwnd: " & n
    Debug.Print "Application Class Name: " & strClassName

    End Sub

    Public Function GetHwnd(ByVal strAppCaption As String, _
    ByRef strClassName As String) As Long

    Dim hWnd As Long
    Dim strCaption As String
    Dim bFound As Boolean

    bFound = False

    ' Get the desktop window, then the first top-level window:
    hWnd = apiGetDesktopWindow()
    hWnd = apiGetWindow(hWnd, GW_CHILD)

    ' Loop thru top-level windows:
    Do While hWnd <> 0
    strCaption = GetCaption(hWnd)
    If strCaption = strAppCaption Then
    bFound = True
    Exit Do
    Else
    ' Move to the next top-level window:
    hWnd = apiGetWindow(hWnd, GW_HWNDNEXT)
    End If
    Loop

    If bFound = True Then
    GetHwnd = hWnd
    strClassName = GetClassName(hWnd)
    Else
    GetHwnd = 0
    strClassName = ""
    End If

    End Function

    Example of use (with an open Word window):

    TestGetHwndAndClassName("Hwnd.doc - Microsoft Word")
    Hwnd: 3480
    Application Class Name: OpusApp

    (OpusApp being the arbitrary class name for MS Word.) The GetHwnd function loops thru all top-level windows till it finds a windows caption that matches the caption passed to function. As shown by TestGetHwndAndClassName sub, since the strClassName argument is passed by reference (as an empty string), the GetHwnd function also "returns" the application's class name as string (if found), in addition to actual return value (the window's hwnd). Once you know the hwnd you can use it to call any number of API functions such as PostMessage to close window, etc. Maybe someone knows a simpler way to determine the application class name....?

Posting Permissions

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