學習windows編程 day3 之捲軸完善

來源:互聯網
上載者:User

標籤:ram   day   translate   stp   設定   全域   over   client   尺寸   

1.不再使用setscrollrange,setscrollpos,getscrollrange,getscrollpos這些函數,這隻是有助於理解其中運行原理

2.改用setscrollinfo,getscrollinfo函數和結構體scrollinfo去改變和擷取捲軸資訊,相對於上面會更加靈活,方便擴充

3.scrollwindow:滾動視窗客戶區的內容,只滾動當前顯示的內容,要顯示其他內容,需要重繪失效的視窗,但是相對於重繪整個視窗是一個很節省記憶體的方法

#include <windows.h>#include "Sysmet.h"#include <strsafe.h>LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd){    //聲明全域資料:類名    static TCHAR szClassName[] = TEXT("MyWindows");    HWND hwnd;    MSG msg;    //註冊視窗類別    WNDCLASS wndclass;    wndclass.hInstance = hInstance;    wndclass.lpszClassName = szClassName;    wndclass.cbClsExtra = 0;    wndclass.cbWndExtra = 0;    wndclass.lpfnWndProc = WndProc;    wndclass.lpszMenuName = NULL;    wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);    wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);    wndclass.style = CS_HREDRAW;    if (!RegisterClass(&wndclass))    {        MessageBox(NULL, TEXT("this program must run in Windows NT!"), szClassName, MB_ICONERROR);        return 0;    }    hwnd = CreateWindow(        szClassName,        TEXT("MyFirstPractice"),        WS_OVERLAPPEDWINDOW|WS_VSCROLL,        CW_USEDEFAULT,        CW_USEDEFAULT,        CW_USEDEFAULT,        CW_USEDEFAULT,        NULL,        NULL,        hInstance,        NULL        );    ShowWindow(hwnd, nShowCmd);    UpdateWindow(hwnd);    while (GetMessage(&msg, NULL, 0, 0))    {        TranslateMessage(&msg);        DispatchMessage(&msg);    }    return msg.wParam;}LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){    HDC hdc;    PAINTSTRUCT ps;    RECT rect;    //擷取字型大小,初始化資料    static int cxChar, cyChar, cxCaps;    //擷取每次重繪視窗後的大小尺寸    static int cxClient, cyClient;    //擷取總行數和當前行數    static numCount, curCount;    static int y;    int FirstLine, LastLine;    TEXTMETRIC tm;    TCHAR szBuffer[100];    size_t st;    SCROLLINFO si;    switch (message)    {    case WM_CREATE:        hdc = GetDC(hwnd);        //擷取字型大小,初始化資料        GetTextMetrics(hdc, &tm);        cxChar = tm.tmAveCharWidth;        cyChar = tm.tmHeight + tm.tmExternalLeading;        cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2)*cxChar / 2;        //初始化總行數和當前行數        numCount = NUMLINES;        curCount = 0;        //初始化捲軸位置        SetScrollRange(hwnd, SB_VERT, 0, numCount, FALSE);        SetScrollPos(hwnd, SB_VERT, 0, TRUE);        ReleaseDC(hwnd, &hdc);        break;    case WM_SIZE:        //擷取每次重繪後的螢幕大小        cxClient = LOWORD(lParam);    //這是擷取當前視窗的大小        cyClient = HIWORD(lParam);        //設定垂直捲軸的範圍和頁面大小        si.cbSize = sizeof(si);    //為了更好的相容版本        si.fMask = SIF_RANGE | SIF_PAGE;        si.nMin = 0;        si.nMax = numCount - 1;        si.nPage = cyClient / cyChar;    //頁面的大小設定        SetScrollInfo(hwnd, SB_VERT, &si, TRUE);        break;    case WM_VSCROLL:        //獲得垂直捲軸的資訊        si.cbSize = sizeof(si);        si.fMask = SIF_ALL;        GetScrollInfo(hwnd, SB_VERT, &si);        //儲存當前滑塊的位置        curCount = si.nPos;        switch (LOWORD(wParam))        {        case SB_LINEUP:            si.nPos -= 1;            break;        case SB_LINEDOWN:            si.nPos += 1;            break;        case SB_PAGEUP:            //先擷取當前頁面有幾行            si.nPos -= si.nPage;            break;        case SB_PAGEDOWN:            //先擷取當前頁面的行數            si.nPos += si.nPage;            break;        case SB_THUMBTRACK:            si.nPos = si.nTrackPos;            break;            //在si.nTrackPos中存放著SB_THUMBTRACK和SB_THUMBPOSITION的位置資訊        case SB_THUMBPOSITION:            si.nPos = si.nTrackPos;            break;        default:            break;        }        //設定滾動滑塊的新位置        si.fMask = SIF_POS;        SetScrollInfo(hwnd, SB_VERT, &si, TRUE);        //再次獲得滾動滑塊的位置,由於視窗調整,他可能不是同一個值        GetScrollInfo(hwnd, SB_VERT, &si);        //curCount是前面未滾動的資料,si.nPos是剛剛滾動後的資料(除非是在頂部或者底部,不然由於視窗調整,兩種一定不是同一個值)        if (si.nPos != curCount)        {            ScrollWindow(hwnd, 0, cyChar*(curCount-si.nPos), NULL, NULL);            /*                hwnd                     :視窗控制代碼                0                         :水平滾動的數量                cyChar*(curCount-si.nPos):垂直滾動的距離                NULL(lpRect)             :為NULL時,當前整個客戶區將被滾動                NULL(lpClipRect)         :與上一個參數有關,當上一個設定地區後,該參數在其地區中裁剪地區進行滾動            */            UpdateWindow(hwnd);            //不進入訊息佇列,直接發送WM_PAINT訊息進行處理        }        break;    case WM_PAINT:        hdc = BeginPaint(hwnd, &ps);                //擷取垂直捲軸的位置        si.cbSize = sizeof(si);        si.fMask = SIF_POS;        GetScrollInfo(hwnd,SB_VERT, &si);        curCount = si.nPos;        //計算需要重繪的地區        FirstLine = max(0, curCount + ps.rcPaint.top / cyChar);        LastLine = min(numCount - 1, curCount + ps.rcPaint.bottom / cyChar);        /*            ps是結構體,ps.rcPaint是指需要重繪的部分視窗矩形,ps.rcPaint.top是該矩形的上部        */        for (int i = FirstLine; i < LastLine;i++)        {            y = cyChar*(i - curCount);    //相當於將這個重繪地區看著新視窗,重這個地區的頂部開始重新繪製            StringCchLength(sysmetrics[i].szLabel, 100, &st);            TextOut(hdc, 0, y, sysmetrics[i].szLabel, st);            StringCchLength(sysmetrics[i].szDesc, 100, &st);            TextOut(hdc, 40 * cxChar, y, sysmetrics[i].szDesc, st);            SetTextAlign(hdc, TA_RIGHT | TA_TOP);            StringCchPrintf(szBuffer, 100, L"%5d", GetSystemMetrics(sysmetrics[i].iIndex));            StringCchLength(szBuffer, 100, &st);            TextOut(hdc, 40 * cxChar + 40 * cxCaps, y, szBuffer, st);            SetTextAlign(hdc, TA_LEFT);        }        EndPaint(hwnd, &ps);        break;    case WM_DESTROY:        PostQuitMessage(0);        return 0;    }    return DefWindowProc(hwnd, message, wParam, lParam);}

 

學習windows編程 day3 之捲軸完善

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.