鱼C论坛

 找回密码
 立即注册
查看: 1994|回复: 0

[技术交流] windows 官方例子滚动条

[复制链接]
发表于 2019-10-10 11:48:18 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
  1. // ScrollWindow.cpp : 定义应用程序的入口点。
  2. //

  3. #include "stdafx.h"
  4. #include "ScrollWindow.h"
  5. #include "strsafe.h"
  6. #define MAX_LOADSTRING 100

  7. // 全局变量:
  8. HINSTANCE hInst;                                                                // 当前实例
  9. TCHAR szTitle[MAX_LOADSTRING];                                        // 标题栏文本
  10. TCHAR szWindowClass[MAX_LOADSTRING];                        // 主窗口类名

  11. // 此代码模块中包含的函数的前向声明:
  12. ATOM                                MyRegisterClass(HINSTANCE hInstance);
  13. BOOL                                InitInstance(HINSTANCE, int);
  14. LRESULT CALLBACK        WndProc(HWND, UINT, WPARAM, LPARAM);
  15. INT_PTR CALLBACK        About(HWND, UINT, WPARAM, LPARAM);

  16. int APIENTRY _tWinMain(HINSTANCE hInstance,
  17.                      HINSTANCE hPrevInstance,
  18.                      LPTSTR    lpCmdLine,
  19.                      int       nCmdShow)
  20. {
  21.         UNREFERENCED_PARAMETER(hPrevInstance);
  22.         UNREFERENCED_PARAMETER(lpCmdLine);

  23.         // TODO: 在此放置代码。
  24.         MSG msg;
  25.         HACCEL hAccelTable;

  26.         // 初始化全局字符串
  27.         LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
  28.         LoadString(hInstance, IDC_SCROLLWINDOW, szWindowClass, MAX_LOADSTRING);
  29.         MyRegisterClass(hInstance);

  30.         // 执行应用程序初始化:
  31.         if (!InitInstance (hInstance, nCmdShow))
  32.         {
  33.                 return FALSE;
  34.         }

  35.         hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_SCROLLWINDOW));

  36.         // 主消息循环:
  37.         while (GetMessage(&msg, NULL, 0, 0))
  38.         {
  39.                 if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
  40.                 {
  41.                         TranslateMessage(&msg);
  42.                         DispatchMessage(&msg);
  43.                 }
  44.         }

  45.         return (int) msg.wParam;
  46. }



  47. //
  48. //  函数: MyRegisterClass()
  49. //
  50. //  目的: 注册窗口类。
  51. //
  52. //  注释:
  53. //
  54. //    仅当希望
  55. //    此代码与添加到 Windows 95 中的“RegisterClassEx”
  56. //    函数之前的 Win32 系统兼容时,才需要此函数及其用法。调用此函数十分重要,
  57. //    这样应用程序就可以获得关联的
  58. //    “格式正确的”小图标。
  59. //
  60. ATOM MyRegisterClass(HINSTANCE hInstance)
  61. {
  62.         WNDCLASSEX wcex;

  63.         wcex.cbSize = sizeof(WNDCLASSEX);

  64.         wcex.style                        = CS_HREDRAW | CS_VREDRAW;
  65.         wcex.lpfnWndProc        = WndProc;
  66.         wcex.cbClsExtra                = 0;
  67.         wcex.cbWndExtra                = 0;
  68.         wcex.hInstance                = hInstance;
  69.         wcex.hIcon                        = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SCROLLWINDOW));
  70.         wcex.hCursor                = LoadCursor(NULL, IDC_ARROW);
  71.         wcex.hbrBackground        = (HBRUSH)(COLOR_WINDOW+1);
  72.         wcex.lpszMenuName        = MAKEINTRESOURCE(IDC_SCROLLWINDOW);
  73.         wcex.lpszClassName        = szWindowClass;
  74.         wcex.hIconSm                = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

  75.         return RegisterClassEx(&wcex);
  76. }

  77. //
  78. //   函数: InitInstance(HINSTANCE, int)
  79. //
  80. //   目的: 保存实例句柄并创建主窗口
  81. //
  82. //   注释:
  83. //
  84. //        在此函数中,我们在全局变量中保存实例句柄并
  85. //        创建和显示主程序窗口。
  86. //
  87. BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
  88. {
  89.    HWND hWnd;

  90.    hInst = hInstance; // 将实例句柄存储在全局变量中

  91.    hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW | WS_VSCROLL |WS_HSCROLL,
  92.       CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

  93.    if (!hWnd)
  94.    {
  95.       return FALSE;
  96.    }

  97.    ShowWindow(hWnd, nCmdShow);
  98.    UpdateWindow(hWnd);

  99.    return TRUE;
  100. }

  101. //
  102. //  函数: WndProc(HWND, UINT, WPARAM, LPARAM)
  103. //
  104. //  目的: 处理主窗口的消息。
  105. //
  106. //  WM_COMMAND        - 处理应用程序菜单
  107. //  WM_PAINT        - 绘制主窗口
  108. //  WM_DESTROY        - 发送退出消息并返回
  109. //
  110. //
  111. LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
  112. {
  113.       HDC hdc;
  114.           PAINTSTRUCT ps;
  115.           TEXTMETRIC tm;
  116.           SCROLLINFO  si;

  117.           static int xClient;
  118.           static int yClient;
  119.           static int xClientMax;

  120.           static int xChar;
  121.           static int yChar;
  122.           static int xUpper;

  123.           static int xPos;
  124.           static int yPos;

  125.           int i;
  126.           int x,y;

  127.           int FirstLine;
  128.           int LastLine;
  129.           HRESULT hr;
  130.           size_t abcLength;

  131.       #define LINES 28
  132.           static TCHAR *abc[]={
  133.                 TEXT("anteater"), TEXT("bear"), TEXT("cougar"),
  134.                 TEXT("dingo"), TEXT("elephant"), TEXT("falcon"),
  135.                 TEXT("gazelle"), TEXT("hyena"), TEXT("iguana"),
  136.                 TEXT("jackal"), TEXT("kangaroo"), TEXT("llama"),
  137.                 TEXT("moose"), TEXT("newt"), TEXT("octopus"),
  138.                 TEXT("penguin"), TEXT("quail"), TEXT("rat"),
  139.                 TEXT("squid"), TEXT("tortoise"), TEXT("urus"),
  140.                 TEXT("vole"), TEXT("walrus"), TEXT("xylophone"),
  141.                 TEXT("yak"), TEXT("zebra"),
  142.                 TEXT("This line contains words, but no character. Go figure."),
  143.                 TEXT("")
  144.                    };
  145.                 switch(message)
  146.             {
  147.               case WM_CREATE:
  148.                hdc=GetDC(hwnd);
  149.                            GetTextMetrics(hdc,&tm);

  150.                            xChar=tm.tmAveCharWidth;
  151.                            yChar=tm.tmHeight+tm.tmExternalLeading;
  152.                            xUpper=(tm.tmPitchAndFamily & 1 ?3 :2)*xChar/2;

  153.                            ReleaseDC(hwnd,hdc);

  154.                            xClientMax=48*xChar+12*xUpper;
  155.                break;
  156.                          case WM_SIZE:

  157.                           yClient = HIWORD(lParam);
  158.                           xClient = LOWORD(lParam);

  159.                           si.cbSize = sizeof(si);
  160.                           si.fMask = SIF_RANGE | SIF_PAGE;

  161.                           si.nMin = 0;
  162.                           si.nMax = 2+xClientMax/xChar;
  163.                           si.nPage= xClient /xChar;

  164.                           SetScrollInfo(hwnd,SB_HORZ,&si,TRUE);

  165.                           break;
  166.              case WM_HSCROLL:
  167.                           si.cbSize =sizeof(si);
  168.                           si.fMask = SIF_ALL;
  169.                           GetScrollInfo(hwnd,SB_HORZ,&si);

  170.                           xPos = si.nPos;
  171.                           switch(LOWORD(wParam))
  172.                           {

  173.                                   case SB_LINELEFT:
  174.                                           si.nPos -=1;
  175.                                           break;

  176.                                   case SB_LINERIGHT:
  177.                                           si.nPos+=1;
  178.                                           break;

  179.                                   case SB_PAGELEFT:
  180.                                           si.nPos-=si.nPage;
  181.                                           break;

  182.                                   case SB_PAGERIGHT:
  183.                                           si.nPos+=si.nPage;
  184.                                           break;
  185.                                   
  186.                                   case SB_THUMBTRACK:
  187.                                           si.nPos = si.nTrackPos;
  188.                                           break;
  189.                                   default:
  190.                                           break;

  191.                        }

  192.                           si.fMask  =  SIF_POS;
  193.                           SetScrollInfo(hwnd,SB_HORZ,&si,FALSE);

  194.                           GetScrollInfo(hwnd,SB_HORZ,&si);
  195.                      //如果相同,则不改,如果不同,则改变
  196.                           if(si.nPos != xPos)
  197.                           {
  198.                                  ScrollWindow(hwnd,xChar*(xPos-si.nPos),0,NULL,NULL);
  199.                           }
  200.                           return 0;
  201.          case WM_VSCROLL:
  202.                 // 获得垂直滚动条的所有信息
  203.                si.cbSize = sizeof (si);
  204.                si.fMask = SIF_ALL;
  205.                GetScrollInfo(hwnd, SB_VERT, &si);

  206.                 // 保存当前滑块位置,迟些进行比较
  207.                yPos = si.nPos;
  208.                switch (LOWORD(wParam))
  209.                {
  210.                         // 用户点击键盘 Home 按键
  211.                                    case SB_TOP:
  212.                                                   si.nPos = si.nMin;
  213.                                                         break;

  214.                                                         // 用户点击键盘 End 按键
  215.                                    case SB_BOTTOM:
  216.                                                         si.nPos = si.nMax;
  217.                                                         break;

  218.                                                         // 用户点击滚动条上边的三角形
  219.                                    case SB_LINEUP:
  220.                                                         si.nPos -= 1;
  221.                                                         break;

  222.                                                         // 用户点击滚动条下边的三角形
  223.                                    case SB_LINEDOWN:
  224.                                                         si.nPos += 1;
  225.                                                         break;

  226.                                                         // 用户点击滑块上边的滚动条轴
  227.                                    case SB_PAGEUP:
  228.                                                         si.nPos -= si.nPage;
  229.                                                         break;

  230.                                                         // 用户点击滑块下边的滚动条轴
  231.                                    case SB_PAGEDOWN:
  232.                                                         si.nPos += si.nPage;
  233.                                                         break;

  234.                                                         // 用户拖动滚动条
  235.                                    case SB_THUMBTRACK:
  236.                                                         si.nPos = si.nTrackPos;
  237.                                                         break;

  238.                                    default:
  239.                                                     break;
  240.                                 }

  241.                 // 设置滚动条滑块的新位置
  242.                 si.fMask = SIF_POS;
  243.                 SetScrollInfo(hwnd, SB_VERT, &si, TRUE);

  244.                 // 获得滚动条滑块的位置,由于窗口调整,它可能不是同一个值
  245.                 GetScrollInfo(hwnd, SB_VERT, &si);

  246.                 // 与此前的保存的值进行比较,如果不同则滚动窗口
  247.                 if (si.nPos != yPos)
  248.                 {
  249.                         ScrollWindow(hwnd, 0, yChar * (yPos - si.nPos), NULL, NULL);
  250.                         UpdateWindow(hwnd);
  251.                 }

  252.                 return 0;
  253.          case WM_PAINT:
  254.                            hdc=BeginPaint(hwnd,&ps);

  255.                            si.cbSize  =sizeof(si);
  256.                            si.fMask  =SIF_POS;
  257.                            GetScrollInfo(hwnd,SB_VERT,&si);
  258.                            yPos= si.nPos;


  259.                            GetScrollInfo(hwnd,SB_HORZ,&si);
  260.                            xPos=  si.nPos;

  261.                                     //当前滑块移动的位置和已经绘制的top坐标相加下同
  262.                            FirstLine  = max(0,yPos + ps.rcPaint.top/yChar);
  263.                            LastLine   = min(LINES-1,yPos+ps.rcPaint.bottom/yChar);

  264.                            for(i=FirstLine;i<=LastLine;i++)
  265.                            {
  266.                                         x=xChar * (1-xPos);
  267.                                         y=yChar * (i-yPos);
  268.                            
  269.                                         hr =  StringCchLength(abc[i],55,&abcLength);
  270.                                         if((FAILED(hr)) |  (abcLength == NULL))
  271.                                         {
  272.                                        
  273.                                        
  274.                                         }
  275.                                         TextOut(hdc, x, y, abc[i], abcLength);
  276.                                  }

  277.                                         EndPaint(hwnd, &ps);
  278.                                         return 0;                    

  279.            case WM_DESTROY:
  280.                                         PostQuitMessage(0);
  281.                                         return 0;
  282.         }

  283.         return DefWindowProc(hwnd, message, wParam, lParam);
  284. }

复制代码



学习笔记:
第一个是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
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-6 14:01

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表