计机羊咩咩 发表于 2014-9-12 11:30:16

滑动条2及其位置保存

本帖最后由 计机羊咩咩 于 2014-9-12 11:35 编辑

LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
      HDC hdc;
      SCROLLINFO vScroll, hScroll;
      PAINTSTRUCT ps;
      TEXTMETRIC WordStyle;
      int LengthMath, iScrollPos;
      int iPaintBeg, iPaintEnd, X, Y;
      static int cxWord, cyWord, cxClient, cyClient;
      static float vScrollPos;
      switch (message)
      {
      case WM_CREATE:
                hdc = GetDC(hwnd);

                GetTextMetrics(hdc, &WordStyle);
                cxWord = WordStyle.tmAveCharWidth;
                cxWord = (WordStyle.tmPitchAndFamily & 1 ? 3 : 2) * cxWord / 2;
                cyWord = WordStyle.tmInternalLeading + WordStyle.tmHeight;

                ReleaseDC(hwnd, hdc);
                return 0;

      case WM_SIZE:
                cxClient = LOWORD(lParam);
                cyClient = HIWORD(lParam);

                vScroll.cbSize = sizeof(vScroll);
                vScroll.fMask = SIF_ALL;
                GetScrollInfo(hwnd, SB_VERT, &vScroll);
                vScrollPos = (float)vScroll.nPos / (float)vScroll.nMax;
                if (vScrollPos)
                {
                        switch (wParam)
                        {
                        case SIZE_RESTORED:
                              vScroll.nPage = cyClient / cyWord;
                              vScroll.nPos = (int)(vScrollPos * (float)vScroll.nMax);
                              SetScrollInfo(hwnd, SB_VERT, &vScroll, TRUE);
                              break;

                        case SIZE_MAXIMIZED:
                              break;

                        case SIZE_MINIMIZED:
                              break;

                        default:break;
                        }
                }
                else
                {
                        vScroll.cbSize = sizeof(vScroll);
                        vScroll.fMask = SIF_ALL;
                        vScroll.nMin = 0;
                        vScroll.nMax = txtLine;
                        vScroll.nPage = cyClient / cyWord;
                        SetScrollInfo(hwnd, SB_VERT, &vScroll, TRUE);
                }
                return 0;
/*
WM_SIZE:   
vScrollPos = (float)vScroll.nPos / (float)vScroll.nMax;以比例为数据保存当前滑动条位置
if (vScrollPos)滑动条不在原始位置时恢复滑动条在窗口变化前的比例位置   ps:如果系统对nMax初始化为0则另行处理
*/
      case WM_VSCROLL:
                vScroll.cbSize = sizeof(vScroll);
                vScroll.fMask = SIF_POS | SIF_PAGE;
                GetScrollInfo(hwnd, SB_VERT, &vScroll);
                iScrollPos = vScroll.nPos;

                switch (LOWORD(wParam))
                {
                case SB_LINEUP:
                        vScroll.nPos -= 1;
                        break;

                case SB_LINEDOWN:
                        vScroll.nPos += 1;
                        break;

                case SB_PAGEUP:
                        vScroll.nPos -= vScroll.nPage;
                        break;

                case SB_PAGEDOWN:
                        vScroll.nPos += vScroll.nPage;
                        break;

                case SB_THUMBPOSITION:
                        vScroll.nPos = HIWORD(wParam);
                        break;

                case SB_THUMBTRACK:
                        vScroll.nPos = HIWORD(wParam);
                        break;

                default:break;
                }

                SetScrollInfo(hwnd, SB_VERT, &vScroll, TRUE);
                GetScrollInfo(hwnd, SB_VERT, &vScroll);
                if (iScrollPos != vScroll.nPos)
                {
                        ScrollWindow(hwnd, 0, cyWord * (iScrollPos - vScroll.nPos), NULL, NULL);
                        UpdateWindow(hwnd);
                }
                return 0;

      case WM_PAINT:
                hdc = BeginPaint(hwnd, &ps);

                vScroll.cbSize = sizeof(vScroll);
                vScroll.fMask = SIF_ALL;
                GetScrollInfo(hwnd, SB_VERT, &vScroll);

                iPaintBeg = max(0, vScroll.nPos + ps.rcPaint.top / cyWord);
                iPaintEnd = min(vScroll.nMax, vScroll.nPos + ps.rcPaint.bottom / cyWord);
                for (; iPaintBeg <= iPaintEnd; iPaintBeg++)
                {
                        X = 0;
                        Y = cyWord * (iPaintBeg - vScroll.nPos);
                        StringCchLength(txt, 256, &LengthMath);
                        TextOut(hdc, X, Y, txt, LengthMath);
                }

                EndPaint(hwnd, &ps);
                return 0;
/*
WM_PAINT:
Y = cyWord * (iPaintBeg - vScroll.nPos); 和 vScroll.nPos + ps.rcPaint.top / cyWord
iPaintBeg会自增   其实每个循环后Y的结果是每一行的top
for循环中的"<="如果少了“=”窗口滚动前的最后一行可能在滚动窗口后不更新
*/

      case WM_DESTROY:
                PostQuitMessage(0);
                return 0;
      }
      return DefWindowProc(hwnd, message, wParam, lParam);
}

其实关于这个内容我之前发过一个帖子然而我觉得上次说的很含糊(当时我还没理解透....)   这个帖子就当是对上次的补充而且还加了
保存滑动条的语句其实就是一个if语句加上几行代码   希望能帮到看到帖子的人(不处理的话最大最小化和窗口变化滑动条会恢复噢)
上次帖子的链接:http://bbs.fishc.com/thread-51415-1-1.html   (如果不能按那就直接复制访问)

关于水平滑动条我还不会如何去定位文本和绘制位置   如果有人懂得清在留言内赐教不胜感激

OSKer 发表于 2014-10-5 18:17:35

感谢楼主分享

智商是硬伤 发表于 2015-8-18 08:29:06

{:7_146:}
页: [1]
查看完整版本: 滑动条2及其位置保存