Windows程序设计——窗口键盘消息滚动事件

简介: Windows程序设计——窗口键盘消息滚动事件
+关注继续查看

头文件


#pragma once
#include <Windows.h>

#define NUMLINES ((int)(sizeof sysmetrics/sizeof sysmetrics[0]))

struct {
    int Index;
    char szLabel[100];  //第一列内容
    char szDesc[50];    //第二列内容
}sysmetrics[] = {
SM_CXSCREEN,"各位同学大家好","官方标准提示数据",
SM_CYSCREEN,"C/C++高级工程师","官方标准发布版本"
};


NUMLINES 宏定义是为了得到sysmetrics的数量


源文件


#include <Windows.h>
#include "systems.h"

LRESULT CALLBACK WndProcFun(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
    static TCHAR szAppName[] = TEXT("CKDemoTest");
    HWND hwnd;
    MSG msg;
    WNDCLASS windclass;

    windclass.style = CS_HREDRAW | CS_VREDRAW;
    windclass.lpfnWndProc = WndProcFun;
    windclass.cbClsExtra = 0;
    windclass.cbWndExtra = 0;
    windclass.hInstance = hInstance;
    windclass.hIcon = NULL;
    windclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    windclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    windclass.lpszMenuName = NULL;
    windclass.lpszClassName = szAppName;

    if (!RegisterClass(&windclass))
    {
        // 提示信息自己完成 
        return 0;
    }

    hwnd = CreateWindow(szAppName, TEXT("第五讲 键盘控制窗口垂直水平滚事件"), WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL,CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);

    ShowWindow(hwnd, iCmdShow);
    UpdateWindow(hwnd);

    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return msg.wParam;

}


LRESULT CALLBACK WndProcFun(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    static int cxChar, cxCaps, cyChar, cxClient, cyClient, iMaxWidth;
    HDC hdc;
    int i, x, y, iVertPos, iHorzPos=0, iPaintBeg, iPaintEnd;
    PAINTSTRUCT ps;
    SCROLLINFO si;
    TCHAR szBuffer[20];
    TEXTMETRIC tm;

    switch (message)
    {
    case WM_CREATE:  // 应用程序创建一个窗口
        hdc = GetDC(hwnd);
        GetTextMetrics(hdc, &tm);
        cxChar = tm.tmAveCharWidth;
        cyChar = tm.tmHeight + tm.tmExternalLeading;
        cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2)*cxChar / 2;
        ReleaseDC(hwnd, hdc);

        // 保存三列宽度
        iMaxWidth = 40 * cxChar + 22 * cxCaps;
        return 0;

    case WM_SIZE:   // 改变一个窗口的大小
        cxClient = LOWORD(lParam);
        cyClient = HIWORD(lParam);

        // 设置垂直滚动条范围 和 页面大小
        si.cbSize = sizeof(si);

        // SIF_RANGE 设置滚动范围值
        // SIF_PAGE 设置滚动页码
        si.fMask = SIF_RANGE | SIF_PAGE;
        si.nMin = 0;
        si.nMax = NUMLINES - 1;
        si.nPage = cyClient / cyChar;
        // SB_VERT 设置所给定的窗体上标准垂直滚动条参数
        SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
        return 0;

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

        // 获取垂直滚动条位置
        si.cbSize = sizeof(si);
        si.fMask = SIF_POS;
        GetScrollInfo(hwnd, SB_VERT, &si);
        iVertPos = si.nPos;

        // 查找绘制限制
        iPaintBeg = max(0, iVertPos + ps.rcPaint.top / cyChar);
        iPaintEnd = min(NUMLINES - 1, iVertPos + ps.rcPaint.bottom / cyChar);

        for (i = iPaintBeg; i <= iPaintEnd; i++)
        {
            x = cxChar * (1 - iHorzPos);
            y = cyChar * (i - iVertPos);

            TextOut(hdc, x, y, sysmetrics[i].szLabel, lstrlen(sysmetrics[i].szLabel));
            TextOut(hdc, x+80*cxCaps, y, sysmetrics[i].szDesc, lstrlen(sysmetrics[i].szDesc));
            SetTextAlign(hdc, TA_RIGHT | TA_TOP);       // 指定设备环境设置文字对齐标志

            TextOut(hdc, x + 100 * cxCaps + 40 * cxChar, y, szBuffer, wsprintf(szBuffer, TEXT("%d"), GetSystemMetrics(sysmetrics[i].Index)));
            SetTextAlign(hdc, TA_LEFT | TA_TOP);
        }

        EndPaint(hwnd, &ps);
        return 0;

    case WM_KEYDOWN:
        switch (wParam)
        {
        case VK_HOME:   // Home
            SendMessage(hwnd, WM_VSCROLL, SB_TOP, 0);   // 消息发送到一个或多个窗口
            break;

        case VK_END:    // End
            SendMessage(hwnd, WM_VSCROLL, SB_BOTTOM, 0);
            break;

        case VK_PRIOR:  // Page Up
            SendMessage(hwnd, WM_VSCROLL, SB_PAGEUP, 0);
            break;

        case VK_NEXT:   // Page Down
            SendMessage(hwnd, WM_VSCROLL, SB_PAGEDOWN, 0);
            break;

        case VK_UP: // 箭头向上
            SendMessage(hwnd, WM_VSCROLL, SB_LINEUP, 0);
            break;

        case VK_DOWN:   // 箭头向下
            SendMessage(hwnd, WM_VSCROLL, SB_LINEDOWN, 0);
            break;
        }
        return 0;

    case WM_VSCROLL:
        // 获取所有垂直滚动条信息
        si.cbSize = sizeof(si);
        si.fMask = SIF_ALL; // 整个结构都有效
        GetScrollInfo(hwnd, SB_VERT, &si);      // SB_VERT 设置所绽的窗口上标准垂直滚动条参数

        iVertPos = si.nPos;

        switch (LOWORD(wParam))
        {
        case SB_TOP:
            si.nPos = si.nMin;
            break;

        case SB_BOTTOM:
            si.nPos = si.nMax;
            break;

        case SB_LINEUP:
            si.nPos -= 1;
            break;

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

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

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

        case SB_THUMBTRACK:
            si.nPos = si.nTrackPos;
            break;

        default:
            break;

        }
        si.fMask = SIF_POS;
        SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
        GetScrollInfo(hwnd, SB_VERT, &si);

        // 如果位置已经更改,滚动窗口并且进行更新
        if (si.nPos != iVertPos)
        {
            ScrollWindow(hwnd, 0, cyChar*(iVertPos - si.nPos), NULL, NULL);
            UpdateWindow(hwnd);
        }

        return 0;

    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }

    return DefWindowProc(hwnd, message, wParam, lParam);
}



运行结果只能垂直滚动,水平滚动参考即可

相关文章
|
3天前
|
存储 固态存储 Windows
在 Windows 中,当一个应用程序窗口被关闭,该应用程序将会保留在哪里?
在 Windows 中,当一个应用程序窗口被关闭,该应用程序将会保留在哪里?
10 0
|
2月前
|
API C++ Windows
Windows入门篇一之MSDN手册的使用和第一个窗口程序
Windows入门篇一之MSDN手册的使用和第一个窗口程序
Windows入门篇一之MSDN手册的使用和第一个窗口程序
|
2月前
|
Windows
Windows DOS窗口查看历史执行过的命令的三种方式
Windows DOS窗口查看历史执行过的命令的三种方式
|
4月前
|
Windows
WGCLOUD日常使用 - windows启动server,dos窗口显示乱码的问题处理
首先,这个乱码没有影响,忽略即可 这个是windows窗口编码导致的,不会影响程序运行,server/log下日志文件没有出现乱码,我们主要看日志文件
WGCLOUD日常使用 - windows启动server,dos窗口显示乱码的问题处理
|
4月前
|
Windows
Windows编程基础,第一个Windows程序,注册窗口,创建窗口(下)
Windows编程基础,第一个Windows程序,注册窗口,创建窗口
|
4月前
|
编译器 API 开发工具
Windows编程基础,第一个Windows程序,注册窗口,创建窗口(上)
Windows编程基础,第一个Windows程序,注册窗口,创建窗口
|
5月前
|
Linux Windows
为了做好 Windows「窗口管理」,我改造了一个软件……(二)
这些年来,「大屏就是生产力」的观念深入人心,越来越多的用户开始使用大尺寸屏幕以及多显示器,但有效利用屏幕面积、快捷操作应用窗口还需要软件辅助。
96 0
|
5月前
|
Linux UED iOS开发
为了做好 Windows「窗口管理」,我改造了一个软件……(一)
这些年来,「大屏就是生产力」的观念深入人心,越来越多的用户开始使用大尺寸屏幕以及多显示器,但有效利用屏幕面积、快捷操作应用窗口还需要软件辅助。
85 0
|
5月前
|
数据可视化 C++ Windows
非可视化编程的windows窗口 C++ 代码设计:附例程并多多知识点
非可视化编程的windows窗口 C++ 代码设计:附例程并多多知识点
98 0
|
5月前
|
C++ Windows
C++ Windows窗口程序:子窗口控件之按钮类button
C++ Windows窗口程序:子窗口控件之按钮类button
221 0
相关产品
云迁移中心
推荐文章
更多