+ Rispondi al Thread
Pagina 1 di 2 12 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 18

Discussione: Impossibile ricavare HWnd da HInst in Windows 10

  1. #1
    collega non è in linea Scolaretto
    Post
    197

    Impossibile ricavare HWnd da HInst in Windows 10

    Con questo codice, (ridotto al minimo), ricavo (ricavavo) l' Handle della Calcolatrice di Windows dopo averla richiamata. Mi serve per forzare la calcolatrice TOPMOST, e per poterla chiudere alla chiusura del programma. Funziona egregiamente da una quindicina di anni. Adesso purtroppo in Win 10, sia 32 che 64 bit, non funziona. Non so proprio come fare. Ho fatto tante ricerche, ho provato altri codici, similari, ma non sono riuscito a risolvere. Non sono queste le API da usare in Win 10? Sicuramente c'è qualche cosa che non so. Per favore, mi potete aiutare?
    codice:
    Option Explicit
    Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
    Private Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As Long
    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As Long, ByVal lpWindowName As Long) As Long
    Private Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long
    Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
    Private Const GW_HWNDNEXT = 2
    
    Private Function InstanceToWnd(ByVal target_pid As Long) As Long
    Dim test_hwnd As Long
    Dim test_pid As Long
    Dim test_thread_id As Long
        
        test_hwnd = FindWindow(ByVal 0&, ByVal 0&)
        Do While test_hwnd <> 0
            If GetParent(test_hwnd) = 0 Then
                test_thread_id = GetWindowThreadProcessId(test_hwnd, test_pid)
                If test_pid = target_pid Then
                    InstanceToWnd = test_hwnd
                    Exit Do
                End If
            End If
            test_hwnd = GetWindow(test_hwnd, GW_HWNDNEXT)
        Loop
    End Function
    
    Private Sub Command1_Click()
    Dim pid As Long
    Dim h_wnd As Long
     
        pid = Shell("Calc.exe", vbMinimizedNoFocus) 'HInst
        h_wnd = InstanceToWnd(pid)                  'HWnd
       
    End Sub
    Grazie in anticipo.

  2. #2
    L'avatar di Brontolo
    Brontolo non è in linea Very Important Person
    Post
    2,898
    Avevo risposto un po' frettolosamente.
    Dovrebbe essere più semplice di come l'hai proposta. La funzione FindWindow restituisce l'handle della finestra identificata dal suo titolo.
    Es.: hWnd = FindWindow(vbNullString, "Calcolatrice")
    Poi la puoi portare in primo piano con SetWindowPos().
    Non ho provato però.
    Il regolamento del forum: la prima cosa da leggere.

  3. #3
    L'avatar di AntonioG
    AntonioG non è in linea Moderatore Globale Ultimo blog: Commodore 64 e Codemotion
    Luogo
    Roma
    Post
    16,520
    Blogs
    5
    Windows 10, a seconda della versione, utilizza Calc.exe come semplice stub per lanciare con una ShellExecute il vero eseguibile che si chiama win32calc.exe.
    Se usi Calc.exe ottieni il pid (non l'Hinst comunque) del processo Calc.exe che viene distrutto subito dopo.

    Prova con questa linea

    pid = Shell("win32calc.exe", vbMinimizedNoFocus)
    Avvisi generali e importanti, a pena CHIUSURA thread e/o BAN
    Il crossposting è vietato.
    Le richieste di "pappa pronta" sono vietate.
    Utilizzate i tag CODE per il codice.
    Leggere il Regolamento per chiarimenti PRIMA di creare nuovi thread.
    Utilizzare sempre i PM per comunicare con i moderatori.
    Non mi contattate in PM per problemi di software, usate il forum

  4. #4
    collega non è in linea Scolaretto
    Post
    197
    @ Brontolo
    codice:
    Dim hwnd As Long
    hwnd = FindWindow(vbNullString, "calcolatrice")
    ottengo: tipo non corrispondente; anche sostituendola con "win32calc.exe" .
    @AntoniG
    codice:
    pid = Shell("win32calc.exe", vbMinimizedNoFocus)
    mi viene restituito: impossibile trovare il file.
    Ho verificato che effettivamente calc.exe è presente sia in \System32 che in \SysWOW64
    Anche grazie al virus, sono diversi giorni che ci giro intorno, ho fatto un sacco di prove, ma non riesco a venirne a capo.
    La versione di Windows sul mio computer è Win 10 Education 64 bit Versione 10.0.18363 build 18363

  5. #5
    L'avatar di Brontolo
    Brontolo non è in linea Very Important Person
    Post
    2,898
    Prova così:
    codice:
    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    Il regolamento del forum: la prima cosa da leggere.

  6. #6
    L'avatar di AntonioG
    AntonioG non è in linea Moderatore Globale Ultimo blog: Commodore 64 e Codemotion
    Luogo
    Roma
    Post
    16,520
    Blogs
    5
    Se cerchi il titolo della finestra ovviamente il programma varrà solo per la calcolatrice e non sarà generico. Dovrai cambiarlo per ogni exe che lanci.

    La calcolatrice nelle edizioni LTSC di Windows 10 è associata al processo win32calc chiamato da calc come ti avevo detto.
    Nelle edizioni non-LTSC è un'app Universal Platform Windows. Dovremmo capire se, in questo caso, il PID restituito è quello corretto.

    Dopo la Shell inserisci un

    MsgBox (pid)

    e controlla che il valore restituito sia quello che trovi nel Task Manager (colonna PID) per la calcolatrice.
    Avvisi generali e importanti, a pena CHIUSURA thread e/o BAN
    Il crossposting è vietato.
    Le richieste di "pappa pronta" sono vietate.
    Utilizzate i tag CODE per il codice.
    Leggere il Regolamento per chiarimenti PRIMA di creare nuovi thread.
    Utilizzare sempre i PM per comunicare con i moderatori.
    Non mi contattate in PM per problemi di software, usate il forum

  7. #7
    L'avatar di Brontolo
    Brontolo non è in linea Very Important Person
    Post
    2,898
    Vero, ma non mi sembrava che volesse essere "generico". Comunque FindWindow si aspetta parametri di tipo string, non long.
    Il regolamento del forum: la prima cosa da leggere.

  8. #8
    L'avatar di AntonioG
    AntonioG non è in linea Moderatore Globale Ultimo blog: Commodore 64 e Codemotion
    Luogo
    Roma
    Post
    16,520
    Blogs
    5
    Quote Originariamente inviato da Brontolo Visualizza il messaggio
    Vero, ma non mi sembrava che volesse essere "generico".
    Sì, giusto, a lui serviva la Calcolatrice ma io cercavo una soluzione generale.

    Comunque FindWindow si aspetta parametri di tipo string, non long.
    Se fai una ricerca mirata con la classe e/o il titolo, allora inserisci parametri Stringa. Se fai una ricerca generica, devi passare NULL e quindi in VB passi 0 (per questo si usa anche Long).
    Avvisi generali e importanti, a pena CHIUSURA thread e/o BAN
    Il crossposting è vietato.
    Le richieste di "pappa pronta" sono vietate.
    Utilizzate i tag CODE per il codice.
    Leggere il Regolamento per chiarimenti PRIMA di creare nuovi thread.
    Utilizzare sempre i PM per comunicare con i moderatori.
    Non mi contattate in PM per problemi di software, usate il forum

  9. #9
    collega non è in linea Scolaretto
    Post
    197
    Brontolo e AntonioG, vi ringrazio di cuore. Con questa mole di informazioni spero di arrivare alla soluzione. Oggi non posso, appena possibile vi farò sapere.
    Grazie

  10. #10
    collega non è in linea Scolaretto
    Post
    197
    Ho fatto diverse prove, ma la calcolatrice viene chiamata dalla shell solo se scrivo ‘calc.exe’.
    Non va bene con ‘win32calc.exe’, né con altre chiamate.
    Dato che una delle cose che il programma faceva era di chiamare una sola istanza della calcolatrice, e che neanche questo funzionava, mi sono accorto che modificando nella GetObject ‘calc.exe in ‘calculator. exe’, almeno questo si sistemava.
    codice:
    Dim procs As Object
      Set procs = GetObject("winmgmts:").ExecQuery("SELECT * FROM Win32_Process WHERE Name='calculator.exe'") 
      VA BENE solo con 'calculator.exe
      If procs.Count = 1 Then Exit Sub
    Allora ho pensato: “bene, devo chiamare ‘calculator.exe’; e quindi ho provato anche:
    codice:
    pid = Shell("calculator.exe", vbMinimizedNoFocus)
      'pid = Shell("win32calculator.exe", vbMinimizedNoFocus)
      'pid = Shell("win32calculator", vbMinimizedNoFocus)
    Ma niente. La shell fuziona solo con 'calc.exe', mentre da GetObject viene riconosciuto solo ‘Calculator.exe’
    Poi ho controllato se il PID visualizzato dal Task Manager fosse lo stesso di quello ricavato con la shell: non è lo stesso. E, ancora, ho scritto due shell consecutive, ognuna seguita da un MsgBox(pid): vengono chiamate due istanze della calcolatrice, con valori di PID diversi, ma il PID visualizzato dal Task Manager non cambia, rimane quello della prima shell, fintanto che tutte le calcolatrici non vengono killate.

    Inoltre mi sono accorto che ci sono problemi anche su Seven virtualizzata con Virtual Box' sul mio Win 10 64 bit: la calcolatrice viene chiamata, e chiusa alla chiusura del programma, però se ne possono chiamare diverse istanze, e non è TOPMOST . Quindi mi è venuto in mente che ci possa essere un problema di fondo con Win 10.
    Insomma, io non ho le conoscenze necessarie per poter “navigare” nei meandri di Windows, non ci cavo le gambe. Ci vorrebbe che qualcuno… provasse sul proprio computer come sistemare la cosa. Lo so, non è proprio una richiesta di pappa pronta.., ma quasi.
    Comunque, dato che in questo mio piccolo programma la calcolatrice è più che altro un optional, e dato che dovrei comunque modificare il programma, per adattarlo alle varie versioni di Windows, mi è venuto in mente che posso sempre implementare una calcolatrice mia, proprio basica, con solo le quattro operazioni o poco più, e considerarla un form qualsiasi. Ma anche per questo non so se si può fare, devo provare. In ogni caso vi ringrazio di cuore.

+ Rispondi al Thread
Pagina 1 di 2 12 ultimoultimo

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi