2010-12-15 11 views
1

Ich arbeite an Win32-Anwendung. Alle Zeichnungen werden in WM_PAINT erstellt. Es funktioniert gut. Ich habe eine weitere Funktionalität hinzugefügt. Wenn ich auf die Schaltfläche klicke, wird die Eingabeaufforderung ausgeführt. Dies kann ich mit WinExec tun. Jetzt, wenn ich Cmd.exe als im Hintergrund verschiebe, wird Zeichnung nicht getan. Ich aktualisiere den Code mit CreateProcess als auch das gleiche passiert ist. Kann mir bitte jemand helfen, was mit diesem Code nicht stimmt. Ist es, weil, wenn ich auf dieses Fenster konzentriere, der Fokus losgelassen wird und das Zeichnen nicht gemacht wird.Zeichnung Problem in Win32-Anwendung

-Code

STARTUPINFO si; 
    PROCESS_INFORMATION pi; 
ZeroMemory(&si, sizeof(si));   
    si.cb = sizeof(si); 
ZeroMemory(&pi, sizeof(pi)); 

TCHAR wchCmdPath[MAX_PATH]; 
memset(wchCmdPath,_T('\0'),MAX_PATH); 
GetSystemDirectory(wchCmdPath,MAX_PATH); 
wcscat(wchCmdPath,_T("\\cmd.exe")); 
// Start the child process. 
    if(!CreateProcess(NULL, // No module name (use command line) 
    wchCmdPath,  // Command line 
    NULL,   // Process handle not inheritable 
    NULL,   // Thread handle not inheritable 
    FALSE,   // Set handle inheritance to FALSE 
    0,    // No creation flags 
    NULL,   // Use parent's environment block 
    NULL,   // Use parent's starting directory 
    &si,   // Pointer to STARTUPINFO structure 
    &pi)   // Pointer to PROCESS_INFORMATION structure 
) 
{ 
    printf("CreateProcess failed (%d).\n", GetLastError()); 
    return; 
} 



// Close process and thread handles. 
CloseHandle(pi.hProcess); 
CloseHandle(pi.hThread); 


     InvalidateRect(hwnd,NULL,TRUE); 
     UpdateWindow(hwnd); 

Vielen Dank im Voraus

+1

Es wäre viel einfacher, das Problem zu erkennen, wenn Sie die relevanten Teile Ihres Codes veröffentlicht haben. –

Antwort

4

Es weil WinExec zurückkehrt sein kann, wenn der erzeugte ausführbare Anrufe GetMessage oder bis ein Timeout angegeben wird (siehe: http://msdn.microsoft.com/en-us/library/ms687393(v=vs.85).aspx).

Dies bedeutet, dass Ihr Programm bis zu diesem Zeitpunkt an dieser Leitung hängen bleibt und daher keine Nachrichten verarbeitet (einschließlich WM_PAINT). CreateProcess hat dieses Problem nicht, aber haben Sie darauf gewartet?

+0

Mit WaitForSingleObject (infinite) hatte ich es nicht, aber wenn ich das Befehlsfenster n Anzahl Male verschiebe, erscheint n Anzahl der Befehlsfenster auf dem Bildschirm. :) Wenn ich es in einigen Millisekunden 2000 benutze, bleibt das Problem gleich –

+0

Siehe meine Antwort - während Sie darauf warten, dass Ihre Anwendung die Nachrichten verarbeiten und malen muss, wenn sie dazu aufgefordert wird. Niemand sonst wird es tun. – Suma

0

Das Problem liegt höchstwahrscheinlich außerhalb des von Ihnen angegebenen Codes. Ihr InvalidateRect/UpdateWindow wird das Fenster einmal nach dem Erstellen des untergeordneten Prozesses malen, aber es wird das Neuzeichnen nicht behandeln, wenn Sie es später verschieben.

Was Sie brauchen, um zu lösen "Jetzt, wenn ich Cmd.exe als im Hintergrund Zeichnung nicht getan" Problem ist, darüber nachzudenken, was Sie tun, während Sie auf den Prozess warten. Während Sie auf den Prozess warten, müssen Sie noch eingehende Nachrichten bearbeiten (mindestens WM_PAINT).

Sie können WaitForSingleObject nicht verwenden, um auf den Prozess zu warten, Sie müssen eine Funktion verwenden, mit der Sie auch Nachrichten verarbeiten können, wie MsgWaitForMultipleObjects - es ist Ihre Anwendung, die das Fenster bei jedem Senden von WM_PAINT neu streichen muss TU es für dich. Ein anderer Ansatz besteht nicht darin, auf den Prozess zu warten, sondern auf die Verarbeitung seines Ergebnisses in einer ereignisgesteuerten Weise, direkt in der Hauptnachrichtenschleife (was Sie jetzt vielleicht als einen "modalen" Prozess betrachten können) Sie können Ihre Anwendung überdenken, um sie "modeless" zu machen.

+0

I Suma, Danke für Ihre Antwort. Eigentlich bin ich neu für Win32-Programmierung. Ich arbeitete nur an MFC, ATL und COM. Was ich verstehe ist, dass anstelle von WaitForSingleObject verwenden Sie MsgWaitForMultipleObject. MsgWaitForMultipleObjects (MAXIMUM_WAIT_OBJECTS-1, & pi.hProcess, TRUE, 2000, QS_ALLEVENTS); Auf WM_PAINT ist alle Zeichenlogik abgeschlossen. Ich verstehe deinen anderen Ansatz nicht. Kannst du es mir bitte im Detail erklären? Noch einmal Danke. –

+0

Für den ereignisgesteuerten Ansatz muss Ihre Nachrichtenschleife (Sie haben eine?) MsgWaitForMultipleObject verwenden, damit sie auch das Prozessergebnis abfangen kann. Was die ereignisgesteuerte Programmierung als Stil betrifft, googeln Sie einfach - seien Sie sich bewusst, wenn Sie etwas anderes über den Programmfluss denken müssen. – Suma

+0

Auch warum MsgWaitForMultipleObjects (MAXIMUM_WAIT_OBJECTS-1,? Dies ist einfach falsch - verwenden Sie einfach MsgWaitForMultipleObjects (1, wie Sie nur ein Objekt testen. – Suma