Visual Basic Development Bookmark and Share   
 Home > Visual Basic Language > The code 'ProcID=shell(MSPAINT.EXE,AppWinStyle.NormalFocus)' results in ProcID = 0.
 

The code 'ProcID=shell(MSPAINT.EXE,AppWinStyle.NormalFocus)' results in ProcID = 0.

My application has a NotifyIcon to provide a context menu. It should have the ability to launch another app and send a short sequence of keystrokes to the app so the app can paste a screen shot. The code is as follows:

    Private Sub LaunchMSPaintToolStripMenuItem_Click( _

ByVal sender As System.Object, _

ByVal e As System.EventArgs) _

 Handles LaunchMSPaintToolStripMenuItem.Click



        Dim ProcID As Integer

        ProcID = Shell("MSPAINT.EXE", _

AppWinStyle.NormalFocus)

        AppActivate(ProcID)    'Problem AppActivate(0)
'Paste
My.Computer.Keyboard.SendKeys(keys.Control + _ keys.V, True)
'Open File menu
My
.Computer.Keyboard.SendKeys(keys.Alt + _
keys.F)

'Move selection down to Save As and select.
My.Computer.Keyboard.SendKeys(keys.Down + _ keys.Down + keys.Down + keys.Down + keys.Down + _ keys.Enter) End Sub

My app throws an unhandled exception at AppActivate(ProcID). How do I fix it so that ProcID = the process ID of the shelled app MSPAINT.EXE instead of 0?

How do I attach the jitDebugger to my app?

Thanks,
BLeRg.
  • Edited byiamBLeRg Wednesday, May 13, 2009 12:51 PMMissing a line of code. Added comments.
  •  
iamBLeRg  Wednesday, May 13, 2009 12:37 PM
Looks its working, but I never trust sendkeys, I have added True (wait)

 My.Computer.Keyboard.SendKeys("^v")
        My.Computer.Keyboard.SendKeys("%F")
        My.Computer.Keyboard.SendKeys("A")
        My.Computer.Keyboard.SendKeys("2")
        My.Computer.Keyboard.SendKeys("{Down}")
        My.Computer.Keyboard.SendKeys("+{Tab}", True)
        My.Computer.Keyboard.SendKeys("{END}", True)
        My.Computer.Keyboard.SendKeys("+{Home}", True)
        My.Computer.Keyboard.SendKeys("{Delete}", True)
        My.Computer.Keyboard.SendKeys("Most stable image format is preselected")
        My.Computer.Keyboard.SendKeys("{Home}", True)
        My.Computer.Keyboard.SendKeys("+{END}", True)


Arjun Paudel
  • Marked As Answer byiamBLeRg Wednesday, May 13, 2009 6:08 PM
  •  
Arjun Paudel  Wednesday, May 13, 2009 4:23 PM
Nope. Still had problems. Here's the ultimate solution with no explanation as to why it works great now, but it could be becausea thread had to die or something. So spreading the code out like:
Public Class Form1

    'Make the declaration in the class,
    'this way you don't have to code 
    'a decision, which might, unfortunately, 
    'take advantage of multi-threading.
    Dim ProcID As Integer

'**********************************************
'**********  NOTE:
'**********  You will need a valid bitmap path and
'**********    filename in the following line.
'**********************************************
    Dim fileName As String = "path and name to a _
bitmap on your system"
    Dim bmp As Bitmap = New Bitmap(fileName)

    Private Sub Form1_FormClosed( _
ByVal sender As Object,  _
ByVal e As System.Windows.Forms.FormClosedEventArgs) _
 Handles Me.FormClosed
        Dim myProcesses() As Process
        Dim instance As Process
        myProcesses = Process.GetProcessesByName( _
"mspaint")
        For Each instance In myProcesses
            'Can be nice?
            If instance.CloseMainWindow Then
                'Yes, so be it.
                instance.Close()
            Else
                'No.  So be it!
                instance.Kill()
            End If
        Next
    End Sub

    Private Sub Form1_Load( _
ByVal sender As System.Object, _
 ByVal e As System.EventArgs) Handles MyBase.Load
        ProcID = Shell( _
"MSPAINT.EXE", AppWinStyle.NormalFocus)
        My.Computer.Clipboard.Clear()
        My.Computer.Clipboard.SetImage(Me.bmp)
        'You might be able to get away with, say 
        'msec > 100 and msec < 200. _
        '100 didn't work for me.
        'But you only need the following line if you 
        'want the form on top of paint.
        Threading.Thread.Sleep(200)
        Me.BringToFront()
    End Sub

    Private Sub Form1_MouseUp( _
ByVal sender As Object, _
 ByVal e As System.Windows.Forms.MouseEventArgs) _
 Handles Me.MouseUp
        AppActivate(ProcID)
        My.Computer.Keyboard.SendKeys("%F", True) 
' Threading.Thread.Sleep(500)
        My.Computer.Keyboard.SendKeys("N", True)  
' Threading.Thread.Sleep(500)
        My.Computer.Keyboard.SendKeys("N", True)  
' Threading.Thread.Sleep(500)
        My.Computer.Keyboard.SendKeys("^v", True)
        My.Computer.Keyboard.SendKeys("%F", True)
        My.Computer.Keyboard.SendKeys("A", True)
    End Sub
End Class
So as can be seen, the single threadsleep method is optional, depending on whether you care if Form1 is on top of Paint.
It isn't necessary to call the threadsleep method and have MSPaint.exe respond to sent keystrokes. Of course now you'll probably want to close paint, but, in case you haven't examined the code closely enough, you may find that I have closed it for you if you have closed Form1.

Thanx for all your great help,
BLeRg.
  • Marked As Answer byiamBLeRg Sunday, June 07, 2009 4:03 AM
  •  
iamBLeRg  Sunday, June 07, 2009 4:03 AM
First I added the thread sleep code
bracketed with beeps, rebuilt and installed it.
The error went away, but MSPAINT.EXE
still does not respond to the keystrokes
sent to it.

Next I rebuilt and installed with the following code:
        Dim ProcID As Integer
        ProcID = Shell("MSPAINT.EXE", _
 AppWinStyle.NormalFocus)
        'Beep()
        'Threading.Thread.Sleep(3000)  '3 seconds
        'Beep()
        MsgBox(ProcID.ToString)
        AppActivate(ProcID)
        My.Computer.Keyboard.SendKeys(keys.Control _
 + keys.V, True)
        My.Computer.Keyboard.SendKeys(keys.Alt + keys.F)
        My.Computer.Keyboard.SendKeys(keys.Down + _
 keys.Down + keys.Down + keys.Down + keys.Down + _
 keys.Enter)
Still not throwing an exception, still not responding to the keys sent. Any ideas?
iamBLeRg  Wednesday, May 13, 2009 2:33 PM
What are you trying to accomplish, following gives you print preview

 Dim ProcID As Integer
        ProcID = Shell("MSPAINT.EXE", _
 AppWinStyle.NormalFocus)
        
        Threading.Thread.Sleep(3000)  '3 seconds
      
       
        AppActivate(ProcID)
        My.Computer.Keyboard.SendKeys("^v")
        My.Computer.Keyboard.SendKeys("%f")
        My.Computer.Keyboard.SendKeys("v")


Arjun Paudel
Arjun Paudel  Wednesday, May 13, 2009 2:47 PM
        Dim ProcID As Integer

        ProcID = Shell("MSPAINT.EXE", _

AppWinStyle.NormalFocus)

        Threading.Thread.Sleep(500)

        AppActivate(ProcID)

        My.Computer.Keyboard.SendKeys("^v")

        My.Computer.Keyboard.SendKeys("%F")

        My.Computer.Keyboard.SendKeys("A")

        My.Computer.Keyboard.SendKeys("2")

        My.Computer.Keyboard.SendKeys(keys.Down)

        My.Computer.Keyboard.SendKeys(keys.Shift + _

keys.Tab)

        My.Computer.Keyboard.SendKeys(keys.End)

        My.Computer.Keyboard.SendKeys(keys.Shift + _

keys.Home)

        My.Computer.Keyboard.SendKeys(keys.Delete)

        My.Computer.Keyboard.SendKeys( _

"Most stable image format is preselected")

        My.Computer.Keyboard.SendKeys(keys.Home)

        My.Computer.Keyboard.SendKeys(keys.Shift + _

keys.End)

Almost there! But the following appears in the File name: textbox:
'24065545356557246Most stable image format is preselected3665571'
I don't know where these underlined numbers are comming from and the code above doesn't get rid of them. NOTE: There's no underline in the file name textbox. I need some help to eliminate those weird numbers.

Thanks,
BLeRg.
  • Edited byiamBLeRg Wednesday, May 13, 2009 4:13 PMAdd last sentence and signature.
  •  
iamBLeRg  Wednesday, May 13, 2009 4:08 PM
Looks its working, but I never trust sendkeys, I have added True (wait)

 My.Computer.Keyboard.SendKeys("^v")
        My.Computer.Keyboard.SendKeys("%F")
        My.Computer.Keyboard.SendKeys("A")
        My.Computer.Keyboard.SendKeys("2")
        My.Computer.Keyboard.SendKeys("{Down}")
        My.Computer.Keyboard.SendKeys("+{Tab}", True)
        My.Computer.Keyboard.SendKeys("{END}", True)
        My.Computer.Keyboard.SendKeys("+{Home}", True)
        My.Computer.Keyboard.SendKeys("{Delete}", True)
        My.Computer.Keyboard.SendKeys("Most stable image format is preselected")
        My.Computer.Keyboard.SendKeys("{Home}", True)
        My.Computer.Keyboard.SendKeys("+{END}", True)


Arjun Paudel
  • Marked As Answer byiamBLeRg Wednesday, May 13, 2009 6:08 PM
  •  
Arjun Paudel  Wednesday, May 13, 2009 4:23 PM
This is the successful code:
        Dim ProcID As Integer
        ProcID = Shell("MSPAINT.EXE", AppWinStyle.NormalFocus)
        Threading.Thread.Sleep(500)
        AppActivate(ProcID)
        My.Computer.Keyboard.SendKeys("^v")
        My.Computer.Keyboard.SendKeys("%F")
        My.Computer.Keyboard.SendKeys("A")
        My.Computer.Keyboard.SendKeys("{Tab}", True)
        My.Computer.Keyboard.SendKeys("2")
        My.Computer.Keyboard.SendKeys("{Down}", True)
        My.Computer.Keyboard.SendKeys("{Down}", True)
        My.Computer.Keyboard.SendKeys("+{Tab}", True)
        My.Computer.Keyboard.SendKeys("{End}", True)
        My.Computer.Keyboard.SendKeys("+{Home}", True)
        My.Computer.Keyboard.SendKeys("Most stable image format is preselected")
        My.Computer.Keyboard.SendKeys("{Home}", True)
        My.Computer.Keyboard.SendKeys("+{End}", True)
Sorry it took so long for me to get back on this, but I had to simulate a jitDebugger by uncommenting lines, rebuilding and reinstalling. The uninstallation tended to hang from time to time, so it seems I need an automated way to check if a previous version of the app is running and close it if neccessary. Might work.
Thanx,
BLeRg.
  • Unmarked As Answer byiamBLeRg Sunday, June 07, 2009 2:30 AM
  • Marked As Answer byiamBLeRg Wednesday, May 13, 2009 6:09 PM
  •  
iamBLeRg  Wednesday, May 13, 2009 6:08 PM
Nope. Still had problems. Here's the ultimate solution with no explanation as to why it works great now, but it could be becausea thread had to die or something. So spreading the code out like:
Public Class Form1

    'Make the declaration in the class,
    'this way you don't have to code 
    'a decision, which might, unfortunately, 
    'take advantage of multi-threading.
    Dim ProcID As Integer

'**********************************************
'**********  NOTE:
'**********  You will need a valid bitmap path and
'**********    filename in the following line.
'**********************************************
    Dim fileName As String = "path and name to a _
bitmap on your system"
    Dim bmp As Bitmap = New Bitmap(fileName)

    Private Sub Form1_FormClosed( _
ByVal sender As Object,  _
ByVal e As System.Windows.Forms.FormClosedEventArgs) _
 Handles Me.FormClosed
        Dim myProcesses() As Process
        Dim instance As Process
        myProcesses = Process.GetProcessesByName( _
"mspaint")
        For Each instance In myProcesses
            'Can be nice?
            If instance.CloseMainWindow Then
                'Yes, so be it.
                instance.Close()
            Else
                'No.  So be it!
                instance.Kill()
            End If
        Next
    End Sub

    Private Sub Form1_Load( _
ByVal sender As System.Object, _
 ByVal e As System.EventArgs) Handles MyBase.Load
        ProcID = Shell( _
"MSPAINT.EXE", AppWinStyle.NormalFocus)
        My.Computer.Clipboard.Clear()
        My.Computer.Clipboard.SetImage(Me.bmp)
        'You might be able to get away with, say 
        'msec > 100 and msec < 200. _
        '100 didn't work for me.
        'But you only need the following line if you 
        'want the form on top of paint.
        Threading.Thread.Sleep(200)
        Me.BringToFront()
    End Sub

    Private Sub Form1_MouseUp( _
ByVal sender As Object, _
 ByVal e As System.Windows.Forms.MouseEventArgs) _
 Handles Me.MouseUp
        AppActivate(ProcID)
        My.Computer.Keyboard.SendKeys("%F", True) 
' Threading.Thread.Sleep(500)
        My.Computer.Keyboard.SendKeys("N", True)  
' Threading.Thread.Sleep(500)
        My.Computer.Keyboard.SendKeys("N", True)  
' Threading.Thread.Sleep(500)
        My.Computer.Keyboard.SendKeys("^v", True)
        My.Computer.Keyboard.SendKeys("%F", True)
        My.Computer.Keyboard.SendKeys("A", True)
    End Sub
End Class
So as can be seen, the single threadsleep method is optional, depending on whether you care if Form1 is on top of Paint.
It isn't necessary to call the threadsleep method and have MSPaint.exe respond to sent keystrokes. Of course now you'll probably want to close paint, but, in case you haven't examined the code closely enough, you may find that I have closed it for you if you have closed Form1.

Thanx for all your great help,
BLeRg.
  • Marked As Answer byiamBLeRg Sunday, June 07, 2009 4:03 AM
  •  
iamBLeRg  Sunday, June 07, 2009 4:03 AM

You can use google to search for other answers

Custom Search

More Threads

• Generate a random GUID
• Capitalize a string
• Help with ODBC Command
• DateTimePicker Question
• Programing with Visual Studio 2005 (Visual Basic)
• Minimizing to System Tray
• WCF in VB.NET
• .Net Sendkeys
• How to find handle of a textbox on a form using handles.
• Memory Problems - DataTables