2012-06-06 10 views
7

Ho commentato nella maggior parte di ciò che so. Sono abbastanza fiducioso che il problema si presenti a AttachThreadInput. Penso che sia stato progettato solo per funzionare a 32 bit. Credimi, se potessi risolvere io stesso, sarei felice di farlo. Ho letto la documentazione completa per gli eventi in Windows (here) e non sono più vicino a una soluzione. Se hai qualche idea mi piacerebbe ascoltarli.C - win32: AttachThreadInput e SetFocus, 64 bit: nessun indizio

#include <stdio.h> 
#include <windows.h> 

int main() 
{ 
    //Structure prereqs for CreateProcess 
    STARTUPINFO   siStartupInfo; 
    PROCESS_INFORMATION piProcessInfo; 
    memset(&siStartupInfo, 0, sizeof(siStartupInfo)); 
    memset(&piProcessInfo, 0, sizeof(piProcessInfo)); 
    siStartupInfo.cb = sizeof(siStartupInfo); 

    if(CreateProcess("c:\\windows\\notepad.exe", "", 0, 0, FALSE, CREATE_DEFAULT_ERROR_MODE, 0, 0, &siStartupInfo, &piProcessInfo) == FALSE) 
    { 
     GetLastError(); 
    } 
    Sleep(1000); 

    //Target thread, I can't seem to get this to return anything !0 
    DWORD dwTargetThread = GetWindowThreadProcessId(piProcessInfo.hProcess,NULL); 
    //For example: 
    //if(dwTargetThread == 0) return -1; 

    //Print debugging info 
    if (GetCurrentThreadId() == dwTargetThread) return -1; else printf("\nMy thread: %u\n\npiProcessInfo.hThread: %u\n\nDWORD dwTargetThread: %u\n\nunsigned int dwTargetThread: %u", GetCurrentThreadId(), piProcessInfo.hThread,dwTargetThread, GetWindowThreadProcessId(piProcessInfo.hProcess,NULL)); 

    //I've tried using piProcessInfo.hThread for AttachTo but I can't cast it to a DWORD as it's 64bit 
    AttachThreadInput(GetCurrentThreadId(),dwTargetThread,TRUE); 
    printf("\n\nAttached...\n"); 
    Sleep(1000); 

    //Set the focus & bring to foreground 
    SetFocus(piProcessInfo.hProcess); 
    printf("Focus set...\n"); 
    Sleep(1000); 
    SetForegroundWindow(piProcessInfo.hProcess); 
    printf("Brought to foreground...\n"); 
    Sleep(1000); 

    //I know I shouldn't use PostMessage for keyboard input but it's just for the example 
    PostMessage(piProcessInfo.hProcess, WM_CHAR, 'g', 0); 
    printf("Message queued\n"); 

    //No better than SetForegroundWindow: 
    //SetWindowPos(piProcessInfo.hProcess, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); 
} 
+0

Sei sicuro che la chiamata a 'CreateProcess()' ha avuto successo? Tutto sembra incentrato su questo e il tuo codice fa la stessa cosa (a parte la chiamata 'GetLastError()') in entrambi i casi. – MatthewD

+0

Cosa restituisce 'GetLastError()' dopo la chiamata a 'GetWindowThreadProcessId()'? Vedere il commento in basso su questa pagina: http://msdn.microsoft.com/en-us/library/windows/desktop/ms633522%28v=vs.85%29.aspx – MatthewD

+0

Sì, 'CreateProcess()' ha successo. Blocco note si apre perfettamente e SendInput funziona se lo porto manualmente in primo piano. 'GetLastError()' restituisce null dopo 'GetWindowThreadProcessId (piProcessInfo.hProcess, NULL);' – John

risposta

6

GetWindowThreadProcessId riceve come input un handle di finestra. Stai passando un handle di processo che è un beat completamente diverso. Naturalmente questo si traduce in un fallimento. Le successive chiamate a SetFocus, SetForegroundWindow, PostMessage e SetWindowPos commettono lo stesso errore.

Utilizzare EnumWindows o FindWindow per ottenere l'handle della finestra del Blocco note.

AttachThreadInput funziona con gli ID di thread. Hai provato a passare un handle alla funzione e in un handle di processo a 64 bit sono a 64 bit di larghezza e gli ID di thread sono ancora a 32 bit di larghezza. Certamente, AttachThreadInput funziona perfettamente bene a 64 bit. La lezione da apprendere qui è che i cast sono indicativi di errori di programmazione. Se è necessario trasmettere parametri al tipo appropriato, in genere ciò significa che si passa la cosa sbagliata alla funzione. Evitare il casting.

+0

Grazie mille! Ho capito bene: 'HANDLE hTargetWindow = FindWindow (NULL," Untitled - Notepad ");' e ora 'GetWindowThreadProcessId (hTargetWindow, NULL);' funziona magnificamente. – John

+0

Il tipo corretto è HWND anziché HANDLE. SetForegroundWindow ha delle limitazioni descritte precisamente nella sua documentazione. Penso di aver risposto alla domanda che hai chiesto. –

+0

Immediatamente dopo aver postato che ho controllato la documentazione e ora funziona. Grazie mille per il tuo aiuto e la correzione HANDLE/HWND! – John