4、1 字元輸出 4-1 程式 迴圈輸出界面界面 // 4-1_文本輸出.cpp : 定義應用程式的入口點。 // #include "pch.h" #include "framework.h" #include "4-1_文本輸出.h" #define MAX_LOADSTRING 100 #de ...
4、1 字元輸出
4-1 程式
迴圈輸出界面界面
// 4-1_文本輸出.cpp : 定義應用程式的入口點。 // #include "pch.h" #include "framework.h" #include "4-1_文本輸出.h" #define MAX_LOADSTRING 100 #define LINEHEIGHT 15 // 全局變數: HINSTANCE hInst; // 當前實例 WCHAR szTitle[MAX_LOADSTRING]; // 標題欄文本 WCHAR szWindowClass[MAX_LOADSTRING]; // 主視窗類名 // 此代碼模塊中包含的函數的前向聲明: ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // TODO: 在此處放置代碼。 // 初始化全局字元串 LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadStringW(hInstance, IDC_MY41, szWindowClass, MAX_LOADSTRING); MyRegisterClass(hInstance); // 執行應用程式初始化: if (!InitInstance (hInstance, nCmdShow)) { return FALSE; } HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_MY41)); MSG msg; // 主消息迴圈: while (GetMessage(&msg, nullptr, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } return (int) msg.wParam; } // // 函數: MyRegisterClass() // // 目標: 註冊視窗類。 // ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEXW wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MY41)); wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = NULL; // MAKEINTRESOURCEW(IDC_MY41); wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); return RegisterClassExW(&wcex); } // // 函數: InitInstance(HINSTANCE, int) // // 目標: 保存實例句柄並創建主視窗 // // 註釋: // // 在此函數中,我們在全局變數中保存實例句柄並 // 創建和顯示主程式視窗。 // BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { hInst = hInstance; // 將實例句柄存儲在全局變數中 HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr); if (!hWnd) { return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } // // 函數: WndProc(HWND, UINT, WPARAM, LPARAM) // // 目標: 處理主視窗的消息。 // // WM_COMMAND - 處理應用程式菜單 // WM_PAINT - 繪製主視窗 // WM_DESTROY - 發送退出消息並返回 // // LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_COMMAND: { int wmId = LOWORD(wParam); // 分析菜單選擇: switch (wmId) { case IDM_ABOUT: DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } } break; case WM_PAINT: { TCHAR szBuffer[1024]; PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps); // TODO: 在此處添加使用 hdc 的任何繪圖代碼... for (int i = 0; i < 100; ++i) { _sntprintf(szBuffer, 1024, TEXT("文本輸出 %d"), i+1); TextOut(hdc, 0, i*LINEHEIGHT, szBuffer, lstrlen(szBuffer)); } EndPaint(hWnd, &ps); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } // “關於”框的消息處理程式。 INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG: return (INT_PTR)TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; } break; } return (INT_PTR)FALSE; }
4、2 系統字體
4-2 程式
動態計算字體
// 4-2_動態計算字體.cpp : 定義應用程式的入口點。 // #include "pch.h" #include "framework.h" #include "4-2_動態計算字體.h" #define MAX_LOADSTRING 100 // 全局變數: HINSTANCE hInst; // 當前實例 WCHAR szTitle[MAX_LOADSTRING]; // 標題欄文本 WCHAR szWindowClass[MAX_LOADSTRING]; // 主視窗類名 // 此代碼模塊中包含的函數的前向聲明: ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // TODO: 在此處放置代碼。 // 初始化全局字元串 LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadStringW(hInstance, IDC_MY42, szWindowClass, MAX_LOADSTRING); MyRegisterClass(hInstance); // 執行應用程式初始化: if (!InitInstance (hInstance, nCmdShow)) { return FALSE; } HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_MY42)); MSG msg; // 主消息迴圈: while (GetMessage(&msg, nullptr, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } return (int) msg.wParam; } // // 函數: MyRegisterClass() // // 目標: 註冊視窗類。 // ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEXW wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MY42)); wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = NULL;//MAKEINTRESOURCEW(IDC_MY42); wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); return RegisterClassExW(&wcex); } // // 函數: InitInstance(HINSTANCE, int) // // 目標: 保存實例句柄並創建主視窗 // // 註釋: // // 在此函數中,我們在全局變數中保存實例句柄並 // 創建和顯示主程式視窗。 // BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { hInst = hInstance; // 將實例句柄存儲在全局變數中 HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr); if (!hWnd) { return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } // // 函數: WndProc(HWND, UINT, WPARAM, LPARAM) // // 目標: 處理主視窗的消息。 // // WM_COMMAND - 處理應用程式菜單 // WM_PAINT - 繪製主視窗 // WM_DESTROY - 發送退出消息並返回 // // LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { static int cyChar; //字元高度,行高,行間距 static int cxChar;//字元寬度 static int cxCaps; //大寫字元 static int cxScreen, cyScreen; //屏幕的寬高 TCHAR szBuffer[40]; int iLength; TEXTMETRIC tm; PAINTSTRUCT ps; HDC hdc; case WM_CREATE: hdc = GetDC(hWnd); GetTextMetrics(hdc, &tm); //小寫字元的寬度 cxChar = tm.tmAveCharWidth; //小寫字元的高度 + 行間距 cyChar = tm.tmHeight + tm.tmExternalLeading; //大寫字元一般設為小寫字元的1.5倍 或 等寬的字元就和小寫相等 //檢查 低位是 1非等寬字體 0 等寬字體 cxCaps = ((tm.tmPitchAndFamily & 1) ? 3 : 2) * cxChar / 2; //獲取屏幕的寬度 cxScreen = GetSystemMetrics(SM_CXSCREEN); //獲取屏幕的高度 cyScreen = GetSystemMetrics(SM_CYSCREEN); ReleaseDC(hWnd, hdc); break; case WM_COMMAND: { int wmId = LOWORD(wParam); // 分析菜單選擇: switch (wmId) { case IDM_ABOUT: DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } } break; case WM_PAINT: { hdc = BeginPaint(hWnd, &ps); // TODO: 在此處添加使用 hdc 的任何繪圖代碼... //顯示屏幕寬度 TextOut(hdc, 0, 0, TEXT("SM_CXSCREEN"), lstrlen(TEXT("SM_CXSCREEN"))); //寬度describe TextOut(hdc, 22*cxCaps, 0, TEXT("Screen width in pixels"), lstrlen(TEXT("Screen width in pixels"))); //對齊方式 SetTextAlign(hdc,TA_RIGHT | TA_TOP); iLength = _sntprintf(szBuffer, 40, TEXT("%d"), cxScreen); TextOut(hdc, 22 * cxCaps + 40 * cxChar, 0, szBuffer, iLength); //對齊方式 SetTextAlign(hdc, TA_LEFT | TA_TOP); //顯示屏幕高度 TextOut(hdc, 0, cyChar, TEXT("SM_CYSCREEN"), lstrlen(TEXT("SM_CYSCREEN"))); //高度describe TextOut(hdc, 22 * cxCaps, cyChar, TEXT("Screen height in pixels"), lstrlen(TEXT("Screen height in pixels"))); //對齊方式 SetTextAlign(hdc, TA_RIGHT | TA_TOP); iLength = _sntprintf(szBuffer, 40, TEXT("%d"), cyScreen); TextOut(hdc, 22 * cxCaps + 40 * cxChar, cyChar, szBuffer, iLength); //對齊方式 SetTextAlign(hdc, TA_LEFT | TA_TOP); EndPaint(hWnd, &ps); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } // “關於”框的消息處理程式。 INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG: return (INT_PTR)TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; } break; } return (INT_PTR)FALSE; }
4、3 滾動條
4-3 程式
滾動條。(下麵自動創建的代碼中不需要的代碼已刪)
// 4-3_滾動條.cpp : 定義應用程式的入口點。 // #include "pch.h" #include "framework.h" #include "4-3_滾動條.h" #define MAX_LOADSTRING 100 #define MAX_LINE 200 // 全局變數: HINSTANCE hInst; // 當前實例 WCHAR szTitle[MAX_LOADSTRING]; // 標題欄文本 WCHAR szWindowClass[MAX_LOADSTRING]; // 主視窗類名 // 此代碼模塊中包含的函數的前向聲明: ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // TODO: 在此處放置代碼。 // 初始化全局字元串 LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadStringW(hInstance, IDC_MY43, szWindowClass, MAX_LOADSTRING); MyRegisterClass(hInstance); // 執行應用程式初始化: if (!InitInstance (hInstance, nCmdShow)) { return FALSE; } HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_MY43)); MSG msg; // 主消息迴圈: while (GetMessage(&msg, nullptr, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } return (int) msg.wParam; } // // 函數: MyRegisterClass() // // 目標: 註冊視窗類。 // ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEXW wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MY43)); wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = NULL;// MAKEINTRESOURCEW(IDC_MY43); wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); return RegisterClassExW(&wcex); } // // 函數: InitInstance(HINSTANCE, int) // // 目標: 保存實例句柄並創建主視窗 // // 註釋: // // 在此函數中,我們在全局變數中保存實例句柄並 // 創建和顯示主程式視窗。 // BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { hInst = hInstance; // 將實例句柄存儲在全局變數中 HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW | WS_VSCROLL, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr); if (!hWnd) { return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } // // 函數: WndProc(HWND, UINT, WPARAM, LPARAM) // // 目標: 處理主視窗的消息。 // // WM_COMMAND - 處理應用程式菜單 // WM_PAINT - 繪製主視窗 // WM_DESTROY - 發送退出消息並返回 // // LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { PAINTSTRUCT ps; HDC hdc; static int cyChar; //字體高度 int x, y; //文字顯示坐標 static int iVscrollPos; //滾動條位置 static int cyClient; //客戶區 TEXTMETRIC tm; SCROLLINFO si; case WM_SIZE: cyClient = HIWORD(lParam); //調整視窗大小,參數中可獲取高度 si.cbSize = sizeof(si); si.fMask = SIF_RANGE | SIF_PAGE ; si.nMin = 0; si.nMax = MAX_LINE - 1; si.nPage = cyClient / cyChar; SetScrollInfo(hWnd,SB_VERT,&si,TRUE); break; case WM_CREATE: hdc = GetDC(hWnd); GetTextMetrics(hdc,&tm); //文本度量 cyChar = tm.tmHeight + tm.tmExternalLeading; //文字高度 + 行間距 ReleaseDC(hWnd,hdc); iVscrollPos = 0; //滾動條的初始值 SetScrollRange(hWnd,SB_VERT,0,MAX_LINE-1,FALSE); //設置滾動條範圍 SetScrollPos(hWnd,SB_VERT,iVscrollPos,TRUE); //設置位置 return 0; case WM_PAINT: { hdc = BeginPaint(hWnd, &ps); // TODO: 在此處添加使用 hdc 的任何繪圖代碼... TCHAR szBuffer[1024]; //字元緩衝區 for (int i = 0; i < MAX_LINE; i++) { x = 0; //水平垂直坐標 y =cyChar *(i - iVscrollPos); //垂直繪製坐標 _snwprintf(szBuffer, 1024, TEXT("滾動條 %d"), i+1); //格式轉化 TextOut(hdc, x, y, szBuffer, lstrlen(szBuffer)); //文本輸出 } EndPaint(hWnd, &ps); } break; case WM_VSCROLL: switch (LOWORD(wParam)) { case SB_LINEUP: //按鈕上 iVscrollPos -= 1; break; case SB_LINEDOWN: //按鈕下 iVscrollPos+= 1; break; case SB_PAGEDOWN: iVscrollPos += cyClient / cyChar; //點擊下一頁 break; case SB_PAGEUP: iVscrollPos -= cyClient / cyChar; //點擊上一頁 break; case SB_THUMBPOSITION: //拖動滑鼠 iVscrollPos = HIWORD(wParam); //移動是獲取位置 default: break; } iVscrollPos = max(0, min(iVscrollPos, MAX_LINE - 1)); //設置範圍 if (iVscrollPos != GetScrollPos(hWnd, SB_VERT)) //當前位置和實際位置比較 { SetScrollPos(hWnd, SB_VERT, iVscrollPos, TRUE); //重新設置位置 InvalidateRect(hWnd,NULL,TRUE); //重新繪製視窗 } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }
5、例子
用上面你的函數做一個例子。
// 4_4_例子Sysmets.cpp : 定義應用程式的入口點。 // #include "pch.h" #include "framework.h" #include "4_4_例子Sysmets.h" #include "data.h" #define MAX_LOADSTRING 100 // 全局變數: HINSTANCE hInst; // 當前實例 WCHAR szTitle[MAX_LOADSTRING]; // 標題欄文本 WCHAR szWindowClass[MAX_LOADSTRING]; // 主視窗類名 // 此代碼模塊中包含的函數的前向聲明: ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // TODO: 在此處放置代碼。 // 初始化全局字元串 LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadStringW(hInstance, IDC_MY44SYSMETS, szWindowClass, MAX_LOADSTRING); MyRegisterClass(hInstance); // 執行應用程式初始化: if (!InitInstance (hInstance, nCmdShow)) { return FALSE; } HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_MY44SYSMETS)); MSG msg; // 主消息迴圈: while (GetMessage(&msg, nullptr, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } return (int) msg.wParam; } // // 函數: MyRegisterClass() // // 目標: 註冊視窗類。 // ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEXW wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MY44SYSMETS)); wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = NULL;//MAKEINTRESOURCEW(IDC_MY44SYSMETS); wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));