// watcherView.cpp : implementation of the View class // #include "stdafx.h" #include "watcher.h" #include "watcherDoc.h" #include "watcherView.h" #include "WatcherTelnetClient.h" #include "WatcherTCClient.h" #include "tcsrvc.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #include #include "wbemDCpl.h" #define CHECKERROR(HRES) if(FAILED(hres)) {_stprintf(buffer,_T("0x%x"),hres);\ AfxFormatString1(rString, CREATE_WMI_OBJECT_FAILURE, buffer);\ MessageBox(NULL,(LPCTSTR) rString,L"Watcher", MB_OK|MB_ICONEXCLAMATION);\ delete [] messageBuffer;\ return -1;\ } UINT GenerateWMIEvent(LPTSTR messageBuffer ) { TCHAR buffer[MAX_BUFFER_SIZE]; CString rString; HRESULT hres; hres = CoInitializeEx(NULL, COINIT_MULTITHREADED); CHECKERROR(hres); // Load provision code IWbemDecoupledEventSink* pConnection = NULL; hres = CoCreateInstance(CLSID_PseudoSink, NULL, CLSCTX_SERVER, IID_IWbemDecoupledEventSink, (void**)&pConnection); CHECKERROR(hres); // Connect and announce provider name (as in MOF) IWbemObjectSink* pSink = NULL; IWbemServices* pNamespace = NULL; hres = pConnection->Connect(L"root\\default", L"WatcherEventProv", 0, &pSink, &pNamespace); CHECKERROR(hres); BSTR XMLData = SysAllocString(messageBuffer); IWbemObjectTextSrc *pSrc; IWbemClassObject *pInstance; if( SUCCEEDED( hres = CoCreateInstance ( CLSID_WbemObjectTextSrc, NULL, CLSCTX_INPROC_SERVER, IID_IWbemObjectTextSrc, (void**) &pSrc ) ) ) { if( SUCCEEDED( hres = pSrc->CreateFromText( 0, XMLData, WMI_OBJ_TEXT_WMI_DTD_2_0, NULL, &pInstance) ) ) { pSink->Indicate(1,&pInstance); pInstance->Release(); } else{ _stprintf(buffer,_T("0x%x"),hres); AfxFormatString1(rString, CREATE_WMI_OBJECT_FAILURE, buffer); MessageBox(NULL,(LPCTSTR) rString,L"Watcher", MB_OK|MB_ICONEXCLAMATION); pSrc->Release(); } } else{ _stprintf(buffer,_T("0x%x"),hres); AfxFormatString1(rString, CREATE_TEXT_SRC_FAILURE, buffer); MessageBox(NULL,(LPCTSTR) rString,L"Watcher", MB_OK|MB_ICONEXCLAMATION); } SysFreeString(XMLData); // Init data pConnection->Disconnect(); pSink->Release(); pConnection->Release(); MessageBox(NULL,messageBuffer,L"",MB_OK|MB_ICONEXCLAMATION); delete [] messageBuffer; return 0; } ///////////////////////////////////////////////////////////////////////////// // CWatcherView IMPLEMENT_DYNCREATE(CWatcherView, CView) BEGIN_MESSAGE_MAP(CWatcherView, CView) //{{AFX_MSG_MAP(CWatcherView) ON_WM_CHAR() ON_WM_DESTROY() ON_WM_KEYDOWN() //}}AFX_MSG_MAP // Standard printing commands ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CWatcherView construction/destruction CWatcherView::CWatcherView() :xpos(0), ypos(0), CharsInLine(0), height(0), width(0), position(0), index(0), #ifdef _UNICODE dbcsIndex(0), #endif InEscape(FALSE), Socket(NULL), cdc(NULL), background(BLACK), foreground(WHITE), indexBell(0), BellStarted(FALSE), InBell(FALSE), ScrollTop(1), ScrollBottom(MAX_TERMINAL_HEIGHT), seenM(FALSE) { // TODO: add construction code here InitializeCriticalSection(&mutex); return; } CWatcherView::~CWatcherView() { DeleteCriticalSection(&mutex); } BOOL CWatcherView::PreCreateWindow(CREATESTRUCT& cs) { // TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs return CView::PreCreateWindow(cs); } ///////////////////////////////////////////////////////////////////////////// // CWatcherView drawing void CWatcherView::OnDraw(CDC* pDC) { TCHAR *Data,Char; int i,j, Height; int CharWidth, Position; int size; BOOL ret; COLORREF *Foreground; COLORREF *Background; CWatcherDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here ret = pDoc->Lock(); if (ret == FALSE) return; Data = pDoc->GetData(); size = MAX_TERMINAL_WIDTH*MAX_TERMINAL_HEIGHT; Background = pDoc->GetBackground(); Foreground = pDoc->GetForeground(); Height = 0; for(i=0;iSetTextColor(Foreground[i+j]); cdc->SetBkColor(Background[i+j]); if (!cdc->GetOutputCharWidth(Char, Char, &CharWidth)) { return; } if(Char == 0xFFFF){ continue; } if(IsPrintable(Char)){ cdc->FillSolidRect(Position,Height,CharWidth, height,Background[i+j]); cdc->TextOut(Position, Height,&Char, 1); Position = Position + CharWidth; } else{ cdc->FillSolidRect(Position,Height,width, height,Background[i+j]); Position = Position + width; } } cdc->FillSolidRect(Position,Height, MAX_TERMINAL_WIDTH*width-Position, height,Background[i+j-1]); Height = Height + height; } ret = pDoc->Unlock(); return; } ///////////////////////////////////////////////////////////////////////////// // CWatcherView initial update of the document. void CWatcherView::OnInitialUpdate() { BOOL ret; TCHAR Buffer[256]; CLIENT_INFO SendInfo; CFont font; UCHAR Charset; LPBYTE SocketBuffer; CString rString; ParameterDialog &Params=((CWatcherDoc *)GetDocument())->GetParameters(); if(Params.DeleteValue == TRUE){ ret = GetParent()->PostMessage(WM_CLOSE,0,0); return; } CString FaceName; switch(Params.language + IDS_ENGLISH){ case IDS_ENGLISH: CodePage = ENGLISH; Charset = ANSI_CHARSET; FaceName = TEXT("Courier New"); break; case IDS_JAPANESE: CodePage = JAPANESE; Charset = SHIFTJIS_CHARSET; // Locale = MAKELCID(MAKELANGID(LANG_JAPANESE, SUBLANG_NEUTRAL), // SORT_JAPANESE_UNICODE); // SetThreadLocale(Locale); FaceName = TEXT("MS Mincho"); break; case IDS_EUROPEAN: CodePage = EUROPEAN; Charset = EASTEUROPE_CHARSET; FaceName = TEXT("Courier New"); break; default: CodePage = ENGLISH; Charset = ANSI_CHARSET; FaceName = TEXT("Courier New"); break; } VERIFY(font.CreateFont(16, // nHeight 0, // nWidth 0, // nEscapement 0, // nOrientation FW_MEDIUM, // nWeight FALSE, // bItalic FALSE, // bUnderline 0, // cStrikeOut Charset, // nCharSet OUT_DEFAULT_PRECIS, // nOutPrecision CLIP_DEFAULT_PRECIS, // nClipPrecision DEFAULT_QUALITY, // nQuality FIXED_PITCH | FF_MODERN, // nPitchAndFamily FaceName)); // lpszFacename cdc = new CClientDC(this); if(!cdc){ ret = GetParent()->PostMessage(WM_CLOSE,0,0); return; } cdc->SelectObject(&font); CDocument *pDoc = GetDocument(); if(pDoc){ pDoc->SetTitle(Params.Session); pDoc->UpdateAllViews(NULL,0,NULL); } // Now create the socket and start the worker thread if(Params.tcclnt){ // Assuming Unicode always....... (Can remove a lot of other junk) _tcscpy(SendInfo.device, (LPCTSTR) Params.Command); SendInfo.len = Params.history; int strsize = sizeof(CLIENT_INFO); SocketBuffer = new BYTE[strsize]; SocketBuffer = (LPBYTE) ::memcpy(SocketBuffer,&SendInfo, strsize); Socket = new WatcherTCClient(SocketBuffer,strsize); if(!SocketBuffer || !Socket){ AfxFormatString1(rString, CREATE_TC_SOCKET_FAILURE, L""); MessageBox((LPCTSTR) rString, L"Watcher", MB_OK|MB_ICONSTOP); ret = GetParent()->PostMessage(WM_CLOSE,0,0); return; } } else{ LPBYTE LoginBuffer; int strsize,cmdsize; CString login; CString comm; login = Params.LoginName + _TEXT("\r\n") + Params.LoginPasswd + _TEXT("\r\n"); strsize = ::_tcslen((LPCTSTR) login); LoginBuffer = new BYTE [strsize*sizeof(TCHAR) + 2]; strsize = WideCharToMultiByte(CodePage,0,(LPCTSTR)login,strsize, (LPSTR) LoginBuffer,strsize*sizeof(TCHAR),NULL,NULL); comm = Params.Command + _TEXT("\r\n"); cmdsize = ::_tcslen((LPCTSTR) comm); SocketBuffer = new BYTE [cmdsize*sizeof(TCHAR) + 2]; cmdsize = WideCharToMultiByte(CodePage,0,(LPCTSTR) comm,cmdsize, (LPSTR) SocketBuffer,cmdsize*sizeof(TCHAR),NULL,NULL); Socket = new WatcherTelnetClient(SocketBuffer,cmdsize,LoginBuffer,strsize); if(!Socket || !LoginBuffer || !SocketBuffer || !cmdsize || !strsize){ AfxFormatString1(rString, CREATE_TELNET_SOCKET_FAILURE, L""); MessageBox((LPCTSTR) rString, L"Watcher",MB_OK|MB_ICONSTOP); ret = GetParent()->PostMessage(WM_CLOSE,0,0); return; } } ASSERT ( Socket != NULL ); Socket->SetParentView(this); TEXTMETRIC TextProps; ret = cdc->GetOutputTextMetrics(&TextProps); if(!ret){ _stprintf(Buffer, _T("%d"),GetLastError()); AfxFormatString1(rString, CDC_TEXT_FAILURE, Buffer); MessageBox((LPCTSTR) rString,L"Watcher", MB_OK|MB_ICONSTOP); ret = GetParent()->PostMessage(WM_CLOSE,0,0); return; } height = TextProps.tmHeight + 1; width = (TextProps.tmAveCharWidth); CWnd *parent = GetParent(); if(!parent){ // this is an orphan child window return; } CRect wrect, crect; parent->GetClientRect(&crect); parent->GetWindowRect(&wrect); wrect.SetRect(0, 0, wrect.Width() - crect.Width() + width*MAX_TERMINAL_WIDTH, wrect.Height() - crect.Height() + height*MAX_TERMINAL_HEIGHT ); parent->MoveWindow(&wrect,TRUE); parent->GetClientRect(&crect); ret =Socket->Create(0,SOCK_STREAM,NULL); if(!ret){ _stprintf(Buffer,_T("%d"),GetLastError()); AfxFormatString1(rString, SOCKET_CREATION_FAILED, Buffer); MessageBox((LPCTSTR) rString, L"Watcher", MB_OK|MB_ICONSTOP); ret = parent->PostMessage(WM_CLOSE,0,0); return; } position = 0; ret = Socket->Connect((LPCTSTR) Params.Machine,Params.Port); if (!ret){ _stprintf(Buffer,_T("%d"),GetLastError()); AfxFormatString1(rString, SOCKET_CONNECTION_FAILED, (LPCTSTR) Buffer); MessageBox((LPCTSTR) rString, L"Watcher", MB_OK|MB_ICONSTOP); ret = parent->PostMessage(WM_CLOSE,0,0); return; } if(Params.tcclnt){ ret = Socket->Send(SocketBuffer,sizeof(CLIENT_INFO),0); } CView::OnInitialUpdate(); if(cdc){ OnDraw(cdc); } return; } ///////////////////////////////////////////////////////////////////////////// // CWatcherView diagnostics #ifdef _DEBUG void CWatcherView::AssertValid() const { CView::AssertValid(); } void CWatcherView::Dump(CDumpContext& dc) const { CView::Dump(dc); } CWatcherDoc* CWatcherView::GetDocument() // non-debug version is inline { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CWatcherDoc))); return (CWatcherDoc*)m_pDocument; } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CWatcherView message handlers void CWatcherView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) { // TODO: Add your message handler code here and/or call default // We will send the character across the network and that is all we do. int nRet; nRet=Socket->Send(&nChar, 1, 0); //CView::OnChar(nChar, nRepCnt, nFlags); } // REMARK - should we make this also a virtual function so that // if bell sequences are to be trapped, you just need to // extend this class ?? void CWatcherView::ProcessByte(BYTE byte) { //Currently, just do a textout on the device // Store the character in the screen buffer // A boolean variable to check if we are processing an escape sequence EnterCriticalSection(&mutex); if(byte == 27){ InEscape = TRUE; EscapeBuffer[0] = byte; index = 1; LeaveCriticalSection(&mutex); return; } // Escape characters are not found in the characters sent across the // wire. Similarly, when we enter the Bell protocol, no bells can // be found. if(InEscape == TRUE){ if(index == MAX_TERMINAL_WIDTH){ // vague escape sequence,give up processing InEscape = FALSE; index=0; LeaveCriticalSection(&mutex); return; } EscapeBuffer[index]=byte; index++; if(FinalCharacter((CHAR) byte)){ ProcessEscapeSequence((PCHAR)EscapeBuffer, index); InEscape = FALSE; index=0; } LeaveCriticalSection(&mutex); return; } if(InBell == TRUE){ if(indexBell > MAX_BELL_SIZE){ // What a bell sequence, I give up.... InBell = FALSE; // Print all that stuff onto the screen for(int i = 0; i\007",indexBell) == 0){ if(indexBell == 9){ BellStarted = TRUE; } }else{ InBell = FALSE; for(int i = 0; iLock(); if (ypos == ScrollBottom) { pDoc->ScrollData(0,foreground,background,ScrollTop,ScrollBottom); } else{ pDoc->ScrollData(0,foreground,background,1,MAX_TERMINAL_HEIGHT); } ypos = ypos -1; ret = pDoc->Unlock(); OnDraw(cdc); } return; } if(byte == 13){ xpos = 0; position = 0; return; } if (byte == 0x8) { // backspace character. ret = pDoc->Lock(); if(xpos>0){ xpos--; pDoc->SetData(xpos, ypos, 0, foreground, background); DataLine = pDoc->GetDataLine(ypos); position = 0; if (xpos > 0){ position = GetTextWidth(DataLine, xpos); } } ret = pDoc->Unlock(); OnDraw(cdc); return; } Char = byte; #ifdef _UNICODE DBCSArray[dbcsIndex] = byte; if(dbcsIndex ==0){ if(IsDBCSLeadByteEx(CodePage, byte)){ dbcsIndex ++; return; } } else{ MultiByteToWideChar(CodePage,0,(const char *)DBCSArray,2,&Char,1); dbcsIndex = 0; } #endif if(xpos >= MAX_TERMINAL_WIDTH){ //Before moving over to the next line clear to end of display // using the current background if(cdc){ cdc->FillSolidRect(position,ypos*height, MAX_TERMINAL_WIDTH*width-position, height,background); } xpos = 0; position = 0; ypos++; if((ypos == MAX_TERMINAL_HEIGHT) || (ypos == ScrollBottom)){ ret = pDoc->Lock(); if (ypos == ScrollBottom) { pDoc->ScrollData(0,foreground,background,ScrollTop,ScrollBottom); } else{ pDoc->ScrollData(0,foreground,background,1,MAX_TERMINAL_HEIGHT); } ypos = ypos -1; ret = pDoc->Unlock(); OnDraw(cdc); } } ret =cdc->GetOutputCharWidth(Char, Char, &CharWidth); if(IsPrintable(Char)){ cdc->FillSolidRect(position,ypos*height,CharWidth, height,background); cdc->TextOut(position,ypos*height,&Char, 1); position = position + CharWidth; if (CharWidth >= 2*width){ ret = pDoc->Lock(); pDoc->SetData(xpos, ypos, 0xFFFF, foreground, background); xpos++; ret = pDoc->Unlock(); } } else{ cdc->FillSolidRect(position,ypos*height,width, height,background); position = position + width; } ret = pDoc->Lock(); pDoc->SetData(xpos, ypos, Char, foreground, background); xpos++; ret = pDoc->Unlock(); } void CWatcherView::ProcessEscapeSequence(PCHAR Buffer, int length) { ULONG charsToWrite; ULONG charsWritten; TCHAR *DataLine; CWatcherDoc *pDoc; BOOL ret; pDoc = (CWatcherDoc *) GetDocument(); if(!pDoc){ // something really wrong, queitly ignore this // escape sequence return; } if (length == 3) { // One of the home cursor or clear to end of display if(strncmp(Buffer,"\033[r",length)==0){ ScrollTop = 1; ScrollBottom = MAX_TERMINAL_HEIGHT; return; } if (strncmp(Buffer,"\033[H",length)==0) { // Home the cursor xpos = 0; ypos = 0; position = 0; return; } if(strncmp(Buffer,"\033[J", length) == 0){ // clear to end of display assuming 80 X 24 size ret = pDoc->Lock(); if(cdc){ cdc->FillSolidRect(0,(ypos+1)*height,MAX_TERMINAL_WIDTH*width, (MAX_TERMINAL_HEIGHT-ypos)*height,background); cdc->FillSolidRect(position,ypos*height, MAX_TERMINAL_WIDTH*width - position, height,background); } pDoc->SetData(xpos, ypos, 0, (MAX_TERMINAL_HEIGHT - ypos)*MAX_TERMINAL_WIDTH -xpos, foreground, background); ret = pDoc->Unlock(); } if(strncmp(Buffer,"\033[K", length) == 0){ // clear to end of line assuming 80 X 24 size if(cdc){ cdc->FillSolidRect(position,ypos*height,MAX_TERMINAL_WIDTH*width - position, height,background); } ret = pDoc->Lock(); pDoc->SetData(xpos, ypos, 0, MAX_TERMINAL_WIDTH -xpos, foreground, background); ret = pDoc->Unlock(); return; } if(strncmp(Buffer,"\033[m", length) == 0){ // clear all attributes and set Text attributes to black on white background = BLACK; foreground = WHITE; seenM = TRUE; if(cdc){ cdc->SetBkColor(background); cdc->SetTextColor(foreground); } return; } } if (length == 4) { // One of the home cursor or clear to end of display if (strncmp(Buffer,"\033[0H",length)==0) { // Home the cursor xpos = 0; ypos = 0; position = 0; return; } if(strncmp(Buffer,"\033[2J",length) == 0){ xpos = 0; ypos = 0; position =0; sprintf(Buffer,"\033[0J"); } if(strncmp(Buffer,"\033[0J", length) == 0){ // clear to end of display assuming 80 X 24 size if (IsWindowEnabled()){ cdc->FillSolidRect(0,(ypos+1)*height,MAX_TERMINAL_WIDTH*width, (MAX_TERMINAL_HEIGHT-ypos)*height,background); cdc->FillSolidRect(position,ypos*height, MAX_TERMINAL_WIDTH*width - position, height,background); } ret = pDoc->Lock(); pDoc->SetData(xpos, ypos, 0, (MAX_TERMINAL_HEIGHT - ypos)*MAX_TERMINAL_WIDTH -xpos, foreground, background); ret = pDoc->Unlock(); } if((strncmp(Buffer,"\033[0K", length) == 0) || (strncmp(Buffer,"\033[2K",length) == 0)){ // clear to end of line assuming 80 X 24 size if(cdc){ cdc->FillSolidRect(position,ypos*height, MAX_TERMINAL_WIDTH*width-position, height,background); } ret = pDoc->Lock(); pDoc->SetData(xpos, ypos, 0, MAX_TERMINAL_WIDTH -xpos, foreground, background); ret = pDoc->Unlock(); return; } if((strncmp(Buffer,"\033[0m", length) == 0)|| (strncmp(Buffer,"\033[m\017", length) == 0)){ // clear all attributes and set Text attributes to black on white background = BLACK; foreground = WHITE; if(cdc){ cdc->SetBkColor(background); cdc->SetTextColor(foreground); } return; } } if(Buffer[length-1] == 'm'){ //set the text attributes // clear all attributes and set Text attributes to black on white ProcessTextAttributes((PCHAR) Buffer, length); return; } if(Buffer[length -1] == 'r'){ if (sscanf(Buffer,"\033[%d;%dr", &charsToWrite, &charsWritten) == 2) { ScrollTop = (SHORT)charsToWrite; ScrollBottom = (SHORT)charsWritten; } return; } if(Buffer[length -1] == 'H'){ if (sscanf(Buffer,"\033[%d;%dH", &charsToWrite, &charsWritten) == 2) { ypos = (SHORT)(charsToWrite -1); xpos = (SHORT)(charsWritten -1); ret = pDoc->Lock(); DataLine = pDoc->GetDataLine(ypos); if (xpos >0){ position = GetTextWidth(DataLine, xpos); } else{ position = 0; } pDoc->Unlock(); } } return; } void CWatcherView::ProcessTextAttributes(PCHAR Buffer, int length) { PCHAR CurrLoc = Buffer; ULONG Attribute; PCHAR pTemp; COLORREF temp; while(*CurrLoc != 'm'){ if((*CurrLoc < '0') || (*CurrLoc >'9' )){ CurrLoc ++; }else{ if (sscanf(CurrLoc,"%d", &Attribute) != 1) { return; } switch(Attribute){ case 7: // switch the colors. This will make this code // work for applications (written in an Unix world // for real VT100. ) temp = foreground; foreground = background; background = temp; break; case 37: foreground = WHITE; break; case 47: background = WHITE; break; case 34: foreground = BLUE; break; case 44: background = BLUE; break; case 30: foreground = BLACK; break; case 40: background = BLACK; case 33: foreground = YELLOW; break; case 43: background = YELLOW; case 31: foreground = RED; break; case 41: background = RED; default: break; } pTemp = strchr(CurrLoc, ';'); if(pTemp == NULL){ pTemp = strchr(CurrLoc, 'm'); } if(pTemp == NULL) { break; } CurrLoc = pTemp; } } cdc->SetBkColor(background); cdc->SetTextColor(foreground); return; } BOOL CWatcherView::FinalCharacter(CHAR c) { CHAR FinalCharacters[]="mHJKr"; if(strchr(FinalCharacters,c)){ return TRUE; } return FALSE; } BOOL CWatcherView::IsPrintable(TCHAR Char) { if (Char > 32) return TRUE; return FALSE; } void CWatcherView::OnDestroy() { if(Socket){ delete Socket; } if(cdc){ delete cdc; } CView::OnDestroy(); // TODO: Add your message handler code here } int CWatcherView::GetTextWidth(TCHAR *Data, int number) { int textWidth=0; int CharWidth; for(int i=0;iGetOutputCharWidth(Data[i], Data[i], &CharWidth)) { textWidth += CharWidth; } } else{ textWidth += width; } } return textWidth; } // REMARK - Make this a virtual function so that // later writers can just extend this class and work // with the same framework. Now, the bell sequence // processing consists of nothing, but later can be // expanded to include WMI kind of processing. void CWatcherView::ProcessBellSequence(CHAR *Buffer, int len) { // Set this as the active window. // We will probably bring up a dialog box with // the bell parameters. WCHAR *messageBuffer; CHAR tempBuffer[MAX_BELL_SIZE + 1]; int index =0; memset(tempBuffer,0, MAX_BELL_SIZE + 1); memcpy(tempBuffer, Buffer+16, len-24); tempBuffer[len-24] = (CHAR) 0; CWnd *parent = GetParent(); CWnd *prev = parent->GetParent(); if (prev && prev->IsKindOf(RUNTIME_CLASS(CMDIFrameWnd))){ ((CMDIFrameWnd *) prev)->MDIActivate(parent); ((CMDIFrameWnd *) prev)->MDIRestore(parent); } else{ ((CMDIChildWnd *)parent)->MDIActivate(); ((CMDIChildWnd *)parent)->MDIRestore(); } int convlen; messageBuffer = new WCHAR [MAX_BELL_SIZE + 1]; messageBuffer[0] = 0; convlen = MultiByteToWideChar(CP_ACP, 0, tempBuffer, -1, messageBuffer, MAX_BELL_SIZE); messageBuffer[convlen] = (WCHAR) 0; CWinThread *th = ::AfxBeginThread(AFX_THREADPROC (GenerateWMIEvent), messageBuffer ); return; } void CWatcherView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { // TODO: Add your message handler code here and/or call default switch(nChar) { case VK_LEFT: Socket->Send("\033OC",sizeof("\033OC"),0); break; case VK_RIGHT: Socket->Send("\033OD",sizeof("\033OD"),0); break; case VK_UP: Socket->Send("\033OA",sizeof("\033OA"),0); break; case VK_DOWN: Socket->Send("\033OB",sizeof("\033OB"),0); break; case VK_F1: Socket->Send("\033""1",sizeof("\033""1"),0); break; case VK_F2: Socket->Send("\033""2",sizeof("\033""2"),0); break; case VK_F3: Socket->Send("\033""3",sizeof("\033""3"),0); break; case VK_F4: Socket->Send("\033""4",sizeof("\033""4"),0); break; case VK_F12: Socket->Send("\033@",sizeof("\033@"),0); break; default: break; } CView::OnKeyDown(nChar, nRepCnt, nFlags); }