控制台程式添加滾輪滑動支援

來源:互聯網
上載者:User

標籤:

控制台程式預設只能通過拖動捲軸來查看視窗中列印的內容,操作起來十分不方便。

本文通過多線程技術為控制台表單添加滑鼠滾輪滑動功能。值得注意的是,在有內容輸出時,視窗會自動定位到輸出的游標處;

這種情況最好是先暫停住主線程,然後再滾動滑鼠查看列印的內容,查看完畢後,再繼續執行主線程。

首先,需要讓控制台程式的螢幕緩衝區高度 > 視窗高度(此時視窗右側會產生捲軸),否則無需滾動視窗。

下列代碼實現了如下功能:

(1)滾動滑鼠滑動視窗

(2)按空格鍵,暫停/繼續主線程

#include <windows.h>/*** Scroll console window by relative coordinate*/static int ScrollByRelativeCoord(int iRows){    CONSOLE_SCREEN_BUFFER_INFO csbiInfo;     SMALL_RECT srctWindow;         // Get the current screen buffer window position.     HANDLE hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);        if (! GetConsoleScreenBufferInfo(hConsoleOutput, &csbiInfo))     {         return 0;    }        // Check whether the window is too close to the screen buffer top or bottom    if (csbiInfo.srWindow.Top < iRows)    {        iRows = csbiInfo.srWindow.Top;    }    else if (csbiInfo.srWindow.Bottom > csbiInfo.dwSize.Y+iRows-1)    {        iRows = -1* (csbiInfo.dwSize.Y -1 - csbiInfo.srWindow.Bottom);    }        srctWindow.Top =- (SHORT)iRows;     // move top up    srctWindow.Bottom =- (SHORT)iRows;  // move bottom up     srctWindow.Left = 0;         // no change     srctWindow.Right = 0;        // no change         if (! SetConsoleWindowInfo(         hConsoleOutput,          // screen buffer handle         FALSE,            // relative coordinates        &srctWindow))     // specifies new location     {        return 0;    }    return iRows;}DWORD WINAPI ConsoleInputEventProc(LPVOID lParam){    // vc6 version sdk don‘t has OpenThread API, need get by call GetProcAddress;    HANDLE hMainThreadHandle = NULL;#if _MSC_VER <= 1200    HMODULE hDll =::LoadLibrary("Kernel32.dll");    if (hDll)    {        typedef HANDLE (__stdcall *OPENTHREAD) (DWORD, BOOL, DWORD);        OPENTHREAD fnOpenThread = (OPENTHREAD)::GetProcAddress(hDll, "OpenThread");        if (fnOpenThread)        {            hMainThreadHandle = fnOpenThread(THREAD_SUSPEND_RESUME, FALSE, (DWORD)lParam);        }    }#else    hMainThreadHandle = OpenThread(THREAD_SUSPEND_RESUME, FALSE, (DWORD)lParam);#endif        HANDLE hConsoleInput = GetStdHandle(STD_INPUT_HANDLE);        BOOL bSuspend = FALSE;    BOOL fContinue = TRUE;    DWORD dwEvents;    INPUT_RECORD input;    while (fContinue &&        ReadConsoleInput(hConsoleInput, &input, 1, &dwEvents) &&        dwEvents > 0)     {        switch (input.EventType)         {        case KEY_EVENT:            if (input.Event.KeyEvent.wVirtualKeyCode == VK_SPACE)             {                if (input.Event.KeyEvent.bKeyDown && hMainThreadHandle != NULL)                {                    HANDLE hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);                    if (bSuspend)                    {                        SetConsoleTextAttribute(hConsoleOutput, FOREGROUND_GREEN);                        printf("Resume MainThread\n");                        ResumeThread(hMainThreadHandle);                    }                    else                     {                        SetConsoleTextAttribute(hConsoleOutput, FOREGROUND_RED);                        printf("Suspend MainThread\n");                        SuspendThread(hMainThreadHandle);                    }                                        SetConsoleTextAttribute(hConsoleOutput, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);                    bSuspend = !bSuspend;                }            }        case MOUSE_EVENT:            if (input.Event.MouseEvent.dwEventFlags==4)// mousewheel            {                const int nLine = 5;                if ((int)input.Event.MouseEvent.dwButtonState>0)// scroll up                {                    ScrollByRelativeCoord(nLine);                }                else// scroll up                {                    ScrollByRelativeCoord(-1*nLine);                }            }            break;        }    }        CloseHandle(hMainThreadHandle);    return 0;}int main(int argc, char* argv[]){        CreateThread(NULL, 0, ConsoleInputEventProc, (LPVOID)GetCurrentThreadId(), 0, NULL);    int nLine = 60;    while (nLine--)    {        printf("Hello World!\n");        Sleep(1000);    }    Sleep(INFINITE);    return 0;}

 

控制台程式添加滾輪滑動支援

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.