|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
- // ScrollWindow.cpp : 定义应用程序的入口点。
- //
- #include "stdafx.h"
- #include "ScrollWindow.h"
- #include "strsafe.h"
- #define MAX_LOADSTRING 100
- // 全局变量:
- HINSTANCE hInst; // 当前实例
- TCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本
- TCHAR 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 _tWinMain(HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- LPTSTR lpCmdLine,
- int nCmdShow)
- {
- UNREFERENCED_PARAMETER(hPrevInstance);
- UNREFERENCED_PARAMETER(lpCmdLine);
- // TODO: 在此放置代码。
- MSG msg;
- HACCEL hAccelTable;
- // 初始化全局字符串
- LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
- LoadString(hInstance, IDC_SCROLLWINDOW, szWindowClass, MAX_LOADSTRING);
- MyRegisterClass(hInstance);
- // 执行应用程序初始化:
- if (!InitInstance (hInstance, nCmdShow))
- {
- return FALSE;
- }
- hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_SCROLLWINDOW));
- // 主消息循环:
- while (GetMessage(&msg, NULL, 0, 0))
- {
- if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- }
- return (int) msg.wParam;
- }
- //
- // 函数: MyRegisterClass()
- //
- // 目的: 注册窗口类。
- //
- // 注释:
- //
- // 仅当希望
- // 此代码与添加到 Windows 95 中的“RegisterClassEx”
- // 函数之前的 Win32 系统兼容时,才需要此函数及其用法。调用此函数十分重要,
- // 这样应用程序就可以获得关联的
- // “格式正确的”小图标。
- //
- ATOM MyRegisterClass(HINSTANCE hInstance)
- {
- WNDCLASSEX 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_SCROLLWINDOW));
- wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
- wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
- wcex.lpszMenuName = MAKEINTRESOURCE(IDC_SCROLLWINDOW);
- wcex.lpszClassName = szWindowClass;
- wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
- return RegisterClassEx(&wcex);
- }
- //
- // 函数: InitInstance(HINSTANCE, int)
- //
- // 目的: 保存实例句柄并创建主窗口
- //
- // 注释:
- //
- // 在此函数中,我们在全局变量中保存实例句柄并
- // 创建和显示主程序窗口。
- //
- BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
- {
- HWND hWnd;
- hInst = hInstance; // 将实例句柄存储在全局变量中
- hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW | WS_VSCROLL |WS_HSCROLL,
- CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
- 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)
- {
- HDC hdc;
- PAINTSTRUCT ps;
- TEXTMETRIC tm;
- SCROLLINFO si;
- static int xClient;
- static int yClient;
- static int xClientMax;
- static int xChar;
- static int yChar;
- static int xUpper;
- static int xPos;
- static int yPos;
- int i;
- int x,y;
- int FirstLine;
- int LastLine;
- HRESULT hr;
- size_t abcLength;
- #define LINES 28
- static TCHAR *abc[]={
- TEXT("anteater"), TEXT("bear"), TEXT("cougar"),
- TEXT("dingo"), TEXT("elephant"), TEXT("falcon"),
- TEXT("gazelle"), TEXT("hyena"), TEXT("iguana"),
- TEXT("jackal"), TEXT("kangaroo"), TEXT("llama"),
- TEXT("moose"), TEXT("newt"), TEXT("octopus"),
- TEXT("penguin"), TEXT("quail"), TEXT("rat"),
- TEXT("squid"), TEXT("tortoise"), TEXT("urus"),
- TEXT("vole"), TEXT("walrus"), TEXT("xylophone"),
- TEXT("yak"), TEXT("zebra"),
- TEXT("This line contains words, but no character. Go figure."),
- TEXT("")
- };
- switch(message)
- {
- case WM_CREATE:
- hdc=GetDC(hwnd);
- GetTextMetrics(hdc,&tm);
- xChar=tm.tmAveCharWidth;
- yChar=tm.tmHeight+tm.tmExternalLeading;
- xUpper=(tm.tmPitchAndFamily & 1 ?3 :2)*xChar/2;
- ReleaseDC(hwnd,hdc);
- xClientMax=48*xChar+12*xUpper;
- break;
- case WM_SIZE:
- yClient = HIWORD(lParam);
- xClient = LOWORD(lParam);
- si.cbSize = sizeof(si);
- si.fMask = SIF_RANGE | SIF_PAGE;
- si.nMin = 0;
- si.nMax = 2+xClientMax/xChar;
- si.nPage= xClient /xChar;
- SetScrollInfo(hwnd,SB_HORZ,&si,TRUE);
- break;
- case WM_HSCROLL:
- si.cbSize =sizeof(si);
- si.fMask = SIF_ALL;
- GetScrollInfo(hwnd,SB_HORZ,&si);
- xPos = si.nPos;
- switch(LOWORD(wParam))
- {
- 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_THUMBTRACK:
- si.nPos = si.nTrackPos;
- break;
- default:
- break;
- }
- si.fMask = SIF_POS;
- SetScrollInfo(hwnd,SB_HORZ,&si,FALSE);
- GetScrollInfo(hwnd,SB_HORZ,&si);
- //如果相同,则不改,如果不同,则改变
- if(si.nPos != xPos)
- {
- ScrollWindow(hwnd,xChar*(xPos-si.nPos),0,NULL,NULL);
- }
- return 0;
- case WM_VSCROLL:
- // 获得垂直滚动条的所有信息
- si.cbSize = sizeof (si);
- si.fMask = SIF_ALL;
- GetScrollInfo(hwnd, SB_VERT, &si);
- // 保存当前滑块位置,迟些进行比较
- yPos = si.nPos;
- switch (LOWORD(wParam))
- {
- // 用户点击键盘 Home 按键
- case SB_TOP:
- si.nPos = si.nMin;
- break;
- // 用户点击键盘 End 按键
- 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;
- }
- // 设置滚动条滑块的新位置
- si.fMask = SIF_POS;
- SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
- // 获得滚动条滑块的位置,由于窗口调整,它可能不是同一个值
- GetScrollInfo(hwnd, SB_VERT, &si);
- // 与此前的保存的值进行比较,如果不同则滚动窗口
- if (si.nPos != yPos)
- {
- ScrollWindow(hwnd, 0, yChar * (yPos - si.nPos), NULL, NULL);
- UpdateWindow(hwnd);
- }
- return 0;
- case WM_PAINT:
- hdc=BeginPaint(hwnd,&ps);
- si.cbSize =sizeof(si);
- si.fMask =SIF_POS;
- GetScrollInfo(hwnd,SB_VERT,&si);
- yPos= si.nPos;
- GetScrollInfo(hwnd,SB_HORZ,&si);
- xPos= si.nPos;
- //当前滑块移动的位置和已经绘制的top坐标相加下同
- FirstLine = max(0,yPos + ps.rcPaint.top/yChar);
- LastLine = min(LINES-1,yPos+ps.rcPaint.bottom/yChar);
- for(i=FirstLine;i<=LastLine;i++)
- {
- x=xChar * (1-xPos);
- y=yChar * (i-yPos);
-
- hr = StringCchLength(abc[i],55,&abcLength);
- if((FAILED(hr)) | (abcLength == NULL))
- {
-
-
- }
- TextOut(hdc, x, y, abc[i], abcLength);
- }
- EndPaint(hwnd, &ps);
- return 0;
- case WM_DESTROY:
- PostQuitMessage(0);
- return 0;
- }
- return DefWindowProc(hwnd, message, wParam, lParam);
- }
复制代码
学习笔记:
第一个是SCROLlINFO结构 传送门: https://fishc.com.cn/forum.php?m ... peid%26typeid%3D420
第二个是函数SetScrollInfo 传送门: https://fishc.com.cn/forum.php?m ... peid%26typeid%3D420
第三个是PAINTSTRUCT结构 传送门: https://fishc.com.cn/forum.php?m ... peid%26typeid%3D420
第四个是TextOut函数。该函数
TextOut(1,2,3,4,5)
1.句柄指针,通常默认固定填写hwnd
2.在客户区的逻辑坐标 应该是客户区还是屏幕的坐标。我觉得是客户区。你们看看,底下告诉我对不对。
3.同2
4.打印的字符串
5.字符串个数
5.1一般通常使用StringCchLength(szBuffer,128,&iTarget) 一般和StringCchPrint组合使用。传送门:https://fishc.com.cn/forum.php?m ... peid%26typeid%3D420 |
|