Windows平臺中用WaitForSingleObject API,採用阻塞模型偵聽標準文件輸入事件

爲命令行C/C++編程時,通常我們使用getch/getche或C++的cin來等待用戶輸入。在Linux編程中,工程中更常用的做法是通過select阻塞/偵聽模型同時偵聽標準輸入和socket句柄等,這樣可以很方便地根據用戶鍵入的命令及時處理不同的任務。那麼,在Windows Console編程中是否也能夠實現同樣的功能呢?答案是肯定的,但是用到的是WaitForSingleObject/WaitForMultiObject API。


#include "stdafx.h"


#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <strsafe.h>
#include <string>
#include <iostream>


using namespace std;


enum {
CMD_ERROR = -1,
CMD_NONE,
CMD_QUIT,
};


static int Reading(HANDLE hStdIn);


int _tmain(int argc, _TCHAR* argv[])
{
//獲取標準輸入句柄
HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE);
while (1) {
//阻塞
DWORD dwWaitResult = WaitForSingleObject(hStdIn, 5000);
try { 
switch (dwWaitResult) 
{
case WAIT_OBJECT_0: 
// 標準輸入有鍵入動作,讀鍵入的命令
switch(Reading(hStdIn)) {
case CMD_QUIT:
case CMD_ERROR:
Sleep(500);
return 0;
}
FlushConsoleInputBuffer(hStdIn); 
break;


case WAIT_ABANDONED: 
break;
}
}
catch(...)

// Handle error.
}
}
return 0;
}


static int Reading(HANDLE hStdIn) 

DWORD cbRead; 
BOOL fResult; 
HANDLE hEvent;
OVERLAPPED ov;


char buffer[512];


hEvent = CreateEvent(NULL, FALSE, FALSE, TEXT("EtEvent"));
if( NULL == hEvent ) {
printf("Create overlap event failed !!! \n"); 
return CMD_ERROR;
}
ov.Offset = 0;
ov.OffsetHigh = 0;
ov.hEvent = hEvent;


while (hEvent)  // retrieve all messages

memset(buffer, 0, sizeof(buffer));
fResult = ReadFile(hStdIn, 
buffer, 
sizeof(buffer) - 1, 
&cbRead, 
&ov); 


if (!fResult) 

printf("ReadFile failed with %d.\n", GetLastError()); 
CloseHandle(hEvent);
return CMD_NONE; 
}


for (DWORD i = 0; i < cbRead; i++) {
switch (buffer[i + 0]) {
case 'Q':
CloseHandle(hEvent);
return CMD_QUIT;
default:
break;
}
}

CloseHandle(hEvent);
return CMD_ERROR; 
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章