鱼C论坛

 找回密码
 立即注册
查看: 1536|回复: 1

处理键盘消息实现滚动条滚动,文本滚动了,但是滚动条没有重绘

[复制链接]
发表于 2018-11-19 20:36:50 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 weijunyu 于 2018-11-19 21:08 编辑

来个大佬帮我看看什么情况,处理键盘消息的时候,文本内容重绘了,但是滚动条没重绘。




  1. //滚动条和显示文本
  2. #include <windows.h>;
  3. #include "strsafe.h";
  4. #include "SysMets.h";

  5. LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);

  6. int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR szCmdLine,int iCmdShow) {
  7.         HWND hwnd;
  8.         MSG msg;
  9.         static TCHAR szAppName[] = TEXT("MyWindows");//指定窗口类名,面向程序员

  10.         WNDCLASS wndclass;
  11.         wndclass.style = CS_HREDRAW | CS_VREDRAW;//窗口风格
  12.         wndclass.lpfnWndProc = WndProc;//回调函数
  13.         wndclass.cbClsExtra = 0;//预留的额外空间
  14.         wndclass.cbWndExtra = 0;//预留的额外空间
  15.         wndclass.hInstance = hInstance;//该窗口的句柄
  16.         wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);//为所有基于该窗口类的窗口设定一个图标
  17.         wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);//为所有基于该窗口类的窗口设定一个鼠标指针
  18.         wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);//指定窗口背景色
  19.         wndclass.lpszMenuName = NULL;
  20.         wndclass.lpszClassName = szAppName;//指定窗口类名,面向程序员
  21.         RegisterClass(&wndclass);
  22.         hwnd = CreateWindow(
  23.                 szAppName,
  24.                 TEXT("WindowsApp"),
  25.                 WS_OVERLAPPEDWINDOW | WS_VSCROLL,
  26.                 0,
  27.                 0,
  28.                 800,
  29.                 600,
  30.                 NULL,
  31.                 NULL,
  32.                 hInstance,
  33.                 NULL
  34.         );
  35.         ShowWindow(hwnd, iCmdShow);
  36.         UpdateWindow(hwnd);
  37.         while (GetMessage(&msg,NULL,0,0))
  38.         {
  39.                 TranslateMessage(&msg);
  40.                 DispatchMessage(&msg);
  41.         }
  42.         return msg.wParam;
  43. }

  44. LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
  45.         TCHAR szBuffer[128];
  46.         HDC hdc;
  47.         static int cxChar,cxCaps,cyChar,cxClient, cyClient;
  48.         static size_t iTarget,iTarget1;
  49.         TEXTMETRIC tm;
  50.         size_t i = 0;
  51.         int yPos,FirstLine,LastLine;
  52.         SCROLLINFO si;
  53.         PAINTSTRUCT ps;

  54.         switch (message)
  55.         {
  56.         case WM_CREATE:
  57.                 hdc = GetDC(hwnd);
  58.                 //获取窗口尺寸
  59.                 GetTextMetrics(hdc,&tm);

  60.                 //每个字符的平均宽度
  61.                 cxChar = tm.tmAveCharWidth;
  62.                 //每个字符的实际宽度
  63.                 cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2;

  64.                 //字符的高度
  65.                 cyChar = tm.tmHeight + tm.tmExternalLeading;

  66.                 ReleaseDC(hwnd, hdc);
  67.         case WM_SIZE:
  68.                 cxClient = LOWORD(lParam);
  69.                 cyClient = HIWORD(lParam);

  70.                 si.cbSize = sizeof(si);
  71.                 si.fMask = SIF_PAGE | SIF_RANGE;
  72.                 si.nMin = 0;
  73.                 si.nMax = NUMLINES - 1;
  74.                 si.nPage = cyClient / cyChar;
  75.                 SetScrollInfo(hwnd, SB_VERT, &si, FALSE);

  76.         case WM_VSCROLL:
  77.                 hdc = GetDC(hwnd);
  78.                 SetTextAlign(hdc, TA_TOP | TA_RIGHT);

  79.                 si.cbSize = sizeof(si);
  80.                 si.fMask = SIF_ALL;
  81.                 GetScrollInfo(hwnd, SB_VERT, &si);

  82.                 yPos = si.nPos;
  83.                 switch (LOWORD(wParam))
  84.                 {
  85.                 case SB_TOP:
  86.                         si.nPos = si.nMin;
  87.                         break;
  88.                 case SB_BOTTOM:
  89.                         si.nPos = si.nMax;
  90.                         break;
  91.                 case SB_LINEDOWN:
  92.                         si.nPos++;
  93.                         break;
  94.                 case SB_PAGEDOWN:
  95.                         si.nPos += cyClient / cyChar;
  96.                         break;
  97.                 case SB_PAGEUP:
  98.                         si.nPos -= cyClient / cyChar;
  99.                         break;
  100.                 case SB_LINEUP:
  101.                         si.nPos--;
  102.                         break;
  103.                 case SB_THUMBTRACK:
  104.                         si.nPos = si.nTrackPos;
  105.                         break;
  106.                 }

  107.                 ReleaseDC(hwnd, hdc);

  108.                 //设置滚动条的新位置
  109.                 si.fMask = SIF_POS;
  110.                 SetScrollInfo(hwnd, SB_VERT, &si, FALSE);

  111.                 //获得滚动条的位置
  112.                 GetScrollInfo(hwnd, SB_VERT, &si);

  113.                 if (yPos != si.nPos)
  114.                 {
  115.                         ScrollWindow(hwnd, 0, cyChar * (yPos - si.nPos), NULL, NULL);
  116.                         /*UpdateWindow(hwnd);*/
  117.                 }
  118.                
  119.                 return 0;
  120.         case WM_PAINT:
  121.                 hdc = BeginPaint(hwnd, &ps);

  122.                 //获得滚动条的位置
  123.                 si.cbSize = sizeof(&si);
  124.                 si.fMask = SIF_POS;
  125.                 GetScrollInfo(hwnd, SB_VERT, &si);
  126.                 yPos = si.nPos;

  127.                 //计算需要重绘的区域
  128.                 FirstLine = max(0, yPos + ps.rcPaint.top / cyChar);
  129.                 LastLine = min(NUMLINES - 1, yPos + ps.rcPaint.bottom / cyChar);

  130.                 for (size_t i = FirstLine; i < LastLine; i++)
  131.                 {
  132.                         int y = cyChar * (i - yPos);
  133.                         //第一列
  134.                         StringCchLength(sysmetrics[i].szLabel, 1024, &iTarget);
  135.                         TextOut(hdc , 0 , y , sysmetrics[i].szLabel, iTarget);

  136.                         //第二列
  137.                         StringCchLength(sysmetrics[i].szDesc, 12, &iTarget);
  138.                         TextOut(hdc,17 * cxCaps, y, sysmetrics[i].szDesc, iTarget == 0 ? 12 : iTarget);

  139.                         //第三列
  140.                         SetTextAlign(hdc, TA_TOP | TA_RIGHT);
  141.                         StringCchPrintf(szBuffer, 10,TEXT("%i"), GetSystemMetrics(sysmetrics[i].iIndex));
  142.                         StringCchLength(szBuffer, 10, &iTarget);
  143.                         TextOut(hdc, 40 * cxCaps, y, szBuffer, iTarget);

  144.                         SetTextAlign(hdc, TA_TOP | TA_LEFT);
  145.                 }
  146.                 EndPaint(hwnd, &ps);
  147.                 break;
  148.         case WM_KEYDOWN:
  149.                 switch (wParam)
  150.                 {
  151.                 case VK_DOWN:
  152.                         SendMessage(hwnd, WM_VSCROLL, SB_LINEDOWN, 0);
  153.                         break;
  154.                 case VK_UP:
  155.                         SendMessage(hwnd, WM_VSCROLL, SB_LINEUP, 0);
  156.                         break;
  157.                 case VK_HOME:
  158.                         SendMessage(hwnd, WM_VSCROLL, SB_TOP, 0);
  159.                         break;
  160.                 case VK_END:
  161.                         SendMessage(hwnd, WM_VSCROLL, SB_BOTTOM, 0);
  162.                         break;
  163.                 case VK_PRIOR:
  164.                         SendMessage(hwnd, WM_VSCROLL, SB_PAGEUP, 0);
  165.                         break;
  166.                 case VK_NEXT:
  167.                         SendMessage(hwnd, WM_VSCROLL, SB_PAGEDOWN, 0);
  168.                         break;
  169.                 }
  170.                 return 0;
  171.         case WM_DESTROY:
  172.                 PostQuitMessage(0);
  173.                 break;
  174.         default:
  175.                 return DefWindowProc(hwnd, message, wParam, lParam);
  176.         }
  177. };
复制代码

·
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2018-11-19 21:07:10 | 显示全部楼层
已解决,没有重绘的原因是因为SetScrollInfo()设置滚动条位置的时候,最后一个参数为false,改为true,滚动条在设置的时候就会自动重画了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-24 17:09

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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