Acrobat Viewer
Afx:400000:8:14a6:0:6b3f
CoolTypeFontChange
EWHAcrobatTransportWindow
La ultima duda, porque cuando llamo a la funcion
ShellExecute(hwnd,"open","algo.txt",vbnullstring,"c:\",SW_SHOWNORMAL)
no se abre una instancia del Notepad? lo mismo sucede para el HTML no se abre
una instancia del iexplorer.exe. Si sucede cambiando "algo.txt" con
"algo.doc" y "algo.pdf"
se abren las instancias del word y acrobat reader. GRACIAS POR SU TIEMPO.
Private Sub Form_Load()
Dim hInstance as Long
Dim sPath As String
Dim hWndApp As Long
sPath = Path & "\htmls\fallos\"
hInstance = ShellExecute(Me.hwnd, "open", sFileName, vbNullString, Path,
SW_SHOWNORMAL)
hWndApp = FindWindow("AdobeAcrobat", vbNullString)
Call SetParent(hWndApp, Me.hwnd)
End Sub
cuando cambio "AdobeAcrobat" por "OpusApp" la instancia de word si se me
abre dentro del area cliente de mi form, pero el acrobat no. A que direccion
me mandaste el ejemplo? muchas gracias por tu tiempo
intenta darle tiempo de carga, el Adobe es más lento que MSWord, por eso
es posible que abriendo un '.doc' y buscando la 'OpusApp' inmediatamente en
la siguiente línea sí que te funcionase, con el Adobe puede que se necesiten
una treintena (relativo a la máquina y al estado del SO) de iteraciones
antes de haberse creado la ventana:
'*********
do
hWndApp = FindWindow("AdobeAcrobat", vbNullString):Doevents
Loop Until hWndApp
'*********
Es evidente que en un momento dado esto podría provocar un DeadLock, por
lo que te sugiero que primero verifiques si se produjo error al abrir el
fichero.
Además pondría una variable con la que se pudiera cancelar, ya sea por
intervención del usuario o con un 'Timer' estableciendo un tiempo de margen
(bueno, esto lo tendrás que evaluar tú si es que lo encuentras necesario,
además de que es difícil determinar un tiempo de margen porque dependerá de
varios factores).
Por si quieres probarlo, te paso la siguiente propuesta:
'****************************
Private Const SW_NORMAL As Long = 1
'Constantes de error para ShellExecute
Private Const ERROR_FILE_NOT_FOUND As Long = 2&
Private Const ERROR_PATH_NOT_FOUND As Long = 3&
Private Const ERROR_BAD_FORMAT As Long = 11&
Private Const SE_ERR_ACCESSDENIED As Long = 5
Private Const SE_ERR_ASSOCINCOMPLETE As Long = 27
Private Const SE_ERR_DDEBUSY As Long = 30
Private Const SE_ERR_DDEFAIL As Long = 29
Private Const SE_ERR_DDETIMEOUT As Long = 28
Private Const SE_ERR_DLLNOTFOUND As Long = 32
Private Const SE_ERR_FNF As Long = 2
Private Const SE_ERR_NOASSOC As Long = 31
Private Const SE_ERR_OOM As Long = 8
Private Const SE_ERR_PNF As Long = 3
Private Const SE_ERR_SHARE As Long = 26
Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" ( _
ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
Private Declare Function GetParent Lib "user32.dll" ( _
ByVal hwnd As Long) As Long
Private Declare Function SetParent Lib "user32.dll" ( _
ByVal hWndChild As Long, _
ByVal hWndNewParent As Long) As Long
Private Declare Function ShellExecute _
Lib "shell32.dll" Alias "ShellExecuteA" ( _
ByVal hwnd As Long, _
ByVal lpOperation As String, _
ByVal lpFile As String, _
ByVal lpParameters As String, _
ByVal lpDirectory As String, _
ByVal nShowCmd As Long) As Long
'Miembros privados
Private m_hWndAdobe As Long
Private m_hWndParentAnt As Long
Private boolCancelar As Boolean
Private Sub Form_Load()
Call AbrirPDF("c:\kk.pdf")
End Sub
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
Call SetParent(m_hWndAdobe, m_hWndParentAnt)
End Sub
Private Sub AbrirPDF(ByVal sFilePath As String)
Dim hInstance As Long
Dim sMsgErr As String
hInstance = ShellExecute(hwnd, "Open", sFilePath, _
vbNullString, vbNullString, SW_NORMAL)
If hInstance > 32 Then
Do
m_hWndAdobe = FindWindow("AdobeAcrobat", vbNullString): DoEvents
Loop Until m_hWndAdobe Or boolCancelar
If boolCancelar Then
'Se canceló sin haber encontrado la ventana.
Exit Sub
End If
Else
Select Case hInstance
Case 0: sMsgErr = "The operating system is out of memory" & _
" or resources."
Case ERROR_FILE_NOT_FOUND: sMsgErr = "The specified file" & _
" was not found."
Case ERROR_PATH_NOT_FOUND: sMsgErr = "The specified path" & _
" was not found."
Case ERROR_BAD_FORMAT: sMsgErr = "The .EXE file is inval" & _
"id (non-Win32 .EXE or error in .EXE" & _
" image)."
Case SE_ERR_ACCESSDENIED: sMsgErr = "The operating syste" & _
"m denied access to the specified file."
Case SE_ERR_ASSOCINCOMPLETE: sMsgErr = "The filename ass" & _
"ociation is incomplete or invalid."
Case SE_ERR_DDEBUSY: sMsgErr = "The DDE transaction coul" & _
"d not be completed because other DD" & _
"E transactions were being processed."
Case SE_ERR_DDEFAIL: sMsgErr = "The DDE transaction failed."
Case SE_ERR_DDETIMEOUT: sMsgErr = "The DDE transaction c" & _
"ould not be completed because the r" & _
"equest timed out."
Case SE_ERR_DLLNOTFOUND: sMsgErr = "The specified dynami" & _
"c-link library was not found."
Case SE_ERR_FNF: sMsgErr = "The specified file was not found."
Case SE_ERR_NOASSOC: sMsgErr = "There is no application " & _
"associated with the given filename " & _
"extension."
Case SE_ERR_OOM: sMsgErr = "There was not enough memory " & _
"to complete the operation."
Case SE_ERR_PNF: sMsgErr = "The specified path was not found."
Case SE_ERR_SHARE: sMsgErr = "A sharing violation occurred."
End Select
MsgBox "Error:" & vbCrLf & sMsgErr, vbCritical
Exit Sub
End If
m_hWndParentAnt = GetParent(m_hWndAdobe)
Call SetParent(m_hWndAdobe, Me.hwnd)
End Sub
'****************************
--
:-) Un saludo
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
( ! ) Respuestas precedentes en Google:
http://tinyurl.com/43b3q
( i ) Temperancia en el foro:
http://www.mvp-access.com/rubenvigon/foro
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
como podrás comprobar, Hernán dió en el clavo (gracias Hernán, eres un
fenómeno). En el apartado 'Remarks' verás que es exactamente lo que se
precisa en este caso:
· WaitForInputIdle
http://tinyurl.com/c88rd
Enmiendo el ejemplo anterior con el presente. Sólo cambian un par de
cosas. Deberás usar 'ShellExecuteEx' en lugar de 'ShellExecute' para pasarle
una estructura de tipo 'ShellExecuteInfo', en cuyo miembro 'hInstApp'
recibirás el valor con el que determinarás si se produjo error. Por contra,
le pasarás el 'hProcess' a 'WaitForInputIdle'. Cambia el tiempo de espera al
valor que consideres oportuno.
Revisa la estructura:
· SHELLEXECUTEINFO Structure
http://tinyurl.com/52dlz
'****************************
Private Type SHELLEXECUTEINFO
cbSize As Long
fMask As Long
hwnd As Long
lpVerb As String
lpFile As String
lpParameters As String
lpDirectory As String
nShow As Long
hInstApp As Long
' fields
lpIDList As Long
lpClass As String
hkeyClass As Long
dwHotKey As Long
hIcon As Long
hProcess As Long
End Type
Private Const SW_NORMAL As Long = 1
'Constantes de error para ShellExecute
Private Const ERROR_FILE_NOT_FOUND As Long = 2&
Private Const ERROR_PATH_NOT_FOUND As Long = 3&
Private Const ERROR_BAD_FORMAT As Long = 11&
Private Const SE_ERR_ACCESSDENIED As Long = 5
Private Const SE_ERR_ASSOCINCOMPLETE As Long = 27
Private Const SE_ERR_DDEBUSY As Long = 30
Private Const SE_ERR_DDEFAIL As Long = 29
Private Const SE_ERR_DDETIMEOUT As Long = 28
Private Const SE_ERR_DLLNOTFOUND As Long = 32
Private Const SE_ERR_FNF As Long = 2
Private Const SE_ERR_NOASSOC As Long = 31
Private Const SE_ERR_OOM As Long = 8
Private Const SE_ERR_PNF As Long = 3
Private Const SE_ERR_SHARE As Long = 26
Private Const SEE_MASK_NOCLOSEPROCESS As Long = &H40
Private Const SEE_MASK_FLAG_DDEWAIT As Long = &H100
Private Const WAIT_TIMEOUT As Long = 258&
Private Const WAIT_FAILED As Long = &HFFFFFFFF
Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" ( _
ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
Private Declare Function GetParent Lib "user32.dll" ( _
ByVal hwnd As Long) As Long
Private Declare Function SetParent Lib "user32.dll" ( _
ByVal hWndChild As Long, _
ByVal hWndNewParent As Long) As Long
Private Declare Function ShellExecuteEx Lib "shell32.dll" ( _
ByRef lpExecInfo As SHELLEXECUTEINFO) As Long
Private Declare Function WaitForInputIdle Lib "user32" ( _
ByVal hProcess As Long, ByVal dwMilliseconds As Long) As Long
'Miembros privados
Private m_hWndAdobe As Long
Private m_hWndParentAnt As Long
Private Sub Form_Load()
Call AbrirPDF("c:\kk.pdf")
End Sub
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
Call SetParent(m_hWndAdobe, m_hWndParentAnt)
End Sub
Private Sub AbrirPDF(ByVal sFilePath As String)
Dim sMsgErr As String
Dim SEI As SHELLEXECUTEINFO
With SEI
.cbSize = Len(SEI)
.fMask = SEE_MASK_NOCLOSEPROCESS Or SEE_MASK_FLAG_DDEWAIT
.hwnd = Me.hwnd
.lpVerb = "Open"
.lpFile = sFilePath
.lpParameters = vbNullChar
.lpDirectory = vbNullChar
.nShow = SW_NORMAL
.hInstApp = 0
.lpIDList = 0
End With
Call ShellExecuteEx(SEI)
If SEI.hInstApp > 32 Then
Select Case WaitForInputIdle(SEI.hProcess, 3000)
Case WAIT_TIMEOUT
MsgBox "Tiempo de espera agotado.", vbExclamation
Exit Sub
Case WAIT_FAILED 'Error, usa GetLastError
MsgBox "Error", vbCritical
Exit Sub
Case Else 'i.e. cero, ergo concluyó correctamente.
End Select
m_hWndAdobe = FindWindow("AdobeAcrobat", vbNullString)
Else
Select Case SEI.hInstApp
End If 'SEI.hInstApp > 32
If m_hWndAdobe = 0 Then
MsgBox "No se pudo encontrar la vantana.", vbExclamation