调用SCROOLLWINDOW函数后是否产生WM_PAINT消息?
问题:这是WINDOWS程序设计这本书上第四章输出文字中的一个例子(例4-4),主要功能
是练习处理滚动条,程序有些长,我只显示了垂直滚动条的部分.版排的不好,请大家见谅
我的问题是:
1、当我单击垂直滚动条时,显示区域中的信息发生卷动,这个卷是由函数SCROLLWINDOW产生的,
还是由WM_PAINT消息中的TEXTOUT输出的.如果是由函数SCROOLLWINDOW产生的,能否解释一下卷动的过程.
2、调用SCROOLLWINDOW函数后是否产生WM_PAINT消息.
3、WM_PAINT消息中的代码的除了初始化将信息输出到窗口中外,还有没有其它的作用?
#include<windows.h>
#include"SYSMETS.H"
LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam );
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow )
{
static TCHAR szAppName[] = TEXT("SysMets3");
WNDCLASS wndclass;
HWND hwnd;
MSG msg;
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 ) )
{
MessageBox( NULL, TEXT("Program requires Windows NT"), szAppName,
MB_ICONERROR );
return 0;
}
hwnd = CreateWindow( szAppName, TEXT("Get System Metrics NO.3"),
WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL ,
0, 0,
1000, 400,
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 = 0;
static int cyChar = 0;
static int cxCaps = 0;
static int iMaxWidth = 0;
static int cxClient = 0;
static int cyClient = 0;
int iVertPos = 0;
int iHorzPos = 0;
int iPaintBeg = 0;
int iPaintEnd = 0;
int iCount = 0;
int iXCoordinate = 0;
int iYCoordinate = 0;
HDC hdc = 0;
PAINTSTRUCT ps;
TEXTMETRIC tm;
TCHAR szBuffer[ 10 ];
TCHAR szNewBuffer[ 10 ] = {0};
SCROLLINFO si;
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 = 80 * 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 | SIF_DISABLENOSCROLL;
si.nMin = 0;
si.nMax = 2 + iMaxWidth / cxChar;
si.nPage = cxClient / cxChar;
SetScrollInfo( hwnd, SB_HORZ, &si, TRUE );
return 0;
}
//垂直滚动
case WM_VSCROLL:
{
//Get all the vertical scroll bar information
si.cbSize = sizeof( si );
si.fMask = SIF_ALL;
GetScrollInfo( hwnd, SB_VERT, &si );
//Save the position for comparison later on
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;
break;
}
case SB_PAGEUP:
{
si.nPos -= si.nPage;
break;
}
case SB_PAGEDOWN:
{
si.nPos += si.nPage;
break;
}
case SB_THUMBTRACK:
{
si.nPos = si.nTrackPos;
break;
}
default:
break;
}
// Set the position and then retrieve it. Due to
// adjustments
// by Windows it may not be the same as the value set
si.fMask = SIF_POS;
SetScrollInfo( hwnd, SB_VERT, &si, TRUE );
GetScrollInfo( hwnd, SB_VERT, &si );
//If the position has changed, scroll the window and
//update it
if( si.nPos != iVertPos )
{
ScrollWindow( hwnd, 0, cyChar * ( iVertPos - si.nPos ), NULL, NULL );
//UpdateWindow( hwnd );
}
return 0;
}
case WM_PAINT:
{
hdc = BeginPaint( hwnd, &ps );
//Get vertical scroll bar position
si.cbSize = sizeof( si );
si.fMask = SIF_POS;
GetScrollInfo( hwnd, SB_VERT, &si );
iVertPos = si.nPos;
//Get horizontal scroll bar position
GetScrollInfo( hwnd, SB_HORZ, &si );
iHorzPos = si.nPos;
//Find painting limits
iPaintBeg = max( 0, iVertPos + ps.rcPaint.top / cyChar );
iPaintEnd = min( NUMLINES - 1, iVertPos + ps.rcPaint.bottom /
cyChar );
for( iCount = iPaintBeg; iCount <= iPaintEnd; iCount++ )
{
iXCoordinate = cxChar * ( 1 - iHorzPos );
iYCoordinate = cyChar * ( iCount - iVertPos );
TextOut( hdc, iXCoordinate, iYCoordinate,
sysmetrics[ iCount ].szLabel,
lstrlen( sysmetrics[ iCount ].szLabel ) );
TextOut( hdc, iXCoordinate + 22 * cxCaps,
iYCoordinate,
sysmetrics[ iCount ].szDesc,
lstrlen( sysmetrics[ iCount ].szDesc ) );
TextOut( hdc, iXCoordinate + 22 * cxCaps + 40 *
cxChar, iYCoordinate,
szBuffer, wsprintf( szBuffer, TEXT("%5d"),
GetSystemMetrics( sysmetrics[ iCount ].index ) ) );
}
EndPaint( hwnd, &ps );
return 0;
}
//QUIT PROGRAM
case WM_DESTROY:
{
PostQuitMessage( 0 );
return 0;
}
default:
break;
}
return DefWindowProc( hwnd, message, wParam, lParam );
}