C++ API常用函数简单例子大全四

第三十个CreateToolhelp32Snapshot给当前进程拍一个照

HANDLE hProcessSnap=::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);

//记住这种格式就行了,返回的句柄,存储有进程信息,可以Process32Firs函数找出来。

第三十一个Process32First根据CreateToolhelp32Snapshot函数返回的句柄获取进程信息

结合Process32Next函数使用,有点像文件寻找函数。

看完整例子:显示系统进程名,以及进程ID号

#include<windows.h>
#include<tlhelp32.h>//声明快照函数的头文件
#include<stdio.h>
int main()
{
 PROCESSENTRY32 pe32;//进程的信息将会存储在这个结构里
 //在使用这个结构之前,先设置它的大小
 pe32.dwSize=sizeof(pe32);
 //给系统内的所有进程拍一个快照
 HANDLE hProcessSnap=::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
 BOOL bMore=::Process32First(hProcessSnap,&pe32);//第一次查找
 while(bMore)
 {
  printf("进程名称:%s/n",pe32.szExeFile);//szExeFile是进程名
  printf("进程ID号:%u/n/n",pe32.th32ProcessID);//th32ProcessID是进程ID号
  bMore=::Process32Next(hProcessSnap,&pe32);//寻找下个进程,函数返回0,则没有进程可寻
 }
 return 0;
}

第三十二个OpenProcess根据进程ID号获得进程句柄,句柄通过函数返回

函数定义:HANDLE OpenProcess( DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId);

第一个参数不要管它,填PROCESS_ALL_ACCESS,第二个参数也一样,填FALSE,那最后一个参数就是进程ID号。

第三十三个TerminateProcess结束一个进程(需进程句柄做参数

该函数只有两个参数,第一个是进程句柄,第二个填0就行了。

现在给个例子:假设当前有一个进程名为abc.exe的进程正在运行,编一个程序结束它。

#include<windows.h>
#include<tlhelp32.h>//声明快照函数的头文件
int main(int argc,char *argv[])


 PROCESSENTRY32 pe32;
 //在使用这个结构之前,先设置它的大小
 pe32.dwSize=sizeof(pe32);
 //给系统内的所有进程拍一个快照
 HANDLE hProcessSnap=::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
 //遍历进程快照,轮流显示每个进程的信息
 BOOL bMore=::Process32First(hProcessSnap,&pe32);
 while(bMore)
 {

      if(strcmp("abc.exe",pe32.szExeFile)==0)//如果找到进程名为abc.exe
   {
    HANDLE hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,pe32.th32ProcessID);//获取句柄
     ::TerminateProcess(hProcess,0);//结束它
   }
  bMore=::Process32Next(hProcessSnap,&pe32);//寻找下一个
 }
 return 0;
}

上面的这个例子,只能结束普通权限进程,如果为系统进程的话,则没有用,结束不了。在后面的提升权限函数,会有例子说明如何结束系统进程。

第三十四个CreatePen创建一个画笔(返回画笔句柄)

函数定义:BOOL CreatePen(int nPenStyle, int nWidth, COLORREF crColor);

第一个参数,表示是什么类型的线,取值有以下:

 如创建一个画笔:HPEN pen=CreatePen(PS_SOLID,3,RGB(255,78,99));

PS_SOLID  画笔画出的是实线   PS_DASH 画笔画出的是虚线(nWidth必须是1) PS_DOT 画笔画出的是点线(nWidth必须是1)
PS_DASHDOT 画笔画出的是点划线(nWidth必须是1) PS_DASHDOTDOT 画笔画出的是点-点-划线(nWidth必须是1)
第二个参数是画笔的宽度,第三个参数是画笔的颜色,COLORREF类型可以RGB来获得如RGB(233,128,88);分别是红绿蓝。

第三十五个CreateSolidBrush建一个画刷

只有一个COLORREF类型的参数

HBRUSH brush=CreateSolidBrush(RGB(22,182,111));

第三十六个SelectObject把GDI对象选入相应的DC中

像画笔(句柄HPEN),画刷(HBURSH),位图(HBITMAP)等都是GID对象。因为画图函数,如画圆,画矩形,画直线,它们所画出图形,默认属性都是不变的,如线的宽度。那么想要改变画出来时线的宽度,比如我想画出来的图形它的线条宽度为5(像素),那么就要创建一个宽度为5的画笔,然后再通过SelectObject函数,给这个画笔选入,就可以了.

接下举个例子:SelectObject应用


#include "stdafx.h"
#include<windows.h>
LRESULT CALLBACK WinSunProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
 static HPEN pen=CreatePen(PS_SOLID,3,RGB(255,78,99));//创建画笔
 static HBRUSH brush=CreateSolidBrush(RGB(22,182,111));//创建画刷
 if(uMsg==WM_PAINT)//窗口需要重画的时候
 {
    HDC hDC;
    PAINTSTRUCT ps;
    hDC=BeginPaint(hwnd,&ps);    //BeginPaint只能在响应WM_PAINT,不能用GetDC获取设备上下文
 SelectObject(hDC,pen);//选入画笔
 SelectObject(hDC,brush);//选入画刷
 Rectangle(hDC,100,100,200,200);
    EndPaint(hwnd,&ps);
}
else if(uMsg==WM_CLOSE)//用户关闭了窗口
 DestroyWindow(hwnd);//销毁窗口,并发送WM_DESTROY消息
else if(uMsg==WM_DESTROY)//如果窗口被销毁
 PostQuitMessage(0);//让进程退出
 return DefWindowProc(hwnd,uMsg,wParam,lParam); //未处理的消息通过DefWindowProc函数交给系统处理
}
int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{

  WNDCLASS wndcls; //定义一个存储窗口信息WNDCLASS变量
  wndcls.cbClsExtra=0; //默认为0
  wndcls.cbWndExtra=0; //默认为0
  wndcls.hbrBackground=(HBRUSH)GetStockObject(GRAY_BRUSH); //背景画刷
  wndcls.hCursor=LoadCursor(NULL,IDC_ARROW); //光标
  wndcls.hIcon=LoadIcon(NULL,IDI_ERROR); //窗口图标
  wndcls.hInstance=hInstance;   //应用程序实例句柄由WinMain函数传进来
  wndcls.lpfnWndProc=WinSunProc; //窗口消息处理函数
  wndcls.lpszClassName="windowclass"; //窗口类名
  wndcls.lpszMenuName=NULL; //窗口菜单名,没有菜单,为NULL
  wndcls.style=CS_HREDRAW | CS_VREDRAW;//窗口类型,CS_HREDRAW和CS_VERDRAW 表明
  //当窗口水平方向垂直方向的宽度变化时重绘整个窗口
  RegisterClass(&wndcls); //把窗口信息提交给系统,注册窗口类
  HWND hwnd; //用以存储CreateWindow函数所创建的窗口句柄
   hwnd=CreateWindow("windowclass","first windows",
  WS_OVERLAPPEDWINDOW,0,0,600,400,NULL,NULL,hInstance,NULL);//创建窗口
   ShowWindow(hwnd,SW_SHOWNORMAL);//窗口创建完了,显示它
   UpdateWindow(hwnd); //更新窗口,让窗口毫无延迟的显示
   MSG msg;//消息结构类型
   while(GetMessage(&msg,NULL,0,0))//获取消息
   {
    //TranslateMessage(&msg); //此函数用于把键盘消息(WM_KEYDOWN,WM_KEYUP)转换成字符消息WM_CHAR
    DispatchMessage(&msg); //这个函数调用窗口过程处理函数,并把MSG里的信息处理后传给过程函数的四个参数
 }
  return 0;
}

第三十七个 ReadProcessMemory根据进程句柄读取相应的一段内存(读其它进程里的内存)

函数定义:BOOL ReadProcessMemory(HANDLE hProcess,PVOID pvAddressRemote,PVOID pvBufferLocal,DWORD dwSize,

PDWORD pdwNumBytesRead);总共四个参数

第一个参数hProcess是远程进程句柄,被读取者 。第二个pvAddressRemote是远程进程中内存地址。 从具体何处读取

pvBufferLocal是本地进程中内存地址. 函数将读取的内容写入此处 ,dwSize是要读取字节数。要读取多少 

pdwNumBytesRead是实际读取的内容(函数执行后,实际读了多少字节,将存储在该变量里)

远程进程的内存地址是什么意思呢,比如我现在定义一个变量a,int a;就是了,大家知道int型是占四个字节的,也就是说如果a变量所占的内存起始地址是0x1234,那么变量a就占用0x1234,0x1235,0x1236,0x1237这四个字节,这四个字节的内容决定了a变量的值。

好了知道了这个,我们就来举个例子,读取另一个进程里一个变量的值:需设计两个程序,一个用于读(Read)一个用于被读(BeRead);

那么要如何获得另一个进程中一个变量的地址呢?这里我们用一个简单的方法,让另一个进程自己去获取,然后输出地址值。

被读的程序代码如下:假设该进程名为:BeRead.exe
#include<stdio.h>
int main()
{
 int a=10;//要读取的变量。
  printf("%x/n",&a);//输出这个变量的起始地址,假设输出为12ff7c
  while(1)
  {
   Sleep(1000);
  }

 return 0;
}

必须先让这个程序运行,然后根据输出的地址值,才能在下面的程序填入地址值。

读取的程序代码如下:

#include<windows.h>
#include<stdio.h>
#include<tlhelp32.h>
int main()
{

//先要获取进程句柄,如何获取,参照TerminateProcess函数,结束一个进程

 HANDLE ReProcess;
 PROCESSENTRY32 pe32;
 pe32.dwSize=sizeof(pe32);
 HANDLE hProcessSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
 BOOL bMore=::Process32First(hProcessSnap,&pe32);
 while(bMore)
 {
  if(strcmp(pe32.szExeFile,"BeRead.exe")==0)//如果是BeRead.exe
  {
   ReProcess=::OpenProcess(PROCESS_ALL_ACCESS,FALSE,pe32.th32ProcessID);//获取该进程句柄
   break;
  }
  bMore=Process32Next(hProcessSnap,&pe32);
 }
 int *ReAddress=(int *)0x12ff7c;//要读取的内存的地址值
 int  *p=new int;
    unsigned long size;
 ReadProcessMemory(ReProcess,ReAddress,p,4,&size);//读取BeRead进程的内存
 printf("%d/n",*p);//输出读取来的值
 return 0;
}

第三十八个WriteProcessMemory根据进程句柄写入相应的一段内存(写入其它进程里的内存)

这个函数里的参数跟ReadProcessMemory函数参数意思一样,只不过一个是写,一个是读。

下面直接举个例子,形式跟读内存函数的例子一样。

被写的程序代码如下:假设该进程名为:BeWrite.exe

#include<stdio.h>
int main()
{
 int a=10;
  printf("%x/n",&a);//假设输出为12ff7c
  while(1)
  {
   printf("%d/n",a);//每隔一秒输出,查看值有没有改变
   Sleep(1000);
  }

 return 0;
}

写入的代码如下:

#include<windows.h>
#include<stdio.h>
#include<tlhelp32.h>
int main()
{
 HANDLE ReProcess;
 PROCESSENTRY32 pe32;
 pe32.dwSize=sizeof(pe32);
 HANDLE hProcessSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
 BOOL bMore=::Process32First(hProcessSnap,&pe32);
 while(bMore)
 {
  if(strcmp(pe32.szExeFile,"BeWrite.exe")==0)
  {
   ReProcess=::OpenProcess(PROCESS_ALL_ACCESS,FALSE,pe32.th32ProcessID);
   break;
  }
  bMore=Process32Next(hProcessSnap,&pe32);
 }
 int *ReAddress=(int *)0x12ff7c;
 int  *p=new int;
 *p=300;
    unsigned long size;
 WriteProcessMemory(ReProcess,ReAddress,p,4,&size);

 return 0;
}

第三十九个CreateThread创建一个线程(多线程)

线程是什么意思呢,代码是由线程来执行的,一个程序默认只有一个线程(主线程),打个比方,线程就好比一个人,而不同功能的代码或函数就好是一件件不同的事情,如洗碗,洗衣服,擦地。一个人要把这几种事情做完,可以有好几种方案,第一种就是,洗完碗,就去洗衣服,衣服洗完了,再去擦地。第二种就是:洗一分钟碗,再去洗一分钟衣服,再去擦一分钟,然后又去洗一分钟衣服.......直到做完。好了,现在你可以再创造一个人帮你做事,创造这个人后,你就叫他洗衣服,而你就洗碗,这样两件事就可以同时被做了。而这里的创造一个人指的就是CreateThread函数。

函数定义:HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,DWORD dwStackSize,LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpParameter,DWORD dwCreationFlags,LPDWORD lpThreadId);

该函数有六个参数,第一个参数不用管它,填NULL,第二个参数dwStackSize用于新线程的初始堆栈大小,默认为0,第三个lpStartAddress填函数名(指标),但这个函数必须是这种固定格式的DWORD _stdcall ThreadProc(LPVOID lpParameter),新的线程将会执行这个函数里面的代码,直到函数结束,线程死亡。第四个lpParameter是一自定义参数,用户可以通过这个参数,传递需要的类型,这个参数与线程函数的参数相对应。第五个dwCreationFlags填0表示立即执行,如果是CREATE_SUSPENDED表示挂起,直到用ResumeThread函数唤醒。第六个lpThreadId填NULL就行了。

现举个例子,两个线程同时每隔一秒输出一个数字,也就是一秒会有两数字输出。

#include<windows.h>
#include<stdio.h>
DWORD _stdcall ThreadProc(LPVOID lpParameter)//线程执行函数
{
 int si=100;
 while(si>0)
 {
  printf("子线程输出数字:%d/n",si--);
  Sleep(1000);
 }
 return 0;
}

int main()
{
 int mi=0;
 CreateThread(NULL,0,ThreadProc,NULL,0,NULL);//创建一个线程,去执行ThreadProc函数
 while(mi<100)
 {
  printf("主线程输出数字:%d/n",mi++);
  Sleep(1000);
 }
 return 0;
}

第四十个GetCurrentProcessId获得当前进程ID

 DWORD currentPID;
 currentPID=::GetCurrentProcessId();//返回进程ID号
 cout<<currentPID<<endl;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值