《Windows API每日一练》4.6 矩形、区域和裁剪

在前面的4.3节中我们讲述了绘制矩形的API函数Rectangle和RoundRect。本节我们将介绍另外一组使用RECT矩形结构和区域的绘图函数。

本节必须掌握的知识点:

        矩形

        第28练:绘制随机矩形

        矩形与区域的裁剪

        第29练:区域裁剪

4.6.1 矩形

FillRect函数

FillRect函数用于在指定的设备上下文(Device Context)中,用指定的画刷(Brush)填充一个矩形区域。FillRect函数的函数原型如下:

int FillRect(

  HDC        hDC,   //指向目标设备上下文的句柄

  const RECT *lprc,      //指向RECT结构的指针,指定要填充的矩形区域

  HBRUSH     hbr     //指向画刷的句柄,用于指定填充矩形的颜色和样式

);

函数返回一个非零值表示成功,返回零表示失败。

●以下是使用FillRect函数的示例代码:

HDC hdc = GetDC(hwnd);  // 获取窗口的设备上下文

RECT rect;

HBRUSH hBrush;

SetRect(&rect, 100, 100, 200, 200);  // 设置矩形的坐标

hBrush = CreateSolidBrush(RGB(255, 0, 0));  // 创建红色实心画刷

FillRect(hdc, &rect, hBrush);  // 使用画刷填充矩形区域

DeleteObject(hBrush);  // 删除画刷对象

ReleaseDC(hwnd, hdc);  // 释放设备上下文

FillRect函数对于在设备上下文中绘制填充矩形非常有用,可以用于创建背景色、填充区域、绘制图形等操作。

FrameRect函数

FrameRect函数用于绘制指定矩形区域的边框。函数原型如下:

BOOL FrameRect(

  HDC        hdc,    //设备环境句柄

  const RECT *lprc,      //指向RECT结构的指针,用于指定要绘制边框的矩形区域

  HBRUSH     hbr     //画刷句柄(Brush Handle),用于指定绘制边框的颜色或图案

);

FrameRect函数返回一个BOOL值,表示绘制成功与否。如果绘制成功,返回值为非零;如果失败,返回值为零。

       FrameRect函数使用指定的画刷(可以是单色画刷或带图案的画刷)来绘制矩形的边框。边框的粗细和样式可以通过选择不同的画刷对象来实现。

需要注意的是,FrameRect函数绘制的边框不包括矩形区域本身,只会绘制边框线条。如果需要同时填充矩形区域的内部,请使用其他函数,如FillRect函数。

例如,下面的代码片段演示了如何使用FrameRect函数绘制一个红色的边框:

RECT rect = { 100, 100, 200, 200 }; // 定义要绘制边框的矩形区域

HBRUSH hbr = CreateSolidBrush(RGB(255, 0, 0)); // 创建一个红色画刷

FrameRect(hdc, &rect, hbr); // 绘制红色边框

DeleteObject(hbr); // 删除

InvertRect函数

InvertRect函数用于在指定的设备上下文(Device Context)中反转(翻转)一个矩形区域的颜色。InvertRect函数的函数原型如下:

BOOL InvertRect(

  HDC        hDC,   //指向目标设备上下文的句柄

  const RECT *lprc       //指向RECT结构的指针,指定要反转颜色的矩形区域

);

函数返回一个布尔值,表示是否成功反转矩形区域的颜色。

以下是使用InvertRect函数的示例代码:

HDC hdc = GetDC(hwnd);  // 获取窗口的设备上下文

RECT rect;

SetRect(&rect, 100, 100, 200, 200);  // 设置矩形的坐标

InvertRect(hdc, &rect);  // 反转矩形区域的颜色

ReleaseDC(hwnd, hdc);  // 释放设备上下文

上述代码中,通过调用GetDC函数获取窗口的设备上下文,并定义一个RECT结构rect。然后,使用SetRect函数设置矩形的坐标。接下来,通过调用InvertRect函数将矩形区域的颜色进行反转,即将原来的颜色取反。最后,通过调用ReleaseDC函数释放设备上下文。

InvertRect函数对于在设备上下文中反转矩形区域的颜色非常有用,可以用于创建反色效果、闪烁效果等视觉效果。

SetRect函数

SetRect函数是Windows API中的一个函数,用于设置一个RECT结构的坐标。SetRect函数的函数原型如下:

void SetRect(

  LPRECT lprc,      //指向RECT结构的指针,用于接收设置后的坐标信息

  int    left,         //指定矩形的左上角和右下角的坐标

  int    top,

  int    right,

  int    bottom

);

以下是使用SetRect函数的示例代码:

       RECT rect;

SetRect(&rect, 100, 100, 200, 200);  // 设置矩形的坐标

SetRect函数用于设置RECT结构的坐标,方便地定义一个矩形区域的位置和大小。

OffsetRect函数

OffsetRect函数用于将一个RECT结构的坐标进行偏移或移动。OffsetRect函数的函数原型如下:

BOOL OffsetRect(

  LPRECT lprc,      //指向RECT结构的指针,指定要进行偏移或移动的矩形

  int    dx,          // dx和dy分别表示在x轴和y轴上的偏移量

  int    dy

);

函数返回一个布尔值,表示是否成功进行矩形的偏移或移动。

以下是使用OffsetRect函数的示例代码:

RECT rect;

int dx = 10;

int dy = 20;

SetRect(&rect, 100, 100, 200, 200);  // 设置矩形的坐标

OffsetRect(&rect, dx, dy);  // 对矩形进行偏移或移动

// 偏移后的矩形坐标

int newLeft = rect.left;

int newTop = rect.top;

int newRight = rect.right;

int newBottom = rect.bottom;

上述代码中,定义了一个RECT结构rect,并定义了偏移量dx和dy。然后,通过调用SetRect函数将矩形的坐标设置为左上角(100, 100)、右下角(200, 200)。接下来,通过调用OffsetRect函数对矩形进行偏移或移动,将矩形的坐标在x轴上向右偏移10个单位,在y轴上向下偏移20个单位。最后,可以通过读取偏移后的矩形坐标,即rect的左上角和右下角的坐标,来获取偏移后的矩形位置。

OffsetRect函数对于在RECT结构中对矩形进行偏移或移动非常有用,可以用于调整矩形的位置、进行布局等操作。

InflateRect函数

InflateRect函数用于在原有的RECT结构基础上扩大或缩小矩形的尺寸。InflateRect函数的函数原型如下:

BOOL InflateRect(

  LPRECT lprc,      //指向RECT结构的指针,指定要进行尺寸调整的矩形

  int    dx,          // dx和dy分别表示在x轴和y轴方向上的扩展或收缩量

  int    dy

);

函数返回一个布尔值,表示是否成功进行矩形的尺寸调整。

以下是使用InflateRect函数的示例代码:

RECT rect;

int dx = 10;

int dy = 20;

SetRect(&rect, 100, 100, 200, 200);  // 设置矩形的坐标

InflateRect(&rect, dx, dy);  // 扩大或缩小矩形的尺寸

// 调整后的矩形坐标

int newLeft = rect.left;

int newTop = rect.top;

int newRight = rect.right;

int newBottom = rect.bottom;

上述代码中,定义了一个RECT结构rect,并定义了扩展或缩小量dx和dy。然后,通过调用SetRect函数将矩形的坐标设置为左上角(100, 100)、右下角(200, 200)。接下来,通过调用InflateRect函数对矩形的尺寸进行调整,将矩形的宽度在x轴上增加10个单位,在y轴上增加20个单位。最后,可以通过读取调整后的矩形坐标,即rect的左上角和右下角的坐标,来获取调整后的矩形尺寸。

InflateRect函数对于在RECT结构中调整矩形的尺寸非常有用,可以用于动态改变矩形的大小、进行裁剪等操作。

SetRectEmpty函数

SetRectEmpty函数是Windows API中的一个函数,用于将一个RECT结构设置为空矩形。

SetRectEmpty函数的函数原型如下:

       BOOL SetRectEmpty(

             LPRECT lprc   //指向RECT结构的指针,指定要设置为空矩形的RECT

);

       函数返回一个布尔值,表示是否成功将RECT设置为空矩形。

以下是使用SetRectEmpty函数的示例代码:

       RECT rect;

SetRectEmpty(&rect);  // 设置rect为空矩形

上述代码中,定义了一个RECT结构rect。然后,通过调用SetRectEmpty函数将rect设置为空矩形。

空矩形是一个宽度和高度都为0的矩形,即左上角坐标和右下角坐标相等。

SetRectEmpty函数对于将RECT结构设置为空矩形非常有用,可以用于初始化矩形或在需要时将矩形重置为空矩形。

CopyRect函数

CopyRect函数用于将一个RECT结构的坐标复制到另一个RECT结构。

CopyRect函数的函数原型如下:

BOOL CopyRect(

  LPRECT lprcDst,        //指向目标RECT结构的指针,用于接收源RECT结构的坐标

  const RECT *lprcSrc //指向源RECT结构的指针,指定要复制坐标的源RECT结构

);

函数返回一个布尔值,表示是否成功将源RECT结构的坐标复制到目标RECT结构。

以下是使用CopyRect函数的示例代码:

RECT rectSrc;

RECT rectDst;

SetRect(&rectSrc, 100, 100, 200, 200);  // 设置源矩形的坐标

CopyRect(&rectDst, &rectSrc);  // 复制源矩形的坐标到目标矩形

// 目标矩形坐标

int dstLeft = rectDst.left;

int dstTop = rectDst.top;

int dstRight = rectDst.right;

int dstBottom = rectDst.bottom;

上述代码中,定义了两个RECT结构rectSrc和rectDst。然后,通过调用SetRect函数将源矩形的坐标设置为左上角(100, 100)、右下角(200, 200)。接下来,通过调用CopyRect函数将源矩形的坐标复制到目标矩形rectDst。最后,可以通过读取目标矩形坐标,即rectDst的左上角和右下角的坐标,来获取复制后的矩形位置。

CopyRect函数对于在不同的RECT结构之间复制矩形的坐标非常有用,可以用于复制、传递矩形的位置信息。

大多数情况下,还有一些简单的代码可以实现与这些函数相同的功能。例如,复制结构时,可以通过逐个字段的结构复制操作,来代替调用CopyRect函数,如下面的语句:

DestRect = SrcRect ;

IntersectRect函数

IntersectRect函数用于计算两个矩形的交集,即它们重叠的部分。IntersectRect函数的函数原型如下:

BOOL IntersectRect(

  LPRECT lprcDst,        //指向目标RECT结构的指针,用于接收两个源RECT结构的交集

  const RECT *lprcSrc1,//指向源RECT结构的指针1

  const RECT *lprcSrc2//指向源RECT结构的指针2

);

函数返回一个布尔值,表示是否成功计算出两个矩形的交集。

以下是使用IntersectRect函数的示例代码:

RECT rect1;

RECT rect2;

RECT rectIntersect;

SetRect(&rect1, 100, 100, 200, 200);  // 设置矩形1的坐标

SetRect(&rect2, 150, 150, 250, 250);  // 设置矩形2的坐标

BOOL result = IntersectRect(&rectIntersect, &rect1, &rect2);  // 计算两个矩形的交集

if (result)

{

    // 交集矩形坐标

    int intersectLeft = rectIntersect.left;

    int intersectTop = rectIntersect.top;

    int intersectRight = rectIntersect.right;

    int intersectBottom = rectIntersect.bottom;

}

上述代码中,定义了两个RECT结构rect1和rect2,并定义了一个用于接收交集的RECT结构rectIntersect。然后,通过调用SetRect函数分别设置矩形1和矩形2的坐标。接下来,通过调用IntersectRect函数计算矩形1和矩形2的交集,并将结果存储在rectIntersect中。最后,可以通过读取交集矩形的坐标,即rectIntersect的左上角和右下角的坐标,来获取两个矩形的交集位置。

IntersectRect函数对于计算两个矩形的交集非常有用,可以用于碰撞检测、裁剪等应用场景。

UnionRect函数

UnionRect函数是Windows API中的一个函数,用于计算两个矩形的并集,即包含这两个矩形的最小矩形。UnionRect函数的函数原型如下:

BOOL UnionRect(

  LPRECT lprcDst,        //指向目标RECT结构的指针,用于接收两个源RECT结构的并集

  const RECT *lprcSrc1,//指向源RECT结构的指针1

  const RECT *lprcSrc2//指向源RECT结构的指针2

);

函数返回一个布尔值,表示是否成功计算出两个矩形的并集。

以下是使用UnionRect函数的示例代码:

RECT rect1;

RECT rect2;

RECT rectUnion;

SetRect(&rect1, 100, 100, 200, 200);  // 设置矩形1的坐标

SetRect(&rect2, 150, 150, 250, 250);  // 设置矩形2的坐标

BOOL result = UnionRect(&rectUnion, &rect1, &rect2);  // 计算两个矩形的并集

if (result)

{

    // 并集矩形坐标

    int unionLeft = rectUnion.left;

    int unionTop = rectUnion.top;

    int unionRight = rectUnion.right;

    int unionBottom = rectUnion.bottom;

}

上述代码中,定义了两个RECT结构rect1和rect2,并定义了一个用于接收并集的RECT结构rectUnion。然后,通过调用SetRect函数分别设置矩形1和矩形2的坐标。接下来,通过调用UnionRect函数计算矩形1和矩形2的并集,并将结果存储在rectUnion中。最后,可以通过读取并集矩形的坐标,即rectUnion的左上角和右下角的坐标,来获取两个矩形的并集位置。

UnionRect函数对于计算两个矩形的并集非常有用,可以用于合并矩形、计算包围框等应用场景。

IsRectEmpty函数

IsRectEmpty函数是Windows API中的一个函数,用于检查一个RECT结构是否为空矩形。IsRectEmpty函数的函数原型如下:

BOOL IsRectEmpty(

  const RECT *lprc       //指向要检查的RECT结构的指针

);

函数返回一个布尔值,表示指定的RECT结构是否为空矩形。如果RECT结构的宽度和高度都为0,则被认为是空矩形,函数返回TRUE;否则,函数返回FALSE。

以下是使用IsRectEmpty函数的示例代码:

RECT rect1;

RECT rect2;

SetRect(&rect1, 100, 100, 200, 200);  // 设置矩形1的坐标

SetRectEmpty(&rect2);  // 设置矩形2为空矩形

BOOL isEmpty1 = IsRectEmpty(&rect1);  // 检查矩形1是否为空矩形

BOOL isEmpty2 = IsRectEmpty(&rect2);  // 检查矩形2是否为空矩形

上述代码中,定义了两个RECT结构rect1和rect2。通过调用SetRect函数设置了矩形1的坐标,使其不为空矩形。而通过调用SetRectEmpty函数设置了矩形2为空矩形。接下来,通过调用IsRectEmpty函数分别检查矩形1和矩形2是否为空矩形,返回的布尔值isEmpty1和isEmpty2表示检查结果。

IsRectEmpty函数对于判断一个RECT结构是否为空矩形非常有用,可以用于条件判断、验证矩形是否有效等应用场景。

PtInRect函数

PtInRect函数是Windows API中的一个函数,用于判断一个点是否在一个矩形内部。

PtInRect函数的函数原型如下:

       BOOL PtInRect(

             const RECT *lprc,   //指向要检查的RECT结构的指针,表示要进行判断的矩形

            POINT       pt   //是一个POINT结构,表示要检查的点的坐标

);

       函数返回一个布尔值,表示指定的点是否在矩形内部。如果点在矩形内部,则返回TRUE;否则,返回FALSE。

以下是使用PtInRect函数的示例代码:

RECT rect;

POINT point;

SetRect(&rect, 100, 100, 200, 200);  // 设置矩形的坐标

point.x = 150;  // 设置要检查的点的X坐标

point.y = 150;  // 设置要检查的点的Y坐标

BOOL isPointInRect = PtInRect(&rect, point);  // 判断点是否在矩形内部

上述代码中,定义了一个RECT结构rect,并使用SetRect函数设置了矩形的坐标。然后,定义了一个POINT结构point,并设置了要检查的点的坐标。接下来,通过调用PtInRect函数判断点point是否在矩形rect内部,返回的布尔值isPointInRect表示判断结果。

PtInRect函数对于判断一个点是否在一个矩形内部非常有用,可以用于鼠标事件处理、碰撞检测等应用场景。

4.6.2 第28练:绘制随机矩形

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

028  WIN32 API 每日一练

     第28个例子RANDRECT.C:绘制随机矩形

      PeekMessage函数

      SetRect函数

      CreateSolidBrush函数

      FillRect函数

(c) www.bcdaren.com, 2020

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

#include <windows.h>

#include <stdlib.h>

//int cxClient,cyClient;

void DrawRectangle(HWND hwnd);

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

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,

 PSTR szCmdLine, int iCmdShow)

{

     //static int cxClient, cyClient;//不可以,改为全局变量

     static TCHAR szAppName[] = TEXT ("RandRect.C") ;

    (略)

     ShowWindow (hwnd, iCmdShow) ;

     UpdateWindow (hwnd) ;

     //消息循环

     while (TRUE)

     {

          if (PeekMessage(&msg, NULL, 0, 0,PM_REMOVE))//消息队列不为空

          {

               if (msg.message == WM_QUIT)//如果是WM_QUIT消息退出循环

                    break;

               TranslateMessage(&msg);

               DispatchMessage(&msg);

          }

          else//消息队列为空

          {

               DrawRectangle(hwnd);//绘制随机矩形

          }

     }

     return msg.wParam ;

}

//绘制随机矩形

void DrawRectangle(HWND hwnd)

{

     HBRUSH hBrush;

     HDC hdc;

     RECT rect;

    

     if (cxClient == 0 || cyClient == 0)

          return;

     SetRect(&rect,rand() %cxClient,rand()% cyClient,rand() %cxClient,rand()% cyClient);

//生成画刷,取随机色

     hBrush = CreateSolidBrush(RGB(rand()%256,rand()%256,rand()%256));

     hdc = GetDC(hwnd);//获取设备环境句柄

     FillRect(hdc,&rect,hBrush);//填充矩形    

     ReleaseDC(hwnd,hdc);//释放设备环境句柄

     DeleteObject(hBrush);//删除画刷

}

//窗口过程

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

{

     switch (message)

     {

     case WM_SIZE:

          cxClient = LOWORD(lParam);

          cyClient = HIWORD(lParam);

          return 0 ;

     case WM_DESTROY:

          PostQuitMessage(0);

          return 0;

     }

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

}

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

PeekMessage函数:调度传入的已发送消息,检查线程消息队列中是否有已发布消息,并检索消息(如果存在)。

BOOL PeekMessageA(

  LPMSG lpMsg,           //指向接收消息信息的MSG结构的指针

  HWND  hWnd,            //要获取其消息的窗口的句柄。该窗口必须属于当前线程

  UINT  wMsgFilterMin,   //在要检查的消息范围内的第一条消息的值

  UINT  wMsgFilterMax,   //在要检查的消息范围内的最后一条消息的值

  UINT  wRemoveMsg       //指定如何处理消息。此参数可以是以下一个或多个值

                         //PM_REMOVE允许一个程序检查程序队列中的下一个消息,而不是真实地获得并删除它看到的消息。

);

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

SetRect函数:设置指定矩形的坐标。这等效于将left,top,right和bottom参数分配给RECT结构的适当成员。

BOOL SetRect(

  LPRECT lprc, //指向包含要设置的矩形的RECT结构的指针

  int    xLeft,

  int    yTop,

  int    xRight,

  int    yBottom

);

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

FillRect函数:通过使用指定的刷子填充的矩形。此功能包括左侧和顶部边框,但不包括矩形的右侧和底部边框

int FillRect(

  HDC        hDC,

  const RECT *lprc, //指向RECT结构的指针,该结构包含要填充的矩形的逻辑坐标。

  HBRUSH     hbr    //画刷句柄

);

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

CreateSolidBrush函数:创建具有指定的纯色的逻辑刷

HBRUSH CreateSolidBrush(

  COLORREF color    //要创建COLORREF颜色值,请使用RGB宏

);

*/

       运行结果:

图4-16 绘制随机矩形

 

总结

       1.上述实例的核心是PeekMessage函数,Peek是窥探的意思,该函数用于从消息队列中检索并移除一个消息(如果存在)。函数返回一个布尔值,表示是否成功检索到消息。如果存在消息并成功检索到,返回TRUE;否则,返回FALSE。

       我们将消息循环中的GetMessage函数替换为PeekMessage函数,如果窥探到消息队列中有消息,且不是WM_QUIT消息则翻译和转发消息,是WM_QUIT消息则退出消息循环。如果消息队列中没有消息,则绘制随机矩形。

       GetMessage与PeekMesssage的区别:

GetMessage

PeekMessage

作用

获取一条消息,并从消息队列里删掉除该消息(除WM_PAINT外)。

检查消息队列的消息,是否删除,取决于最后一个参数是PM_REMOVE或PM_NOREMOVE。

控制权

获得消息,才返回。

立即返回,不管是否有消息

返回值

获得非WM_QUIT消息时,返回非零

获得WM_QUIT时,返回0

TRUE表示有消息,FALSE表示没有消息。

       2.随机矩形的绘制方法:

       调用SetRect函数设置随机大小的矩形;

       调用CreateSolidBrus函数生成随机颜色的画刷;

       调用GetDC获取设备环境句柄;

       调用FillRect函数填充随机矩形;

       最后调用ReleaseDC函数是释放设备环境句柄,调用DeleteObject函数删除创建的GDI对象画刷。

       3.动手实验:假如将变量int cxClient, cyClient设置为static变量,将无法通过编译。需要将其定义为全局变量。

4.6.3 矩形与区域的裁剪

在前面的章节中我们已经介绍了GDI对象:画笔、画刷。本小节将介绍另外一个GDI对象:区域。

区域在剪裁中也扮演着重要角色。InvalidRect函数使显示的矩形区域无效,并产生一 个WM_PAINT消息。例如,可以使用InvalidateRect函数来擦除客户区的内容,并产生一 个WM_PAINT消息:

InvalidateRect (hwnd, NULL, TRUE);

       ■无效区域和有效区域

可以通过调用GetUpdateRect函数获取无效矩形的坐标,并且使用ValidateRect函数使客户区的矩形有效。当接收到一个WM_PAINT消息时,PAINTSTRUCT结构中的无效矩形的 坐标是可以利用的。这个结构是通过BeginPaint函数填充的。这个无效矩形也定义了一个 “剪裁区域”。不能在剪裁区域之外绘图。

●GetUpdateRect函数

GetUpdateRect函数用于获取指定窗口的更新区域的矩形坐标。GetUpdateRect函数的函数原型如下:

BOOL GetUpdateRect(

  HWND  hWnd, //指定窗口的句柄,表示要获取更新区域的窗口

  LPRECT lpRect,   //指向RECT结构的指针,用于接收获取到的更新区域的矩形坐标

  BOOL  bErase  //一个布尔值,指定在绘制更新区域之前是否擦除背景

);

函数返回一个布尔值,表示是否成功获取到更新区域的矩形坐标。如果成功获取到,返回TRUE;否则,返回FALSE。

以下是使用GetUpdateRect函数的示例代码:

HWND hWnd = GetDesktopWindow();  // 获取桌面窗口的句柄

RECT rect;

// 获取更新区域的矩形坐标,不擦除背景

BOOL result = GetUpdateRect(hWnd, &rect, FALSE);

if (result)

{

    // 成功获取到更新区域的矩形坐标

    // 可以在矩形区域内进行绘制操作

}

上述代码中,通过调用GetDesktopWindow函数获取桌面窗口的句柄hWnd。然后,定义了一个RECT结构rect,用于接收更新区域的矩形坐标。接下来,通过调用GetUpdateRect函数获取桌面窗口的更新区域的矩形坐标,参数bErase设置为FALSE,表示不擦除背景。如果成功获取到更新区域的矩形坐标,可以在矩形区域内进行绘制操作。

GetUpdateRect函数通常在处理窗口的绘制操作时使用,用于获取需要进行更新绘制的区域。

●ValidateRect函数

ValidateRect函数用于使指定窗口的一个矩形区域无效,从而导致系统重新绘制该区域。

ValidateRect函数的函数原型如下:

BOOL ValidateRect(

  HWND       hWnd,//指定窗口的句柄,表示要使其矩形区域无效的窗口

  const RECT *lpRect   //指向RECT结构的指针,指定要使无效的矩形区域的坐标

);

函数返回一个布尔值,表示是否成功使矩形区域无效。如果成功,返回TRUE;否则,返回FALSE。

以下是使用ValidateRect函数的示例代码:

HWND hWnd = GetDesktopWindow();  // 获取桌面窗口的句柄

RECT rect;

// 设置要使无效的矩形区域坐标

rect.left = 100;

rect.top = 100;

rect.right = 200;

rect.bottom = 200;

BOOL result = ValidateRect(hWnd, &rect);  // 使指定矩形区域无效

if (result)

{

    // 成功使矩形区域无效

    // 系统会重新绘制该区域

}

上述代码中,通过调用GetDesktopWindow函数获取桌面窗口的句柄hWnd。然后,定义了一个RECT结构rect,用于指定要使无效的矩形区域的坐标。接下来,通过调用ValidateRect函数使桌面窗口的指定矩形区域无效。如果成功使矩形区域无效,系统会重新绘制该区域。

ValidateRect函数通常在窗口的绘制操作中使用,用于标记特定的区域需要重新绘制。

Windows有两个类似InvalidateRect和ValidateRect的函数,用于处理区域而不是矩形:

●InvalddateRgn函数

InvalidateRgn函数用于使指定窗口的一个区域无效,从而导致系统重新绘制该区域。

InvalidateRgn函数的函数原型如下:

BOOL InvalidateRgn(

  HWND hWnd,   //指定窗口的句柄,表示要使其区域无效的窗口

  HRGN hRgn,      //指向区域的句柄,用于指定要使无效的区域

  BOOL bErase     //布尔值,用于确定在窗口重新绘制之前是否擦除无效区域的背景

);

函数返回一个布尔值,表示是否成功使区域无效。如果成功,返回TRUE;否则,返回FALSE。

以下是使用InvalidateRgn函数的示例代码:

HWND hWnd = GetDesktopWindow();  // 获取桌面窗口的句柄

HRGN hRgn = CreateRectRgn(100, 100, 200, 200);  // 创建一个矩形区域

BOOL result = InvalidateRgn(hWnd, hRgn, FALSE);  // 使指定区域无效

if (result)

{

    // 成功使区域无效

    // 系统会重新绘制该区域

}

DeleteObject(hRgn);  // 删除区域对象

在上述代码中,通过调用GetDesktopWindow函数获取桌面窗口的句柄hWnd。然后,使用CreateRectRgn函数创建一个具有指定坐标的矩形区域的句柄hRgn。接下来,通过调用InvalidateRgn函数使桌面窗口的指定区域无效。如果成功使区域无效,系统会重新绘制该区域。最后,使用DeleteObject函数删除区域对象。

InvalidateRgn函数通常在窗口的绘制操作中使用,用于请求窗口在其内容发生变化或需要更新时重新绘制。

●ValidateRgn函数

ValidateRgn函数用于验证指定窗口的一个区域,标记该区域为有效,使系统不再重新绘制该区域。ValidateRgn函数的函数原型如下:

BOOL ValidateRgn(

  HWND hWnd,   //指定窗口的句柄,表示要验证的窗口

  HRGN hRgn      //指向区域的句柄,用于指定要验证的区域

);

函数返回一个布尔值,表示是否成功验证区域。如果成功,返回TRUE;否则,返回FALSE。

以下是使用ValidateRgn函数的示例代码:

HWND hWnd = GetDesktopWindow();  // 获取桌面窗口的句柄

HRGN hRgn = CreateRectRgn(100, 100, 200, 200);  // 创建一个矩形区域

BOOL result = ValidateRgn(hWnd, hRgn);  // 验证指定区域

if (result)

{

    // 成功验证区域

    // 该区域将被标记为有效,系统不再重新绘制该区域

}

DeleteObject(hRgn);  // 删除区域对象

在上述代码中,通过调用GetDesktopWindow函数获取桌面窗口的句柄hWnd。然后,使用CreateRectRgn函数创建一个具有指定坐标的矩形区域的句柄hRgn。接下来,通过调用ValidateRgn函数验证指定的区域。如果成功验证区域,该区域将被标记为有效,系统不再重新绘制该区域。最后,使用DeleteObject函数删除区域对象。

ValidateRgn函数通常在窗口的绘制操作中使用,用于标记特定的区域为有效,告诉系统不再重新绘制该区域。

选入裁剪区域

当接收一条由无效区域产生的WM_PAINT消息时,剪裁区域在形状上不一定是矩形。

可以通过将一个区域选入到设备环境来创建你自己的剪裁区域,将区域选入设备环境。可以使用SelectObject (hdc, hRgn);或SelectClipRgn (hdc, hRgn);

●SelectClipRgn函数

SelectClipRgn函数用于设置设备上下文(DC)的剪辑区域,限制绘图操作只在指定的区域内有效。SelectClipRgn函数的函数原型如下:

int SelectClipRgn(

  HDC hdc,          //要设置剪辑区域的设备上下文句柄

  HRGN hrgn       //设置的剪辑区域句柄

);

函数返回一个整数值,表示设置剪辑区域的结果。如果函数调用成功,则返回值为COMPLEXREGION、SIMPLEREGION或NULLREGION,分别表示剪辑区域的类型。如果函数调用失败,则返回ERROR。

以下是使用SelectClipRgn函数的示例代码:

HWND hWnd = GetDesktopWindow();  // 获取桌面窗口的句柄

HDC hdc = GetDC(hWnd);  // 获取桌面窗口的设备上下文

HRGN hRgn = CreateRectRgn(100, 100, 200, 200);  // 创建一个矩形剪辑区域

int result = SelectClipRgn(hdc, hRgn);  // 设置剪辑区域

if (result != ERROR)

{

    // 设置剪辑区域成功

    // 绘图操作将受到剪辑区域的限制

}

DeleteObject(hRgn);  // 删除剪辑区域对象

ReleaseDC(hWnd, hdc);  // 释放设备上下文

在上述代码中,通过调用GetDesktopWindow函数获取桌面窗口的句柄hWnd。然后,通过调用GetDC函数获取桌面窗口的设备上下文hdc。接下来,使用CreateRectRgn函数创建一个具有指定坐标的矩形剪辑区域的句柄hRgn。然后,通过调用SelectClipRgn函数将剪辑区域设置到设备上下文中。如果成功设置剪辑区域,则绘图操作将受到剪辑区域的限制。最后,使用DeleteObject函数删除剪辑区域对象,并通过ReleaseDC函数释放设备上下文。

SelectClipRgn函数通常在绘图操作中使用,用于限制绘图操作的有效区域。

创建区域

●创建矩形区域

CreateRectRgn 函数用于创建一个矩形区域(Region)对象。矩形区域定义为左上角坐标 (nLeftRect, nTopRect) 和右下角坐标 (nRightRect, nBottomRect) 所围成的矩形。

函数原型如下:

HRGN CreateRectRgn(

  int nLeftRect,         // 矩形左上角的 x 坐标

  int nTopRect,        // 矩形左上角的 y 坐标

  int nRightRect,       // 矩形右下角的 x 坐标

  int nBottomRect     // 矩形右下角的 y 坐标

);

返回值:

如果函数成功,返回一个表示矩形区域的句柄(HRGN)。

如果函数失败,返回值为 NULL。

●创建椭圆区域

CreateEllipticRgn 函数用于创建一个由给定椭圆外接矩形定义的椭圆区域对象。

HRGN CreateEllipticRgn(

  int nLeftRect,         // 椭圆外接矩形左上角的 x 坐标

  int nTopRect,        // 椭圆外接矩形左上角的 y 坐标

  int nRightRect,       // 椭圆外接矩形右下角的 x 坐标

  int nBottomRect     // 椭圆外接矩形右下角的 y 坐标

);    

返回值:

如果函数成功,返回一个表示椭圆区域的句柄(HRGN)。

如果函数失败,返回值为 NULL。

●创建多边形区域

CreatePolygonRgn 函数用于创建一个由给定顶点坐标定义的多边形区域对象。

HRGN CreatePolygonRgn(

  const POINT *lpPoints,    // 指向一个 POINT 结构数组,包含多边形的顶点坐标

  int      nCount,             // 多边形顶点的数量

  int       fnPolyFillMode      // 多边形的填充模式,可以是 ALTERNATE 或 WINDING

);

返回值:

如果函数成功,返回一个表示多边形区域的句柄(HRGN)。

如果函数失败,返回值为 NULL。

操作裁剪区域

GDI为剪裁区域做了一个副本,因此当把区域对象选入到设备环境后,可以删除它。 Windows还包括几个操纵这个剪裁区域的函数,例如ExcludeClipRect函数用来从剪裁区域 中去除一个矩形;IntersectClipRect函数用来建立一个新的剪裁区域,这个新的剪裁区域是 先前的剪裁区域和某个矩形的交集。OffsetClipRgn函数用来把一个剪裁区域移动到客户区的另外一部分。

●CombineRgn函数

CombineRgn 函数用于根据给定的组合模式,将两个区域进行组合操作,将结果存储在目标区域中。hDestRgn在初始时可以是一个很小的矩形区域。将两个源区域组合起来,并产生目标句柄,hDestRgn先前的区域将被销毁。

int CombineRgn(

  HRGN hrgnDest,  // 目标区域句柄,表示结果将存储在其中

  HRGN hrgnSrc1,  // 第一个源区域句柄

  HRGN hrgnSrc2,  // 第二个源区域句柄

  int  fnCombineMode // 区域的组合模式,可以是 RGN_AND、RGN_OR、RGN_XOR、RGN_DIFF、RGN_COPY

);

fnCombineMode:区域的组合模式,可以是以下常量之一:

RGN_AND:计算 hrgnSrc1 和 hrgnSrc2 的交集。

RGN_OR:计算 hrgnSrc1 和 hrgnSrc2 的并集。

RGN_XOR:计算 hrgnSrc1 和 hrgnSrc2 的异或。

RGN_DIFF:计算 hrgnSrc1 减去 hrgnSrc2 的差集。

RGN_COPY:将 hrgnSrc1 的副本复制到 hrgnDest。

返回值:

如果函数成功,返回值表示操作的结果:

COMPLEXREGION:结果是一个复杂区域。

SIMPLEREGION:结果是一个简单区域。

NULLREGION:结果是一个空区域。

如果函数失败,返回值为错误代码。

●ExcludeClipRect函数

       ExcludeClipRect函数是Windows API中的一个函数,用于在设备上下文(DC)中排除指定的矩形区域,将该区域从剪辑区域中移除。ExcludeClipRect函数的函数原型如下:

       int ExcludeClipRect(

  HDC hdc,   //要操作的设备上下文句柄

  int left,        //要排除的矩形区域的左上角和右下角的坐标

  int top,       //

  int right,     //

  int bottom //

);

       函数返回一个整数值,表示排除操作的结果。如果函数调用成功,则返回值为SIMPLEREGION、COMPLEXREGION或NULLREGION,分别表示剪辑区域的类型。如果函数调用失败,则返回ERROR。

以下是使用ExcludeClipRect函数的示例代码:

HWND hWnd = GetDesktopWindow();  // 获取桌面窗口的句柄

HDC hdc = GetDC(hWnd);  // 获取桌面窗口的设备上下文

int left = 100;

int top = 100;

int right = 200;

int bottom = 200;

int result = ExcludeClipRect(hdc, left, top, right, bottom);  // 排除矩形区域

if (result != ERROR)

{

    // 排除矩形区域成功

    // 绘图操作将不会在该区域内绘制

}

ReleaseDC(hWnd, hdc);  // 释放设备上下文

在上述代码中,通过调用GetDesktopWindow函数获取桌面窗口的句柄hWnd。然后,通过调用GetDC函数获取桌面窗口的设备上下文hdc。接下来,定义了要排除的矩形区域的坐标。然后,通过调用ExcludeClipRect函数将该矩形区域从设备上下文的剪辑区域中移除。如果成功排除矩形区域,则绘图操作将不会在该区域内绘制。最后,通过ReleaseDC函数释放设备上下文。

ExcludeClipRect函数通常在绘图操作中使用,用于将指定的矩形区域从剪辑区域中排除,使得该区域不受剪辑的影响。

●IntersectClipRect函数

       IntersectClipRect函数用于在设备上下文(DC)中与指定的矩形区域求交集,将剪辑区域限制为该交集区域。IntersectClipRect函数的函数原型如下:

       int IntersectClipRect(

  HDC hdc,   //要操作的设备上下文句柄

  int left,        //要排除的矩形区域的左上角和右下角的坐标

  int top,

  int right,

  int bottom

);

       函数返回一个整数值,表示求交集操作的结果。如果函数调用成功,则返回值为SIMPLEREGION、COMPLEXREGION或NULLREGION,分别表示剪辑区域的类型。如果函数调用失败,则返回ERROR。

以下是使用IntersectClipRect函数的示例代码:

       HWND hWnd = GetDesktopWindow();  // 获取桌面窗口的句柄

HDC hdc = GetDC(hWnd);  // 获取桌面窗口的设备上下文

int left = 100;

int top = 100;

int right = 200;

int bottom = 200;

int result = IntersectClipRect(hdc, left, top, right, bottom);  // 与矩形区域求交集

if (result != ERROR)

{

    // 与矩形区域求交集成功

    // 剪辑区域将被限制为交集区域

}

ReleaseDC(hWnd, hdc);  // 释放设备上下文

在上述代码中,通过调用GetDesktopWindow函数获取桌面窗口的句柄hWnd。然后,通过调用GetDC函数获取桌面窗口的设备上下文hdc。接下来,定义了要与剪辑区域求交集的矩形区域的坐标。然后,通过调用IntersectClipRect函数将设备上下文的剪辑区域限制为与该矩形区域的交集。如果成功求交集,则剪辑区域将被限制为交集区域。最后,通过ReleaseDC函数释放设备上下文。

IntersectClipRect函数通常在绘图操作中使用,用于将设备上下文的剪辑区域限制为与指定矩形区域的交集。

●OffsetClipRgn函数

       OffsetClipRgn函数用于将设备上下文(DC)的剪辑区域沿指定的偏移量进行平移。

OffsetClipRgn函数的函数原型如下:

       int OffsetClipRgn(

  HDC hdc,   //表示要操作的设备上下文句柄

  int x,           //表示横向偏移量

  int y           //表示纵向偏移量

);

       函数返回一个整数值,表示平移操作的结果。如果函数调用成功,则返回值为非零值。如果函数调用失败,则返回值为零。

以下是使用OffsetClipRgn函数的示例代码:

HWND hWnd = GetDesktopWindow();  // 获取桌面窗口的句柄

HDC hdc = GetDC(hWnd);  // 获取桌面窗口的设备上下文

HRGN hRgn = CreateRectRgn(100, 100, 200, 200);  // 创建一个矩形剪辑区域

int x = 50;

int y = 50;

int result = OffsetClipRgn(hdc, x, y);  // 平移剪辑区域

if (result != ERROR)

{

    // 平移剪辑区域成功

}

DeleteObject(hRgn);  // 删除剪辑区域对象

ReleaseDC(hWnd, hdc);  // 释放设备上下文

       在上述代码中,通过调用GetDesktopWindow函数获取桌面窗口的句柄hWnd。然后,通过调用GetDC函数获取桌面窗口的设备上下文hdc。接下来,使用CreateRectRgn函数创建一个具有指定坐标的矩形剪辑区域的句柄hRgn。然后,定义了要进行的平移偏移量x和y。通过调用OffsetClipRgn函数将剪辑区域沿指定偏移量进行平移。如果成功平移剪辑区域,则剪辑区域被移动到新的位置。最后,使用DeleteObject函数删除剪辑区域对象,并通过ReleaseDC函数释放设备上下文。

OffsetClipRgn函数通常在绘图操作中使用,用于将设备上下文的剪辑区域沿指定偏移量进行平移。

区域绘图函数

FillRgn(hdc,hRgn,hBrush)

//与FillRect类似

FrameRgn(hdc,hRgn,hBrush,xFrame,yFrame)

//xFrame,yFrame表示区域周围的边框的逻辑宽度和高度

InvertRgn(hdc,hRgn);

//与InvertRect类似

PaintRgn(hdc,hRgn);

//用当前设备环境的画刷来填充区域

【注意】 区域作为GDI对象,不用的时候需要删除:

DeleteObject(hRgn); //删除GDI对象。

4.6.4 第29练:区域裁剪

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

029  WIN32 API 每日一练

     第29个例子CLOVER.C:区域裁剪

      SetCursor函数

      ShowCursor函数

      CombineRgn函数

      SetViewportOrgEx函数

      SelectClipRgn函数

      CreateEllipticRgn函数

      CreateRectRgn函数

(c) www.bcdaren.com, 2020

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

#include <windows.h>

#include <math.h>

#define TWO_PI (2.0 * 3.14159)

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

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,

 PSTR szCmdLine, int iCmdShow)

{

     static TCHAR szAppName[] = TEXT ("RandRect.C") ;

    (略)

     return msg.wParam ;

}

//窗口过程

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

{

     static HRGN hRgnClip;

     static int cxClient,cyClient;

     double fAngle,fRadius;//角度和半径

     HCURSOR hCursor;

     HDC hdc;

     HRGN hRgntemp[6];

     PAINTSTRUCT ps;

     switch (message)

     {

     case WM_SIZE:

          cxClient = LOWORD(lParam);

          cyClient = HIWORD(lParam);

          hCursor = SetCursor(LoadCursor(NULL,IDC_WAIT));//设置光标形状

          ShowCursor(TRUE);//显示光标

          if (hRgnClip)//如果裁剪区域已存在

               DeleteObject(hRgnClip);

          //创建4个椭圆形区域

hRgntemp[0] = CreateEllipticRgn(0,cyClient/3,cxClient/2,2*cyClient/3);

hRgntemp[1] =

CreateEllipticRgn(cxClient/2,cyClient/3,cxClient,2*cyClient/3);

        hRgntemp[2] =

CreateEllipticRgn(cxClient/3,0,2*cxClient/3,cyClient/2);

        hRgntemp[3] =

CreateEllipticRgn(cxClient/3,cyClient/2,2*cxClient/3,cyClient);

          //创建3个空区域

          hRgntemp[4] = CreateRectRgn(0,0,0,0);

          hRgntemp[5] = CreateRectRgn(0,0,1,1);

          hRgnClip = CreateRectRgn(0,0,1,1);

          //合并0,1椭圆

          CombineRgn(hRgntemp[4],hRgntemp[0],hRgntemp[1],RGN_OR);

          //合并2,3椭圆

          CombineRgn(hRgntemp[5], hRgntemp[2], hRgntemp[3], RGN_OR);

          //最后一次合并

         CombineRgn(hRgnClip, hRgntemp[4], hRgntemp[5], RGN_XOR);//共同区域之外

          //删除6个临时区域

          for (int i = 0;i < 6;i++)

          {

               DeleteObject(hRgntemp[i]);

          }

          SetCursor(hCursor);

          ShowCursor(FALSE);//隐藏光标

          return 0 ;

     case WM_PAINT:

          hdc = BeginPaint(hwnd,&ps);

          //视口原点设置在客户区中心

          SetViewportOrgEx(hdc,cxClient/2,cyClient/2,NULL);

          SelectClipRgn(hdc,hRgnClip);//选入区域

          //区域内画直线,共360条,每一度画一条

          fRadius = _hypot(cxClient/2.0,cyClient/2.0);//计算斜边

          for (fAngle = 0.0;fAngle < TWO_PI;fAngle+=TWO_PI/360)

          {

               MoveToEx(hdc,0,0,NULL);

               LineTo(hdc,(int)(fRadius*cos(fAngle)+0.5),(int)(-fRadius*sin(fAngle)+0.5));

          }

          EndPaint(hwnd,&ps);

          return 0;

     case WM_DESTROY:

          DeleteObject(hRgnClip);

          PostQuitMessage(0);

          return 0;

     }

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

}

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

SetCursor函数:设置光标形状。

HCURSOR SetCursor(

  HCURSOR hCursor   //光标的句柄

);

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

ShowCursor函数:显示或隐藏光标。

int ShowCursor(

  BOOL bShow   //如果bShow为TRUE,则显示计数增加一。如果bShow为FALSE,则显示计数减一。

);

备注

Windows 8:调用GetCursorInfo确定光标的可见性。

此功能设置一个内部显示计数器,该计数器确定是否应显示光标。仅当显示计数大于或等于0时才显示光标。

如果安装了鼠标,则初始显示计数为0。如果未安装鼠标,则显示计数为–1。

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

CombineRgn函数:结合了两个区域,并将结果存储在第三区域中。根据指定的模式将两个区域组合在一起。

int CombineRgn(

  HRGN hrgnDst,//组合后的新区域句柄

  HRGN hrgnSrc1,//组合区域1

  HRGN hrgnSrc2,//组合区域2

  int  iMode   //组合方式

);

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

SetViewportOrgEx函数:指定哪些设备点映射到窗口原点(0,0)

BOOL SetViewportOrgEx(

  HDC     hdc,

  int     x,//新视口原点的X坐标(以设备为单位)

  int     y,//新视口原点的Y坐标(以设备为单位)

  LPPOINT lppt//指向POINT结构的指针,该结构接收设备坐标中的先前视口原点,NULL不使用该参数

);

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

SelectClipRgn函数:选择的区域作为用于指定设备上下文的当前剪辑区域

int SelectClipRgn(

  HDC  hdc,

  HRGN hrgn//要选择的区域的句柄

);

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

CreateEllipticRgn函数:创建一个椭圆区域

HRGN CreateEllipticRgn(

  int x1,   //以逻辑单位指定椭圆边界矩形左上角的 x 坐标

  int y1,

  int x2,

  int y2

);

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

CreateRectRgn函数:创建一个矩形区域

HRGN CreateRectRgn(

  int x1,   //以逻辑单位指定区域左上角的 x 坐标

  int y1,

  int x2,

  int y2

);

*/

运行结果:

图4-17 区域裁剪

 

总结

       上述实例的窗口过程在处理WM_SIZE消息时,先创建4个椭圆区域,接着创建3个空区域备用。然后调用CombineRgn函数分别合并椭圆0和1,椭圆2和3,存入空区域4和5。最后再次调用CombineRgn函数合并区域4和5,并删除6个临时区域,保留最后一个合并区域。

       在处理WM_PAINT消息时,调用SetViewportOrgEx函数将视口原点设置在客户区中心,并调用SelectClipRgn函数选人区域句柄。最后调用数学函数_hypo在区域内画直线,共360条,每一度画一条。

       【注意】遵守GDI对象三原则,退出程序前,在WM_DESTROY消息中调用DeleteObject函数删除区域句柄。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2025年计算机毕业设计题目参考-简单容易

2025年最新计算机毕业设计题目参考-第二批 以下可以参考 企业员工薪酬关系系统的设计 基于SpringBoot在线远程考试系统 SpringBootVue的乡政府管理系统 springboot青年公寓服务平台 springboot大学生就业需求分析系统 基于Spring Boot的疗养院管理系统 基于SpringBoot的房屋交…

堆优化版Dijkstra求最短路-java

主要通过堆优化Dijkstra算法解决最短路&#xff0c;可以跟朴素版的Dijkstra算法进行对比。 文章目录 前言 一、Dijkstra求最短路 二、算法思路 1.邻接表存储图 2.用小根堆优化Dijkstra 三、代码如下 1.代码如下&#xff08;示例&#xff09;&#xff1a; 2.读入数据 3.代码运行…

高压线防外破警示灯在电力安全发挥的作用_鼎跃安全

高压输电线路往往跨越城市、乡村和野外&#xff0c;覆盖范围广泛。随着城乡建设和交通运输的快速发展&#xff0c;高压线路周围的活动频繁&#xff0c;外部破坏风险增加。车辆撞击电线杆、施工机械误碰线路以及人为破坏等事件时有发生&#xff0c;严重影响电力供应的稳定性和安…

人工智能--自然语言处理NLP概述

欢迎来到 Papicatch的博客 目录 &#x1f349;引言 &#x1f348;基本概念 &#x1f348;核心技术 &#x1f348;常用模型和方法 &#x1f348;应用领域 &#x1f348;挑战和未来发展 &#x1f349;案例分析 &#x1f348;机器翻译中的BERT模型 &#x1f348;情感分析在…

深入了解Java的ConcurrentHashMap类

深入了解Java的ConcurrentHashMap类 在多线程编程中&#xff0c;线程安全的数据结构至关重要。ConcurrentHashMap是Java提供的一种线程安全的哈希表实现&#xff0c;它在不使用显式同步的情况下允许并发的读取和写入操作。 ConcurrentHashMap属于java.util.concurrent包。它是…

19.Docker跨宿主机容器之间的通信macvlan

Docker跨宿主机容器之间的通信macvlan&#xff0c;类似桥接网络模式 macvlan通信类型&#xff0c;设置IP地址只能手动指定&#xff08;–ip&#xff09;一台一台设置IP地址 默认一个物理网卡&#xff0c;只有一个物理mac地址&#xff0c;虚拟多个mac地址&#xff08;让人感觉是…

【机器学习】第7章 集成学习(小重点,混之前章节出题但小题)

一、概念 1.集成学习&#xff0c;顾名思义&#xff0c;不是一个玩意&#xff0c;而是一堆玩意混合到一块。 &#xff08;1&#xff09;基本思想是先 生成一定数量基学习器&#xff0c;再采用集成策略 将这堆基学习器的预测结果组合起来&#xff0c;从而形成最终结论。 &#x…

C# 利用XejeN框架源码,编写一个在 Winform 界面上的语法高亮的编辑器,使用 Monaco 编辑器

析锦基于Monaco技术实现的Winform语法高亮编辑器 winform中&#xff0c;我们有时需要高亮显示基于某种语言的语法编辑器。 目前比较强大且UI现代化的&#xff0c;无疑是宇宙最强IDE的兄弟&#xff1a;VS Code。 类似 VS Code 的体验&#xff0c;可以考虑使用 Monaco Editor&a…

【机器学习】第6章 支持向量机(SVM)

一、概念 1.支持向量机&#xff08;support vector machine&#xff0c;SVM&#xff09;&#xff1a; &#xff08;1&#xff09;基于统计学理论的监督学习方法&#xff0c;但不属于生成式模型&#xff0c;而是判别式模型。 &#xff08;2&#xff09;支持向量机在各个领域内的…

【系统架构设计师】三、数据库系统(事务并发|封锁协议|数据库安全|商业智能|SQL语句)

目录 一、事务并发 1.1 事务概述 1.2 并发控制 1.3 封锁 1.3.1 X 封锁和 S 封锁 1.3.2 三级封锁协议 二、数据库安全 2.1 备份(转储)与恢复 2.2 备份分类 2.3 数据库故障 三、商业智能 3.1 数据仓库 3.2 数据仓库的结构-OLAP 3.3 数据挖掘 3.4 分布式数据库 四…

DS1302实时时钟芯片完整使用介绍(配合51单片机)

DS1302是一款由美国DALLAS Semiconductor公司&#xff08;现已被Maxim Integrated公司收购&#xff09;设计的高性能、低功耗的实时时钟集成电路。这款芯片因其简单易用的接口和丰富的功能&#xff0c;在嵌入式系统、消费电子、工业控制等多个领域得到广泛应用。 原理图 寄存器…

Vscode中的行尾序列CRLF/LF不兼容问题

最近开发的的时候&#xff0c;打开项目文件经常会出现爆红错误提示信息&#xff0c;显示如下图&#xff1a; 这东西太烦人了&#xff0c;毕竟谁都不希望在遍地都是爆红的代码里写东西&#xff0c;就像能解决这个问题&#xff0c;根据提示可以知道这是vscode中使用的prettier插件…

QT基础 - 布局管理器间隔控件

目录 一. QVBoxLayout 二. QHBoxLayout 三. QGridLayout 四. QFormLayout 五. Spacers 六.总结 一. QVBoxLayout QVBoxLayout 主要用于将控件在垂直方向上进行排列。 它具有以下特点&#xff1a; 可以方便地管理和组织控件&#xff0c;使其按照垂直顺序依次排列。能够自动…

数据治理平台报Invalid CORS request

文章目录 背景一、步骤1.修改治理conf配置文件 背景 问题描述&#xff1a;俩个域名&#xff08;都能进入同一个平台&#xff09;其中一个正常使用&#xff0c;另外一个无法进入 报错截图&#xff1a; *备注&#xff1a;本文主要从配置文件入手解决。 一、步骤 1.修改治理co…

无需付费,没有广告,驱动人生海外版本DriverTalent_Pro_v8.0.0.2单文件

如果你是一位电脑爱好者&#xff0c;你一定知道驱动程序的重要性。驱动程序是连接电脑硬件和操作系统的桥梁&#xff0c;它们可以让你的电脑运行更流畅&#xff0c;更稳定&#xff0c;更高效。但是&#xff0c;驱动程序也会随着时间的推移而过时&#xff0c;或者与新的系统不兼…

HTTP/3 协议学习

前一篇&#xff1a; HTTP/2 协议学习-CSDN博客 HTTP/3 协议介绍 HTTP/3 是互联网上用于传输超文本的协议 HTTP 的第三个主要版本。它是 HTTP/2 的后继者&#xff0c;旨在进一步提高网络性能和安全性。HTTP/3 与前两个版本的主要区别在于它使用了一个完全不同的底层传输协议—…

【linux】TCP交流状态变迁及一些函数调用

代码 登录 - Gitee.comhttps://gitee.com/r77683962/linux-6.9.0/commit/50bb00d844b9423c9bacf44d9b06604fab941686 https://gitee.com/r77683962/linux-6.9.0/raw/50bb00d844b9423c9bacf44d9b06604fab941686/dmesg_log/kern_tcp_with_state.log 从打印的日志&#xff0c;…

UE4中性能优化和检测工具

UE4中性能优化和检测工具合集 简述CPUUnreal InsightUnreal ProfilerSimpleperfAndroid StudioPerfettoXCode TimeprofilerBest Practice GPUAdreno GPUMali GPUAndroid GPU Inspector (AGI) 内存堆内存分析Android StudioLoliProfilerUE5 Memory InsightsUnity Mono 内存Memre…

QT基础 - 窗口弹窗

目录 零. 窗口简介 一. 普通窗口 二. 无边框窗口 三. 顶层窗口 四. 模态对话框 五. 非模态对话框 六. 消息对话框 七. 文件对话框 八. 颜色对话框 九. 进度对话框 十. 总结 零. 窗口简介 在 Qt中&#xff0c;普通窗口是指程序的整体界面&#xff0c;可以包含标题栏、…

低市值Pow赛道解析,探寻百倍潜力项目

随着铭文的火爆出圈&#xff0c;比特币减半的到来&#xff0c;关于Pow赛道的讨论也在变得火热&#xff0c;不少投资机构都将Pow赛道作为2024年分析的重点。Pow赛道又来已久&#xff0c;不少项目的市值都超过10亿美元&#xff0c;而对于大多数投资者来说&#xff0c;低市值高回报…