C
Hi,
ich hab mir letztens mal eine kleine Klasse geschrieben die das oben genannte Problem loest:
class Console : public Singleton<Console>
{
DECLARE_AS_SINGLETON(Console);
protected:
struct InputHandlerInfo
{
INPUT_TYPE InputType;
void* pData;
ConsoleInputHandler Handler;
};
static unsigned __stdcall InputHandlerThread(void* args);
Console();
public:
bool CreateConsole(bool bRedirectHandles);
void DestroyConsole();
bool RedirectHandles();
void RegisterInputFunc(INPUT_TYPE InputType,void* pData, ConsoleInputHandler InputHandler);
void RemoveInputFunc(ConsoleInputHandler InputHandler);
virtual ~Console();
private:
std::vector<InputHandlerInfo> m_vecInputHandler;
bool m_bAllocated;
bool m_bRedirectedHandles;
bool m_bThreadRun;
HANDLE m_hThread;
std::string m_strLastError;
CRITICAL_SECTION m_CritSecInputHandler;
FILE* stdOutputErrHandle_;
FILE* stdInputHandle_;
FILE* stdOutputHandle_;
};
void Console::RegisterInputFunc(INPUT_TYPE InputType,void* pData, ConsoleInputHandler InputHandler)
{
InputHandlerInfo HandlerInfo;
if(m_vecInputHandler.size() == 0)
{
m_bThreadRun = true;
m_hThread = (HANDLE)_beginthreadex(NULL, 0, InputHandlerThread , NULL, 0, NULL);
}
EnterCriticalSection(&m_CritSecInputHandler);
for(std::vector<InputHandlerInfo>::iterator iter = m_vecInputHandler.begin();
iter != m_vecInputHandler.end(); iter++)
{
if( iter->Handler == InputHandler)
{
iter->InputType = InputType;
iter->pData = pData;
LeaveCriticalSection(&m_CritSecInputHandler);
return;
}
}
HandlerInfo.pData = pData;
HandlerInfo.Handler = InputHandler;
HandlerInfo.InputType = InputType;
m_vecInputHandler.push_back(HandlerInfo);
LeaveCriticalSection(&m_CritSecInputHandler);
}
void Console::RemoveInputFunc(ConsoleInputHandler InputHandler)
{
EnterCriticalSection(&m_CritSecInputHandler);
for(std::vector<InputHandlerInfo>::iterator iter = m_vecInputHandler.begin();
iter != m_vecInputHandler.end(); iter++)
{
if( iter->Handler == InputHandler)
{
m_vecInputHandler.erase(iter);
break;
}
}
LeaveCriticalSection(&m_CritSecInputHandler);
if(m_vecInputHandler.size() == 0)
m_bThreadRun = false;
}
unsigned __stdcall Console::InputHandlerThread(void* args)
{
Console& Con = Console::Get();
HANDLE hStdInput = GetStdHandle(STD_INPUT_HANDLE);
DWORD dwEvents;
DWORD dwRead;
PINPUT_RECORD pInputRecord;
while(Con.m_bThreadRun)
{
switch( WaitForSingleObject( hStdInput, 500) )
{
case WAIT_OBJECT_0:
{
if( GetNumberOfConsoleInputEvents(hStdInput, &dwEvents) )
{
pInputRecord = new INPUT_RECORD[dwEvents];
if( pInputRecord)
{
if( ReadConsoleInput(hStdInput, pInputRecord, dwEvents, &dwRead) )
{
EnterCriticalSection(&Con.m_CritSecInputHandler);
for(std::vector<Console::InputHandlerInfo>::iterator iter = Con.m_vecInputHandler.begin();
iter !=Con. m_vecInputHandler.end(); iter++)
{
for(DWORD i = 0; i < dwRead; i++)
{
if(iter->InputType == BOTH ||
pInputRecord[i].EventType == KEY_EVENT && iter->InputType == KEYBOARD ||
pInputRecord[i].EventType == MOUSE_EVENT && iter->InputType == MOUSE)
{
iter->Handler(&pInputRecord[i], iter->pData);
}
}
}
LeaveCriticalSection(&Con.m_CritSecInputHandler);
}
delete[] pInputRecord;
}
}
break;
}
}
}
_endthreadex(0);
return 0;
}
Und zum anwenden einfach:
bool g_bRun = true;
void KeyHandler(PINPUT_RECORD pRec, void* pArgs)
{
if( pRec->Event.KeyEvent.wVirtualKeyCode == VK_ESC)
g_bRun = false;
}
int main(int argc, char** argv)
{
Console& Con = Console::Get();
Con.RegisterInputFunc( KEYBOARD, NULL, KeyHandler);
while( g_bRun )
Sleep(500);
return 0;
}
Ich hoffe es hat dir geholfen.
Gruessli C0de4Fun