#include #define WIN32_LEAN_AND_MEAN #include #define BUFSIZE 4096 #define IDW_STATUS 010 LRESULT WINAPI MainWndProc ( HWND, UINT, WPARAM, LPARAM ); BOOL StatusWrite (char *); BOOL ReadFromPipe(HANDLE); BOOL CreateChildProcess(VOID); HWND hwndStatus; // handle to status window HINSTANCE hInst; // current instance HANDLE PipeReadHandle; HANDLE PipeWriteHandle; BOOL ReadPipeOK = FALSE; int WINAPI WinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow ) { WNDCLASS wc; MSG msg; HWND hWnd; hInst = hInstance; // Store instance handle in our global variable wc.lpszClassName = "TestClass"; wc.lpfnWndProc = MainWndProc; wc.style = CS_VREDRAW | CS_HREDRAW; wc.hInstance = hInstance; wc.hIcon = LoadIcon( NULL, IDI_APPLICATION ); wc.hCursor = LoadCursor( NULL, IDC_ARROW ); wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); wc.lpszMenuName = NULL; wc.cbClsExtra = 0; wc.cbWndExtra = 0; RegisterClass( &wc ); hWnd = CreateWindow ( wc.lpszClassName, "Testing Make", WS_OVERLAPPEDWINDOW|WS_HSCROLL|WS_VSCROLL, 0, 0, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL ); ShowWindow( hWnd, nCmdShow ); while( GetMessage( &msg, NULL, 0, 0 ) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); if (ReadPipeOK) { ReadPipeOK = ReadFromPipe(PipeReadHandle); } else { StatusWrite("Read Pipe Failed"); } } return msg.wParam; } LRESULT CALLBACK MainWndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) { PAINTSTRUCT ps; HDC hDC; switch( msg ) { case WM_CREATE: // Create an MLE for status messages hwndStatus = CreateWindow ("LISTBOX", // Class NULL, // Window Name WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL, // Style 0, 0, 0, 0, // x, y, Width, Height hWnd, // Parent Window (HMENU) IDW_STATUS, // Child ID hInst, // Application instance NULL); // Window-creation data Sleep(5); StatusWrite("Creating Child Process"); if (CreateChildProcess()) { StatusWrite("CreateChildProcess Completed OK"); ReadPipeOK = TRUE; } else { StatusWrite("CreateChildProcess Completed Not OK"); } break; case WM_PAINT: hDC = BeginPaint( hWnd, &ps ); EndPaint( hWnd, &ps ); break; case WM_DESTROY: PostQuitMessage( 0 ); break; case WM_SIZE: // Make the edit control the size of the window's client area. MoveWindow (hwndStatus, 0, 0, LOWORD (lParam), HIWORD (lParam), TRUE); default: return( DefWindowProc( hWnd, msg, wParam, lParam )); } return 0; } //--------------------------------------------------------------------------- // FUNCTION: StatusWrite ( char * szText ) // COMMENTS: Writes the specified string to the status window // // Uses the buffer pointed to by hmemStatusBuf (of size MAX_STATUS_BUFFER) // (effectively a zero-terminated string) // Converts \n to \r\n for proper line-breaks // // Returns FALSE if no error, TRUE if error locating buffer //--------------------------------------------------------------------------- void AppendText (char *szText) { DWORD dwLogLength; const DWORD dwMAX_LOG_LENGTH = 10000; dwLogLength = SendMessage (hwndStatus, LB_GETCOUNT, 0, 0); while (dwLogLength > dwMAX_LOG_LENGTH) { SendMessage (hwndStatus, LB_DELETESTRING, (WPARAM) 0, (LPARAM) 0); -- dwLogLength; } // insert text SendMessage (hwndStatus, LB_INSERTSTRING, (WPARAM) dwLogLength, (LPARAM) szText); } BOOL StatusWrite (char *szText) { char szBuffer[BUFSIZ]; char *szCurrentPosition = szText; char *szEnd = szText + strlen (szText); char *szLineEnd; int HasCR = 0; while (szCurrentPosition < szEnd) { memset (szBuffer, (int) '\0', BUFSIZ); if ((szLineEnd = strchr (szCurrentPosition, (int) '\n')) == 0) szLineEnd = szEnd; if (*(szLineEnd - 1) == '\r') HasCR = 1; else HasCR = 0; strncat (szBuffer, szCurrentPosition, (int) ((szLineEnd - HasCR) - szCurrentPosition)); szCurrentPosition = szLineEnd + 1; AppendText (szBuffer); } return (FALSE); } BOOL CreateChildProcess(VOID) { SECURITY_ATTRIBUTES SecurityAttributes; STARTUPINFO StartupInfo; PROCESS_INFORMATION ProcessInfo; ZeroMemory( &StartupInfo, sizeof( StartupInfo )); ZeroMemory( &ProcessInfo, sizeof( ProcessInfo )); ZeroMemory( &SecurityAttributes, sizeof( SecurityAttributes )); SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); SecurityAttributes.bInheritHandle = TRUE; SecurityAttributes.lpSecurityDescriptor = NULL; CreatePipe ( &PipeReadHandle, // address of variable for read handle &PipeWriteHandle, // address of variable for write handle &SecurityAttributes, // pointer to security attributes 0 // default num bytes reserved for pipe ); StartupInfo.cb = sizeof(STARTUPINFO); StartupInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; StartupInfo.wShowWindow = SW_HIDE; StartupInfo.hStdOutput = PipeWriteHandle; StartupInfo.hStdError = PipeWriteHandle; return CreateProcess ( NULL, // pointer to name of executable module //LPTSTR( "c:\\cygwin\\bin\\make.exe -D test-cygwin",//), // command line NULL, // pointer to process security attributes NULL, // pointer to thread security attributes (use primary thread security attributes) TRUE, // inherit handles 0, // creation flags NULL, // pointer to new environment block(use parent's) "c:\\cygwin\\usr\\local\\src\\test-make", // pointer to current directory name &StartupInfo, // pointer to STARTUPINFO &ProcessInfo // pointer to PROCESS_INFORMATION ); } BOOL ReadFromPipe(HANDLE hFile) { DWORD dwRead, dwBytesAvaliable, dwBytesLeft; char chBuf[BUFSIZE]; // Read output from the child process, and write to parent's STDOUT. memset (chBuf, (int) '\0', BUFSIZ); if( !PeekNamedPipe( hFile, chBuf, BUFSIZE, &dwRead, &dwBytesAvaliable, &dwBytesLeft) ) { return FALSE; } else if ( dwBytesAvaliable != 0 && ReadFile( hFile, chBuf, BUFSIZE, &dwRead, NULL) && dwRead != 0) { chBuf[dwRead] = 0; StatusWrite(chBuf); } return TRUE; }