16,472
社区成员
发帖
与我相关
我的任务
分享
#include "stdafx.h"
#include "SYSMETS1.h"
LRESULT CALLBACK WndProc(HWND hWnd,UINT msg, WPARAM wp,LPARAM lp);
int WINAPI WinMain(__in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in_opt LPSTR lpCmdLine, __in int nShowCmd)
{
static TCHAR szAppName[] = _T("SysMets1");
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
wndclass.style = CS_HREDRAW|CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
// load the icon of application
wndclass.hIcon = ::LoadIcon(NULL,IDI_APPLICATION);
// load the cursor of application
wndclass.hCursor = ::LoadCursor(NULL,IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;
// register the window class
if (!::RegisterClass(&wndclass))
{
::MessageBox(NULL,TEXT("This program require Window NT"),szAppName,MB_ICONERROR);
return 0;
}
// create really window
hwnd = ::CreateWindow(szAppName,_T("Get System Metric No.1"),WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,
CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL);
::ShowWindow(hwnd,nShowCmd);
::UpdateWindow(hwnd); // immedially post WM_PAINT message
// when get the meaages,translte the message and dispatch message.
while (::GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd,UINT message, WPARAM wp,LPARAM lp)
{
static int cxChar;
static int cxCaps;
static int cyChar;
static int cyClient; // the height of client
static int cxClient; // the width of client
static int nPaintBeg;
static int nPaintEnd;
static int nMaxWidth;
int nVertPos = 0;
int nHorzPos = 0;
SCROLLINFO si;
HDC hdc = NULL;
PAINTSTRUCT ps;
TCHAR szBuffer[10];
TEXTMETRIC tm;
switch (message)
{
case WM_CREATE:
{
hdc = ::GetDC(hWnd);
::GetTextMetrics(hdc,&tm); // get text size of system
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,nVscrollPos,TRUE);
// save the width of three columns
nMaxWidth = 40*cxChar+22*cxCaps;
return 0;
}
case WM_SIZE:
{
// cyClient = HIWORD(lp); // get the height of client
// save the width and height of window when changed the size of window
cxClient = LOWORD(lp);
cyClient = HIWORD(lp);
// set vertical scroll bar range and page size
si.cbSize = sizeof(SCROLLBARINFO);
si.fMask = SIF_RANGE|SIF_PAGE;
si.nMin = 0;
si.nMax = NUMLINES - 1;
si.nPage = cyClient/cyChar;
SetScrollInfo(hWnd,SB_VERT,&si,TRUE);
// set horizontal scroll bar and page size
si.cbSize = sizeof(SCROLLBARINFO);
si.fMask = SIF_RANGE|SIF_PAGE;
si.nMin = 0;
si.nMax = 2 + nMaxWidth/cxChar;
si.nPage = cxClient/cxChar;
SetScrollInfo(hWnd,SB_HORZ,&si,TRUE);
return 0;
}
case WM_VSCROLL:
{
// get all vertical scroll bar information
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_ALL;
::GetScrollInfo(hWnd,SB_VERT,&si);
// save the position for comparison later on
nVertPos = si.nPos;
switch (LOWORD(wp))
{
case SB_LINEUP:
{
si.nPos -=1;// the height decrease 1 unit
break;
}
case SB_LINEDOWN:
{
si.nPos +=1;// the height increase 1 unit
break;
}
case SB_PAGEUP:
{
// back to prev page, the cyClient/cyChar is the number of row in one page
si.nPos -= cyClient/cyChar;
break;
}
case SB_PAGEDOWN:
{
// back to next page
si.nPos += cyClient/cyChar;
break;
}
case SB_THUMBPOSITION:
{
si.nPos = HIWORD(wp);
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 update it
if (si.nPos!=nVertPos)
{
::ScrollWindow(hWnd,0,cyChar*(nVertPos-si.nPos),NULL,NULL);
::UpdateWindow(hWnd);
}
return 0;
}
case WM_HSCROLL:
{
// get all the vertical scroll bar information
si.cbSize = sizeof(si);
si.fMask = SIF_ALL;
// save the position for comparison later on
::GetScrollInfo(hWnd,SB_HORZ,&si);
nHorzPos = si.nPos;
switch (LOWORD(wp))
{
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;
}
// 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_HORZ,&si,TRUE);
::GetScrollInfo(hWnd,SB_HORZ,&si);
// if the postion has changed ,scroll the window
if (si.nPos!=nHorzPos)
{
// why (nHorzPos-si.nPos)
::ScrollWindow(hWnd,cxChar*(nHorzPos-si.nPos),0,NULL,NULL);
}
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);
nVertPos = si.nPos;
// get horizontal scroll bar position
GetScrollInfo(hWnd,SB_HORZ,&si);
nHorzPos = si.nPos;
// find painting limits
int nPaintBeg = max(0,nVertPos+ps.rcPaint.top/cyChar); // the begin row
int nPaintEnd = min(NUMLINES-1,nVertPos+ps.rcPaint.bottom/cyChar); // the end row
for (int i =nPaintBeg;i<=nPaintEnd;i++)
{
// calculate the y position of draw region, when y position less 0,skip
int x = cxChar*(1-nHorzPos); // why is 1-nHorzPos
int y = cyChar*(i-nVertPos);
::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,_T("%5d"),::GetSystemMetrics(sysmetrics[i].Index)));
::SetTextAlign(hdc,TA_LEFT|TA_TOP);
}
::EndPaint(hWnd,&ps);
return 0;
}
case WM_DESTROY:
// close the application
::PostQuitMessage(0);
return 0;
default:
break;
}
// default process
return ::DefWindowProc(hWnd,message,wp,lp);
}
if (si.nPos!=nHorzPos)
{
// why (nHorzPos-si.nPos)
::ScrollWindow(hWnd,cxChar*(nHorzPos-si.nPos),0,NULL,NULL);
}