如何获取到cmd.exe中的消息

Q:请问如何获取到cmd.exe中的消息?比如点击鼠标右键弹出菜单的消息,我用spy++无法获取到cmd窗口,请高手帮忙谢谢

A:

DOS程序通过一个名为Winoldap的控制台程序来运行,而这个程序则是在32位Windows控制台窗口中运行。原理上,Winoldap利用x86的"Virtual86"模式来虚拟实模式。
创建控制台时,操作系统自动创建三个"标准"文件句柄。在高级控制台编程中,用两个API函数控制这些句柄

GetStdHandle和SetStdHandle

控制台使用的不是我们常见的Win32消息队列,而是事件队列。
事件队列和Windows消息队列差不多,不过是接收输入事件,而非消息。所以Spy++当然得不到消息

ReadConsoleInput可以用来获得控制台的输入,参考

MSDN给出了一个创建标准信息队列的例子

C/C++ code
    
    
    
    
#include < windows.h > #include < stdio.h > VOID ErrorExit(LPSTR); VOID KeyEventProc(KEY_EVENT_RECORD); VOID MouseEventProc(MOUSE_EVENT_RECORD); VOID ResizeEventProc(WINDOW_BUFFER_SIZE_RECORD); int main(VOID) { HANDLE hStdin; DWORD cNumRead, fdwMode, fdwSaveOldMode, i; INPUT_RECORD irInBuf[ 128 ]; int counter = 0 ; // Get the standard input handle. hStdin = GetStdHandle(STD_INPUT_HANDLE); if (hStdin == INVALID_HANDLE_VALUE) ErrorExit( " GetStdHandle " ); // Save the current input mode, to be restored on exit. if ( ! GetConsoleMode(hStdin, & fdwSaveOldMode) ) ErrorExit( " GetConsoleMode " ); // Enable the window and mouse input events. fdwMode = ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT; if ( ! SetConsoleMode(hStdin, fdwMode) ) ErrorExit( " SetConsoleMode " ); // Loop to read and handle the input events. while (counter ++ <= 100 ) { // Wait for the events. if ( ! ReadConsoleInput( hStdin, // input buffer handle irInBuf, // buffer to read into 128 , // size of read buffer & cNumRead) ) // number of records read ErrorExit( " ReadConsoleInput " ); // Dispatch the events to the appropriate handler. for (i = 0 ; i < cNumRead; i ++ ) { switch (irInBuf[i].EventType) { case KEY_EVENT: // keyboard input KeyEventProc(irInBuf[i].Event.KeyEvent); break ; case MOUSE_EVENT: // mouse input MouseEventProc(irInBuf[i].Event.MouseEvent); break ; case WINDOW_BUFFER_SIZE_EVENT: // scrn buf. resizing ResizeEventProc( irInBuf[i].Event.WindowBufferSizeEvent); break ; case FOCUS_EVENT: // disregard focus events case MENU_EVENT: // disregard menu events break ; default : ErrorExit( " Unknown event type " ); break ; } } } return 0 ; } VOID ErrorExit (LPSTR lpszMessage) { fprintf(stderr, " %s/n " , lpszMessage); ExitProcess( 0 ); } VOID KeyEventProc(KEY_EVENT_RECORD ker) { printf( " Key event: " ); if (ker.bKeyDown) printf( " key pressed/n " ); else printf( " key released/n " ); } VOID MouseEventProc(MOUSE_EVENT_RECORD mer) { #ifndef MOUSE_HWHEELED #define MOUSE_HWHEELED 0x0008 #endif printf( " Mouse event: " ); switch (mer.dwEventFlags) { case 0 : printf( " button press/n " ); break ; case DOUBLE_CLICK: printf( " double click/n " ); break ; case MOUSE_HWHEELED: printf( " horizontal mouse wheel/n " ); break ; case MOUSE_MOVED: printf( " mouse moved/n " ); break ; case MOUSE_WHEELED: printf( " vertical mouse wheel/n " ); break ; default : printf( " unknown/n " ); break ; } } VOID ResizeEventProc(WINDOW_BUFFER_SIZE_RECORD wbsr) { printf( " Resize event/n " ); }


我就花点事件给你解释下
WINDOW_BUFFER_SIZE_EVENT 屏幕大小改变时发出
MENU_EVENT 用户使用控制台菜单或工具栏时发出
FOCUS_EVENT 控制台得到输入焦点时发出


这是内部实现,当然我们外部也可以获得。利用管道,然后GetStdHandle(STD_INPUT_HANDLE);

然后即可读取Console窗口的事件。

好久没见到这么值得我回,详细解释的帖子。希望对后面看帖的朋友有帮助

你可能感兴趣的:(windows,buffer,input,menu,events,keyboard)