• windows学习记录----滚动条、GDI基础


    1.滚动条

    1 #include<windows.h>
     2 #include"text.h"  
     3
      4 LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM ) ;        //声明窗口过程函数
      5
      6 int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow )
      7{
      8static TCHAR szAppName[] = TEXT("LearnScroll") ;
      9    HWND hwnd ;
     10    MSG msg ;
     11    WNDCLASS wndclass ;
     12
     13//窗口类成员属性
     14     wndclass.lpfnWndProc = WndProc ;
     15     wndclass.style = CS_HREDRAW | CS_VREDRAW ;
     16     wndclass.hInstance = hInstance ;
     17     wndclass.lpszClassName = szAppName ;
     18     wndclass.lpszMenuName = NULL ;
     19     wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH) ;
     20     wndclass.hCursor = LoadCursor(NULL, IDI_APPLICATION) ;
     21     wndclass.hIcon = LoadIcon(NULL, IDC_ARROW) ;
     22     wndclass.cbClsExtra = 0 ;
     23     wndclass.cbWndExtra = 0 ;
     24
     25//注册窗口类
     26if( !RegisterClass(&wndclass) )
     27    {
     28         MessageBox( NULL, TEXT("无法注册窗口类!"), TEXT("错误"), MB_OK | MB_ICONERROR ) ;
     29return0 ;
     30    }
     31
     32//创建窗口
     33     hwnd = CreateWindow(
     34  szAppName, TEXT("滚动条示例"),
     35         WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL,
     36        CW_USEDEFAULT, CW_USEDEFAULT,
     37        CW_USEDEFAULT, CW_USEDEFAULT,
     38        NULL, NULL, hInstance, NULL
     39    ) ;
     40
     41//显示窗口
     42    ShowWindow( hwnd, iCmdShow ) ;
     43    UpdateWindow( hwnd ) ;
     44
     45//获取、翻译、分发消息
     46while( GetMessage( &msg, NULL, 0, 0 ) )
     47    {
     48         TranslateMessage( &msg ) ;
     49         DispatchMessage( &msg ) ;
     50    }
     51
     52return msg.wParam ;
     53}
     54
      1  LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
      2{
      3staticint cxChar, cxCaps, cyChar, cyClient, cxClient, iVscrollPos, iHscrollPos ;
      4//cxChar:平均字符宽度; cxCaps: 大写字母平均宽度; cyChar: 字符高; cyClient、cxClient: 客户区y、x方向尺寸; 
      5//iVscrollPos: 竖直方向滚动条滑块位置; iHscrollPos: 水平方向滚动条滑块位置
      6    HDC hdc ;
      7     RECT rect ;            //记录客户区RECT结构
      8int i, x, y;        //i循环控制, x记录水平方向坐标, y竖直方向坐标
      9    PAINTSTRUCT ps ;
     10    TEXTMETRIC tm ;
     11     SCROLLINFO  si ;    //SCROLLINFO结构对象
     12int iMaxLength ;    //所有语句中的最大长度
     13
     14     iMaxLength = GetMaxLength() ;        //取得最大长度
     15
     16switch(message)
     17    {
     18case WM_CREATE:        //处理WM_CREATE消息
     19         hdc = GetDC(hwnd) ;
     20         GetTextMetrics( hdc, &tm ) ;    //获取系统字体信息
     21         cxChar = tm.tmAveCharWidth ;    //获取平均宽度
     22         cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2 ;        //大写字母平均宽度
     23         cyChar = tm.tmHeight + tm.tmExternalLeading ;                    //字符高度
     24        ReleaseDC( hwnd, hdc );
     25
     26return0 ;
     27
     28case WM_SIZE:        //处理WM_SIZE
     29         GetClientRect( hwnd, &rect ) ;
     30         cxClient = LOWORD (lParam) ;
     31         cyClient = HIWORD (lParam) ;
     32
     33//设置垂直滚动条相关参数
     34         si.cbSize = sizeof (si) ;
     35         si.fMask  = SIF_RANGE | SIF_PAGE ;
     36         si.nMin   = 0 ;
     37         si.nMax   = NUMLINES - 1 ;
     38         si.nPage  = cyClient / cyChar ;
     39         SetScrollInfo(hwnd, SB_VERT, &si, TRUE) ;
     40
     41//设置水平滚动条相关参数
     42         si.cbSize = sizeof (si) ;
     43         si.fMask  = SIF_RANGE | SIF_PAGE ;
     44         si.nMin   = 0 ;
     45         si.nMax   = 2 + iMaxLength ;
     46         si.nPage  = cxClient / cxCaps ;
     47         SetScrollInfo(hwnd, SB_HORZ, &si, TRUE) ;
     48
     49return0;
     50
     51case WM_VSCROLL:    //处理垂直滚动条消息
     52         si.cbSize = sizeof (si) ;
     53         si.fMask  = SIF_ALL ;
     54         GetScrollInfo(hwnd, SB_VERT, &si) ;
     55
     56         iVscrollPos = si.nPos ;    //记录当前滑块位置
     57
     58switch( LOWORD(wParam) )    //处理滚动条消息
     59        {
     60case SB_TOP:            //到达顶部
     61             si.nPos = si.nMin ;
     62break ;
     63
     64case SB_BOTTOM:            //到达底部
     65             si.nPos = si.nMax ;
     66break ;
     67
     68case SB_LINEUP:            //上翻一行
     69             si.nPos -= 1 ;
     70break ;
     71
     72case SB_LINEDOWN:        //下翻一行
     73             si.nPos += 1 ;
     74break ;
     75
     76case SB_PAGEUP:            //向上翻一整页
     77             si.nPos -= si.nPage ;
     78break ;
     79
     80case SB_PAGEDOWN:        //向下翻一整页
     81             si.nPos += si.nPage ;
     82break ;
     83
     84case SB_THUMBTRACK:        //移动滑块时
     85             si.nPos = si.nTrackPos ;
     86break ;
     87
     88default:
     89break;
     90        }
     91         si.fMask = SIF_POS ;
     92         SetScrollInfo(hwnd, SB_VERT, &si, TRUE) ;        //重置滑块位置
     93         GetScrollInfo(hwnd, SB_VERT, &si) ;
     94if( si.nPos != iVscrollPos )
     95        {
     96                ScrollWindow(hwnd, 0, cyChar * (iVscrollPos - si.nPos), NULL, NULL) ;        //滚动内容
     97               UpdateWindow(hwnd) ;
     98        }
     99return0 ;
    100
    101case WM_HSCROLL:    //处理水平滚动条消息
    102         si.cbSize = sizeof (si) ;
    103         si.fMask  = SIF_ALL ;
    104         GetScrollInfo (hwnd, SB_HORZ, &si) ;
    105
    106         iHscrollPos = si.nPos ;    //记录当前滑块位置
    107switch( LOWORD(wParam) )
    108        {
    109case SB_TOP:            //到达顶部
    110             si.nPos = si.nMin ;
    111break ;
    112
    113case SB_BOTTOM:            //到达底部
    114             si.nPos = si.nMax ;
    115break ;
    116
    117case SB_LINELEFT:        //左翻一行
    118             si.nPos -= 1 ;
    119break ;
    120
    121case SB_LINERIGHT:        //右翻一行
    122             si.nPos += 1 ;
    123break ;
    124
    125case SB_PAGELEFT:        //左翻一页
    126             si.nPos -= si.nPage ;
    127break ;
    128
    129case SB_PAGERIGHT:        //右翻一页
    130             si.nPos += si.nPage ;
    131break ;
    132
    133case SB_THUMBTRACK:        //移动滑块时
    134             si.nPos = si.nTrackPos ;
    135break ;    
    136
    137default:
    138break ;
    139        }
    140         si.fMask = SIF_POS ;
    141         SetScrollInfo(hwnd, SB_HORZ, &si, TRUE) ;        //重置滑块位置
    142         GetScrollInfo(hwnd, SB_HORZ, &si) ;
    143if( si.nPos != iHscrollPos )
    144        {
    145                ScrollWindow(hwnd, cxCaps * (iHscrollPos - si.nPos), 0, NULL, NULL) ;        //滚动内容
    146               UpdateWindow(hwnd) ;
    147        }
    148return0 ;
    149
    150case WM_PAINT:        //处理WM_PAINT消息
    151         hdc = BeginPaint( hwnd, &ps ) ;
    152
    153         si.cbSize = sizeof (si) ;
    154         si.fMask  = SIF_POS ;
    155         GetScrollInfo(hwnd, SB_VERT, &si) ;
    156         iVscrollPos = si.nPos ;                    //获取当前垂直滑块位置
    157
    158         GetScrollInfo(hwnd, SB_HORZ, &si) ;
    159         iHscrollPos = si.nPos ;                    //获取当前水平滑块位置
    160
    161for( i= 0; i < NUMLINES; i++ )
    162        {
    163             y = cyChar * ( i - iVscrollPos ) ;
    164             x = cxCaps * ( 0 - iHscrollPos ) ;
    165             TextOut( hdc, x, y, statement[i], lstrlen(statement[i]) ) ;        //输出文字
    166        }
    167
    168         EndPaint( hwnd, &ps ) ;
    169return0 ;
    170
    171case WM_DESTROY:    //处理WM_DESTROY消息
    172         PostQuitMessage( 0 ) ;
    173return0 ;
    174    }
    175
    176return DefWindowProc( hwnd, message, wParam, lParam ) ;
    177 }

     

      

     

    1>. SetScrollInfo

        函数功能: 用于设置滚动条的相关参数, 包括滚动范围的最大值和最小值, 页面大小, 滑块的位置, 函数的原型:

    int SetScrollInfo(
        HWND hWnd;              //窗口句柄
            int fnBar,               //指定被设定参数的滚动条的类型
        LPSCROLLINFO lpsi,       //指向一个SCROLLINFO结构
        BOOL fRedraw             //重绘标志
      ) ;
    

      SCROLLINFO的成员记录有关滚动条的信息, 其结构定义如下:

    typedef struct tagSCROLLINFO 
      { 
        UINT cbSize ;             //设置为sizeof (SCROLLINFO), 表示该结构的大小
        UINT fMask ;             //要设置或获取的值
            int nMin ;               //滚动条范围的最小值
            int nMax ;               //滚动条范围的最大值
        UINT nPage ;            //页面大小
           int nPos ;               //当前位置
    int nTrackPos ;           //当前追踪位置 
      }SCROLLINFO;
    
    成员一UINT cbSize :  该参数必须在函数调用之前设置,  cbSize表示该结构的大小, 用sizeof (SCROLLINFO)表示即可。
    成员二UINT fMask: 用于指定指定结构中的哪些成员是有效的, 通过位或运算进行组合, 可组合的标识符如下:
     SIF_ALL                     //整个结构都有效
      SIF_DISABLENOSCROLL         //禁用滚动条
      SIF_PAGE                //用于指定或获取页面的大小, 在SetScrollInfo中用于设定页面的大小, 在GetScrollInfo用于获取页面的大小
      SIF_POS//设置/取得滚动条滑块当前的位置
      SIF_RANGE//滚动条的范围
      SIF_TRACKPOS               //仅在GetScrollInfo函数中使用, 并且仅用在处理SB_THUMBTRACK或者SB_THUMBPOSITION的WM_VSCROLL消息或WM_HSCROLL消息时使用。取得当前滑块的跟踪位置。
    

    2>. GetScrollInfo

    用于取得滚动条的相关参数, 包括滚动范围的最大值和最小值, 页面大小, 滑块的位置, 函数的原型:

    BOOL GetScrollInfo( 
        HWND hWnd,                    //窗口句柄
            int fnBar,                     //指定被设定参数的滚动条的类型
        LPSCROLLINFO lpsi              //指向一个SCROLLINFO结构
       );
    

      

    3>. ScrollWindow

        该函数的作用是滚动所指定的窗口客户区域内容, 原型如下:

    BOOL ScrollWindow(
        HWND hWnd,               //窗口句柄
            int XAmount,                //指定水平滚动的距离
            int YAmount,                //指定垂直滚动的距离
          CONST RECT *IpRect,         //指向RECT结构的指针, 该结构指定了将要滚动的客户区范围。若此参数为NULL,则整个客户区域将被滚动。 
        CONST RECT *lpClipRect      //指向RECT结构的指针, 该结构指定了要滚动的裁剪区域。只有这个矩形中才会被滚动。
    

      

      2.GDI基础

    在诸多的GDI函数中从功能上来说实际上可以主要分为以下5种类型:
            1>. 获取、释放设备环境的函数;
            2>. 获取设备环境信息的函数;
            3>. 绘图函数;
            4>. 设置、获取设备环境属性的函数;
            5>. 使用GDI"对象"的函数;

            
      在屏幕上绘图的相关流程:

     获取设备环境的句柄(当获取成功时就意味着你的应用程序有了在屏幕上绘图的权限)-----调用GDI中的绘图函数通过设备环境句柄对屏幕进行绘制------释放句柄

    获取设备环境句柄:

    1>. 使用BeginPaint函数和EndPaint函数:

    HDC BeginPaint(
              HWND hwnd,                 // 窗口的句柄
              LPPAINTSTRUCT lpPaint     // 绘制信息
          );

    2>. 使用GetDC函数   

    HDC GetDC( HWND hWnd ) ;

    3>. 使用GetWindowDC  

    HDC GetWindowDC( HWND hWnd // 窗口句柄 );与GetDC不同, GetDC可以用来获取窗口的客户区部分的设备环境句柄, 而GetWindowDC用来获取整个窗口的设备环境句柄, 整个窗口是指包括窗口的标题栏、菜单栏、滚动条、状态栏以及客户区和客户区的外缘边框部分

    4>. 使用CreateDC
    HDC CreateDC(
                LPCTSTR lpszDriver,
                LPCTSTR lpszDevice,
                LPCTSTR lpszOutput,
                const DEVMODE *lpInitData
            );
     
     1LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
     2{
     3    HDC hdc ;
     4    PAINTSTRUCT ps ;
     5     POINT apn[4] = { {150, 50}, {200, 200}, {150, 300}, {150, 500} } ;        //坐标组
     6     POINT apt[8] = { { 200, 50}, {300, 200}, {250, 200}, {200, 300}, {250, 300}, {300, 350}, {250, 400}, {250, 500} } ;        //坐标组
     7     DWORD  lpPts[] = { 4, 4 };        //使用PolyPolyline进行多条折线绘制时的分组
     8int i ;
     9
    10switch( message )
    11    {
    12case WM_PAINT:
    13         hdc = BeginPaint( hwnd, &ps ) ;
    14
    15//在(50, y)方向上绘制90个点, 颜色为黑色
    16for( i = 0; i < 90; i++ )
    17             SetPixel( hdc, 50, 50 + i * 5, RGB( 0, 0, 0 ) ) ;
    18
    19//画线, 起点坐标( 100, 50 ), 终点坐标( 100, 500 )
    20         MoveToEx( hdc, 100, 50, NULL );
    21         LineTo( hdc, 100, 500 );
    22
    23
    //画一条折线 24 Polyline( hdc, apn, 4 ) ; 25
    26
    //画2条折线, 将apt分为2组 27 PolyPolyline( hdc, apt, lpPts, 2 ) ; 28 29//画椭圆弧线 30 Arc(hdc, 350, 50, 500, 500, 400, 100, 400, 500 ) ; 31 32//画矩形 33 Rectangle( hdc, 450, 50, 500, 500 ) ; 34 35 //画椭圆 36 Ellipse( hdc, 550, 50, 600, 500 ) ; 37 38 //画圆角矩形 39 RoundRect( hdc, 650, 50, 700, 500, 20, 20 ) ; 40 41 //画扇形 42 Pie( hdc, 750, 50, 850, 150, 850, 80, 850, 160 ) ; 43
    44
    //画拱形 45 Chord( hdc, 750, 400, 850, 500, 850, 450, 750, 450 ) ; 46
    47
    EndPaint( hwnd, &ps ) ; 48return0 ; 49
    50
    case WM_DESTROY: 51 PostQuitMessage( 0 ) ; 52return0 ; 53 } 54
    55
    return DefWindowProc( hwnd, message, wParam, lParam ) ; 56 }

     

  • 相关阅读:
    实现 js 数据类型的判断函数type
    函数防抖 debounce
    验证对象属性是否存在
    解析字串
    完成将 toChineseNum, 可以将数字转换成中文大写的表示,处理到万级别,例如 toChineseNum(12345),返回 一万二千三百四十五
    前端开发仓库
    javascript功能插件大集合,写前端的亲们记得收藏
    Memcached存储命令
    Memcached存储命令
    Memcached 简介、安装和基本使用
  • 原文地址:https://www.cnblogs.com/yanjunfeng/p/7482301.html
Copyright © 2020-2023  润新知