Windows程序设计——窗口键盘消息滚动事件[通俗易懂]
2023-06-13 09:11:02 时间
大家好,又见面了,我是你们的朋友全栈君。
文章目录
头文件
#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);
}
运行结果只能垂直滚动,水平滚动参考即可,
不懂得可以留言,希望可以帮助到各位朋友。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/171006.html原文链接:https://javaforall.cn
相关文章
- 极域电子书包全新windows-android功能介绍[通俗易懂]
- Windows平台上也可以进行iOS App的开发
- Windows Mac 等不同平台2022年最佳PDF工具
- Windows 系统 PhpStorm 2020无限试用30天
- Django Export XLS 【Windows安装】
- Windows系统日志有多少种登录类型?
- 实现Windows客户端通过SSH连接Linux服务器(windows连接linux服务器)
- windows激活Windows:Linux下的秘诀(linux激活)
- 在Windows与Linux之间传输文件(windows向linux传文件)
- Linux系统下安装Windows软件的简便方法(linux安装windows软件)
- windows分步实现:双系统Linux挂载Windows(双系统Linux挂载)
- 在Linux上运行Windows程序的方法(linux运行windows程序)
- windows比较:Linux与Windows的优势对比(linuxvss)
- 和windows比较Octave在Linux和Windows上的性能(octavelinux)
- Windows与Linux的区别 – 深入比较两个操作系统(windows和linux区别)
- Windows 10 21H1获累积更新 物联网企业版可删除“Windows”等术语
- 微软年度安全报告:Windows 7比XP更不安全
- windows混搭环境中的EGL、Linux和Windows(egllinux)
- 实现无缝连接:Linux远程桌面Windows,保持高效办公(linux远程桌面windows)
- 桌面操作系统大杀器:Windows与Linux比拼(windowlinux)
- 在Windows环境下安装双系统:WindowsLinux(windows下安装linux)
- Windows 下 cmd 管理 mysql 的默认设置(cmd默认mysql)
- Windows命令行连接MySQL数据库(cmd中链接mysql)
- 仿windows工具条样式
- 基于linux与windows平台下如何下载androidsdk源代码的方法详解