本文的程序來(lái)自《windows程序設(shè)計(jì)(第五版)》
設(shè)計(jì)滾動(dòng)條的初衷,是因?yàn)榭蛻?hù)區(qū)需要顯示的東西太多了,在這個(gè)頭文件中,我們包含了一大堆的系統(tǒng)的信息:
-
- #define NUMLINES ((int) (sizeof sysmetrics / sizeof sysmetrics [0]))
-
- struct
- {
- int Index ;
- TCHAR* szLabel;
- TCHAR* szDesc ;
-
- }
-
- sysmetrics [] =
-
- {
-
- SM_CXSCREEN, TEXT ("SM_CXSCREEN"), TEXT ("Screen width in pixels"),
- SM_CYSCREEN, TEXT ("SM_CYSCREEN"), TEXT ("Screen height in pixels"),
- SM_CXVSCROLL, TEXT ("SM_CXVSCROLL"), TEXT ("Vertical scroll width"),
- SM_CYHSCROLL, TEXT ("SM_CYHSCROLL"), TEXT ("Horizontal scroll height"),
- SM_CYCAPTION, TEXT ("SM_CYCAPTION"), TEXT ("Caption bar height"),
- SM_CXBORDER, TEXT ("SM_CXBORDER"), TEXT ("Window border width"),
- SM_CYBORDER, TEXT ("SM_CYBORDER"), TEXT ("Window border height"),
- SM_CXFIXEDFRAME, TEXT ("SM_CXFIXEDFRAME"), TEXT ("Dialog window frame width"),
- SM_CYFIXEDFRAME, TEXT ("SM_CYFIXEDFRAME"), TEXT ("Dialog window frame height"),
- SM_CYVTHUMB, TEXT ("SM_CYVTHUMB"), TEXT ("Vertical scroll thumb height"),
- SM_CXHTHUMB, TEXT ("SM_CXHTHUMB"), TEXT ("Horizontal scroll thumb width"),
- SM_CXICON, TEXT ("SM_CXICON"), TEXT ("Icon width"),
- SM_CYICON, TEXT ("SM_CYICON"), TEXT ("Icon height"),
- SM_CXCURSOR, TEXT ("SM_CXCURSOR"), TEXT ("Cursor width"),
- SM_CYCURSOR, TEXT ("SM_CYCURSOR"), TEXT ("Cursor height"),
- SM_CYMENU, TEXT ("SM_CYMENU"), TEXT ("Menu bar height"),
- SM_CXFULLSCREEN, TEXT ("SM_CXFULLSCREEN"), TEXT ("Full screen client area width"),
- SM_CYFULLSCREEN, TEXT ("SM_CYFULLSCREEN"), TEXT ("Full screen client area height"),
- SM_CYKANJIWINDOW, TEXT ("SM_CYKANJIWINDOW"), TEXT ("Kanji window height"),
- SM_MOUSEPRESENT, TEXT ("SM_MOUSEPRESENT"), TEXT ("Mouse present flag"),
- SM_CYVSCROLL, TEXT ("SM_CYVSCROLL"), TEXT ("Vertical scroll arrow height"),
- SM_CXHSCROLL, TEXT ("SM_CXHSCROLL"), TEXT ("Horizontal scroll arrow width"),
- SM_DEBUG, TEXT ("SM_DEBUG"), TEXT ("Debug version flag"),
- SM_SWAPBUTTON, TEXT ("SM_SWAPBUTTON"), TEXT ("Mouse buttons swapped flag"),
- SM_CXMIN, TEXT ("SM_CXMIN"), TEXT ("Minimum window width"),
- SM_CYMIN, TEXT ("SM_CYMIN"), TEXT ("Minimum window height"),
- SM_CXSIZE, TEXT ("SM_CXSIZE"), TEXT ("Min/Max/Close button width"),
- SM_CYSIZE, TEXT ("SM_CYSIZE"), TEXT ("Min/Max/Close button height"),
- SM_CXSIZEFRAME, TEXT ("SM_CXSIZEFRAME"), TEXT ("Window sizing frame width"),
- SM_CYSIZEFRAME, TEXT ("SM_CYSIZEFRAME"), TEXT ("Window sizing frame height"),
- SM_CXMINTRACK, TEXT ("SM_CXMINTRACK"), TEXT ("Minimum window tracking width"),
- SM_CYMINTRACK, TEXT ("SM_CYMINTRACK"), TEXT ("Minimum window tracking height"),
- SM_CXDOUBLECLK, TEXT ("SM_CXDOUBLECLK"), TEXT ("Double click x tolerance"),
- SM_CYDOUBLECLK, TEXT ("SM_CYDOUBLECLK"), TEXT ("Double click y tolerance"),
- SM_CXICONSPACING, TEXT ("SM_CXICONSPACING"), TEXT ("Horizontal icon spacing"),
- SM_CYICONSPACING, TEXT ("SM_CYICONSPACING"), TEXT ("Vertical icon spacing"),
- SM_MENUDROPALIGNMENT, TEXT ("SM_MENUDROPALIGNMENT"), TEXT ("Left or right menu drop"),
- SM_PENWINDOWS, TEXT ("SM_PENWINDOWS"), TEXT ("Pen extensions installed"),
- SM_DBCSENABLED, TEXT ("SM_DBCSENABLED"), TEXT ("Double-Byte Char Set enabled"),
- SM_CMOUSEBUTTONS, TEXT ("SM_CMOUSEBUTTONS"), TEXT ("Number of mouse buttons"),
- SM_SECURE, TEXT ("SM_SECURE"), TEXT ("Security present flag"),
- SM_CXEDGE, TEXT ("SM_CXEDGE"), TEXT ("3-D border width"),
- SM_CYEDGE, TEXT ("SM_CYEDGE"), TEXT ("3-D border height"),
- SM_CXMINSPACING, TEXT ("SM_CXMINSPACING"), TEXT ("Minimized window spacing width"),
- SM_CYMINSPACING, TEXT ("SM_CYMINSPACING"), TEXT ("Minimized window spacing height"),
- SM_CXSMICON, TEXT ("SM_CXSMICON"), TEXT ("Small icon width"),
- SM_CYSMICON, TEXT ("SM_CYSMICON"), TEXT ("Small icon height"),
- SM_CYSMCAPTION, TEXT ("SM_CYSMCAPTION"), TEXT ("Small caption height"),
- SM_CXSMSIZE, TEXT ("SM_CXSMSIZE"), TEXT ("Small caption button width"),
- SM_CYSMSIZE, TEXT ("SM_CYSMSIZE"), TEXT ("Small caption button height"),
- SM_CXMENUSIZE, TEXT ("SM_CXMENUSIZE"), TEXT ("Menu bar button width"),
- SM_CYMENUSIZE, TEXT ("SM_CYMENUSIZE"), TEXT ("Menu bar button height"),
- SM_ARRANGE, TEXT ("SM_ARRANGE"), TEXT ("How minimized windows arranged"),
- SM_CXMINIMIZED, TEXT ("SM_CXMINIMIZED"), TEXT ("Minimized window width"),
- SM_CYMINIMIZED, TEXT ("SM_CYMINIMIZED"), TEXT ("Minimized window height"),
- SM_CXMAXTRACK, TEXT ("SM_CXMAXTRACK"), TEXT ("Maximum draggable width"),
- SM_CYMAXTRACK, TEXT ("SM_CYMAXTRACK"), TEXT ("Maximum draggable height"),
- SM_CXMAXIMIZED, TEXT ("SM_CXMAXIMIZED"), TEXT ("Width of maximized window"),
- SM_CYMAXIMIZED, TEXT ("SM_CYMAXIMIZED"), TEXT ("Height of maximized window"),
- SM_NETWORK, TEXT ("SM_NETWORK"), TEXT ("Network present flag"),
- SM_CLEANBOOT, TEXT ("SM_CLEANBOOT"), TEXT ("How system was booted"),
- SM_CXDRAG, TEXT ("SM_CXDRAG"), TEXT ("Avoid drag x tolerance"),
- SM_CYDRAG, TEXT ("SM_CYDRAG"), TEXT ("Avoid drag y tolerance"),
- SM_SHOWSOUNDS, TEXT ("SM_SHOWSOUNDS"), TEXT ("Present sounds visually"),
- SM_CXMENUCHECK, TEXT ("SM_CXMENUCHECK"), TEXT ("Menu check-mark width"),
- SM_CYMENUCHECK, TEXT ("SM_CYMENUCHECK"), TEXT ("Menu check-mark height"),
- SM_SLOWMACHINE, TEXT ("SM_SLOWMACHINE"), TEXT ("Slow processor flag"),
- SM_MIDEASTENABLED, TEXT ("SM_MIDEASTENABLED"), TEXT ("Hebrew and Arabic enabled flag"),
- SM_MOUSEWHEELPRESENT, TEXT ("SM_MOUSEWHEELPRESENT"), TEXT ("Mouse wheel present flag"),
- SM_XVIRTUALSCREEN, TEXT ("SM_XVIRTUALSCREEN"), TEXT ("Virtual screen x origin"),
- SM_YVIRTUALSCREEN, TEXT ("SM_YVIRTUALSCREEN"), TEXT ("Virtual screen y origin"),
- SM_CXVIRTUALSCREEN, TEXT ("SM_CXVIRTUALSCREEN"), TEXT ("Virtual screen width"),
- SM_CYVIRTUALSCREEN, TEXT ("SM_CYVIRTUALSCREEN"), TEXT ("Virtual screen height"),
- SM_CMONITORS, TEXT ("SM_CMONITORS"), TEXT ("Number of monitors"),
- SM_SAMEDISPLAYFORMAT, TEXT ("SM_SAMEDISPLAYFORMAT"), TEXT ("Same color format flag")
-
- } ;
第一行定義的,是數(shù)組有多少個(gè)元素。之后我們定義了結(jié)構(gòu)體數(shù)組。元素個(gè)數(shù)很多,一行顯示不下,那么如何添加滾動(dòng)條呢?
我們先看程序:
- #include <windows.h>
- #include "sysmets.h"
-
- LRESULT CALLBACK WndProc (HWND,UINT,WPARAM,LPARAM);
-
- int WINAPI WinMain(HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- LPSTR lpCmdLine,
- int iCmdShow)
- {
- static TCHAR szAppName[] = TEXT("顯示系統(tǒng)內(nèi)容");
-
- HWND hwnd;
-
- MSG msg;
-
- WNDCLASS wndclass;
-
- wndclass.style = CS_HREDRAW | CS_VREDRAW;
-
- wndclass.lpfnWndProc = WndProc;
-
- wndclass.cbClsExtra = 0;
-
- wndclass.cbWndExtra = 0;
-
- wndclass.hInstance = hInstance;
-
- wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
-
- wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);
-
- wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
-
- wndclass.lpszMenuName = NULL;
-
- wndclass.lpszClassName = szAppName;
-
-
- if(!RegisterClass(&wndclass))
- {
- return -1;
- }
-
-
- hwnd = CreateWindow(szAppName,
- TEXT("系統(tǒng)內(nèi)容"),
- WS_OVERLAPPEDWINDOW | WS_VSCROLL,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- NULL,
- NULL,
- hInstance,
- NULL);
-
-
-
- ShowWindow (hwnd, iCmdShow);
-
-
- 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)
- {
-
- static int cxChar, cxCaps, cyChar ;
-
- static int cxClient, cyClient ;
-
- static int iVscrollPos;
- HDC hdc;
-
- int i;
-
- int y;
-
- PAINTSTRUCT ps;
-
- TCHAR szBuffer [10];
-
- TEXTMETRIC tm;
- switch(message)
- {
- case WM_CREATE:
- hdc = GetDC(hwnd);
-
- GetTextMetrics (hdc, &tm);
-
- cxChar = tm.tmAveCharWidth ;
-
- cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2 ;
-
- cyChar = tm.tmHeight + tm.tmExternalLeading ;
-
- ReleaseDC(hwnd,hdc);
-
-
- SetScrollRange (hwnd, SB_VERT, 0, NUMLINES - 1, FALSE);
-
- SetScrollPos (hwnd, SB_VERT, iVscrollPos, TRUE);
-
- return 0;
- case WM_SIZE:
- cxClient = LOWORD (lParam) ;
- cyClient = HIWORD (lParam) ;
- return 0;
- case WM_PAINT:
- hdc = BeginPaint (hwnd, &ps) ;
- for(i = 0;i < NUMLINES;i++ )
- {
-
-
- y = cyChar * (i - iVscrollPos) ;
-
-
-
- TextOut(hdc,0, y,sysmetrics[i].szLabel,lstrlen(sysmetrics[i].szLabel));
-
- TextOut(hdc,22*cxCaps, y,sysmetrics[i].szDesc,lstrlen(sysmetrics[i].szDesc));
-
- SetTextAlign(hdc,TA_RIGHT | TA_TOP);
-
-
-
- TextOut(hdc,22*cxCaps+40*cxChar,y,szBuffer,wsprintf(szBuffer,TEXT("%5d"),GetSystemMetrics (sysmetrics[i].Index)));
-
- SetTextAlign(hdc,TA_LEFT | TA_TOP);
- }
- EndPaint (hwnd, &ps) ;
- return 0;
-
-
- case WM_VSCROLL:
-
-
- switch(LOWORD (wParam))
- {
-
- case SB_LINEUP:
- iVscrollPos -=1;
- break;
-
- case SB_LINEDOWN:
- iVscrollPos +=1;
- break;
-
- case SB_PAGEUP:
- iVscrollPos -= cyClient / cyChar ;
- break;
-
- case SB_PAGEDOWN:
- iVscrollPos += cyClient / cyChar ;
- break;
-
- case SB_THUMBPOSITION:
- iVscrollPos = HIWORD (wParam) ;
- break;
- default:
- break;
- }
-
-
- iVscrollPos = max (0, min (iVscrollPos, NUMLINES - 1)) ;
-
-
- if (iVscrollPos != GetScrollPos (hwnd, SB_VERT))
- {
-
- SetScrollPos (hwnd, SB_VERT, iVscrollPos, TRUE) ;
-
- InvalidateRect (hwnd, NULL, TRUE) ;
- }
-
- return 0;
-
-
- case WM_DESTROY:
- PostQuitMessage(0);
- return 0;
- }
- return DefWindowProc (hwnd, message, wParam, lParam) ;
-
- }
程序的思路是這樣的:在創(chuàng)建窗口時(shí),就要告訴系統(tǒng)你要加一個(gè)滾動(dòng)條(垂直的),在WM_CREATE消息中,就要對(duì)滾動(dòng)條進(jìn)行一些基本的設(shè)置。WM_VSCROLL對(duì)滾動(dòng)條做出相應(yīng),可以分為3部分:第一部分接收滾動(dòng)條的消息;第二部分是讓滾動(dòng)條的那個(gè)小方塊滾動(dòng)到特定的位置,第三部分是頁(yè)面的文字出現(xiàn)“滾動(dòng)”的效果。
先看第一部分:滾動(dòng)條的作用是什么:當(dāng)點(diǎn)擊一下向上或者向下的按鈕時(shí),會(huì)滾動(dòng)一行文字;當(dāng)點(diǎn)擊滾動(dòng)的小方塊的上面或者下面時(shí),會(huì)滾動(dòng)一頁(yè)文字;而拖著滾動(dòng)條走,能滾動(dòng)到指定的地方。到底是這幾種操作的哪一種,是通過(guò)WM_VSCROLL消息的wParam的低字節(jié)傳過(guò)來(lái)的。在程序中,使用iVscrollPos這個(gè)全局變量來(lái)記錄滾動(dòng)的位置,每一次對(duì)滾動(dòng)條都會(huì)改變位置。
iVscrollPos = max (0, min (iVscrollPos, NUMLINES - 1)) ;是為了不讓滾動(dòng)條的位置超出一定為范圍,大家可以把它屏蔽之后,將滾動(dòng)條向上或者向下滾,就可以理解結(jié)果了。 而通過(guò)SetScrollPos (hwnd, SB_VERT, iVscrollPos, TRUE) ;就將滾動(dòng)條的方塊放到了可定位位置。而第三部分讓頁(yè)面滾動(dòng),則是WM_PAINT的作用了:其實(shí)當(dāng)你看到第二行顯示在原來(lái)第一行為位置上時(shí),其實(shí)并不是系統(tǒng)沒(méi)有輸出第一行,而是第一行輸出的位置已經(jīng)到了客戶(hù)區(qū)的上面,所以你看不到!第二行緊跟在第一行下面,剛好就放到了開(kāi)始的位置。
這個(gè)滾動(dòng)條有一個(gè)明顯的缺點(diǎn),就是他并不是我們希望看到的那樣:滾動(dòng)條的長(zhǎng)度反應(yīng)的當(dāng)前頁(yè)面占顯示的內(nèi)容總的內(nèi)容的百分比,具體的說(shuō),就是:
頁(yè)面方塊的大小/滾動(dòng)的長(zhǎng)度=頁(yè)面大小/整個(gè)范圍=顯示文件的數(shù)量/整個(gè)文件的數(shù)量
別看這只是一點(diǎn)小小的改動(dòng),但是他的實(shí)現(xiàn)方法卻與上面的差別很大??傮w上來(lái)說(shuō),他需要使用SCROLLINFO結(jié)構(gòu)來(lái)記錄滾動(dòng)條的信息,然后使用GetScrollInfo獲取信息,通過(guò)SetScrollInfo設(shè)置信息。在對(duì)滾動(dòng)條的響應(yīng)消息中,通過(guò)ScrollWindow來(lái)實(shí)現(xiàn)內(nèi)容的滾動(dòng)(而不像前面那個(gè)程序,在WM_PAINT消息下實(shí)現(xiàn))。
我們?cè)诳纯闯绦颍?/P>
- #include <windows.h>
- #include "sysmets.h"
-
- LRESULT CALLBACK WndProc (HWND,UINT,WPARAM,LPARAM);
-
- int WINAPI WinMain(HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- LPSTR lpCmdLine,
- int iCmdShow)
- {
- static TCHAR szAppName[] = TEXT("顯示系統(tǒng)內(nèi)容");
-
- HWND hwnd;
-
- MSG msg;
-
- WNDCLASS wndclass;
-
- wndclass.style = CS_HREDRAW | CS_VREDRAW;
-
- wndclass.lpfnWndProc = WndProc;
-
- wndclass.cbClsExtra = 0;
-
- wndclass.cbWndExtra = 0;
-
- wndclass.hInstance = hInstance;
-
- wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
-
- wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);
-
- wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
-
- wndclass.lpszMenuName = NULL;
-
- wndclass.lpszClassName = szAppName;
-
-
- if(!RegisterClass(&wndclass))
- {
- return -1;
- }
-
-
- hwnd = CreateWindow(szAppName,
- TEXT("系統(tǒng)內(nèi)容"),
- WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- NULL,
- NULL,
- hInstance,
- NULL);
-
-
-
- ShowWindow (hwnd, iCmdShow);
-
-
- 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)
- {
-
- static int cxChar, cxCaps, cyChar ;
-
- static int cxClient, cyClient ;
-
- static int iMaxWidth;
-
- static int iVertPos,iHorzPos,iPaintBeg,iPaintEnd;
- HDC hdc;
-
- int i;
-
- int x,y;
-
- PAINTSTRUCT ps;
-
-
- SCROLLINFO si;
-
- TCHAR szBuffer [10];
-
- TEXTMETRIC tm;
- switch(message)
- {
- case WM_CREATE:
- hdc = GetDC(hwnd);
-
- GetTextMetrics (hdc, &tm);
-
- cxChar = tm.tmAveCharWidth ;
-
- cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2 ;
-
- cyChar = tm.tmHeight + tm.tmExternalLeading ;
-
- ReleaseDC(hwnd,hdc);
-
- iMaxWidth = 40*cxChar+22*cxCaps;
- return 0;
- case WM_SIZE:
- cxClient = LOWORD (lParam) ;
- cyClient = HIWORD (lParam) ;
-
-
- si.cbSize = sizeof(si);
-
- si.fMask = SIF_RANGE | SIF_PAGE ;
-
- si.nMin = 0;
-
- si.nMax = NUMLINES - 1 ;
-
- si.nPage = cyClient / cyChar ;
-
- SetScrollInfo(hwnd, SB_VERT,&si,TRUE);
-
-
- si.cbSize = sizeof(si);
- si.fMask = SIF_RANGE | SIF_PAGE ;
- si.nMin = 0;
- si.nMax = 2+ iMaxWidth/cxChar ;
- si.nPage = cxClient / cxChar ;
- SetScrollInfo (hwnd, SB_HORZ, &si, TRUE) ;
-
- return 0;
-
- case WM_PAINT:
- hdc = BeginPaint (hwnd, &ps) ;
-
- si.cbSize = sizeof(si);
- si.fMask = SIF_POS;
- GetScrollInfo(hwnd,SB_VERT,&si);
- iVertPos = si.nPos;
- GetScrollInfo(hwnd,SB_HORZ,&si);
- iHorzPos = si.nPos;
-
-
- iPaintBeg = max(0,iVertPos);
-
- iPaintEnd = min(NUMLINES -1,iVertPos+ps.rcPaint.bottom/cyChar);
-
- for(i = iPaintBeg; i <= iPaintEnd;i++)
- {
-
- x = cxChar * (1 - iHorzPos) ;
-
- y = cyChar * (i - iVertPos) ;
- TextOut(hdc,x, y,sysmetrics[i].szLabel,lstrlen(sysmetrics[i].szLabel));
-
- TextOut(hdc,x+22*cxCaps,y,sysmetrics[i].szDesc,lstrlen(sysmetrics[i].szDesc));
- SetTextAlign(hdc,TA_RIGHT | TA_TOP);
- TextOut(hdc,x+22*cxCaps+40*cxChar,y,szBuffer,wsprintf(szBuffer,TEXT("%5d"),GetSystemMetrics (sysmetrics[i].Index)));
- SetTextAlign(hdc,TA_LEFT | TA_TOP);
- }
- EndPaint (hwnd, &ps) ;
- return 0;
-
-
- case WM_VSCROLL:
-
-
- si.cbSize = sizeof(si);
-
- si.fMask = SIF_ALL;
- GetScrollInfo(hwnd,SB_VERT,&si);
-
- iVertPos = si.nPos ;
-
- switch(LOWORD (wParam))
- {
- case SB_TOP:
- si.nPos = si.nMin;
- break;
- case SB_BOTTOM:
- si.nPos = si.nMax;
- break;
- case SB_LINEUP:
- si.nPos -= 1;
- break;
- case SB_LINEDOWN:
- si.nPos +=1;
- case SB_PAGEUP:
- si.nPage -= si.nPage;
- break;
- case SB_PAGEDOWN:
- si.nPos +=si.nPage;
- break;
- case SB_THUMBTRACK:
- si.nPos = si.nTrackPos;
- break;
- default:
- break;
- }
-
-
- si.fMask = SIF_POS;
- SetScrollInfo(hwnd,SB_VERT,&si,TRUE);
- GetScrollInfo(hwnd,SB_VERT,&si);
- if(si.nPos != iVertPos)
- {
-
- ScrollWindow(hwnd,0,cyChar*(iVertPos-si.nPos),NULL,NULL);
- UpdateWindow(hwnd);
- }
- return 0;
-
- case WM_HSCROLL:
- si.cbSize = sizeof(si);
- si.fMask = SIF_ALL;
- GetScrollInfo(hwnd,SB_HORZ,&si);
- iHorzPos = si.nPos;
- switch(LOWORD(wParam))
- {
- case SB_LINELEFT:
- si.nPos -= 1;
- break;
- case SB_LINERIGHT:
- si.nPos +=1;
- break;
- case SB_PAGELEFT:
- si.nPos -= si.nPage;
- break;
- case SB_PAGERIGHT:
- si.nPos += si.nPage;
- break;
- case SB_THUMBPOSITION:
- si.nPos = si.nTrackPos;
- break;
- default:
- break;
-
- }
- si.fMask = SIF_POS;
- SetScrollInfo(hwnd,SB_HORZ,&si,TRUE);
- GetScrollInfo(hwnd,SB_HORZ,&si);
- if(si.nPos != iHorzPos)
- {
- ScrollWindow(hwnd,cxChar*(iHorzPos-si.nPos),0,NULL,NULL);
-
-
- }
- return 0;
- case WM_DESTROY:
- PostQuitMessage(0);
- return 0;
- }
- return DefWindowProc (hwnd, message, wParam, lParam) ;
-
- }
程序中有幾點(diǎn)需要注意:
1.程序中設(shè)置了垂直滾動(dòng)條和水平滾動(dòng)條。在WM_SIZE消息中,隨著窗口的變化,滾動(dòng)條的那個(gè)小方塊的大小也在變化。
2.在每次使用GetScrollInfo或者SetScrollInfo之前,都必須有si.cbSize = sizeof(si);這是因?yàn)榧嫒莸木壒?。而且還得指明操作的是SCROLLINFO中的哪些內(nèi)容,這通過(guò)fMask來(lái)控制。
3.程序中有幾行代碼很費(fèi)解:
iPaintBeg = max(0,iVertPos+ps.rcPaint.top/cyChar);實(shí)際上,由于ps.rcPaint.top=0,這行代碼也可以寫(xiě)為:iPaintBeg = max(0,iVertPos);
iPaintEnd = min(NUMLINES -1,iVertPos+ps.rcPaint.bottom/cyChar);畫(huà)圖的結(jié)束位置=滾動(dòng)條當(dāng)前的位置+繪制的行數(shù),而行數(shù)=客戶(hù)區(qū)寬度/每一行的寬度;
x = cxChar * (1 - iHorzPos) ;繪圖的x坐標(biāo),那個(gè)1是為了不是太“頂格”,你也可以把它設(shè)置大一點(diǎn),結(jié)果就很明顯了。
|