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

chiudere file esterno

127 views
Skip to first unread message

alberto...@gmail.com

unread,
Feb 15, 2020, 9:04:52 AM2/15/20
to
Salve!
come faccio a chiudere un file esterno
p.e. formato pdf o txt da Vba?

grz.

@Alex

unread,
Feb 15, 2020, 12:25:55 PM2/15/20
to
Intanto se lo hai aperto con Shell potresti recuperare il ProcessId e da quello l'handle... quindi con PostMessage o SendMessage lo chiudi.

Altrimenti devi usare findwindows ricercare l'handle...e poi sempre SendMessage o PostMessage...

Ovviamente parlo delle API.

@Alex

alberto...@gmail.com

unread,
Feb 16, 2020, 3:53:12 PM2/16/20
to
bene, così ho ottenuto l'handle
Hw = hWndShell("PDFXCview.exe", vbNormalFocus)
come si usa PostMessage o SendMessage per chiuderlo?
grazie

@Alex

unread,
Feb 17, 2020, 2:23:22 AM2/17/20
to
> bene, così ho ottenuto l'handle
> Hw = hWndShell("PDFXCview.exe", vbNormalFocus)
> come si usa PostMessage o SendMessage per chiuderlo?
> grazie

Pubblica anceh il Codice della chiamata [hWndShell] così che altri che magari leggono possono averne utilità...!

Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long

Private Const WM_CLOSE = &H10


PostMessage Hw , WM_CLOSE, CLng(0), CLng(0)

Userei PostMessage al posto di SENDMESSAGE... la differenza sta nel modo di elaborare il Messaggio e l'exit della chiamata...!

POSTMESSAGE invia il messaggio all'APP che viene messo in CODA, ed esce
SENDMESSAGE invia il messaggio all'APP e non esce finchè non viene processato

Nel tuo caso userei POSTMESSAGE, ma se vuoi essere certo usa SENDMESSAGE e controlla il valore restituito dalla chiamata...

@Alex

alberto...@gmail.com

unread,
Feb 17, 2020, 2:45:21 AM2/17/20
to
l'ho copiato dal tuo sito; sezione Api/n.54:

Option Compare Database
Option Explicit

Declare Function GetParent Lib "user32" _
(ByVal hwnd As Long) As Long
Declare Function EnumWindows Lib "user32.dll" _
(ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Declare Function GetWindowThreadProcessId Lib "user32" _
(ByVal hwnd As Long, lpdwProcessId As Long) As Long

Private Type EnumWindowsData
ProcessID As Long
hwnd As Long
End Type

'******************************************************************
' Esegue il nuovo processo e restituisce l'Hwnd
' della sua Finestra principale.
'******************************************************************
Public Function hWndShell(ByVal Job As String, _
Optional WindowStyle As VbAppWinStyle = vbMinimizedNoFocus) As Long
Dim ProcessID As Long

' Verifica che il WindowStyle sia applicabile
If (WindowStyle < vbHide) Or (WindowStyle > vbMinimizedNoFocus) Then
WindowStyle = vbMinimizedNoFocus
End If
' Lancia il processo con la modalità richiesta.
On Error Resume Next
ProcessID = Shell(Job, WindowStyle)
On Error GoTo 0
' Recupera l'Handle della finestra relativa al nuovo processo.
If ProcessID Then
hWndShell = hWndProcess(ProcessID)
End If
End Function

Public Function hWndProcess(ByVal ProcessID As Long) As Long
Dim ewd As EnumWindowsData
'******************************************************************
' Cicla attraverso l'Enumerazione delle Finestre di sistema cercando di recuperare
' l'hWnd della Main Window puntata dal Processo.
'******************************************************************
ewd.ProcessID = ProcessID
Call EnumWindows(AddressOf EnumWindowsProc, VarPtr(ewd))
hWndProcess = ewd.hwnd
End Function

'***********************************
' Private Methods
'***********************************
Private Function EnumWindowsProc(ByVal hwnd As Long, _
lParam As EnumWindowsData) As Long
Dim PID As Long ' Verifica che sia una top-level window.
If GetParent(hwnd) = 0 Then
' Verifica il processo di appartenenza
Call GetWindowThreadProcessId(hwnd, PID)
If PID = lParam.ProcessID Then
lParam.hwnd = hwnd
End If
End If
' Restituisce True per continuare se non ha trovato
' l'Hwnd relativo al PID.
EnumWindowsProc = (lParam.hwnd = 0)
End Function

il codice che mi hai scritto
va nello stesso modulo dove ho inserito il codice
della chiamata?
grazie

alberto...@gmail.com

unread,
Feb 17, 2020, 3:04:50 AM2/17/20
to
> grazie

@Alex

unread,
Feb 17, 2020, 3:16:42 AM2/17/20
to
No lo metti a seguire:

Hw = hWndShell("PDFXCview.exe", vbNormalFocus)
If Hw>0 Then
PostMessage Hw , WM_CLOSE, CLng(0), CLng(0)
Else
MsgBox "ERROR..."
End if


Le dichiarazioni API invece le puoi mettere in calce allo stesso modulo dove trovi le altre.

Fai attenzione alla possibile necessità di adeguare il codice a 64Bit...

@Alex

alberto...@gmail.com

unread,
Feb 17, 2020, 4:52:39 AM2/17/20
to
però non me lo chiude.
Ho fatto in questo modo:

Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" ( _
ByVal hwnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
ByVal lParam As Long) As Long

Private Hw As Long
Private Const WM_CLOSE = &H10

Private Sub Comando100_Click()
Hw = hWndShell("PDFXCview.exe", vbNormalFocus)
If Hw > 0 Then
PostMessage Hw, WM_CLOSE, CLng(0), CLng(0)
Else
MsgBox "ERROR..."
End If

Debug.Print Hw, WM_CLOSE, CLng(0), CLng(0)

End Sub

valori di debug.print 26214926 16 0 0

@Alex

unread,
Feb 17, 2020, 6:42:44 AM2/17/20
to
L'unico Parametro da guartdare è [Hw] gli altri sono COSTANTI.
Puoi provare con SENDNESSAGE, ma per essere certo di aver beccato l'APP giusta dovresi usare SPY++ e confrontare [Hw] con l'HANDLE recuperato da SPI++
Poi sempre con SPY++ puoi mettere in TRIGGER i messaggi ricevuti da quello specifico HANDLE e monitorare l'arrivo del WM_CLOSE

Sono tutte tecniche di DEBUG con le API che quando si usano serve imparare...

@Alex

alberto...@gmail.com

unread,
Feb 17, 2020, 10:45:57 AM2/17/20
to
nel codice della chiamata ho sostituito
ProcessID = Shell(Job, WindowStyle) con
ProcessID = Shell("rundll32.exe url.dll, FileProtocolHandler mioPath")
forse è questo errato?

@Alex

unread,
Feb 17, 2020, 11:59:35 AM2/17/20
to

> nel codice della chiamata ho sostituito
> ProcessID = Shell(Job, WindowStyle) con
> ProcessID = Shell("rundll32.exe url.dll, FileProtocolHandler mioPath")
> forse è questo errato?

Sicuramente sono 2 cose diverse... hai provato a non fare modifiche...?

@Alex

alberto...@gmail.com

unread,
Feb 17, 2020, 12:56:05 PM2/17/20
to
senza modifica mi da zero,
questa modifica l'ho presa sempre da un tuo vecchio post

@Alex

unread,
Feb 17, 2020, 1:39:22 PM2/17/20
to
Dovrei fare una prova ma quel sistema lo usavo per chiudere l'eseguibile associato alle immagini e funzionava su sistema 32bit... quindi a meno di stranezze introdotte escludo anomalie di codice.

Hai provato con SPY++...? altrimenti non capirai MAI cosa non funziona... e non è detto, tempo permettendo, si possa avere lo stesso problema, e capire...

Trovi gratuitamente la versione portable devi usare quello.

@Alex

Greg

unread,
Feb 18, 2020, 10:50:45 AM2/18/20
to
Il 17/02/20 08:45:19 alberto...@gmail.com ha scritto:

> l'ho copiato dal tuo sito; sezione Api/n.54:

Un link? Grazie :)

--
Greg

alberto...@gmail.com

unread,
Feb 18, 2020, 11:12:48 AM2/18/20
to
https://sourceforge.net/projects/winspyex/


[Process]
Path C:\Program Files\Tracker Software\PDF Viewer\PDFXCview.exe
Command line "C:\Program Files\Tracker Software\PDF Viewer\PDFXCview.exe" "C:\Prova.Pdf"
Process ID 1928
Thread ID 7936
Started 16:48:27 18/02/20
Working Size 32.412 K
Virtual Size 138.496 K
Image Type 32-bit

con questo programma riesco a chiudere il pdf.
Ora... come procedo?

@Alex

unread,
Feb 18, 2020, 1:55:50 PM2/18/20
to
http://mirror.masterdrive.it/alessandrobaraldi/DettaglioFaq.asp%3FIdFAQ=231.html

Come questo se ne trovano molti di esempi simili...

@Alex

alberto...@gmail.com

unread,
Feb 19, 2020, 4:58:06 AM2/19/20
to
grazie
0 new messages