In che modo TranslateMessage viene in primo piano nella finestra principale del processo avviato?

1

Questa domanda su StackOverflow presenta un programma Win32 minimale scritto in C che avvia alcuni processi (Blocco note e Calc) utilizzando CreateProcess .

Il problema dell'OP è che le finestre di questi programmi vengono visualizzate in background, dietro la finestra di Explorer da cui viene avviato il programma di esempio.

Anche se la domanda è chiusa come duplicato, l'OP ha trovato una soluzione che non è stata trovata nella risposta di riferimento. La soluzione consiste nell'inserire una singola chiamata TranslateMsg al programma, prima che la chiamata di CreateProcess :

MSG msg;
TranslateMessage(&msg);

Con questo in atto, le finestre dei processi avviati appaiono in primo piano, come previsto.

La mia domanda è: qualcuno che ha un po 'di conoscenza sugli interni di Windows spiega come questa chiamata di TranslateMessage sta aiutando?

La chiamata non è ben definita nell'utilizzo sopra; TranslateMessage dovrebbe funzionare su un messaggio estratto dalla coda dei messaggi. L'oggetto msg non è nemmeno inizializzato. Il trucco funziona ancora se lo cambiamo in MSG msg = { 0 } . Sembra esserci un bug / hack in Windows basato sull'idea che se un processo non chiama mai TranslateMessage , allora è un processo in background, e la finestra di ogni processo generato da esso va in background. Anche una chiamata inutile a TranslateMessage con dati spazzatura è sufficiente per ingannare questo kludge.

    
posta Kaz 01.07.2016 - 03:12
fonte

1 risposta

2

Il sistema Windows per determinare se un'applicazione può essere messa a fuoco o meno è un po 'arcano (poiché consiste essenzialmente in una serie di euristiche per determinare se l'utente è probabile che desideri che un'applicazione si concentri) e per lo più non documentato ( come i designer di windows ui amano mantenere la flessibilità di modificare cose come questa con ogni nuova versione, il che è più facile se non c'è un comportamento documentato che dovrebbe essere cambiato). La mia comprensione di ciò è che per focalizzarsi, un'applicazione deve essere avviata da un processo che al momento è focalizzato o che potrebbe essere messo a fuoco. Questo è ragionevolmente ben compreso. La seguente, tuttavia, è pura ipotesi per tentare di spiegare il comportamento che si fa notare:

  • controlla se un processo è autorizzato a mettere a fuoco solo se il processo ha una discussione con una coda di messaggi
  • le code dei messaggi vengono assegnate pigramente quando sono necessarie (questo è un comportamento documentato)
  • TranslateMessage innesca l'allocazione anche se non fa nulla con il messaggio che è passato (pura supposizione)

Se è giusto, ci sono due importanti conseguenze:

  • TranslateMessage può essere convertito in qualsiasi funzione di gestione della coda dei messaggi (ad es. PeekMessage)
  • Poiché il fatto che questo funzioni si basa su un dettaglio di implementazione non documentato di TranslateMessage, non si può fare affidamento sul funzionamento nelle future versioni di Windows (che potrebbe decidere di risparmiare risorse non allocando una coda di messaggi in questa situazione) o di fatto ignorando l'allocazione in qualsiasi situazione, poiché TranslateMessage è documentato come funziona solo sui messaggi restituiti da GetMessage e così dovrebbe essere in grado di assumere la coda esistente)

Quindi mi sembra che non dovresti usare questa soluzione, almeno nella situazione in cui le mie supposizioni di cui sopra sono vere, a quel punto possiamo concludere che cambiare la chiamata a una chiamata a PeekMessage sarebbe l'azione più logica.

    
risposta data 02.07.2016 - 20:50
fonte

Leggi altre domande sui tag