《Windows API每日一练》5.5 插入符号

news2024/11/19 12:29:46

当你向程序中输入文本时,通常会有下划线、竖线或方框指示你输入的下一个字符将出现在屏幕上的位置。你也许认为这是“光标”,但在编写Windows程序时,你必须避免这种习惯。在Windows中,它被称为“插入符号”(caret)。“光标”(cursor)特指表示鼠标位置的位图图像,即鼠标指针。

本节必须掌握的知识点:

        关于插入符号的函数

        第34练:文本编辑器插入符号

5.5.1 关于插入符号的函数

■Windows中有五个基本的插入符号函数:

●CreateCaret:创建和窗口关联的插入符号。

●SetCaretPos:设置窗口内的插入符号的位置。

●ShowCaret:显示插入符号。

●HideCaret:险藏插入符号。

●DestroyCaret:销毁插入符号。

操作插入符的函数

此外,还有用于获得当前插入符号位置的函数(GetCaretPos)与获得和设置插入符号闪烁时间的函数(GetCaretBlinkTime 和 SetCaretBlinkTime)。

●GetCaretPos 函数的原型:

BOOL GetCaretPos(

  LPPOINT lpPoint // 接收光标位置的指针

);

返回值:

如果函数调用成功,返回值为非零值(TRUE)。

如果函数调用失败,返回值为零(FALSE)。

使用 GetCaretPos 函数可以获取当前光标的位置,即光标在屏幕上的坐标。通过传递一个指向 POINT 结构的指针,函数将光标的坐标信息存储在该结构中。

示例代码:

#include <Windows.h>

int main() {

    POINT caretPos;

    // 获取光标位置

    if (GetCaretPos(&caretPos)) {

        // 输出光标的坐标

        printf("Caret position: x = %d, y = %d\n", caretPos.x, caretPos.y);

    } else {

        // 获取光标位置失败

        printf("Failed to get caret position.\n");

    }

    return 0;

}

●GetCaretBlinkTime函数原型:

UINT GetCaretBlinkTime();

返回值:

返回一个无符号整数,表示光标闪烁的时间间隔(以毫秒为单位)。

使用 GetCaretBlinkTime 函数可以获取当前系统中光标闪烁的时间间隔。光标闪烁是指光标在显示和隐藏之间的交替效果。

示例代码:

#include <Windows.h>

int main() {

    UINT blinkTime = GetCaretBlinkTime();

    // 输出光标闪烁时间间隔

    printf("Caret blink time: %u ms\n", blinkTime);

    return 0;

}

●SetCaretBlinkTime函数原型:

BOOL SetCaretBlinkTime(

  UINT uMSeconds // 光标闪烁的时间间隔(以毫秒为单位)

);

返回值:

如果函数调用成功,返回值为非零值(TRUE)。

如果函数调用失败,返回值为零(FALSE)。

使用 SetCaretBlinkTime 函数可以设置光标闪烁的时间间隔。你可以将所需的时间间隔(以毫秒为单位)作为参数传递给该函数。

示例代码:

#include <Windows.h>

int main() {

    UINT blinkTime = 500; // 设置光标闪烁时间间隔为 500 毫秒

    // 设置光标闪烁时间间隔

    if (SetCaretBlinkTime(blinkTime)) {

        printf("Caret blink time set successfully.\n");

    } else {

        printf("Failed to set caret blink time.\n");

    }

    return 0;

}

处理插入符

在Windows中,插入符号通常是一个字符大小的水平线或方框,或是与字符高度相一 致的竖线。使用变宽字体的时候推荐使用竖线插入符号,比如Windows默认系统字体。因 为变宽字体字符不是固定大小的,不能把水平线或者方框设置为字符的大小。

如果你的程序中需要插入符号,那么不应该简单地在窗口过程的WM_CREATE消息中创建它并在WM_DESTROY消息中销毁它。不建议你这样做的原因是一个消息队列仅能够支持一个插入符号。因此,如果你的程序有多于一个窗口,则多个窗口必须有效地共享同一个插入符号。

这并不像听起来那样有限制性。你想一下,仅当窗口具有输入焦点时,窗口中插入符号的显示才有意义。的确,闪烁的插入符号的存在是一种视觉提示:它让用户意识到他可以向程序中输入文本。因为任何时候仅有一个窗口具有输入焦点,所有多个窗口同时使插入符号闪烁是没有意义的。

程序能通过处理WM_SETFOCUS消息和WM_KILLFOCUS消息来决定它是否具有输入焦点。正如名称所暗示的,当窗口过程接收输入焦点时,它接收到一个WM_SETFOCUS 消息:当它失去输入焦点时,收到一个WM_KILLFOCUS消息。这些消息成对出现:窗口过程在接收到一条WM_KILLFOCUS消息前,总是会接收到一条WM_SETFOCUS消息。 并且在窗口的生命期窗口过程总是接收到相同数目的WM_SETFOCUS消息和 WM_KILLFOCUS 消息。

使用插入符号的主要规则很简单:在窗口过程处理WM_SETFOCUS消息时调用 CreateCaret 函数,处理 WM_KILLFOCUS 消息时调用 DestroyCaret 函数。

还有一些其他规则:创建的插入符号是隐藏的。在调用CreateCaret之后,窗口过程必 须调用ShowCaret使之可见。另外,如果窗口过程处理的是一个非WM_PAINT消息,但要在窗口内绘制某些东西时,它必须调用HideCaret隐藏插入符号。当它结束在窗口内的绘制之后,再调用ShowCaret来显示插入符号。HideCaret的效果是叠加的:如果你调用了HideCaret很多次,但没调用过ShowCaret,那么你必须再调用同样次数的ShowCaret才能使插入符号可见。

5.5.2 第34练:文本编辑器插入符号

/*------------------------------------------------------------------

034  WIN32 API 每日一练

     第34个例子TYPER.C:文本编辑器---插入符号

     GetFocus函数

     CreateCaret函数     

     SetCaretPos函数

     ShowCaret函数

     HideCaret函数

     DestroyCaret函数

     GetCaretPos函数

     WM_SETFOCUS消息

     WM_KILLFOCUS消息

注:TYPER程序 不允许使用 双字节宽度的字符

无搜索,替换,保存文件,拼写检查,滚动,帮助等扩展功能。

(c) www.bcdaren.com, 2020

----------------------------------------------------------------*/

#include <windows.h>

#define BUFFER(x,y) *(pBuffer + y * cxBuffer + x)

TCHAR * pBuffer = NULL;

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

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,

 PSTR szCmdLine, int iCmdShow)

{

     static TCHAR szAppName[] = TEXT("Typer");

    (略)

     return msg.wParam;

}

LRESULT CALLBACK WndProc ( HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam)

{

     static DWORD dwCharSet = DEFAULT_CHARSET ;//#define DEFAULT_CHARSET 1

     static int cxChar, cyChar, cxClient, cyClient,

cxBuffer, cyBuffer,xCaret, yCaret ;

     //static TCHAR * pBuffer = NULL ;

     HDC hdc ;

     int x, y, i ;

     PAINTSTRUCT ps ;

     TEXTMETRIC tm ;

     switch (message)

     {

     case WM_INPUTLANGCHANGE:

          dwCharSet = wParam

          //继续执行下去

     case WM_CREATE:

          hdc = GetDC (hwnd) ;

          //创建逻辑字体

          SelectObject ( hdc, CreateFont (0, 0, 0, 0, 0, 0, 0, 0,

          dwCharSet, 0, 0, 0, FIXED_PITCH, NULL)) ;

          //获取字体信息

          GetTextMetrics (hdc, &tm) ;

          cxChar = tm.tmAveCharWidth ;

          cyChar = tm.tmHeight ;

          DeleteObject (SelectObject (hdc, GetStockObject (SYSTEM_FONT))) ;

          ReleaseDC (hwnd, hdc) ;

          //继续执行下去

     case WM_SIZE:

          // 获取窗口大小,以像素为单位

          if (message == WM_SIZE)

          {

               cxClient = LOWORD (lParam) ;

               cyClient = HIWORD (lParam) ;

          }

          // 计算窗口大小(字符)

          cxBuffer = max (1, cxClient / cxChar) ; //cxBuffer窗口字符宽度

          cyBuffer = max (1, cyClient / cyChar) ; //cyBuffer窗口字符高度

          // 为缓冲区分配内存并清除它 

          if (pBuffer != NULL)

               free (pBuffer) ;

          //创建保存窗口所有字符的缓冲区

          pBuffer = (TCHAR *) malloc (cxBuffer * cyBuffer * sizeof (TCHAR)) ;

          //初始化pBuffer为一个‘ ’空字符

          for (y = 0 ; y < cyBuffer ; y++)

               for (x = 0 ; x < cxBuffer ; x++)

                    BUFFER(x,y) = ' ' ;

          // 插入符号定位左上角

          xCaret = 0 ;

          yCaret = 0 ;

          if (hwnd == GetFocus ()) //插入符号为当前窗口---焦点窗口

//设置插入符号位置

               SetCaretPos (xCaret * cxChar, yCaret * cyChar) ;

          InvalidateRect (hwnd, NULL, TRUE) ; //重绘窗口

          return 0 ;

     //获得键盘焦点后发送到窗口

     case WM_SETFOCUS:

          // 创建和显示插入符号,指定大小,NULL表示实心

          CreateCaret (hwnd, NULL, cxChar, cyChar) ;

          SetCaretPos (xCaret * cxChar, yCaret * cyChar) ; //设置符号位置

          ShowCaret (hwnd) ; //显示符号

          return 0 ;

     //在失去键盘焦点之前立即发送到窗口

     case WM_KILLFOCUS:

          // 隐藏和删除插入符号

          HideCaret (hwnd) ; //隐藏符号

          DestroyCaret () ; //删除符号

          return 0 ;

     //击键消息---光标移动的处理

     case WM_KEYDOWN:

          switch (wParam)

          {

          case VK_HOME:

               xCaret = 0 ;

               break

          case VK_END:

               xCaret = cxBuffer - 1 ;

               break

          case VK_PRIOR: //Page Up

               yCaret = 0 ;

               break

          case VK_NEXT: //PageDown

               yCaret = cyBuffer - 1 ;

               break

          case VK_LEFT:

               xCaret = max (xCaret - 1, 0) ;

               break

          case VK_RIGHT:

               xCaret = min (xCaret + 1, cxBuffer - 1) ;

               break

          case VK_UP:

               yCaret = max (yCaret - 1, 0) ;

               break

          case VK_DOWN:

               yCaret = min (yCaret + 1, cyBuffer - 1) ;

               break

          case VK_DELETE: //注意VK_BACK键当字符消息去处理,这里只处理VK_DELETE

               //将该行从当前位置后面字符依次前移一格

               for (x = xCaret ; x < cxBuffer - 1 ; x++)

                    BUFFER(x, yCaret) = BUFFER(x + 1, yCaret);

               BUFFER(cxBuffer - 1, yCaret) = ' ';//该行最后一个设为空字符。

               //绘图前必须先隐藏插入符

               HideCaret(hwnd);

               hdc = GetDC(hwnd);

               SelectObject(hdc, CreateFont(0, 0, 0, 0, 0, 0, 0, 0,

                    dwCharSet, 0, 0, 0, FIXED_PITCH, NULL));

               TextOut(hdc, xCaret * cxChar, yCaret * cyChar,

                    &BUFFER(xCaret, yCaret),

                    cxBuffer - xCaret); //重新输出该行xCaret后面的文字

               DeleteObject(SelectObject(hdc, GetStockObject(SYSTEM_FONT)));

               ReleaseDC(hwnd, hdc);

               ShowCaret(hwnd);

               break;

          }

               SetCaretPos(xCaret * cxChar, yCaret * cyChar);

               return 0;

         

     //字符消息

     case WM_CHAR:

          for (i = 0 ; i < (int) LOWORD (lParam) ; i++)

          {

               //转义字符处理

               switch (wParam)

               {

               case '\b': // 退格

                    if (xCaret > 0)

                    {

                         xCaret--;

//1为repeat字段的值

                         SendMessage(hwnd, WM_KEYDOWN, VK_DELETE, 1);

                    }

                    break;

               case '\t': //Tab键,8个字符长度

                    do

                    {

                         SendMessage (hwnd, WM_CHAR, ' ', 1) ;

                    } while (xCaret % 8 != 0) ;

                    break ;

               case '\n': //换行符,改变y到下一行,x坐标没变。

                    if (++yCaret == cyBuffer)

                         yCaret = 0 ;

                    break ;

               case '\r': // 回车

                    xCaret = 0;

                    if (++yCaret == cyBuffer)

                         yCaret = 0;

                    break;

                //ESC键,清空屏幕 \xhh表示1到2位十六进制所代表的任意字符

               case '\x1B':

                    for (y = 0; y < cyBuffer; y++)

                         for (x = 0; x < cxBuffer; x++)

                              BUFFER(x, y) = ' ';

                    xCaret = 0;

                    yCaret = 0;

                    InvalidateRect(hwnd, NULL, FALSE);

                    break;

               default: // 字符编码

                    BUFFER(xCaret, yCaret) = (TCHAR)wParam;

                    HideCaret(hwnd);

                    hdc = GetDC(hwnd);

                    SelectObject(hdc, CreateFont(0, 0, 0, 0, 0, 0, 0, 0,

                         dwCharSet, 0, 0, 0, FIXED_PITCH, NULL));

                    TextOut(hdc, xCaret * cxChar, yCaret * cyChar,

                         &BUFFER(xCaret, yCaret), 1);

                    DeleteObject(

                         SelectObject(hdc, GetStockObject(SYSTEM_FONT)));

                    ReleaseDC(hwnd, hdc);

                    ShowCaret(hwnd);

                    if (++xCaret == cxBuffer)

                    {

                         xCaret = 0;

                         if (++yCaret == cyBuffer)

                              yCaret = 0;

                    }

                    break;

               }

          } 

          SetCaretPos (xCaret * cxChar, yCaret * cyChar) ;

          return 0 ;

     case WM_PAINT:

          hdc = BeginPaint (hwnd, &ps) ;

          SelectObject (hdc, CreateFont (0, 0, 0, 0, 0, 0, 0, 0,

               dwCharSet, 0, 0, 0, FIXED_PITCH, NULL)) ;

          for (y = 0 ; y < cyBuffer ; y++)

               TextOut (hdc, 0, y * cyChar, & BUFFER(0,y), cxBuffer) ;

          DeleteObject (SelectObject (hdc, GetStockObject (SYSTEM_FONT))) ;

          EndPaint (hwnd, &ps) ;

          return 0 ;

     case WM_DESTROY:

          if (pBuffer != NULL) free(pBuffer);

          PostQuitMessage(0);

          return 0;

     }

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

}

/*************************************************************************

CreateCaret:创建和窗口关联的插入符号

SetCaretPos:设置窗口内的插入符号的位置

ShowCaret   :显示插入符号

HideCaret   :隐藏插入符号

DestroyCaret:销毁插入符号

GetCaretPos :当前插入符号的位置

GetFocus函数:检索具有键盘焦点的窗口的句柄

**************************************************************************

WM_SETFOCUS消息:获得键盘焦点后发送到窗口

#define WM_SETFOCUS     0x0007

参数:wParam

失去键盘焦点的窗口句柄。此参数可以为NULL。

lParam:不使用此参数。

**************************************************************************

WM_KILLFOCUS消息:在失去键盘焦点之前立即发送到窗口

#define WM_SETFOCUS     0x0008

参数:wParam

失去键盘焦点的窗口句柄。此参数可以为NULL。

lParam:不使用此参数。

*/

       运行结果:

图5-7 文本编辑器插入符

 

总结

       实例TYPER.C创建了一个简单的文本编辑器。

●窗口过程首先通过M_INPUTLANGCHANGE消息获取当前字符集,然后在WM_CREATE消息中选入新创建的逻辑字体,并获取新逻辑字体的字符宽和高。

       ●在WM_SIZE消息中,当窗口客户区大小发生变化时,使用空格字符清空窗口客户区,然后将插入符置于窗口客户区的左上角,然后重绘窗口。【注意】前提时当前窗口为焦点窗口。

       ●当窗口获得焦点时,窗口过程处理M_SETFOCUS消息,创建、设置并显示插入符。

       ●当窗口失去焦点时,窗口过程处理WM_KILLFOCUS消息,隐藏并删除插入符。

       ●在按键消息WM_KEYDOWN中,处理HOME、END、PageUp、PageDown和上下左右箭头键,计算插入符的新位置。处理Delete键稍微复杂一些,先将当前位置后面的字符依次前移一个位置,并在该行字符的结尾处添加一个空格。【注意】移动字符时,先隐藏插入符,再选入新创建的逻辑字体绘制字符,绘制完成后重新显示插入符。所有字符重新绘制完成后,重新将插入符置于该行字符的结尾处。

       ●窗口过程在WM_CHAR消息代码块绘制字符。我们把字符分为两类:

       转义字符处理:

'\b'将字符位置减一,然后转为Delete按键消息处理。

'\t':转换为空格字符消息处理。

'\n':将字符yCaret加一(行数加一)。

'\r':将字符xCaret清零(列数清零)。

'\x1B':ESC键清空屏幕(窗口客户区输出空格),并将插入符坐标清零。

       正常可见字符的处理:与Delete键的处理过程类似,先隐藏插入符,然后绘制字符后再重新显示插入符,再将插入符置于下一个位置。

       ●WM_PAINT消息选入新的逻辑字体绘制所有字符。

       【注意】

       实例创建的简单文本编辑器并不完善,并不支持复制、粘贴、剪切、选择等功能,也没有对应的菜单选项。我们将在后续的章节中逐步完善此文本编辑器。

此外,当我们输入中文字符时,需要收到将插入符后移一个位置,等待输入下一个字符。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1855412.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

NUS、清华提出STAR:一句话生成高质量4D Avatar,代码已开源

©PaperWeekly 原创 作者 | Chai Zenghao 单位 | 新加坡国立大学博士生 研究方向 | 3D生成 背景 在计算机图形学和数字虚拟人领域&#xff0c;从简单的文本提示生成更真实、可交互的虚拟人物是是目前广受关注的研究课题。然而&#xff0c;先前的 3D Avatar 生成方法存在一…

陀螺仪LSM6DSV16X与AI集成(7)----FIFO数据读取与配置

陀螺仪LSM6DSV16X与AI集成.7--检测自由落体 概述视频教学样品申请源码下载主要内容生成STM32CUBEMX串口配置IIC配置CS和SA0设置串口重定向参考程序初始换管脚获取ID复位操作BDU设置设置量程设置FIFO水印设置速率使用流模式设置FIFO时间戳批处理速率使能时间戳FIFO状态寄存器演示…

【ajax核心05】宏任务与微任务

ES6之后引入Promise对象(用来管理异步任务)&#xff0c;让JS引擎也可以发起异步任务 一&#xff1a;异步任务分类 异步任务分为&#xff1a;宏任务与微任务 宏任务 由浏览器环境执行的异步代码 具体宏任务分类 微任务 由JS引擎执行的代码 创建Promise对象时&#xff0c;…

【鸿蒙】ERROR_GET_BUNDLE_INSTALLER_FAILED

错误信息 [ERROR_GET_BUNDLE_INSTALLER_FAILED] Troubleshooting guide $ hdc file send D:\Huawei\devEcoProjects\entry\build\default\outputs\default\entry-default-unsigned.hap /sdcard/e8a215ea7be1444197e6a58ebda7721f/entry-default-unsigned.hap Error while Depl…

Vue74-路由传参2

一、$route中的params参数 二、在配置路由的index.js文件中&#xff0c;声明传参 占位符用的什么名字&#xff0c;params里面的key就是什么。 三、<router-link>标签中传参 3-1、to字符串写法 3-2、to的对象写法 注意&#xff1a;若是用params携带参数&#xff0c;不…

联盟学习:技术原理、特点及适用场景

一、引言 随着大数据和人工智能技术的快速发展&#xff0c;数据成为了推动科技进步的重要资源。然而&#xff0c;在实际应用中&#xff0c;数据往往呈现出碎片化、分散化的特点&#xff0c;如何有效地利用这些数据成为了业界关注的焦点。联盟学习&#xff08;Federated Learni…

异地组网如何OEM?

在现代信息社会中&#xff0c;企业越来越需要跨地域进行数据传输与共享。面临的挑战却是如何在不暴露在公网的情况下&#xff0c;实现异地组网并保障数据的安全性。本文将介绍一种名为“异地组网OEM”的解决方案&#xff0c;该方案能够通过私有通道传输数据并对数据进行安全加密…

Docker Compose--安装Nginx--方法/实例

原文网址&#xff1a;Docker Compose--安装Nginx--方法/实例_IT利刃出鞘的博客-CSDN博客 简介 说明 本文介绍Docker Compose如何安装Nginx。 目录结构 ├── config │ ├── cert │ │ ├── xxx_bundle.pem │ │ └── xxx.key │ ├── conf.d │ …

解决Windows下移动硬盘无法弹出的问题:\$Extend\$RmMetadata\$TxfLog\$TxfLog.blf

想弹出移动硬盘时&#xff0c;Windows告诉我设备正在使用 然后我使用LockHunter查看到底是哪个应用在使用我的移动硬盘&#xff0c;发现是 System(PID 4) E x t e n d Extend ExtendRmMetadata T x f L o g TxfLog TxfLogTxfLog.blf这个文件正在使用 这是一个索引文件 解决 …

黑马HarmonyOS-NEXT星河版实战

"黑马HarmonyOS-NEXT星河版实战"课程旨在帮助学员深入了解HarmonyOS-NEXT星河版操作系统的开发和实际应用。学员将学习操作系统原理、应用开发技巧和界面设计&#xff0c;通过实战项目提升技能。课程注重实践与理论相结合&#xff0c;为学员提供全面的HarmonyOS开发经…

[分布式网络通讯框架]----ZooKeeper下载以及Linux环境下安装与单机模式部署(附带每一步截图)

首先进入apache官网 点击中间的see all Projects->Project List菜单项进入页面 找到zookeeper&#xff0c;进入 在Zookeeper主页的顶部点击菜单Project->Releases&#xff0c;进入Zookeeper发布版本信息页面&#xff0c;如下图&#xff1a; 找到需要下载的版本 …

段,页,段页,三种内存(RAM)管理机制分析

段&#xff0c;页&#xff0c;段页 是为实现虚拟内存而产生的技术。直接使用物理内存弊端&#xff1a;地址空间不隔离&#xff0c;内存使用效率低。 段 段&#xff1a;就是按照二进制文件的格式&#xff0c;在内存给进程分段&#xff08;包括堆栈、数据段、代码段&#xff09;。…

仿迪恩城市门户分类信息网discuz模板

Discuz x3.3模板 仿迪恩城市门户分类信息网 (GBK) Discuz模板 仿迪恩城市门户分类信息网(GBK)

Spring 内部类获取不到@Value配置值问题排查(附Spring代理方式)

目录 一、实例问题 1、现象 2、原因 3、解决 二、Spring的代理模式 1、静态代理&#xff08;Static Proxy&#xff09; 1&#xff09;原理 2&#xff09;优缺点 3&#xff09;代码实现 2、JDK动态代理&#xff08;JDK Dynamic Proxy&#xff09; 1&#xff09;原理 …

解决 Pyecharts 在 jupyter Lab 上运行图片空白问题!

文章目录 &#x1f3f3;️‍&#x1f308; 1 提前声明 JUPYTER_LAB&#x1f3f3;️‍&#x1f308; 2 load_javascript(&#xff09;&#x1f3f3;️‍&#x1f308; 3 render_notebook()&#x1f3f3;️‍&#x1f308; 4 图示&#x1f3f3;️‍&#x1f308; 5 可视化项目源码…

LoRaWAN在嵌入式网络通信中的应用:打造高效远程监控系统(附代码示例)

引言 随着物联网&#xff08;IoT&#xff09;技术的发展&#xff0c;远程监控系统在各个领域的应用越来越广泛。LoRaWAN&#xff08;Long Range Wide Area Network&#xff09;作为一种低功耗广域网通信协议&#xff0c;因其长距离传输、低功耗和高可靠性等特点&#xff0c;成为…

qt开发-10_LineEdit

QLineEdit 小部件是一个单行文本编辑器。行编辑允许用户使用一组有用的编辑函数输入和 编辑一行纯文本。包括撤消和重做、剪切和粘贴以及拖放。通过更改行编辑的 echoMode()&#xff0c;它 还可以用作“只写”字段&#xff0c;用于输入如密码等. 创建好项目后&#xff0c;进入 …

407串口01发送

实验一&#xff1a; 工程。 链接&#xff1a;https://pan.baidu.com/s/1g8DV4yZWOix0BbcZ08LYDQ?pwd2176 提取码&#xff1a;2176串口1的使用。发送功能。 单片机发送信息到电脑。 通过串口进行通信。 首先单片机这边。 单片机这边&#xff0c;需要对单片机的串口模块进行使…

【面试干货】Java中的四种引用类型:强引用、软引用、弱引用和虚引用

【面试干货】Java中的四种引用类型&#xff1a;强引用、软引用、弱引用和虚引用 1、强引用&#xff08;Strong Reference&#xff09;2、软引用&#xff08;Soft Reference&#xff09;3、弱引用&#xff08;Weak Reference&#xff09;4、虚引用&#xff08;Phantom Reference…

爱心商城管理系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;企业管理&#xff0c;用户管理&#xff0c;论坛管理&#xff0c;商品管理&#xff0c;公告管理&#xff0c;用户捐赠 企业账户功能包括&#xff1a;系统首页&#xff0c;个人中…