• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            C++之竹

            無論是太陽下,還是風雨中,都要成長!

            常用鏈接

            統計

            最新評論

            Windows 控制臺程序的事件捕獲

                  此篇內容屬C++控制臺編程的一點基礎應用,所以嘛,偶就偷個懶,不再做文字的講解,直接代碼。

                  哦,對了!代碼之前,先就代碼的組成作個簡單說明。代碼的內容共分為三塊:

              1. 以宏RUN_ATEXIT_SAMPLE標識的atexit調用樣例
              2. 以宏RUN_SETCONSOLECTRLHANDLER_SAMPLE標識的SetConsoleCtrlHandler調用樣例
              3. 以宏RUN_READCONSOLEINPUT_SAMPLE標識的ReadConsoleInput調用樣例

                  其中,第3段樣例代碼來自于MSDN:http://msdn.microsoft.com/en-us/library/ms685035(v=VS.85).aspx

                  OK,開始代碼!!

            #include <windows.h>
            #include 
            <iostream>
            #include 
            <string>

            using namespace std;

            #define RUN_ATEXIT_SAMPLE
            #define RUN_SETCONSOLECTRLHANDLER_SAMPLE
            #define RUN_READCONSOLEINPUT_SAMPLE

            #define SECOND(n) (n * 1000)

            // ATEXIT_SAMPLE
            void Run_atexit_Sample(void);

            // SETCONSOLECTRLHANDLER_SAMPLE
            BOOL WINAPI ConsoleHandler(__in DWORD dwCtrlType);

            // READCONSOLEINPUT_SAMPLE
            HANDLE hStdin; 
            DWORD fdwSaveOldMode;
            VOID ErrorExit(LPSTR);
            VOID KeyEventProc(KEY_EVENT_RECORD); 
            VOID MouseEventProc(MOUSE_EVENT_RECORD); 
            VOID ResizeEventProc(WINDOW_BUFFER_SIZE_RECORD); 
            VOID Run_ReadConsoleInput_Sample(VOID);


            int main(void)
            {
            #ifdef RUN_ATEXIT_SAMPLE
                Run_atexit_Sample();
            #endif

            #ifdef RUN_SETCONSOLECTRLHANDLER_SAMPLE
                cout 
            << "[RUN_SETCONSOLECTRLHANDLER_SAMPLE] START" << endl;
                cout 
            << "\t (Note: You just have 15sec to do the operations.)" << endl;
                
            // 【SetConsoleCtrlHandler(HandlerRoutine, Add)】:
                
            // Add == TRUE: 處理HandlerRoutine 被添加
                
            //    如果 HandlerRoutine == NULL,則忽略對 CTRL+C 輸入處理
                
            // Add == FALSE: 處理HandlerRoutine 被移除
                
            //    如果 HandlerRoutine == NULL,則恢復對 CTRL+C 輸入的處理
                
            // 對 CTRL+C 輸入處理的忽略與恢復,將被子進程所繼承
                if (SetConsoleCtrlHandler((PHANDLER_ROUTINE)ConsoleHandler, TRUE) == FALSE) {
                    DWORD dwErr 
            = GetLastError();
                    cout 
            << "[RUN_SETCONSOLECTRLHANDLER_SAMPLE] Failed to SetConsoleCtrlHandler! Err: " << dwErr << endl;
                    
            return (int)dwErr;
                }


                Sleep(SECOND(
            15));
                cout 
            << "[RUN_SETCONSOLECTRLHANDLER_SAMPLE] END" << endl;
            #endif

            #ifdef RUN_READCONSOLEINPUT_SAMPLE
                cout 
            << "[RUN_READCONSOLEINPUT_SAMPLE] Enter Run_ReadConsoleInput_Sample()" << endl;
                Run_ReadConsoleInput_Sample();
                cout 
            << "[RUN_READCONSOLEINPUT_SAMPLE] Leave Run_ReadConsoleInput_Sample()" << endl;
            #endif

                system(
            "pause");
                
            return 0;
            }


            //////////////////////////////////////////////////////////////////////////

            void ExitProc_1(void
            {
                cout 
            << "[RUN_ATEXIT_SAMPLE] This is ExitProc_1" << endl;
            }


            void ExitProc_2(void
            {
                cout 
            << "[RUN_ATEXIT_SAMPLE] This is ExitProc_2" << endl;
            }


            // 【注意】:
            // 1. atexit() 成功時返回 0
            // 2. atexit() 的參數類型為 void (__cdecl *func )( void )
            // 3. atexit() 是將所傳入的回調函數放入棧中,故回調函數的執行順序與atexit的順序相反
            // 4. atexit() 只有當應用程序正常結束時,回調函數才能執行
            // 5. atexit() 回調函數不能依賴于任何DLL,因為在回調函數執行時DLL可能已經被卸載
            // 6. 類似函數:
            //    _onexit(_onexit_t)  ==>  int (__clrcall * _onexit_t)(void) 
            //    _onexit_m(_onexit_t_m) ==> int (__clrcall * _onexit_m_t)(void) 
            //    其中,_onexit是微軟的擴展;ANSI程序則應使用atexit;對于混合模式,則可使用_onexit_m版本
            void Run_atexit_Sample(void)
            {
                cout 
            << "[RUN_ATEXIT_SAMPLE] Enter Run_atexit_Sample()" << endl;
                cout 
            << "[RUN_ATEXIT_SAMPLE] Call atexit() first by ExitProc_1, then by ExitProc_2" << endl;
                atexit(ExitProc_1);
                atexit(ExitProc_2);

                cout 
            << "[RUN_ATEXIT_SAMPLE] Leave Run_atexit_Sample()" << endl;
            }


            //////////////////////////////////////////////////////////////////////////

            // 如果事件得到了處理,則返回 TRUE
            // 如果還需要將事件傳遞給下一個事件處理函數,則返回 FALSE
            BOOL WINAPI ConsoleHandler( __in DWORD dwCtrlType )
            {
                
            switch (dwCtrlType) {
                
            case CTRL_C_EVENT: // CTRL + C
                    
            // 亦可通過GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0)觸發
                    cout << "\n[RUN_SETCONSOLECTRLHANDLER_SAMPLE] CTRL_C_EVENT" << endl;
                    
            break;
                
            case CTRL_BREAK_EVENT: // CTRL + BREAK
                    
            // 亦可通過GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, 0)觸發
                    cout << "\n[RUN_SETCONSOLECTRLHANDLER_SAMPLE] CTRL_BREAK_EVENT" << endl;
                    
            break;
                
            case CTRL_CLOSE_EVENT: // 關閉控制臺程序
                    cout << "\n[RUN_SETCONSOLECTRLHANDLER_SAMPLE] CTRL_CLOSE_EVENT" << endl;
                    
            break;
                
            case CTRL_LOGOFF_EVENT: // 用戶注銷(退出登錄)
                    cout << "\n[RUN_SETCONSOLECTRLHANDLER_SAMPLE] CTRL_LOGOFF_EVENT" << endl;
                    
            break;
                
            case CTRL_SHUTDOWN_EVENT: // 關機
                    cout << "\n[RUN_SETCONSOLECTRLHANDLER_SAMPLE] CTRL_SHUTDOWN_EVENT" << endl;
                    
            break;
                
            default:
                    cout 
            << "\n[RUN_SETCONSOLECTRLHANDLER_SAMPLE] Unknown console ctrl event: " << dwCtrlType << endl;
                    
            break;
                }


                
            return TRUE;
            }


            //////////////////////////////////////////////////////////////////////////

            VOID ErrorExit (LPSTR lpszMessage) 

                fprintf(stderr, 
            "%s\n", lpszMessage); 

                
            // Restore input mode on exit.

                SetConsoleMode(hStdin, fdwSaveOldMode);

                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:

                    
            if(mer.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED)
                    
            {
                        printf(
            "left button press \n");
                    }

                    
            else if(mer.dwButtonState == RIGHTMOST_BUTTON_PRESSED)
                    
            {
                        printf(
            "right button press \n");
                    }

                    
            else
                    
            {
                        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");
                printf(
            "Console screen buffer is %d columns by %d rows.\n", wbsr.dwSize.X, wbsr.dwSize.Y);
            }


            VOID Run_ReadConsoleInput_Sample( VOID )
            {    
                DWORD cNumRead, fdwMode, 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 next 100 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
                        }
             
                    }

                }
             

                
            // Restore input mode on exit.

                SetConsoleMode(hStdin, fdwSaveOldMode);
            }

            最后,本人還是博客新人,有什么好的意見或建議,還望各位能大力提點??!

             

            posted on 2012-04-23 00:07 青碧竹 閱讀(1003) 評論(0)  編輯 收藏 引用 所屬分類: C++基礎

            日韩欧美亚洲国产精品字幕久久久| 久久久无码精品亚洲日韩按摩 | 久久久久久久综合日本| 久久久久久亚洲Av无码精品专口 | 精品久久一区二区三区| 亚洲综合日韩久久成人AV| 精品久久久久久久国产潘金莲| 久久伊人精品青青草原日本| 欧美精品丝袜久久久中文字幕 | Xx性欧美肥妇精品久久久久久| 国产成人久久精品区一区二区| 欧美精品久久久久久久自慰| 亚洲精品无码久久久久sm| 奇米影视7777久久精品| 久久夜色精品国产噜噜亚洲AV| 久久超乳爆乳中文字幕| 91精品国产91热久久久久福利| 日本精品久久久久中文字幕8| 91久久精品视频| 一本色综合久久| 男女久久久国产一区二区三区| 人妻无码久久一区二区三区免费| 成人免费网站久久久| 国产精品va久久久久久久| 亚洲欧美另类日本久久国产真实乱对白| 一本久久a久久精品亚洲| 九九精品99久久久香蕉| 国产午夜福利精品久久| 三级三级久久三级久久| 69久久夜色精品国产69| 日韩中文久久| 国产精品久久成人影院| 久久综合伊人77777| 久久精品水蜜桃av综合天堂| 久久久久这里只有精品| 久久久无码精品亚洲日韩按摩| 狠狠色丁香婷婷综合久久来来去| 久久精品国产99国产精品导航| 99久久精品费精品国产| 日韩久久久久久中文人妻| 日本欧美国产精品第一页久久|