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 }

 

原文地址:https://www.cnblogs.com/yanjunfeng/p/7482301.html