VC API常用函数简单例子大全十一

第一百零一个OpenFileMapping获取CreateFileMapping函数创建的文件映射对象句柄

函数定义:HANDLE
OpenFileMappingW(
    DWORD dwDesiredAccess,//取值参考MapViewOfFile函数的dwDesiredAccess参数
    BOOL bInheritHandle,//依据CreateFileMapping函数的lpFileMappingAttributes参数而定,不能被新进程继承,为FALSE
    LPCWSTR lpName//指明获取哪个文件映射对象句柄,对应着CreateFileMapping函数的lpName参数
    );

函数返回文件映射对象句柄。

例子:两进程间传递数据

进程1程序代码:

#include<windows.h>
#include<stdio.h>
int main()
{
 char Data[11]="0123456789";
HANDLE hMap=CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE,0,11,"ShareMemory");
LPVOID lpBase = ::MapViewOfFile(hMap, FILE_MAP_WRITE, 0, 0, 0);
strcpy((char *)lpBase,Data);//写入数据
while(1)
{
 Sleep(2000);
}
return 0;
}
进程2程序代码:

#include<stdio.h>
#include<windows.h>
int main()
{
 HANDLE hMap=::OpenFileMapping(FILE_MAP_WRITE,FALSE,"ShareMemory");
 LPVOID lpBase = ::MapViewOfFile(hMap, FILE_MAP_WRITE, 0, 0, 0);
 printf("ShareMemory Data:%s\n",lpBase);//输出数据
 return 0;
}

第一百零二个CopyMemory复制一段内存

函数定义: VOID CopyMemory( 
  PVOID Destination, //目的地址
  CONST VOID *Source, //源地址
  DWORD Length //复制多少字节
  );
这个函数跟C语言的memcpy函数一样,这里仅举个例子:
#include<stdio.h>
#include<windows.h>
int main()
{
DWORD dwDestin=0;
DWORD dwSource=120;
CopyMemory((void *)&dwDestin,(void *)&dwSource,sizeof(DWORD));
printf("%d\n",dwDestin);
return 0;
}

第一百零三个SetParent设置(更改)一个子窗口的父窗口

该函数有两个参数,第一个是子窗口的句柄,第二个是父窗口的句柄。

如果父窗口句柄为空,则以桌面窗口作为父窗口

例子:把记事本里状态栏的父窗口改为编辑框窗口

用spy++查看记事本编辑框窗口的类名为"Edit",状态栏为"msctls_statusbar32"(可能会有差异,具体可以用Spy++查看)

#include<windows.h>
int main()
{
HWND wnd=FindWindow(NULL,"无标题.txt - 记事本");
HWND EditWnd=FindWindowEx(wnd,NULL,"Edit",NULL);//查找获取编辑框窗口句柄
HWND StatusWnd=FindWindowEx(wnd,NULL,"msctls_statusbar32",NULL);//查找获取状态栏窗口句柄
::SetParent(StatusWnd,EditWnd);//设置状态栏父窗口
RECT rect;
GetClientRect(StatusWnd,&rect);//获取状态栏客户区大小

//移动状态栏窗口,如果编辑框窗口不是状态栏的父窗口,则状态栏是移不进编辑框窗口的
MoveWindow(StatusWnd,0,0,rect.right,rect.bottom,TRUE);

return 0;
}

第一百零四个OpenClipboard打开一个剪切板

剪切板是什么意思呢,可以把它看做一块内存,这块内存可以被任何进程调用相关函数进行读写。事实上,像我们平常的复制粘贴就是在读写这块内存,比如用选中一段文字,然后右击,选择复制,这时对应程序就会调用OpenClipboard函数打开剪切板,往里面写入数据,

当不再需要操作剪切板的时候就调用CloseClipboard函数关闭剪切板,剪切板不能同时被多个程序打开,也就是说如果其它程序已经调用OpenClipboard打开剪切板了,并且没有调用CloseClipboard关闭剪切板的话,那么其它程序调用OpenClipboard就会失败,这一点从下面的例子可以说明。

这个函数只有一个参数,是一个窗口句柄,也就是具体在哪个窗口里进行复制粘贴操作(剪切也算),如果为NULL,则跟调用这个函数的进程相关联。

例子:让粘贴复制失效

#include<windows.h>
int main()
{
 OpenClipboard(NULL);
 while(1)
  Sleep(1000);
}

由于这个程序打开了剪切板却并不关闭它,导致了其它程序无法调用OpenClipboard函数打开剪切板,无法打开剪切板,自然也就无法复制粘贴数据了

第一百零五个SetClipboardData写入一段数据到剪切板(设置剪切板的数据)

HANDLE SetClipboardData( UINT uFormat,HANDLE hMem);

像我们使用windows的复制粘贴的时候,不仅能复制文字,也能复制文件,图片等。所以uFormat指明要写入的是什么数据。

uFormat的常用取值如下:

CF_UNICODETEXT含有Unicode文字的内存块

CF_BITMAP与设备相关的位图格式。位图是通过位图句柄传送给剪切板的

CF_TEXT以NULL结尾的ANSI字符集字符串

第二个指向存储要写入的数据内存,注意,存储数据的内存必须是在堆中分配的。

例子1:写入ASCII字符串到剪切版

#include<windows.h>
#include<string.h>
int main()
{
 char *pData=new char[15];//在堆中申请内存
 strcpy(pData,"ABCDEFG");
 OpenClipboard(NULL);//打开剪切板
 EmptyClipboard();//清空剪切板的数据
 SetClipboardData(CF_TEXT,pData);//往剪切板里写入数据
 CloseClipboard();//关闭剪切板
 delete pData;
 return 0;
}

//随便到可以输入文字的地方,右击->粘贴看写入是否成功

例子2:写入宽字符串(Unicode)到剪切板

#include<string.h>
#include<windows.h>
int main()
{
WCHAR *pData=new WCHAR[15];
WCHAR str[15]=L"ABC我们D";//用L把ASCII转换成Unicode
CopyMemory((void *)pData,(void *)str,sizeof(str));//相当于ASCII字符串处理函数strcpy
OpenClipboard(NULL);
EmptyClipboard();
SetClipboardData(CF_UNICODETEXT,pData);
CloseClipboard();
return 0;
}

第一百零六个GlobalAlloc从堆中分配一定数目的字节数

HGLOBAL
WINAPI
GlobalAlloc(
    UINT uFlags,//分配属性(方式)
    DWORD dwBytes//分配多少字节
    );

uFlags常用取值:
GMEM_FIXED 分配固定的内存,返回值是一个指针

GMEM_MOVEABLE  返回值是一个内存句柄,可用GlobalLock函数根据一个内存句柄,返回内存句柄对应的首地址,并锁定内存中指定的内存块,对应的函数是:GlobalUnlock

对应的释放内存函数是GlobalFree,这里还是说明一个函数GlobalSize,这个根据内存句柄获得对应内存块大小

例子:GlobalAlloc函数应用

#include<stdio.h>
#include<windows.h>
int main()
{
HGLOBAL hMem=GlobalAlloc(GMEM_MOVEABLE,8);//按GEME_MOVEABLE方式分配内存

DWORD dwSize=GlobalSize(hMem);//获取内存块大小
int *pNumber=(int *)GlobalLock(hMem);//把内存句柄转换成内存首地址
pNumber[0]=5;pNumber[1]=6;
printf("内存块大小%d\n%d,%d\n",dwSize,pNumber[0],pNumber[1]);
GlobalFree(hMem);//释放内存
return 0;
}

第一百零七个GetClipboardData该函数获得剪切板里的数据,函数返回剪切板内存句柄

该函数只有一个参数,指明获取的是什么类型的数据,跟SetClipboardData函数的uFormat参数相对应,这里有一个问题,如何知道剪切板存储的是什么类型数据呢,用 IsClipboardFormatAvailable函数,这个函数只有一个参数,如: IsClipboardFormatAvailable(CF_TEXT)

这个语句用于判断当前剪切板有没有含有CF_TEXT数据,如果有的话,返回真(TRUE),否返回假。这个函数不用事先打开剪切板,也可以正常调用。

 注意如果如果剪切板的数据是CF_UNICODETEXT形式的,用CF_TEXT类型打开也是可以的,因为windows系统会自动进行转换。

例子:获取剪切板里的CF_TEXT数据(先随便复制一段文字)

#include<stdio.h>
#include<windows.h>
int main()
{
  if(IsClipboardFormatAvailable(CF_TEXT))//判断剪切板里是否有CF_TEXT数据
  {
 ::OpenClipboard(NULL);
 HGLOBAL hGlobal = GetClipboardData(CF_TEXT);//以CF_TEXT方式打开剪切板
 char *pGlobal=(char *)GlobalLock(hGlobal);//获得剪切板内存的首地址,直接转换也可以,如(char *)hGlobal
 printf("%s\n",pGlobal);//输出剪切板里的文字

GlobalUnlock(hGlobal);
 CloseClipboard();
  }
   return 0;
}

第一百零八个Shell_NotifyIcon在任务栏里注册图标(任务栏托盘菜单)

(PS:今天看了一下以前写的这个函数,我描述这个函数为托盘菜单,今天来看,似乎压根就跟菜单没关系,我想,应该是那时候是在MFC里看到这个函数,那个例子是做一个托盘菜单,我就用了托盘菜单了,却没有实现托盘菜单的功能,不过,并不影响理解这个函数用法,以及它的意思,我也较烦)

函数定义:Shell_NotifyIcon(DWORD dwMessage, PNOTIFYICONDATAW lpData);

要想注册一个托盘菜单,首先你得提供一些信息,如在任务栏要显示的图标,系托盘菜单属于哪个窗口(严格来说,是托盘菜单产生的消息,发送给哪个窗口)

而这些信息就由Shell_NotifyIcon函数的第二个参数 lpData指明。它是一个NOTIFYICONDATAW结构指针。

NOTIFYICONDATAW结构定义及各成员意思如下:

typedef struct _NOTIFYICONDATAW {
        DWORD cbSize;//指明NOTIFYICONDATA结构大小,用sizeof(NOTIFYICONDATA)给它赋值。
        HWND hWnd;//窗口句柄,由鼠标在托盘图标产生的消息将发送给这个窗口
        UINT uID;//标识托盘菜单的唯一ID号。
        UINT uFlags;//指明结构中哪些成员有效,可以是NIF_ICON(对应hIcon), NIF_MESSAGE(对应uCallbackMessage),

         //NIF_TIP(对应 szTip),可以用|按位或运算符结合在一起。
        UINT uCallbackMessage;//自定义消息,鼠标在托菜图标上产生的行为将发送这个消息给hWnd成员对应的窗口
        HICON hIcon;//图标句柄,
        WCHAR  szTip[64];//鼠标停留在托盘图标上产生的提示消息内容
} NOTIFYICONDATA, *PNOTIFYICONDATA;

dwMessage参数指明要进行的操作,常用取值有NIM_ADD(添加托盘菜单),NIM_DELETE(删除一个托盘菜单),NIM_MODIFY (修改一个托盘菜单)

了解了上面些我们来简单的在任务栏上显示一个托盘菜单的图标,其它什么也不做。

假设e盘下有一个名为"i.ico"的图标

代码如下:

#include<windows.h>
int main()
{
 NOTIFYICONDATA notify;//定义一个托盘菜单信息结构
  notify.cbSize=sizeof(NOTIFYICONDATA);//设置结构大小
 notify.hIcon=(HICON)LoadImage(NULL,"e:\\i.ico",IMAGE_ICON,48,48,LR_LOADFROMFILE);//设置图标句柄
 notify.uFlags=NIF_ICON;//指明哪些成员有效
 ::Shell_NotifyIcon(NIM_ADD,&notify);//添加托盘菜单
 while(1)
 {
  Sleep(1000);//避免程序退出,自动卸载托盘菜单
 }
 return 0;
}

怎么样任务栏是不是有一个图标显示了,但此时,用鼠单击,或双击任务上的图标都没反应。

如果想响应鼠标操作消息的话,得使 NOTIFYICONDATA结构的uCallbackMessage成员有效,这样当鼠标在托盘菜单图标上单击或双击后,就会产生uCallbackMessage成员对应的消息。而且还必须指定窗口句柄,不然产生了这个消息,发送给哪个窗口呢。

例子2:完整的托盘菜单应用

完整应用,必须得有自己的窗口,新建一个 “Win32 Application"工程。如果对用API函数创建窗口不了解的话,可以参考常用函数CreateWindow.

#include<windows.h>
#include<string.h>
//在WM_USER的基础上定义一个消息类型,用于托盘与窗口之间的消息传递
#define WM_TRAYMESSAGE WM_USER+25 
LRESULT CALLBACK WinSunProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);//函数声明
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","托盘菜单应用",
  WS_OVERLAPPEDWINDOW,0,0,600,400,NULL,NULL,hInstance,NULL);//创建窗口
   NOTIFYICONDATA notify;//定义一个托盘菜单信息结构
  notify.cbSize=sizeof(NOTIFYICONDATA);//设置结构大小
   notify.hIcon=(HICON)LoadImage(NULL,"e:\\i.ico",IMAGE_ICON,48,48,LR_LOADFROMFILE);//设置图标句柄
   notify.hWnd=hwnd;//接收消息的窗口句柄
   strncpy(notify.szTip,"托盘菜单",sizeof("托盘菜单"));
   notify.uCallbackMessage=WM_TRAYMESSAGE;//托盘菜单将发送这个消息给窗口
  notify.uFlags=NIF_ICON|NIF_MESSAGE|NIF_TIP;//指明哪些成员有效
  ::Shell_NotifyIcon(NIM_ADD,&notify);//添加托盘菜单
    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里的信息处理后传给过程函数的四个参数
   }
    ::Shell_NotifyIcon(NIM_DELETE,&notify);//卸载托盘菜单
  return 0;
}
LRESULT CALLBACK WinSunProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
 switch(uMsg)
 {
 case WM_SYSCOMMAND:
  if(wParam==SC_MINIMIZE)//最小化了窗口
  {
  ShowWindow(hwnd,SW_HIDE);//隐藏窗口
  }
  else
  {
   return DefWindowProc(hwnd,uMsg,wParam,lParam);
  }
  break;
 case WM_TRAYMESSAGE:
  if(lParam==WM_LBUTTONDBLCLK)//双击托盘菜单图标,鼠标消息在lParam参数里
  {
   ShowWindow(hwnd,SW_RESTORE);//显示窗口
  }
  break;
  case WM_CLOSE://用户关闭了窗口
    DestroyWindow(hwnd);//销毁窗口,并发送WM_DESTROY消息
    break;
  case WM_DESTROY://如果窗口被销毁
    PostQuitMessage(0);//让进程退出
   break;
    //未处理的消息通过DefWindowProc函数交给系统处理
  default:return DefWindowProc(hwnd,uMsg,wParam,lParam);
 }

return 0;
}

第一百零九个FindResource从应用程序模块句柄找出一个资源

资源就是MFC里的资源,像位图,图标,对话框等这些资源都包含在exe文件里,如果看过PE文件结构分析及应用的话,应该会容易理解。

这个函数就是定位一个资源在模块里的位置。

函数定义:HRSRC FindResource(HMODULE hModule,//应用程序模块句柄,NULL表示本模块句柄

LPCTSTR lpName,//资源名

LPCTSTR lpType//资源类型

);

其中第一个参数hModule应用程序模块句柄,自身模块填NULL就行,如果想获取其它正在运行的应用程序模块,就用GetModuleHandle函数。

资源名就像资源的ID号一样,比如一个MFC的一个资源ID号是147,那么此参数应该是这样的"#147",或用MAKEINTRESOURCE宏转换

如:MAKEINTRESOURCE(147)

lpType用于表明资源类型,它是对话框?菜单?位图?还是自定义资源。。。

常用取值如下:

#define RT_CURSOR           MAKEINTRESOURCE(1)    //光标
#define RT_BITMAP           MAKEINTRESOURCE(2) //位图
#define RT_ICON             MAKEINTRESOURCE(3)//图标
#define RT_MENU             MAKEINTRESOURCE(4)//菜单
#define RT_DIALOG           MAKEINTRESOURCE(5)//对话框
#define RT_STRING           MAKEINTRESOURCE(6)//字符串
#define RT_FONTDIR          MAKEINTRESOURCE(7)
#define RT_FONT             MAKEINTRESOURCE(8)//字体
#define RT_ACCELERATOR      MAKEINTRESOURCE(9)
#define RT_RCDATA           MAKEINTRESOURCE(10)
#define RT_MESSAGETABLE     MAKEINTRESOURCE(11)

#define DIFFERENCE          11
#define RT_GROUP_CURSOR MAKEINTRESOURCE((DWORD)RT_CURSOR + DIFFERENCE)//光标组
#define RT_GROUP_ICON   MAKEINTRESOURCE((DWORD)RT_ICON + DIFFERENCE)//图标组
#define RT_VERSION      MAKEINTRESOURCE(16)
#define RT_DLGINCLUDE   MAKEINTRESOURCE(17)

第一百一十个LoadResource根据资源指向句柄(HRSRC)把资源装载到内存。

函数返回资源所在内存句柄(HGLOBAL),可以用LockResource根据内存句柄,获取内存首地址

函数定义:

HGLOBAL LoadResource(HMODULE hModule,HRSRC hResiInfo);

hModule参数同FindResource对应的参一样,模块句柄,hResiInfo参数对应FindResource函数返回的值

 

 LockResource函数定义:LPVOID LockResource(HGLOBAL hResDate);
hResDate参数对应LoadResource函数返回的值

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值