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

当你向程序中输入文本时,通常会有下划线、竖线或方框指示你输入的下一个字符将出现在屏幕上的位置。你也许认为这是“光标”,但在编写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.mzph.cn/pingmian/33063.shtml

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

相关文章

市政道路乙级资质申报的筹备与执行

一、筹备阶段 1. 政策研读与自我评估 详细了解资质标准&#xff1a;仔细阅读最新的资质申报指南和相关法规&#xff0c;明确乙级资质的具体要求&#xff0c;包括企业资本、技术人员配置、过往业绩等。自我评估&#xff1a;对照资质标准&#xff0c;对企业现状进行全面评估&am…

河南省乙级建筑设计资质标准案例分析

河南省乙级建筑设计资质标准案例分析 虽然我没有具体的河南省乙级建筑设计资质的详细案例分析&#xff0c;但我可以根据一般性的资质标准和流程&#xff0c;构建一个简化的案例分析框架&#xff0c;帮助理解乙级建筑设计资质的获取和应用。 案例背景&#xff1a; 假设“华豫…

如何评估LabVIEW需求中功能的必要性和可行性

评估LabVIEW需求中功能的必要性和可行性涉及多个方面的分析&#xff0c;包括需求的重要性、技术可行性、资源需求以及潜在风险。以下是一个详细的评估方法&#xff1a; ​ 一、功能必要性评估 需求来源和目的&#xff1a; 来源&#xff1a;需求来自哪里&#xff1f;是客户、市…

Lua 绕过元表

Lua 绕过元表&#xff0c;直接访问 table 的字段。 绕过元表 rawset(table, index, value)&#xff0c;在不触发元方法的情况下&#xff0c;设置 table[index] 的值为 value。 rawget(table, index)&#xff0c;在不触发元方法的情况下&#xff0c;获取 table[index] 的值。…

写一个坏越的个人天地(二)

小红书上搜了下博客,感觉好像没有让自己喜欢的。昨天刚好学了点grid布局,来试试 菜单栏直接使用el-menu 下边布局就用grid局部了,这块初步想法是轮播+你的天气和我的天气+自我介绍 天气的话,这边要先找一下有没有天气的api 我这边百度搜了个聚合的api,一天可以免费调用5…

Linux系统iptables应用SNAT和DNAT

一、SNAT 1.SNAT应用环境 局域网主机共享单个公网IP地址接入Internet (私有IP不能在Internet中正常路由) 2.SNAT原理 源地址转换&#xff0c;根据指定条件修改数据包的源IP地址&#xff0c;通常被叫做源映谢 数据包从内网发送到公网时&#xff0c;SNAT会把数据包的源IP由私…

网页抓取和网页爬取之间有何区别?

随着互联网的发展和信息的爆炸式增长&#xff0c;数据收集和处理已成为企业和个人不可或缺的需求。在此背景下&#xff0c;网页抓取和网络爬虫已成为两种常见的数据收集方法。虽然这两种方法看似相似&#xff0c;但它们的方法和目标存在显著差异。本文将为您详细介绍网页抓取和…

H4020 12V24V36V40V1A 同步降压芯片IC Buck-DCDC 低功耗,高效率 100%占空比

H4020是一款12V24V36V40V1A的同步降压&#xff08;Buck&#xff09;DC-DC转换器&#xff0c;专为需要高效率、低功耗和精确电压/电流控制的应用而设计。它内置了高压MOSFET&#xff0c;支持宽范围的输入电压&#xff08;5V-36V&#xff09;&#xff0c;并能提供高达1A的持续输出…

【最佳实践】你肯定不知道的useEffect 钩子的工作原理?知其然不知其所以然

大家好&#xff0c;我是DX3906 useEffect 是 React 库中用于处理副作用的钩子&#xff08;Hook&#xff09;。它允许你在函数组件中执行与 DOM 相关的操作和生命周期函数类似的逻辑。useEffect 钩子的工作原理涉及到 React 的渲染流程和副作用的调度机制。以下是其工作原理的详…

Elasticsearch 使用误区之一——将 Elasticsearch 视为关系数据库!

Elasticsearch 是一个强大的工具&#xff0c;尤其在全文检索、实时分析、机器学习、地理数据应用、日志和事件数据分析、安全信息和事件管理等场景有大量的应用。 然而&#xff0c;Elastic Stack 技术栈的选型及应用效能取决于正确的使用方式。选型错误或者误用 Elasticsearch …

Avalonia 常用控件二 Menu相关

1、Menu 添加代码如下 <Button HorizontalAlignment"Center" Content"Menu/菜单"><Button.Flyout><MenuFlyout><MenuItem Header"打开"/><MenuItem Header"-"/><MenuItem Header"关闭"/&…

LeetCode35.搜索插入位置

LeetCode刷题记录 文章目录 &#x1f4dc;题目描述&#x1f4a1;解题思路⌨C代码 &#x1f4dc;题目描述 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。 如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须…

IOS Swift 从入门到精通:闭包第二部分,高级闭包

文章目录 当闭包接受参数时使用闭包作为参数当闭包返回值时使用闭包作为参数简写参数名称高级闭包: 具有多个参数的闭包高级闭包:从函数返回闭包高级闭包:捕获值总结当闭包接受参数时使用闭包作为参数 这是闭包开始变得有点像线路噪声的地方:传递给函数的闭包也可以接受它…

磁盘未格式化:深度解析、恢复策略与预防措施

一、磁盘未格式化的定义与现象 在计算机存储领域&#xff0c;磁盘未格式化通常指的是磁盘分区或整个磁盘的文件系统信息出现丢失或损坏的情况&#xff0c;导致操作系统无法正确读取和识别磁盘上的数据。当尝试访问这样的磁盘时&#xff0c;系统往往会弹出一个警告框&#xff0…

Makefile实战论(一)

为什么写这个呢&#xff0c;其实我有系统学过Makefile和CMake。但是因为用的不是很多或者说没有深入的使用场景&#xff0c;导致我不是很熟练&#xff0c;或者说没法优雅地使用。刚好最近对Linux的嵌入式编程比较感兴趣&#xff0c;借着demo来分析一下资深工程师写的Makefile&a…

【Python】使用matplotlib绘制图形(曲线图、条形图、饼图等)

文章目录 一、什么是matplotlib二、matplotlib 支持的图形三、如何使用matplotlib1. 安装matplotlib2. 导入matplotlib.pyplot3. 准备数据4. 绘制图形5. 定制图形6. 显示或保存图形7. &#xff08;可选&#xff09;使用subplots创建多个子图注意事项&#xff1a; 四、常见图形使…

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

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

880基础题查漏补缺

高等数学 函数极限连续 无穷大包括∞与-∞ 无穷小≠0 0无穷大0 有界函数无穷大不定 极限不存在极限不存在极限可能存在可能不存在 极限存在极限存在极限存在 等价无穷小替换的x可广义化&#xff0c;比如sin(ax2)~ax2 lim x n e x \dfrac{x^n}{e^x} exxn​时&#xff0c;e…

安卓逆向经典案例—H5appXX运维

H5app的class不一定是android.webkit.WebView 也可能是腾讯X5内核或者是uc webview 殊途同归也要去hook webview的系统函数和可调式方法setWebContentsDebuggingEnabled。突破sign算法&#xff0c;输出协议和加密算法的作用是什么&#xff1f;分析c-sign值 在加密的位置下断点 …

第三十七章 添加和使用自定义标题元素 - 自定义标头的继承

文章目录 第三十七章 添加和使用自定义标题元素 - 自定义标头的继承自定义标头的继承示例 在 SOAPHEADERS 参数中指定支持的标头元素自定义标头的继承 第三十七章 添加和使用自定义标题元素 - 自定义标头的继承 自定义标头的继承 如果创建此Web 服务的子类&#xff0c;该子类…