• <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++之竹

            無(wú)論是太陽(yáng)下,還是風(fēng)雨中,都要成長(zhǎng)!

            常用鏈接

            統(tǒng)計(jì)

            最新評(píng)論

            Windows 控制臺(tái)程序的事件捕獲

                  此篇內(nèi)容屬C++控制臺(tái)編程的一點(diǎn)基礎(chǔ)應(yīng)用,所以嘛,偶就偷個(gè)懶,不再做文字的講解,直接代碼。

                  哦,對(duì)了!代碼之前,先就代碼的組成作個(gè)簡(jiǎn)單說(shuō)明。代碼的內(nèi)容共分為三塊:

              1. 以宏RUN_ATEXIT_SAMPLE標(biāo)識(shí)的atexit調(diào)用樣例
              2. 以宏RUN_SETCONSOLECTRLHANDLER_SAMPLE標(biāo)識(shí)的SetConsoleCtrlHandler調(diào)用樣例
              3. 以宏RUN_READCONSOLEINPUT_SAMPLE標(biāo)識(shí)的ReadConsoleInput調(diào)用樣例

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

                  OK,開(kāi)始代碼!!

            #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,則忽略對(duì) CTRL+C 輸入處理
                
            // Add == FALSE: 處理HandlerRoutine 被移除
                
            //    如果 HandlerRoutine == NULL,則恢復(fù)對(duì) CTRL+C 輸入的處理
                
            // 對(duì) CTRL+C 輸入處理的忽略與恢復(fù),將被子進(jìn)程所繼承
                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() 成功時(shí)返回 0
            // 2. atexit() 的參數(shù)類(lèi)型為 void (__cdecl *func )( void )
            // 3. atexit() 是將所傳入的回調(diào)函數(shù)放入棧中,故回調(diào)函數(shù)的執(zhí)行順序與atexit的順序相反
            // 4. atexit() 只有當(dāng)應(yīng)用程序正常結(jié)束時(shí),回調(diào)函數(shù)才能執(zhí)行
            // 5. atexit() 回調(diào)函數(shù)不能依賴(lài)于任何DLL,因?yàn)樵诨卣{(diào)函數(shù)執(zhí)行時(shí)DLL可能已經(jīng)被卸載
            // 6. 類(lèi)似函數(shù):
            //    _onexit(_onexit_t)  ==>  int (__clrcall * _onexit_t)(void) 
            //    _onexit_m(_onexit_t_m) ==> int (__clrcall * _onexit_m_t)(void) 
            //    其中,_onexit是微軟的擴(kuò)展;ANSI程序則應(yīng)使用atexit;對(duì)于混合模式,則可使用_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
            // 如果還需要將事件傳遞給下一個(gè)事件處理函數(shù),則返回 FALSE
            BOOL WINAPI ConsoleHandler( __in DWORD dwCtrlType )
            {
                
            switch (dwCtrlType) {
                
            case CTRL_C_EVENT: // CTRL + C
                    
            // 亦可通過(guò)GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0)觸發(fā)
                    cout << "\n[RUN_SETCONSOLECTRLHANDLER_SAMPLE] CTRL_C_EVENT" << endl;
                    
            break;
                
            case CTRL_BREAK_EVENT: // CTRL + BREAK
                    
            // 亦可通過(guò)GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, 0)觸發(fā)
                    cout << "\n[RUN_SETCONSOLECTRLHANDLER_SAMPLE] CTRL_BREAK_EVENT" << endl;
                    
            break;
                
            case CTRL_CLOSE_EVENT: // 關(guān)閉控制臺(tái)程序
                    cout << "\n[RUN_SETCONSOLECTRLHANDLER_SAMPLE] CTRL_CLOSE_EVENT" << endl;
                    
            break;
                
            case CTRL_LOGOFF_EVENT: // 用戶(hù)注銷(xiāo)(退出登錄)
                    cout << "\n[RUN_SETCONSOLECTRLHANDLER_SAMPLE] CTRL_LOGOFF_EVENT" << endl;
                    
            break;
                
            case CTRL_SHUTDOWN_EVENT: // 關(guān)機(jī)
                    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);
            }

            最后,本人還是博客新人,有什么好的意見(jiàn)或建議,還望各位能大力提點(diǎn)!!

             

            posted on 2012-04-23 00:07 青碧竹 閱讀(1000) 評(píng)論(0)  編輯 收藏 引用 所屬分類(lèi): C++基礎(chǔ)


            只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            国产精品久久久久久久久软件| 久久中文字幕视频、最近更新| 国产精品免费看久久久| www.久久热.com| 国产亚洲精久久久久久无码AV| 人妻无码久久精品| 久久久亚洲欧洲日产国码aⅴ| 国内精品久久久久| 久久久久亚洲AV无码专区桃色| 久久涩综合| 精品无码久久久久久午夜| 99久久精品无码一区二区毛片| 久久中文字幕视频、最近更新| 亚洲va久久久噜噜噜久久天堂| 国产精品一久久香蕉产线看| 久久人搡人人玩人妻精品首页| 亚洲国产欧洲综合997久久| 中文字幕亚洲综合久久| 热99RE久久精品这里都是精品免费 | 国产成人久久精品一区二区三区| 久久精品国产亚洲AV无码娇色| 精品国产综合区久久久久久| 亚洲va久久久噜噜噜久久狠狠 | 久久综合亚洲色一区二区三区| 97久久超碰国产精品旧版| 久久伊人五月天论坛| 久久香综合精品久久伊人| 久久人人爽人人爽AV片| 99久久99久久| 97久久国产综合精品女不卡 | 国产精品久久久久久久app| 国产精品久久久久久影院| 久久精品成人欧美大片| 久久国产热这里只有精品| 成人久久精品一区二区三区| 久久亚洲精品国产亚洲老地址| 久久综合九色综合97_久久久| 国内高清久久久久久| 麻豆久久| 久久久久无码精品| 99久久精品免费看国产|