32、Windows API GDI(4)

简介: 区域(Regions)、路径(Paths)与修剪(Clip)操作 一、区域[2]     区域是一种对象,具有形状、位置、大小,用于进行填充、绘制、反转、边沿勾勒等操作,或用于限制DC的输出范围(修剪)。

区域(Regions)、路径(Paths)与修剪(Clip)操作

一、区域[2]

    区域是一种对象,具有形状、位置、大小,用于进行填充、绘制、反转、边沿勾勒等操作,或用于限制DC的输出范围(修剪)。

区域的形状可以是任意的,可以是标准的矩形、椭圆、扇形等,也可以是多边形,还可以是这些形状组合(与、或、异或等)。[2]

wps_clip_image-23019

    在创建区域后,可以对区域进行填充和反转等操作。

填充区域使用API函数FillRgnPaintRgnFillRgn可以指定画刷,而PaintRgn使用当前DC画刷。使用DC中被选入的当前画刷。

无论什么形状的区域,都有一个边沿,这个边沿是一个矩形( RECT),是能进入这个区域框的最小的矩形。GetRgnBox函数用于获取这个矩形。

FrameRgn勾勒(Frame)是使用指定的画刷在区域外为区域绘制边框。

1、区域边沿、区域填充、反转与勾勒操作

创建及填充示例

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif 区域的填充和反转
 
   
/* 头文件 */
#include
< windows.h >
/* 全局变量 */
LPSTR szAppName
= " RGN " ;
LPSTR szTitle
= " RGN Sample " ;
/* 函数声明 */
LRESULT CALLBACK WndProc( HWND , UINT , WPARAM , LPARAM );

/* ************************************
* ElliRgns
* 功能 创建椭圆区域,并进行填充和反转
*************************************
*/
HRGN ElliRgns(HWND hwnd, POINT point)
{
// RECT 区域、画刷
RECT rect, rectClient;
HRGN hrgn;
HBRUSH hBrushOld, hBrush;
// DC
HDC hdc = GetDC(hwnd);
GetClientRect(hwnd,
& rectClient);
// 点的周围一块区域
rect.left = point.x - 40 ;
rect.right
= point.x + 40 ;
rect.top
= point.y - 30 ;
rect.bottom
= point.y + 30 ;
// 通过RECT 创建椭圆区域
hrgn = CreateEllipticRgnIndirect( & rect);
// 创建画刷
hBrush = CreateSolidBrush(RGB( 0 , 255 , 0 ));
// 为DC 选择画刷
hBrushOld = (HBRUSH)SelectObject(hdc,hBrush);
// 使用当前画刷绘制区域
PaintRgn(hdc,hrgn);
// 等待一断时间后,将刚才绘制的区域进行反转
Sleep( 3000 );
InvertRgn(hdc,hrgn);
// 释放资源
hBrush = (HBRUSH)SelectObject(hdc,hBrushOld);
DeleteObject(hBrush);
DeleteObject(hrgn);
DeleteDC( hdc );
return 0 ;
}

int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
HWND hWnd;
WNDCLASS wc;

wc.style
= CS_OWNDC;
wc.lpfnWndProc
= (WNDPROC)WndProc;
wc.cbClsExtra
= 0 ;
wc.cbWndExtra
= 0 ;
wc.hInstance
= hInstance;
wc.hIcon
= NULL;
wc.hCursor
= LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground
= (HBRUSH)(COLOR_WINDOW + 1 );
wc.lpszMenuName
= NULL;
wc.lpszClassName
= szAppName;

if ( ! RegisterClass( & wc))
{
return (FALSE);
}

hWnd
= CreateWindow(
szAppName,
szTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
0 , CW_USEDEFAULT, 0 ,
NULL, NULL, hInstance, NULL
);

if ( ! hWnd)
{
return (FALSE);
}

ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);

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

return ( int )(msg.wParam);

UNREFERENCED_PARAMETER(lpCmdLine);
}


LRESULT CALLBACK WndProc(
HWND hWnd,
UINT message,
WPARAM uParam,
LPARAM lParam)
{

switch (message)
{
case WM_CREATE:
break ;

case WM_PAINT:
break ;

case WM_LBUTTONDOWN:
{
// 获得点击的位置,传递给ElliRgns
POINT point;
point.x
= LOWORD(lParam);
point.y
= HIWORD(lParam);
ElliRgns(hWnd, point);
}
break ;

case WM_DESTROY:
PostQuitMessage(
0 );
break ;

default :
return (DefWindowProc(hWnd, message, uParam, lParam));
}
return ( 0 );
}

2、组合、比较、移动等操作

在创建区域后,还可以将若干个区域组合在一起,成为一个新的区域。组合的方式可以是两个区域的交集、合集、差集、合集与交集的差集(两集合异或)。

CombineRgn

EqualRgn

OffsetRgn

PtInRegion Determines whether the specified point is inside the specified region.

组合示例

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif HitTest
 
   
/* 头文件 */
#include
< Windows.h >
/* 全局变量 */
RECT rctGrid;
// 格子
RECT rctBrush; // 演示格式画刷的格子
RECT rctWindow;
UINT bBrushBits[
8 ]; // 用于创建格式画刷
RECT rect[ 64 ]; // 六十四个小格子
HBITMAP hbm; // 位图画刷
HBRUSH hbrush; // 当前画刷
HBRUSH hBrushGrid[ 8 ]; // 用于填充小方格式的画刷
HBRUSH hbrushOld; // 默认画刷
HRGN hrgnCell; // 区域
HDC hdc; // DC句柄
POINTS ptlHit; // 鼠标坐标
int i;

/* ************************************
* VOID InitGridBurshAndRect()
* 功能 初始化程序需要使用到的画刷
* 初始化若干个RECT
*************************************
*/
VOID InitGridBurshAndRect()
{

int x, y, deltaX, deltaY; // 用于画小格子

// 创建了七种不同的画刷
hBrushGrid[ 0 ] = CreateHatchBrush(HS_BDIAGONAL,RGB( 255 , 0 , 0 ));
hBrushGrid[
1 ] = CreateHatchBrush(HS_CROSS,RGB( 0 , 255 , 0 ));
hBrushGrid[
2 ] = CreateHatchBrush(HS_DIAGCROSS,RGB( 0 , 0 , 255 ));
hBrushGrid[
3 ] = CreateHatchBrush(HS_FDIAGONAL,RGB( 255 , 0 , 255 ));
hBrushGrid[
4 ] = CreateHatchBrush(HS_HORIZONTAL,RGB( 255 , 255 , 0 ));
hBrushGrid[
5 ] = CreateHatchBrush(HS_BDIAGONAL,RGB( 0 , 255 , 255 ));
hBrushGrid[
6 ] = CreateHatchBrush(HS_VERTICAL,RGB( 0 , 0 , 0 ));
hBrushGrid[
7 ] = CreateSolidBrush(RGB( 200 , 200 , 200 ));

// 大格子边界的坐标,后面会被划分为8*8个小方格子,用于点击测试
rctGrid.top = rctGrid.left = 10 ;
rctGrid.bottom
= rctGrid.right = 330 ; // 靠左
rctBrush.top = 10 ; rctBrush.left = 340 ;
rctBrush.bottom
= 330 ;rctBrush.right = 660 ; // 靠右

// 计算小格式中的坐标,保存在数组中
deltaX = (rctGrid.right - rctGrid.left) / 8 ;
deltaY
= (rctGrid.bottom - rctGrid.top) / 8 ;

for (y = rctGrid.top, i = 0 ; y < rctGrid.bottom; y += deltaY)
{
for (x = rctGrid.left; x < (rctGrid.right - 8 ) && i < 64 ;
x
+= deltaX, i ++ )
{
rect[i].left
= x; rect[i].top = y;
rect[i].right
= x + deltaX;
rect[i].bottom
= y + deltaY;
}
}
}

/* ************************************
* VOID DrawGridLine(HWND hwnd)
* 功能 根据InitGridBurshAndRect所初始化的小方格的边界
* 画出小方格。
*************************************
*/
VOID DrawGridLine(HWND hwnd)
{
hdc
= GetDC(hwnd);
// 经线和纬线
for (i = rctGrid.left; i <= rctGrid.right;
i
+= (rctGrid.right - rctGrid.left) / 8 )
{
MoveToEx(hdc, i, rctGrid.top, NULL);
LineTo(hdc, i, rctGrid.bottom);
}
for (i = rctGrid.top; i <= rctGrid.bottom;
i
+= (rctGrid.bottom - rctGrid.top) / 8 )
{
MoveToEx(hdc, rctGrid.left, i, NULL);
LineTo(hdc, rctGrid.right, i);
}
ReleaseDC(hwnd, hdc);
DeleteDC( hdc );
}

/* ************************************
*VOID PaintGrid(HWND hwnd,POINTS ptlHit)
* 功能 使用画刷填充ptlHit点所在的小方格
*************************************
*/
VOID PaintGrid(HWND hwnd,POINTS ptlHit)
{
// 创建区域,大方格
hrgnCell = CreateRectRgn(rctGrid.left, rctGrid.top,
rctGrid.right, rctGrid.bottom);
// 获得窗口的DC
hdc = GetDC(hwnd);
// 将区域选择入DC
SelectObject(hdc, hrgnCell);
// 测试点是否在区域中
if (PtInRegion(hrgnCell, ptlHit.x, ptlHit.y))
{
// 如果点在大方格中,循环测试点在哪个小方格中
for (i = 0 ; i < 8 ; i ++ )
bBrushBits[i]
= 0xFF ;
for (i = 0 ; i < 64 ; i ++ )
{
DeleteObject(hrgnCell);
// 每一个小方格创建一个区域
hrgnCell = CreateRectRgn(rect[i].left,
rect[i].top,
rect[i].right, rect[i].bottom);
// 测试是否在小方格中
if (PtInRegion(hrgnCell, ptlHit.x, ptlHit.y))
{
// 如果是的话则填充,第一行使用的填充画刷是一样的。
FillRgn(hdc,hrgnCell,hBrushGrid[i / 8 ]);
}
}
// 释放
SelectObject(hdc, hbrushOld);
DeleteObject(hbrush);
DeleteObject(hbm);
DeleteDC( hdc);
}
}

/* ************************************
*VOID PaintPattern(HWND hwnd, POINTS ptlHit)
* 功能 在演示格式画刷的方格中使用格式画刷进行绘制
*************************************
*/
VOID PaintPattern(HWND hwnd, POINTS ptlHit)
{
// 获取DC
hdc = GetDC(hwnd);
// 根据点击的不同位置创建不同的位图
i = ptlHit.x % 8 ;
bBrushBits[i]
+= 0x50 ;
// 创建位图
hbm = CreateBitmap( 8 , 8 , 1 , 1 , (LPBYTE)bBrushBits);
// 创建格式画刷
hbrush = CreatePatternBrush(hbm);
// 为DC选择画刷
hbrushOld = SelectObject(hdc, hbrush);
// 绘制矩形
Rectangle(hdc, rctBrush.left, rctBrush.top,
rctBrush.right, rctBrush.bottom);
// 释放DC
ReleaseDC(hwnd,hdc);
DeleteDC( hdc );
}

/* ************************************
* MainWndProc
* 功能 窗口消息处理函数
*************************************
*/
LRESULT CALLBACK MainWndProc(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{

switch (uMsg)
{
// 释放资源,退出
case WM_DESTROY:
for (i = 0 ; i < 8 ; i ++ )
DeleteObject(hBrushGrid[i]);
ExitProcess(
0 );
// 初始化画刷、方格
case WM_CREATE:
InitGridBurshAndRect();
break ;
// 绘制
case WM_PAINT:
DrawGridLine(hwnd);
break ;
// 鼠标左键
case WM_LBUTTONDOWN:
ptlHit
= MAKEPOINTS((LPPOINTS)lParam);
// 填充一个小方格
PaintGrid(hwnd, ptlHit);
// 填充右侧的格式画刷方格
PaintPattern(hwnd, ptlHit);
break ;
default :
break ;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

// WinMain
int WINAPI WinMain(HINSTANCE hinstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
WNDCLASSEX wcx;
HWND hwnd;
MSG msg;
WORD wport
= 80 ;
BOOL fGotMessage;
HWND hwndCap
= NULL;

// 注册窗口类,并创建窗口,用于显示截取的位图
wcx.cbSize = sizeof (wcx);
wcx.style
= CS_HREDRAW | CS_VREDRAW;
wcx.lpfnWndProc
= MainWndProc;
wcx.cbClsExtra
= 0 ;
wcx.cbWndExtra
= 0 ;
wcx.hInstance
= hinstance;
wcx.hIcon
= LoadIcon(NULL, MAKEINTRESOURCE(IDI_APPLICATION));
wcx.hCursor
= LoadCursor(NULL, IDC_ARROW);
wcx.hbrBackground
= (HBRUSH)GetStockObject( WHITE_BRUSH );
wcx.lpszMenuName
= NULL;
wcx.lpszClassName
= " MainWClass " ;
wcx.hIconSm
= NULL;

if ( ! RegisterClassEx( & wcx))
return 1 ;
// 创建窗口
hwnd = CreateWindow(
" MainWClass " ,
" Brush_Pen " ,
WS_OVERLAPPEDWINDOW
| WS_CLIPCHILDREN | WS_CLIPSIBLINGS |
WS_MAXIMIZE
| WS_POPUPWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
800 , 600 ,
(HWND) NULL, (HMENU) NULL, hinstance, (LPVOID) NULL);

if ( ! hwnd)
return 1 ;
// 显示
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);

while ((fGotMessage = GetMessage( & msg, (HWND) NULL, 0 , 0 )) != 0 && fGotMessage != - 1 )
{
TranslateMessage(
& msg);
DispatchMessage(
& msg);
}
return msg.wParam;
UNREFERENCED_PARAMETER(lpCmdLine);
}

二、路径[3]

路径是很多被填充或被勾勒了的形状和图形。

路径的创建方法比较特殊。整个创建过程称作“路径托架(bracket)”。

创建路径时,首先调用BeginPath函数,然后可以调用一系统的绘制函数,最后再调用EedPath函数。在这个过程中,所有的绘制函数的输出内容都不会被真正输出到屏幕上,而是输出到“路径”中,路径就是整个BeginPathEedPath之间所有调用的输出的图形的组合。在EndPath调用之后,路径会被选择到DC中。

可以将路径转换为一个区域,然后就可以进行区域的所有操作。将路径转换为区域使用函数PathToRegion,所转换的是DC的当前路径,返回转换后得到的区域。

三、修剪[4]

    修剪是区域和路径比较高级的操作。修剪是使用DC的区域和路径对象来限制绘制输出的范围。修剪区域可以将所有输出都限制在区域的范围内,只有在区域范围内的输出才会显示在界面上,如果输出的范围在区域之外,则不会反映到界面上。

在进行修剪操作前,首先需设置DC的修剪区域和修剪路径。设置使用区域使用API函数SelectClipRgn。还可以设置DC的修剪路径,修剪路径可以和DC原有的修剪区域进行合并,合并的方法也包括集合的交、并、差、复制、异或。设置修剪路径使用API函数SelectClipPath

修剪示例

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif 区域、路径、修剪
 
   
/* 头文件 */
#include
< Windows.h >
#include
< math.h >
#include
" resource.h "
/* 全局变量 */
CHOOSEFONT cf;
// 选择字体
LOGFONT lf; // 逻辑字体
HFONT hfont; // 字体对象
HFONT hfontOld; // DC的原有字体
HDC hdc; // DC句柄
int nXStart, nYStart; // 用于画直线
RECT rc; // 窗口客户区RECT
double aflSin[ 90 ]; // 用于绘制放射直线簇
double aflCos[ 90 ]; // 用于绘制放射状直线簇
double flRadius,a; // 半径
int iMode; // 修剪路径组合模式
HRGN hrgn; // 修剪区域
int i;
COLORREF crOld;

// 窗口消息处理函数
LRESULT APIENTRY MainWndProc(
HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam)

{

PAINTSTRUCT ps;

switch (message)
{
case WM_PAINT:
hdc
= BeginPaint(hwnd, & ps);
EndPaint(hwnd,
& ps);
break ;

case WM_COMMAND: // 菜单命令
switch (wParam)
{
case IDM_VANISH: // 消除客户区(在设置了修剪全其输出范围也会被限制)
hdc = GetDC(hwnd);
GetClientRect(hwnd,
& rc);
FillRect(hdc,
& rc, (HBRUSH)GetStockObject(WHITE_BRUSH));
DeleteDC( hdc);
break ;
// 根据用户的菜单输入,设置修剪路径的组合模式
case IDM_AND:
iMode
= RGN_AND;
break ;
case IDM_COPY:
iMode
= RGN_COPY;
break ;
case IDM_DIFF:
iMode
= RGN_DIFF;
break ;
case IDM_OR:
iMode
= RGN_OR;
break ;
case IDM_XOR:
iMode
= RGN_XOR;
break ;

case IDM_CLIP:
{
// 获取窗口客户区的DC
hdc = GetDC(hwnd);
// 创建并为DC选择字体
// 消息在菜单中点击此项前需先选择字体
hfont = CreateFontIndirect(cf.lpLogFont);
hfontOld
= (HFONT)SelectObject(hdc, hfont);

// 五个点,用于创建五角星区域
POINT point[ 5 ] = {{ 0 , 200 },{ 600 , 200 },{ 100 , 600 },{ 300 , 0 },{ 500 , 600 }};
// 创建多边形区域,五角星
hrgn = CreatePolygonRgn(point, 5 , WINDING);
// 将区域选择为修剪区域
SelectClipRgn(hdc, hrgn);
// 输出的文字
LPSTR szOut = " Lorem ipsum dolor sit amet, consectetur \n "
" adipisicing elit, sed do eiusmod tempor \n "
" incididunt ut labore et dolore magna \n "
" aliqua. Ut enim ad minim veniam, quis \n "
" nostrud exercitation ullamco laboris nisi \n "
" ut aliquip ex ea commodo consequat. Duis \n "
" aute irure dolor in reprehenderit in \n "
" voluptate velit esse cillum dolore eu \n "
" fugiat nulla pariatur. Excepteur sint \n "
" occaecat cupidatat non proident, sunt \n "
" in culpa qui officia deserunt mollit \n "
" anim id est laborum.\n " ;
// 窗口客户区,用于输出文字
RECT rect;
GetClientRect(hwnd,
& rect);
// 设置文字背景为透明
SetBkMode(hdc, TRANSPARENT);
// 开始创建路径
BeginPath(hdc);
// 路径的形状为输出的文字
DrawText(hdc, szOut, lstrlen(szOut), & rect , DT_CENTER);
EndPath(hdc);
// 路径已经为DC的当前路径
// 为DC选择修剪路径,使用用户通过菜单输入的模式
// 注意在进行此操作前需通过菜单选择组合模式
SelectClipPath(hdc, iMode);

// 输出放射状直线,以左上角为原点
// 计算线的终点
for (i = 0 ; i < 90 ; i ++ )
{
aflSin[i]
= sin( ((( double )i) / 180.0 )
* 3.14159 );
}
for (i = 0 ; i < 90 ; i ++ )
{
aflCos[i]
= cos( ((( double )i) / 180.0 )
* 3.14159 );
}
flRadius
= 1000 ; // 线的长度(窗口大小为600*650)
// 画线,第一度画一条线
for (i = 0 ; i < 90 ; i ++ )
{
MoveToEx(hdc, nXStart, nYStart,
(LPPOINT) NULL);
LineTo(hdc, nXStart
+ (( int ) (flRadius
* aflCos[i])),
nYStart
+ (( int ) (flRadius
* aflSin[i])));
}
// 选择回字体,释放
SelectObject(hdc, hfontOld);
DeleteObject(hfont);
DeleteDC( hdc);
// 刷新窗口
UpdateWindow(hwnd);

break ;
}

case IDM_FONT:
// 用户选择字体
cf.lStructSize = sizeof (CHOOSEFONT);
cf.hwndOwner
= hwnd;
cf.lpLogFont
= & lf;
cf.Flags
= CF_SCREENFONTS | CF_EFFECTS;
cf.rgbColors
= RGB( 0 , 255 , 255 );
cf.nFontType
= SCREEN_FONTTYPE;

ChooseFont(
& cf);
break ;

default :
return DefWindowProc(hwnd, message, wParam,
lParam);
}
break ;

case WM_DESTROY:
PostQuitMessage(
0 );
break ;

default :
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0 ;
}

// WinMain
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
HWND hWnd;
WNDCLASS wc;


wc.style
= CS_OWNDC;
wc.lpfnWndProc
= (WNDPROC)MainWndProc;
wc.cbClsExtra
= 0 ;
wc.cbWndExtra
= 0 ;
wc.hInstance
= hInstance;
wc.hIcon
= NULL;
wc.hCursor
= LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground
= (HBRUSH)(COLOR_WINDOW + 1 );
wc.lpszMenuName
= MAKEINTRESOURCE(IDR_MENU_CLIP); // 菜单
wc.lpszClassName = " clip " ;

if ( ! RegisterClass( & wc))
{
return (FALSE);
}

hWnd
= CreateWindow(
" clip " ,
" clip " ,
WS_OVERLAPPEDWINDOW,
100 , 100 , 600 , 650 ,
NULL,
NULL,
hInstance,
NULL
);

if ( ! hWnd)
{
return (FALSE);
}

ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);

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

return ( int )(msg.wParam);

UNREFERENCED_PARAMETER(lpCmdLine);
}

进一步可以参见参考文献[1,2~4]

四、坐标变换

图形输出是在平面上操作,具有坐标。GDI支持对输出的函数进行坐标变换。API函数SetWorldTransform实现了坐标变换的功能。

    此外,[1]中还介绍了调色板的使用。

参考

[1] 精通Windows API 函数、接口、编程实例

[2] http://msdn.microsoft.com/en-us/library/dd162913%28VS.85%29.aspx

[3] http://msdn.microsoft.com/en-us/library/dd162779%28VS.85%29.aspx

[4] http://msdn.microsoft.com/en-us/library/dd183435%28VS.85%29.aspx

目录
相关文章
|
7月前
|
监控 编译器 API
[笔记]Windows核心编程《二十二》注入DLL和拦截API(一)
[笔记]Windows核心编程《二十二》注入DLL和拦截API
148 0
|
4月前
|
API Python Windows
python3应用windows api对后台程序窗口及桌面截图并保存的方法
python3应用windows api对后台程序窗口及桌面截图并保存的方法
118 1
|
8月前
|
编解码 应用服务中间件 开发工具
Windows平台RTMP|RTSP播放器为什么要兼容GDI绘制
先说结论,Windows平台播放渲染这块,一般来说99%以上的机器都是支持D3D的,实现GDI模式绘制,除了为了好的兼容性外,在远程连接的场景下,D3D创建不成功,需要使用GDI模式。
|
7月前
|
存储 缓存 API
[总结]Windows Crypto API 自动更新根证书问题原因及解决方案
[总结]Windows Crypto API 自动更新根证书问题原因及解决方案
|
7月前
|
API Windows
[笔记]Windows核心编程《番外篇》常用的NT API及使用示例
[笔记]Windows核心编程《番外篇》常用的NT API及使用示例
|
7月前
|
安全 API Windows
[笔记]Windows核心编程《二十二》注入DLL和拦截API(三)
[笔记]Windows核心编程《二十二》注入DLL和拦截API(三)
143 0
|
7月前
|
消息中间件 编解码 安全
[笔记]Windows核心编程《二十二》注入DLL和拦截API(二)
[笔记]Windows核心编程《二十二》注入DLL和拦截API(二)
107 0
|
7月前
|
API C++ Windows
Windows API Hooking 学习
Windows API Hooking 学习
|
11月前
|
缓存 安全 Unix
C/C++使用Windows的API实现共享内存以及同步
C/C++使用Windows的API实现共享内存以及同步
791 0
|
11月前
|
安全 Java 编译器
如何用 Go 调用 Windows API | 青训营笔记
如何用 Go 调用 Windows API | 青训营笔记
846 0