Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Obtener el Hwnd de una instancia de una aplicacion usando APIS

23 views
Skip to first unread message

TinCHo

unread,
Nov 18, 2005, 1:16:18 PM11/18/05
to
Hola amigos, tengo una duda: alguien sabe cual es el nombre de clase para las
instancias del Acrobat Reader? necesito obtener su hwnd usando
FindWindow(class_name, window_name), funciona para las instancias de Word
cuya clase es OpusApp pero no se cual es para Acrobat, estoy realizando un
proyecto el cual puedo abrir docuemtos de word, acrobat, rtf txt e html
cuando se abren las aplicaciones correspondientes quiero q se encuentren
dentro del area cliente de un form. Por eso necesito el Hwnd para colocar el
SetParent.
Use la funcion EnumWindows abriendo una instancia del acrobat y estas son
las clases que me salieron pero ninguna funciona en FindWindow

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.

TinCHo

unread,
Nov 18, 2005, 6:02:02 PM11/18/05
to
ferg, gracias por tu ayuda, coloque el nombre de la clase en findwindow pero
no me funciona aqui te mando el codigo que uso:

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

Vinchenzo vinē

unread,
Nov 20, 2005, 9:21:32 AM11/20/05
to
Hola "TinCHo"

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
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


Message has been deleted

TinCHo

unread,
Nov 20, 2005, 2:25:01 PM11/20/05
to
Vinchenzo y Hernan: gracias muchachos por su paciencia y predisposicion a
darme siempre una mano. Les agradezco infinitamente. GRACIAS

Vinchenzo vinē

unread,
Nov 20, 2005, 3:40:28 PM11/20/05
to
Hola "TinCHo",

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

0 new messages