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
50case WM_DESTROY: 51 PostQuitMessage( 0 ) ; 52return0 ; 53 } 54
55return DefWindowProc( hwnd, message, wParam, lParam ) ; 56 }

浙公網安備 33010602011771號