-1

I'm testing an addin in ArcMap to open an existing file, the program stops after the dialog opened, it seems the SendKeys already executed before the dialog. Your advice is much appreciated.

    Dim pCmdItmOpen As ICommandItem 'file open dialog
    Dim pUIDopn As New UID
    pUIDopn.Value = "{119591DB-0255-11D2-8D20-080009EE4E51}"
    pUIDopn.SubType = 2
    pCmdItmOpen = mxApp.Document.CommandBars.Find(pUIDopn)
    pCmdItmOpen.Execute()
    SendKeys.SendWait("C:\TEST.mxd")
    SendKeys.SendWait("{TAB 3}")
    SendKeys.SendWait("{ENTER}")
Paul MJ
  • 3
  • 3

2 Answers2

1

I got this solution:

Detecting whether the dialog has been opened or not, if existing, then execute SendKeys. If not, waiting for a moment, maybe 3 sec, then detecting again.

How to:

Detecting whether the dialog has been opened or not

FindWindow FindWindowEx

Use FindWindow to find the dialog

Waiting for a period then execute the next step

Using timers in vb

Use timer to count the waiting time

Reply: I don't have 50 reputations, so not allowed to post a comment.

To use the FindWindow, you have to use the correct parameter. You could use Spy++ (Visual Studio, Tools/Spy++) to find the parameter of this dialog window.

enter image description here

You could use code below:

Declare:

<DllImport("user32.dll", CharSet:=CharSet.Auto, EntryPoint:="FindWindow")>
Private Shared Function FindWindow(ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr 
End Function

Function catchDialog:

Private Sub catchDialog()
     Dim hwnd As IntPtr = FindWindow("Class", "Caption")
     If hwnd <> IntPtr.Zero Then
        
        yourSendKeyProcess(hwnd)

     Else

     ' dialog not showing, waiting for 3 Sec. then detecting again. 
     ' Use Thread.Sleep() is simple then timer.
        Thread.Sleep(3000)
        catchDialog()

     End if

End Sub     

Function yourSendKeyProcess:

Private Sub yourSendKeyProcess(ByVal window as IntPtr)

     SetForegroundWindow(window)
     SendKeys.SendWait("C:\TEST.mxd")
     SendKeys.SendWait("{TAB 3}")
     SendKeys.SendWait("{ENTER}")

End Sub    

Use Spy++ to find the value of "Caption", and "Class" of the dialog.

enter image description here

The example above, the value of Caption of the window is "Add to Archive" and the value of Class is "#32770(Dialog)", and the code would be:

Dim hWnd As IntPtr = FindWindow("#32770", "Add to Archive")

But even you could catch the dialog window, I am not sure that your code SendKey could work, so why you use those codes?

SendKeys.SendWait("C:\TEST.mxd")
SendKeys.SendWait("{TAB 3}")
SendKeys.SendWait("{ENTER}")

You want to input a string ("C:\TEST.mxd") in the textbox on the dialog, then press a button on the dialog?

Edit: Set the form1 always on top but not influence operation on other window: Add this sub to make the form1 on top in the beginning:

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    Me.TopMost = True
End Sub

and Function catchDialog:

Private Sub catchDialog()
     Dim hwnd As IntPtr = FindWindow("Class", "Caption")
     If hwnd <> IntPtr.Zero Then
        
       
        me.TopMost = false
        yourSendKeyProcess(hwnd)

     Else

     ' dialog not showing, waiting for 3 Sec. then detecting again. 
     ' Use Thread.Sleep() is simple then timer.
        Thread.Sleep(3000)
        catchDialog()

     End if

End Sub     

and Function yourSendKeyProcess:

Private Sub yourSendKeyProcess(ByVal window as IntPtr)

     SetForegroundWindow(window)
     SendKeys.SendWait("C:\TEST.mxd")
     SendKeys.SendWait("{TAB 3}")
     SendKeys.SendWait("{ENTER}")
     me.TopMost = true

End Sub
Community
  • 1
  • 1
Kuo-hsuan Hsu
  • 677
  • 1
  • 6
  • 12
  • I can get the Class and Window name correct and open the "Open" dialog, but the SendKeys.SenWait not continue to execute, looks to wait for the dialog to close. I have created lots of SendKeys code in vba and need to convert to vb.net. This code is just for testing, one of the original vba code like this; – Paul MJ Oct 29 '18 at 01:36
  • DoEvents SendKeys "{ENTER 1}", True SendKeys "W", True SendKeys "{DOWN 4}", True SendKeys "{ENTER 3}", True pCmdItmHSNxtID.Execute DoEvents SendKeys "{ENTER 4}", True pCmdItmHSCrte.Execute pCmdItmHSDisp.Execute DoEvents – Paul MJ Oct 29 '18 at 01:38
  • 1. so, all the senkeys code are not executed on the "open dialog" ? – Kuo-hsuan Hsu Oct 29 '18 at 01:49
  • 2. If 1 is true, where sendkeys are executed ? another form (window) ? if so, you have to do the catch window again, to find the window where all those sendkeys commands are executed with. – Kuo-hsuan Hsu Oct 29 '18 at 01:55
  • The SendKeys execute after the "Open" dialog closed. – Paul MJ Oct 29 '18 at 20:06
  • Now I got the small test code working. Not require to use the FindWindow. First to change the "SendKeys.SendWait" to "SendKeys.Send", second in order to make "SendKeys.Send" working, as the suggestions I researched, use form1.ShowDialog instead of form1.show. Now another issue happened is the form1 become modal and user can't do anything. Because the form1 is an addin in ArcMap and should be opened all the time and user should be able to run other command. Any suggestion? – Paul MJ Oct 30 '18 at 23:36
  • Those sendkeys code are executed on the form1, right? Or those sendkeys are executed on the ArcMap ? I mean, SendKeys "{ENTER 1}" you want to press some button, which form is the button embedded ? And where those sendkeys are written, in the form1.vb ? or in another form ? – Kuo-hsuan Hsu Oct 31 '18 at 01:53
  • There will be more buttons in form1 and this form will stay while user editing the file. The form1 will have more buttons, these button will execute some automation process, like when user click a button, a ArcMap dialog box will open then the sendkeys do some selections, like enter some text in textbox, press "tab" key, "enter" key....then close it. – Paul MJ Oct 31 '18 at 02:32
  • I am a little bit confuse, I suggest that :1. you are coding form1, 2. and you would put several buttons on form1. 3.When user cilck a button on form1, 4. a dialog box show up (could you edit the code of this dialog ? I assume you can't, all you can do is use sendkey to commend), 5. do something on this dailog (for example, use sendkey to enter a string in a textbox of this dailog, then use sendkey to press a button of this dailog, then this dailog close). Is the statement above true ? – Kuo-hsuan Hsu Oct 31 '18 at 03:56
  • If my statement above is correct, after the step 5 been finished, the foucs would return to form1 automatically, you don't need form1.show or form1.showDialog. – Kuo-hsuan Hsu Oct 31 '18 at 04:09
  • ShowDialog would not allow you to control other window, besides close the form. – Kuo-hsuan Hsu Oct 31 '18 at 04:16
  • Exactly what you said. The dialog windows are built-in I can't edit the code. I need to keep the form1 on the screen all the time. Please see the following utube link will explain more, this is a vba application we have been used for years. https://www.youtube.com/watch?v=0PxtW-YQSmE&list=PLsN673CkFzN2MWEyNwyMMykOEhnnsnu9Y – Paul MJ Oct 31 '18 at 19:55
  • Ok, you could use me.TopMost to set the form1 always on top, but not disturb you to operate on other window. But when the dailog show up, you also need sendkey to do something on this dialog. So the logic would be, when dialog show up, the topmost must turn off, when the dialog close, then turn the topmost on. I will edit my answer with this solution. – Kuo-hsuan Hsu Nov 01 '18 at 03:46
  • 1
    It didn't work because I have to run opendialogcommand first to let the dialog open, then run the catchDialog. Because the dialog is modal therefore the catchDialog will not execute until the dialog is closed. Is the order should be 1, open dialog. 2, Run catchDialog. 3, Set dialog foreground. 4, Run sendkeys. – Paul MJ Nov 07 '18 at 22:55
  • Basically, if my suggestion is correct, the dialog that you want to do something is ran (or produced, invoked..) by other program (or process, app...), then even it is a modal, it won't "stop" the catchDialog() to execute. Therefore the problem is made from other factor. – Kuo-hsuan Hsu Nov 08 '18 at 08:26
  • And I think that problem would occur in the step "set Dialog foreground". – Kuo-hsuan Hsu Nov 08 '18 at 08:29
  • I have done some tests, you can see the video https://youtu.be/Lm3XR9xGU0Y – Kuo-hsuan Hsu Nov 08 '18 at 12:01
0

Thanks for your advice. I have tried the code below however the hWnd return 0. It seems the window name parameter "Open" in the FindWindow function not working?

It works in ArcMap vba use "SendKeys" and "Doevents" everything just prefect and easy to debug in ArcMap. Now I'm converting the vba to vb.net and I found it is more difficult than I thought!!

The "SendKeys.SendWait' wait for the dialog to close then proceed. If I use the "SendKeys.Send" the error "SendKeys.Send cannot run inside this application...".

    Dim pCmdItmOpen As ICommandItem 'file open dialog
    Dim pUIDopn As New UID
    pUIDopn.Value = "{119591DB-0255-11D2-8D20-080009EE4E51}"
    pUIDopn.SubType = 2
    pCmdItmOpen = mxApp.Document.CommandBars.Find(pUIDopn)
    pCmdItmOpen.Execute()
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    Dim hWnd As IntPtr = FindWindow("Open", Nothing)
    MsgBox(hWnd)
    If hWnd.Equals(IntPtr.Zero) Then
        Return
    End If
    SetForegroundWindow(hWnd)
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    SendKeys.SendWait("C:\TEST.mxd")
    SendKeys.SendWait("{TAB 3}")
    SendKeys.SendWait("{ENTER}")
Paul MJ
  • 3
  • 3