滾動條 一

/* 滾動條
 *
 * 系統函數:
 *     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中的參數 
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章