/* 滾動條
*
* 系統函數:
* SetScrollRange(hwnd, iBar, iMin, iMax, bRedraw); 設置滾動條範圍
* GetScrollRange
* SetScrollPos(hwnd, iBar, iPos, bRedraw); 指定滾動條滑塊的位置
* GetScrollPos
*
* 系統消息
* WM_VSCROLL wParam 低位字代表滾動條動作
* WM_HSCROLL
*/
#include "stdafx.h"
#include "HelloWnd.h"
/*
// 注意定義的結構方式
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")
};
*/
#include "SysMets.h" // 將以上結構移到頭文件中
LRESULT CALLBACK HelloWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static int cxClient, cyClient; // 客戶端的寬度和高度,在窗口發生變化的時候,windows都會發送WM_SIZE消息,該消息的lParam高位保存高度,地位保存寬度
static int cxLowercaseWidth, cxUppercaseWidth;
static int cyCharHight;
TEXTMETRIC tm;
HDC hdc;
PAINTSTRUCT ps;
static int nVScrollPos = 0;
int y = 0;
switch(uMsg)
{
case WM_CREATE:
{
hdc = GetDC(hwnd); // 在非WM_PAINT消息裏面調用此方法獲得HDC
GetTextMetrics(hdc, &tm);
ReleaseDC(hwnd, hdc);
cyCharHight = tm.tmHeight + tm.tmExternalLeading;
cxLowercaseWidth = tm.tmAveCharWidth;
cxUppercaseWidth = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxLowercaseWidth / 2;
// 設置滾動條範圍
SetScrollRange(hwnd, SB_VERT, 0, NUMLINES-1, FALSE);
// 設置滾動條位置
SetScrollPos(hwnd, SB_VERT, nVScrollPos, FALSE);
}
break;
case WM_VSCROLL: // 水平滾動條消息
{
switch(LOWORD(wParam)) // 低字位代表滾動條動作
{
case SB_LINEUP:
nVScrollPos -= 1;
break;
case SB_LINEDOWN:
nVScrollPos += 1;
break;
case SB_PAGEUP: // 一頁
nVScrollPos -= cyClient/ cyCharHight;
break;
case SB_PAGEDOWN:
nVScrollPos += cyClient / cyCharHight;
break;
case SB_THUMBPOSITION:
nVScrollPos = HIWORD(wParam);
break;
}
nVScrollPos = max(0, min(nVScrollPos, NUMLINES -1));
if(nVScrollPos != GetScrollPos(hwnd, SB_VERT))
{
SetScrollPos(hwnd, SB_VERT, nVScrollPos, TRUE);
InvalidateRect(hwnd, NULL, TRUE);
}
}
break;
case WM_PAINT:
{
hdc = BeginPaint(hwnd, &ps); // WM_PAINT 消息裏面使用該方法獲得HDC
// 繪製文本
for(int i = 0; i<NUMLINES; i++)
{
y = (i - nVScrollPos) * cyCharHight;
TextOut(hdc, 0, y,sysmetrics[i].szLabel, lstrlen(sysmetrics[i].szLabel));
}
EndPaint(hwnd,&ps);
}
break;
case WM_SIZE:
{
// 在窗口每次發生變化的時候,獲取客戶端高度和寬度
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);
}
break;
case WM_CLOSE:
{
if(IDOK == MessageBox(hwnd, _T("是否關閉窗口"), _T("提示"), MB_OK | MB_OKCANCEL))
{
DestroyWindow(hwnd); // 銷燬窗口
}
}
break;
case WM_DESTROY:
{
PostQuitMessage(0); // 發送 WM_CLOSE, 形參 0 將會傳遞給 WPARAM
}
break;
default:
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
return 0;
}
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
// 設計一個窗口類
WNDCLASS wndclass;
wndclass.style = CS_VREDRAW | CS_HREDRAW;
wndclass.lpfnWndProc = HelloWndProc; // 由windows系統調用
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL, MAKEINTRESOURCE(IDI_WINLOGO));
wndclass.hCursor = LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW));
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = _T("hellownd"); // 此處是指定窗口類名稱,用於關聯窗口,CreateWindow第一個參數
// 註冊窗口類
RegisterClass(&wndclass);
// 創建窗口
HWND hwnd = CreateWindow(_T("hellownd"),
_T("hellownd"),
WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL, /*添加了滾動條*/
CW_USEDEFAULT, 0,
CW_USEDEFAULT, 0,
NULL, NULL,
hInstance, NULL); // WM_CREATE
// 顯示窗口
ShowWindow(hwnd, SW_SHOW); // WM_SIZE
// 更新窗口
UpdateWindow(hwnd); // WM_PAINT
// 消息循環
MSG msg;
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
UnregisterClass(_T("hellownd"), hInstance);
return msg.wParam; // 來自與PostQuitMessage中的參數
}
滾動條 一
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.