鱼C论坛

 找回密码
 立即注册
查看: 2116|回复: 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函数重新绘制窗口。

下面是一个示例代码:
#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官方接口),如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-3-28 11:34:51 | 显示全部楼层
应该是吧......
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-4-2 15:32:15 From FishC Mobile | 显示全部楼层
什么叫窗口自适应?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

想知道小甲鱼最近在做啥?请访问 -> 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函数重新绘制窗口。

下面是一个示例代码:
#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官方接口),如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-12-21 22:49

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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