鱼C论坛

 找回密码
 立即注册
查看: 2496|回复: 4

[已解决]关于窗口自适应的问题

[复制链接]
发表于 2022-3-28 01:14:49 | 显示全部楼层 |阅读模式

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

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

x
想知道用TEXTOUT函数输出文本,只有垂直滑动条,如何实现窗口自适应?
最佳答案
2023-11-28 05:40:29
小甲鱼的二师兄 发表于 2023-11-28 05:39
想知道用TEXTOUT函数输出文本,只有垂直滑动条,如何 ...

要实现窗口的自适应,可以通过以下步骤来实现:

1. 创建一个窗口,并设置窗口样式为可滚动的(WS_VSCROLL)。
2. 在窗口的WM_CREATE消息中,创建一个字体,并将其保存到全局变量中。
3. 在窗口的WM_SIZE消息中,获取窗口的客户区大小,并计算出文本输出区域的宽度和高度。
4. 根据窗口的客户区大小,调整滑动条的范围和位置。设置滑动条的范围为文本输出区域的高度,并设置滑块的大小为窗口的高度。
5. 在WM_VSCROLL消息中,根据滑动条的位置,计算出需要显示的文本的起始行数,并调用InvalidateRect函数重新绘制窗口。

下面是一个示例代码:
  1. #include <windows.h>
  2. // 窗口标题和类名
  3. const char g_szClassName[] = "myWindowClass";
  4. // 全局变量
  5. HFONT g_hFont;
  6. LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  7. {
  8.     static int nScrollPos = 0;
  9.     static int nCharHeight;
  10.     static int nLineCount;
  11.     static int nMaxScrollPos;
  12.    
  13.     switch (msg)
  14.     {
  15.         case WM_CREATE:
  16.         {
  17.             // 创建字体
  18.             LOGFONT lf = {0};
  19.             lf.lfHeight = -MulDiv(12, GetDeviceCaps(GetDC(hwnd), LOGPIXELSY), 72);
  20.             g_hFont = CreateFontIndirect(&lf);
  21.             
  22.             // 计算字符高度
  23.             HDC hdc = GetDC(hwnd);
  24.             SelectObject(hdc, g_hFont);
  25.             TEXTMETRIC tm;
  26.             GetTextMetrics(hdc, &tm);
  27.             nCharHeight = tm.tmHeight;
  28.             ReleaseDC(hwnd, hdc);
  29.             // 设置滑动条的最大值和页面大小
  30.             nLineCount = 100; // 假设有100行文本
  31.             nMaxScrollPos = nLineCount - 1;
  32.             SetScrollRange(hwnd, SB_VERT, 0, nMaxScrollPos, TRUE);
  33.             SetScrollPage(hwnd, SB_VERT, 10); // 每次滚动10行
  34.             return 0;
  35.         }
  36.         
  37.         case WM_SIZE:
  38.         {
  39.             int nClientHeight = HIWORD(lParam);
  40.             
  41.             // 根据窗口的客户区大小调整滑动条的范围和位置
  42.             SCROLLINFO si = {0};
  43.             si.cbSize = sizeof(si);
  44.             si.fMask = SIF_RANGE | SIF_PAGE;
  45.             si.nMin = 0;
  46.             si.nMax = nMaxScrollPos;
  47.             si.nPage = nClientHeight / nCharHeight;
  48.             si.nPos = nScrollPos;
  49.             SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
  50.             return 0;
  51.         }
  52.         
  53.         case WM_VSCROLL:
  54.         {
  55.             int nScrollCode = LOWORD(wParam);
  56.             switch (nScrollCode)
  57.             {
  58.                 case SB_LINEUP:
  59.                     nScrollPos -= 1;
  60.                     break;
  61.                     
  62.                 case SB_LINEDOWN:
  63.                     nScrollPos += 1;
  64.                     break;
  65.                     
  66.                 case SB_PAGEUP:
  67.                     nScrollPos -= nClientHeight / nCharHeight;
  68.                     break;
  69.                     
  70.                 case SB_PAGEDOWN:
  71.                     nScrollPos += nClientHeight / nCharHeight;
  72.                     break;
  73.                     
  74.                 case SB_TOP:
  75.                     nScrollPos = 0;
  76.                     break;
  77.                     
  78.                 case SB_BOTTOM:
  79.                     nScrollPos = nMaxScrollPos;
  80.                     break;
  81.                     
  82.                 case SB_THUMBPOSITION:
  83.                     nScrollPos = HIWORD(wParam);
  84.                     break;
  85.             }
  86.             
  87.             nScrollPos = max(0, min(nScrollPos, nMaxScrollPos));
  88.             SetScrollPos(hwnd, SB_VERT, nScrollPos, TRUE);
  89.             
  90.             // 重新绘制窗口
  91.             InvalidateRect(hwnd, NULL, TRUE);
  92.             return 0;
  93.         }
  94.         
  95.         case WM_PAINT:
  96.         {
  97.             PAINTSTRUCT ps;
  98.             HDC hdc = BeginPaint(hwnd, &ps);
  99.             
  100.             // 计算可见的文本行数和起始行号
  101.             int nFirstVisibleLine = nScrollPos;
  102.             int nLastVisibleLine = min(nFirstVisibleLine + (nClientHeight / nCharHeight), nLineCount);
  103.             
  104.             SelectObject(hdc, g_hFont);
  105.             SetBkMode(hdc, TRANSPARENT);
  106.             
  107.             // 循环输出可见的文本行
  108.             for (int i = nFirstVisibleLine; i < nLastVisibleLine; ++i)
  109.             {
  110.                 TEXTOUT(hdc, 0, (i - nFirstVisibleLine) * nCharHeight, "Hello, World!", 13);
  111.             }
  112.             
  113.             EndPaint(hwnd, &ps);
  114.             return 0;
  115.         }
  116.         
  117.         case WM_DESTROY:
  118.         {
  119.             // 销毁字体
  120.             DeleteObject(g_hFont);
  121.             
  122.             PostQuitMessage(0);
  123.             return 0;
  124.         }
  125.     }
  126.    
  127.     return DefWindowProc(hwnd, msg, wParam, lParam);
  128. }
  129. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
  130. {
  131.     // 注册窗口类
  132.     WNDCLASSEX wc = {0};
  133.     wc.cbSize = sizeof(wc);
  134.     wc.lpfnWndProc = WndProc;
  135.     wc.hInstance = hInstance;
  136.     wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  137.     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  138.     wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  139.     wc.lpszClassName = g_szClassName;
  140.     wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
  141.     if (!RegisterClassEx(&wc))
  142.     {
  143.         MessageBox(NULL, "窗口类注册失败!", "错误", MB_ICONERROR | MB_OK);
  144.         return -1;
  145.     }
  146.     // 创建窗口
  147.     HWND hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, g_szClassName, "自适应窗口", WS_OVERLAPPEDWINDOW,
  148.         CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, NULL, NULL, hInstance, NULL);
  149.     if (hwnd == NULL)
  150.     {
  151.         MessageBox(NULL, "窗口创建失败!", "错误", MB_ICONERROR | MB_OK);
  152.         return -1;
  153.     }
  154.     // 显示窗口
  155.     ShowWindow(hwnd, nCmdShow);
  156.     UpdateWindow(hwnd);
  157.     // 消息循环
  158.     MSG msg;
  159.     while (GetMessage(&msg, NULL, 0, 0) > 0)
  160.     {
  161.         TranslateMessage(&msg);
  162.         DispatchMessage(&msg);
  163.     }
  164.     return (int)msg.wParam;
  165. }
复制代码

这段代码创建了一个具有垂直滑动条的自适应窗口,并使用TEXTOUT函数输出文本。你可以将"Hello, World!"替换为其他需要输出的文本。请注意,此代码仅为示例,实际应用可能需要进一步添加错误处理和优化。

以上回复来自 -- ChatGPT(FishC官方接口),如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2022-3-28 11:34:51 | 显示全部楼层
应该是吧......
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-4-2 15:32:15 From FishC Mobile | 显示全部楼层
什么叫窗口自适应?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-11-28 05:39:55 | 显示全部楼层
想知道用TEXTOUT函数输出文本,只有垂直滑动条,如何实现窗口自适应?@FishC_GPT

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-11-28 05:40:29 | 显示全部楼层    本楼为最佳答案   
小甲鱼的二师兄 发表于 2023-11-28 05:39
想知道用TEXTOUT函数输出文本,只有垂直滑动条,如何 ...

要实现窗口的自适应,可以通过以下步骤来实现:

1. 创建一个窗口,并设置窗口样式为可滚动的(WS_VSCROLL)。
2. 在窗口的WM_CREATE消息中,创建一个字体,并将其保存到全局变量中。
3. 在窗口的WM_SIZE消息中,获取窗口的客户区大小,并计算出文本输出区域的宽度和高度。
4. 根据窗口的客户区大小,调整滑动条的范围和位置。设置滑动条的范围为文本输出区域的高度,并设置滑块的大小为窗口的高度。
5. 在WM_VSCROLL消息中,根据滑动条的位置,计算出需要显示的文本的起始行数,并调用InvalidateRect函数重新绘制窗口。

下面是一个示例代码:
  1. #include <windows.h>
  2. // 窗口标题和类名
  3. const char g_szClassName[] = "myWindowClass";
  4. // 全局变量
  5. HFONT g_hFont;
  6. LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  7. {
  8.     static int nScrollPos = 0;
  9.     static int nCharHeight;
  10.     static int nLineCount;
  11.     static int nMaxScrollPos;
  12.    
  13.     switch (msg)
  14.     {
  15.         case WM_CREATE:
  16.         {
  17.             // 创建字体
  18.             LOGFONT lf = {0};
  19.             lf.lfHeight = -MulDiv(12, GetDeviceCaps(GetDC(hwnd), LOGPIXELSY), 72);
  20.             g_hFont = CreateFontIndirect(&lf);
  21.             
  22.             // 计算字符高度
  23.             HDC hdc = GetDC(hwnd);
  24.             SelectObject(hdc, g_hFont);
  25.             TEXTMETRIC tm;
  26.             GetTextMetrics(hdc, &tm);
  27.             nCharHeight = tm.tmHeight;
  28.             ReleaseDC(hwnd, hdc);
  29.             // 设置滑动条的最大值和页面大小
  30.             nLineCount = 100; // 假设有100行文本
  31.             nMaxScrollPos = nLineCount - 1;
  32.             SetScrollRange(hwnd, SB_VERT, 0, nMaxScrollPos, TRUE);
  33.             SetScrollPage(hwnd, SB_VERT, 10); // 每次滚动10行
  34.             return 0;
  35.         }
  36.         
  37.         case WM_SIZE:
  38.         {
  39.             int nClientHeight = HIWORD(lParam);
  40.             
  41.             // 根据窗口的客户区大小调整滑动条的范围和位置
  42.             SCROLLINFO si = {0};
  43.             si.cbSize = sizeof(si);
  44.             si.fMask = SIF_RANGE | SIF_PAGE;
  45.             si.nMin = 0;
  46.             si.nMax = nMaxScrollPos;
  47.             si.nPage = nClientHeight / nCharHeight;
  48.             si.nPos = nScrollPos;
  49.             SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
  50.             return 0;
  51.         }
  52.         
  53.         case WM_VSCROLL:
  54.         {
  55.             int nScrollCode = LOWORD(wParam);
  56.             switch (nScrollCode)
  57.             {
  58.                 case SB_LINEUP:
  59.                     nScrollPos -= 1;
  60.                     break;
  61.                     
  62.                 case SB_LINEDOWN:
  63.                     nScrollPos += 1;
  64.                     break;
  65.                     
  66.                 case SB_PAGEUP:
  67.                     nScrollPos -= nClientHeight / nCharHeight;
  68.                     break;
  69.                     
  70.                 case SB_PAGEDOWN:
  71.                     nScrollPos += nClientHeight / nCharHeight;
  72.                     break;
  73.                     
  74.                 case SB_TOP:
  75.                     nScrollPos = 0;
  76.                     break;
  77.                     
  78.                 case SB_BOTTOM:
  79.                     nScrollPos = nMaxScrollPos;
  80.                     break;
  81.                     
  82.                 case SB_THUMBPOSITION:
  83.                     nScrollPos = HIWORD(wParam);
  84.                     break;
  85.             }
  86.             
  87.             nScrollPos = max(0, min(nScrollPos, nMaxScrollPos));
  88.             SetScrollPos(hwnd, SB_VERT, nScrollPos, TRUE);
  89.             
  90.             // 重新绘制窗口
  91.             InvalidateRect(hwnd, NULL, TRUE);
  92.             return 0;
  93.         }
  94.         
  95.         case WM_PAINT:
  96.         {
  97.             PAINTSTRUCT ps;
  98.             HDC hdc = BeginPaint(hwnd, &ps);
  99.             
  100.             // 计算可见的文本行数和起始行号
  101.             int nFirstVisibleLine = nScrollPos;
  102.             int nLastVisibleLine = min(nFirstVisibleLine + (nClientHeight / nCharHeight), nLineCount);
  103.             
  104.             SelectObject(hdc, g_hFont);
  105.             SetBkMode(hdc, TRANSPARENT);
  106.             
  107.             // 循环输出可见的文本行
  108.             for (int i = nFirstVisibleLine; i < nLastVisibleLine; ++i)
  109.             {
  110.                 TEXTOUT(hdc, 0, (i - nFirstVisibleLine) * nCharHeight, "Hello, World!", 13);
  111.             }
  112.             
  113.             EndPaint(hwnd, &ps);
  114.             return 0;
  115.         }
  116.         
  117.         case WM_DESTROY:
  118.         {
  119.             // 销毁字体
  120.             DeleteObject(g_hFont);
  121.             
  122.             PostQuitMessage(0);
  123.             return 0;
  124.         }
  125.     }
  126.    
  127.     return DefWindowProc(hwnd, msg, wParam, lParam);
  128. }
  129. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
  130. {
  131.     // 注册窗口类
  132.     WNDCLASSEX wc = {0};
  133.     wc.cbSize = sizeof(wc);
  134.     wc.lpfnWndProc = WndProc;
  135.     wc.hInstance = hInstance;
  136.     wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  137.     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  138.     wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  139.     wc.lpszClassName = g_szClassName;
  140.     wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
  141.     if (!RegisterClassEx(&wc))
  142.     {
  143.         MessageBox(NULL, "窗口类注册失败!", "错误", MB_ICONERROR | MB_OK);
  144.         return -1;
  145.     }
  146.     // 创建窗口
  147.     HWND hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, g_szClassName, "自适应窗口", WS_OVERLAPPEDWINDOW,
  148.         CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, NULL, NULL, hInstance, NULL);
  149.     if (hwnd == NULL)
  150.     {
  151.         MessageBox(NULL, "窗口创建失败!", "错误", MB_ICONERROR | MB_OK);
  152.         return -1;
  153.     }
  154.     // 显示窗口
  155.     ShowWindow(hwnd, nCmdShow);
  156.     UpdateWindow(hwnd);
  157.     // 消息循环
  158.     MSG msg;
  159.     while (GetMessage(&msg, NULL, 0, 0) > 0)
  160.     {
  161.         TranslateMessage(&msg);
  162.         DispatchMessage(&msg);
  163.     }
  164.     return (int)msg.wParam;
  165. }
复制代码

这段代码创建了一个具有垂直滑动条的自适应窗口,并使用TEXTOUT函数输出文本。你可以将"Hello, World!"替换为其他需要输出的文本。请注意,此代码仅为示例,实际应用可能需要进一步添加错误处理和优化。

以上回复来自 -- ChatGPT(FishC官方接口),如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

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

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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