Newsgroup: it.comp.appl.access
Titolo: chiudere file esterno

Salve!
come faccio a chiudere un file esterno 
p.e. formato pdf o txt da Vba?
 
grz.

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


bene, così ho ottenuto l'handle
Hw = hWndShell("PDFXCview.exe", vbNormalFocus)
come si usa PostMessage o SendMessage per chiuderlo?
grazie

 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


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

 grazie
 

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


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 


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

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

 forse è questo errato?
 
Sicuramente sono 2 cose diverse... hai provato a non fare modifiche...?
 
@Alex


senza modifica mi da zero,
questa modifica l'ho presa sempre da un tuo vecchio post

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

 l'ho copiato dal tuo sito; sezione Api/n.54:
 
Un link? Grazie :)
 
-- 
Greg

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

http://mirror.masterdrive.it/alessandrobaraldi/DettaglioFaq.asp%3FIdFAQ=231.html
 
 
Come questo se ne trovano molti di esempi simili... 
 
@Alex


grazie