Console I/O 加上CreateThread

//Console I/O 加上CreateThread/*Demonsttrates how to write a program that cna useCreateThread instead of calling _beginthreadex.This program does not need the multithread library.This program could use ReadConsole and WriteConsole.There are minor but significant differences between thestfunctions and ReadFile and WriteFilethis program is ANSI only ,it will not compile for Unicode.*/#define WIN32_LEAN_AND_MEAN#include<stdio.h>#include<stdlib.h>#include<windows.h>#include<time.h>//to init rand()#include "MtVerify.h"/***************************//*Constants*/#define MAX_THREADS 256#define INPUT_BUF_SIZE 80#define BANNER_SIZE 12#define OUTPUT_TEXT_COLOR BACKGROUND_BLUE |\FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE/*******************************Function Prototypes*/void MainLoop(void);void ClearScreen(void);void ShutDownThreads(void);void Prompt(LPCSTR str);//display title bar infoint StripCr(LPSTR buf);/*Thread startup function*/DWORD WINAPI BannerProc(LPVOID pParam);/************************************** Global Variables*/HANDLE hConsoleIn;HANDLE hCONSOLEOut;HANDLE hRunObject;HANDLE ThreadHandles[MAX_THREADS];int nThreads;//number of threads startedCONSOLE_SCREEN_BUFFER_INFO csbiInfo;/*******************************************Stucture passed to thread on startup */typedef struct{TCHAR buf[INPUT_BUF_SIZE];SHORT x;SHORT y;} DataBlock;/***************************************************primary thread enters here*/int main(){/*Get display screen information &clear the screen*/hConsoleIn = GetStdHandle(STD_INPUT_HANDLE);hConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE);GetConsoleScreenBufferInfo(hConsoleOut, &csbiInfo);ClearScreen();/*Create the event object that keeps threads running*/MTVERIFY(hRunObject = CreateEvent(NULL, TRUE, 0, NULL));/*Start waiting for keyboard input to dispatch threads or exit*/MainLoop();ShutDownThreads();ClearScreen();CloseHandle(hRunObject);CloseHandle(hConsoleIn);CloseHandle(hConsoleOut);return EXIT_SUCCESS;}void ShutDownThreads(void){if (nThreads > 0){/*since this is a manual event,all threads will bewoken up at once*/MTVERIFY(SetEvent(hRunObject));MTVERIFY(WaitForMultipleObjects(nThreads,ThreadHandles, TRUE, INFINITE) != WAIT_FAILED);while (–nThreads){MTVERIFY(CloseHandle(ThreadHandles[nThreads]));}}}/*dispatch and count threads*/void MainLoop(void){TCHAR buf[INPUT_BUF_SIZE];DWORD bytesRead;DataBlock *data_block;DWORD thread_id;srand(time(NULL));for (;;){Prompt("Type string to display or ENTER to exit:");MTVERIFY(ReadFile(hConsoleIn, buf, INPUT_BUF_SIZE – 1,&bytesRead, NULL));/*ReadFile is binary,not line oriented,so terminate the string*/buf[bytesRead] = ‘\0’;MTVERIFY(FlushConsoleInputBuffer(hConsoleIn));if (StripCr(buf) == 0)break;if (nThreads < MAX_THREADS){data_block = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DataBlock));strcpy(data_block->buf, buf);data_block->x = rand() *(csbiInfo.dwSize.X – BANNER_SIZE) / RAND_MAX;data_block_->y = rand()*(csbiInfo.dwSize.Y – 1) / RAND_MAX + 1;MTVERIFY(ThreadHandles[nThreads++] = CreateThread(NULL, 0, BannerProc, data_block, 0, &thread_id));}}}void ClearScreen(void){DWORD dummy;COORD Home = { 0, 0 };FillConsoleOutputAttribute(hConsoleOut,csbiInfo.wAttributes,csbiInfo.dwSize.X*csbiInfo.dwSize.Y,Home,&dummy);FillConsoleOutputCharacter(hCOnsoleOut, ‘ ‘,csbiInfo.dwSize.X*csbiInfo.dwSize.Y, Home, &dummy);}void Prompt(LPCSTR str){COORD Home = {0,0};DWORD dummy;int len = strlen(str);SetConsoleCursorPosition(hCONSOLEOut, Home);WriteFile(hConsoleOut, str, len, &dummy, FALSE);Home.X = len;FillConsoleOutputCharacter(hConsoleOut, ‘ ‘,csbiInfo.dwSize.X – len, Home, &dummy);}/*********************************Routines from here down are used only by worker threads*/DWORD WINAPI BannerProc(LPVOID pParam){DataBlock *thread_data_block = pParam;COORD TopLeft = { 0, 0 };COORD Size = { BANNER_SIZE, 1 };int i, j;int len;int ScrollPosition = 0;TCHAR OutputBuf[INPUT_BUF_SIZE + BANNER_SIZE];CHAR_INFO CharBuf[INPUT_BUF_SIZE + BANNER_SIZE];SMALL_RECT rect;rect.Left = thread_data_block->x;rect.Right = rect.Left + BANNER_SIZE;rect.Top = thread_data_block->y;rect.Bottom = rect.Top;strcpy(OutputBuf, thread_data_block->buf);len = strlen(OutputBuf);for (i = len; i < BANNER_SIZE; i++)OutputBuf[i] = ‘ ‘;if (len < BANNER_SIZE) len = BANNER_SIZE;strncpy(OutputBuf + len, OutputBuf, BANNER_SIZE);OutputBuf[len + BANNER_SIZE – 1] = ‘\0’;MTVERIFY(HeapFree(GetProcessHeap(), 0, pParam));do{for (i = ScrollPosition++, j = 0; j < BANNER_SIZE; i++, j++){CharBuf[j].Char.AsciiChar = OutputBuf[i];CharBuf[j].Attributes = OUTPUT_TEXT_COLOR;}if (ScrollPosition == len)ScrollPosition = 0;MTVERIFY(WriteConsoleOutput(hConsoleOut, CharBuf, Size, TopLeft, &rect));} while (WaitForSingleObject(hRunObject, 125L) == WAIT_TIMEOUT);return 0;}

版权声明:本文为博主原创文章,,未经博主允许不得转载。

不敢接受失败的人,往往是那些追求完美的人,

Console I/O 加上CreateThread

相关文章:

你感兴趣的文章:

标签云: