《windows程序设计》上第255页是一个关于鼠标滚轮的消息。
代码如下:
#include <Windows.h> #include "SYSMETS.h" LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam); int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR szCmdLine,int iCmdShow) { TCHAR szAppName[]=TEXT("ParentClass"); HWND hwnd; MSG msg; WNDCLASS wndclass; wndclass.style=CS_HREDRAW|CS_VREDRAW; wndclass.lpfnWndProc=WndProc; wndclass.cbClsExtra=0; wndclass.cbWndExtra=0; wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION); wndclass.hCursor=LoadCursor(NULL,IDC_ARROW); wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.hInstance=hInstance; wndclass.lpszMenuName=NULL; wndclass.lpszClassName=szAppName; if (!RegisterClass(&wndclass)) { MessageBox(hwnd,TEXT("ERROR"),TEXT("ERROR"),MB_OK); return 0; } hwnd=CreateWindow(szAppName,TEXT("First Program"),WS_OVERLAPPEDWINDOW|WS_HSCROLL|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,cyChar,cxCaps,cxClient,cyClient; static int iDeltaPerLine,iAccumDelta; //static int iDeltaPerLine=0; //int iAccumDelta; int iVertPos,i,x,y,iPaintBeg,iPaintEnd; TEXTMETRIC tm; SCROLLINFO si; HDC hdc; PAINTSTRUCT ps; ULONG ulScrollLines; TCHAR szBuffer[10]; 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; ReleaseDC(hwnd,hdc); case WM_SETTINGCHANGE: SystemParametersInfo(SPI_GETWHEELSCROLLLINES,0,&ulScrollLines,0); if (ulScrollLines) { iDeltaPerLine=WHEEL_DELTA/ulScrollLines; } else { iDeltaPerLine=0; } return 0; case WM_SIZE: cxClient=LOWORD(lParam); cyClient=HIWORD(lParam); si.cbSize=sizeof(si); si.fMask=SIF_PAGE|SIF_RANGE; si.nMin=0; si.nMax=NUMLINES-1; si.nPage=cyClient/cyChar; SetScrollInfo(hwnd,SB_VERT,&si,TRUE); 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_PAGEUP: si.nPos-=si.nPage; break; case SB_PAGEDOWN: si.nPos+=si.nPage; break; case SB_LINEUP: si.nPos-=1; break; case SB_LINEDOWN: si.nPos+=1; break; case SB_THUMBTRACK: si.nPos=si.nTrackPos; break; default: break; } SetScrollInfo(hwnd,SB_VERT,&si,TRUE); si.fMask=SIF_POS; GetScrollInfo(hwnd,SB_VERT,&si); if (si.nPos!=iVertPos) { ScrollWindow(hwnd,0,(iVertPos-si.nPos)*cyChar,NULL,NULL); UpdateWindow(hwnd); } return 0; case WM_KEYDOWN: switch (wParam) { case VK_PRIOR: SendMessage(hwnd,WM_VSCROLL,SB_PAGEUP,lParam); break; case VK_NEXT: SendMessage(hwnd,WM_VSCROLL,SB_PAGEDOWN,lParam); break; case VK_UP: SendMessage(hwnd,WM_VSCROLL,SB_LINEUP,lParam); break; case VK_DOWN: SendMessage(hwnd,WM_VSCROLL,SB_LINEDOWN,lParam); break; default: break; } return 0; case WM_MOUSEWHEEL: if (iDeltaPerLine==0) { break; } iAccumDelta+=(short)HIWORD(wParam); //HIWORD(wParam) is a delta value (120 or -120) while (iAccumDelta>=iDeltaPerLine) //iDeltaPerLine is 40,then Rolled up 3 lines { SendMessage(hwnd,WM_VSCROLL,SB_LINEUP,0); iAccumDelta-=iDeltaPerLine; } while (iAccumDelta<=-iDeltaPerLine) //Rolled down 3 lines { SendMessage(hwnd,WM_VSCROLL,SB_LINEDOWN,0); iAccumDelta+=iDeltaPerLine; } return 0; case WM_PAINT: si.cbSize=sizeof(si); GetScrollInfo(hwnd,SB_VERT,&si); iVertPos=si.nPos; hdc=BeginPaint(hwnd,&ps); iPaintBeg=max(0,iVertPos+ps.rcPaint.top/cyChar); iPaintEnd=min(NUMLINES-1,iVertPos+ps.rcPaint.bottom/cyChar); for (i=iPaintBeg;i<=iPaintEnd;i++) { x=0; y=(i-iVertPos)*cyChar; 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+66*cxCaps,y,szBuffer,wsprintf(szBuffer,TEXT("%d"),GetSystemMetrics(sysmetrics[i].Index))); SetTextAlign(hdc,TA_TOP|TA_LEFT); } EndPaint(hwnd,&ps); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd,message,wParam,lParam); }
就是在WM_CREATE消息后千万不能加return 0;
不然WM_SETTINGCHANGE消息就不会触发,那么iDeltaPerLine也就为0,那么WM_MOUSEWHEEL消息得不到执行,于是产生不了预期的效果!!