Hello! I am developing an application to display different documents(txt, doc, xls, ppt, pdf files), arrange them on the desktop and scroll through the pages. I use System.Diagnostics.Process.Start
to open the relevant file with the right application. I use then Process.mainWindowHandle
to resize, to move and scroll those apps with WinAPI methods. It works good for documents for which every Process.Start
call results in an independent process, e.g. I can open two txt-files in Windows' Notepad and I get two processes displayed in the task manager. I can get the mainWindowHandle of both easily and rearrange them. But it crashes on mutex apps(right word?). The Microsoft Word Viewer is such a candidate. I open one document foo.doc, the Word Viewer starts a process. Then I start another "instance" of it with a different file bar.doc and it opens the file, but I don't get the right Process
object returned, because the first instance(with foo.doc) adds bar.doc to its managed windows. My code:
Public Overridable Function Start(ByVal x As Double, ByVal y As Double, _
ByVal width As Double, ByVal height As Double) As Boolean
Dim retValue As Boolean = False
Dim fred As ProcessThread
Dim waited As Boolean
\_x = x
\_y = y
\_width = width
\_height = height
'Starts the application with the file, ...
\_process = Process.Start(\_app\_path, """" & \_file.Path & """")
If Not IsNothing(\_process) Then
'...but it crashes as soon as I try to access a member of \_process
waited = \_process.WaitForInputIdle()
If Not IsNothing(\_process.Threads) Then
fred = \_process.Threads.Item(0)
retValue = EnumThreadWindows(New IntPtr(fred.Id), \_
AddressOf MoveCallback, IntPtr.Zero)
End If
End If
Return retValue
End Function
EnumThreadWindows is a WinAPI call and MoveCallback is a callback for it:
Private Function MoveWindow(ByVal hWnd As IntPtr, ByVal x As Integer, _
ByVal y As Integer, ByVal nWidth As Integer, ByVal nHeight As Integer, _
ByVal bRepaint As Boolean) As Boolean
End Function
_
Private Function EnumThreadWindows(ByVal dwThreadId As IntPtr, _
ByVal lpfn As EnumThreadDelegate, ByVal lParam As IntPtr) As Boolean
End Function
Private Function MoveCallback(ByVal hWnd As IntPtr, _
ByVal lParam As IntPtr) As Boolean
Dim sc