skygod2 发表于 2022-3-28 01:14:49

关于窗口自适应的问题

想知道用TEXTOUT函数输出文本,只有垂直滑动条,如何实现窗口自适应?

python爱好者. 发表于 2022-3-28 11:34:51

应该是吧......

zzxhh628 发表于 2022-4-2 15:32:15

什么叫窗口自适应?

小甲鱼的二师兄 发表于 2023-11-28 05:39:55

想知道用TEXTOUT函数输出文本,只有垂直滑动条,如何实现窗口自适应?@FishC_GPT

FishC_GPT 发表于 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函数重新绘制窗口。

下面是一个示例代码:

#include <windows.h>

// 窗口标题和类名
const char g_szClassName[] = "myWindowClass";

// 全局变量
HFONT g_hFont;

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    static int nScrollPos = 0;
    static int nCharHeight;
    static int nLineCount;
    static int nMaxScrollPos;
   
    switch (msg)
    {
      case WM_CREATE:
      {
            // 创建字体
            LOGFONT lf = {0};
            lf.lfHeight = -MulDiv(12, GetDeviceCaps(GetDC(hwnd), LOGPIXELSY), 72);
            g_hFont = CreateFontIndirect(&lf);
            
            // 计算字符高度
            HDC hdc = GetDC(hwnd);
            SelectObject(hdc, g_hFont);
            TEXTMETRIC tm;
            GetTextMetrics(hdc, &tm);
            nCharHeight = tm.tmHeight;
            ReleaseDC(hwnd, hdc);

            // 设置滑动条的最大值和页面大小
            nLineCount = 100; // 假设有100行文本
            nMaxScrollPos = nLineCount - 1;
            SetScrollRange(hwnd, SB_VERT, 0, nMaxScrollPos, TRUE);
            SetScrollPage(hwnd, SB_VERT, 10); // 每次滚动10行
            return 0;
      }
      
      case WM_SIZE:
      {
            int nClientHeight = HIWORD(lParam);
            
            // 根据窗口的客户区大小调整滑动条的范围和位置
            SCROLLINFO si = {0};
            si.cbSize = sizeof(si);
            si.fMask = SIF_RANGE | SIF_PAGE;
            si.nMin = 0;
            si.nMax = nMaxScrollPos;
            si.nPage = nClientHeight / nCharHeight;
            si.nPos = nScrollPos;
            SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
            return 0;
      }
      
      case WM_VSCROLL:
      {
            int nScrollCode = LOWORD(wParam);
            switch (nScrollCode)
            {
                case SB_LINEUP:
                  nScrollPos -= 1;
                  break;
                  
                case SB_LINEDOWN:
                  nScrollPos += 1;
                  break;
                  
                case SB_PAGEUP:
                  nScrollPos -= nClientHeight / nCharHeight;
                  break;
                  
                case SB_PAGEDOWN:
                  nScrollPos += nClientHeight / nCharHeight;
                  break;
                  
                case SB_TOP:
                  nScrollPos = 0;
                  break;
                  
                case SB_BOTTOM:
                  nScrollPos = nMaxScrollPos;
                  break;
                  
                case SB_THUMBPOSITION:
                  nScrollPos = HIWORD(wParam);
                  break;
            }
            
            nScrollPos = max(0, min(nScrollPos, nMaxScrollPos));
            SetScrollPos(hwnd, SB_VERT, nScrollPos, TRUE);
            
            // 重新绘制窗口
            InvalidateRect(hwnd, NULL, TRUE);
            return 0;
      }
      
      case WM_PAINT:
      {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hwnd, &ps);
            
            // 计算可见的文本行数和起始行号
            int nFirstVisibleLine = nScrollPos;
            int nLastVisibleLine = min(nFirstVisibleLine + (nClientHeight / nCharHeight), nLineCount);
            
            SelectObject(hdc, g_hFont);
            SetBkMode(hdc, TRANSPARENT);
            
            // 循环输出可见的文本行
            for (int i = nFirstVisibleLine; i < nLastVisibleLine; ++i)
            {
                TEXTOUT(hdc, 0, (i - nFirstVisibleLine) * nCharHeight, "Hello, World!", 13);
            }
            
            EndPaint(hwnd, &ps);
            return 0;
      }
      
      case WM_DESTROY:
      {
            // 销毁字体
            DeleteObject(g_hFont);
            
            PostQuitMessage(0);
            return 0;
      }
    }
   
    return DefWindowProc(hwnd, msg, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    // 注册窗口类
    WNDCLASSEX wc = {0};
    wc.cbSize = sizeof(wc);
    wc.lpfnWndProc = WndProc;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wc.lpszClassName = g_szClassName;
    wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

    if (!RegisterClassEx(&wc))
    {
      MessageBox(NULL, "窗口类注册失败!", "错误", MB_ICONERROR | MB_OK);
      return -1;
    }

    // 创建窗口
    HWND hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, g_szClassName, "自适应窗口", WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, NULL, NULL, hInstance, NULL);

    if (hwnd == NULL)
    {
      MessageBox(NULL, "窗口创建失败!", "错误", MB_ICONERROR | MB_OK);
      return -1;
    }

    // 显示窗口
    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    // 消息循环
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0) > 0)
    {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
    }

    return (int)msg.wParam;
}

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

以上回复来自 -- ChatGPT(FishC官方接口),如未能正确解答您的问题,请继续追问。
页: [1]
查看完整版本: 关于窗口自适应的问题