stdcall很多时候被称为pascal调用约定,因为pascal是早期很常见的一种教学用计算机程序设计语言,其语法严谨,使用的函数调用约定就是stdcall。在Microsoft C++系列的C/C++编译器中,常常用PASCAL宏来声明这个调用约定,类似的宏还有WINAPI和CALLBACK。
stdcall调用约定声明的语法为(以前文的那个函数为例):
int __stdcall function(int a,int b)
stdcall的调用约定意味着:1)参数从右向左压入堆栈,2)函数自身修改堆栈 3)函数名自动加前导的下划线,后面紧跟一个@符号,其后紧跟着参数的尺寸
以上述这个函数为例,参数b首先被压栈,然后是参数a
cdecl调用约定
cdecl调用约定又称为C调用约定,是C语言缺省的调用约定,它的定义语法是:
int function (int a ,int b) //不加修饰就是C调用约定
int __cdecl function(int a,int b)//明确指出C调用约定
在写本文时,出乎我的意料,发现cdecl调用约定的参数压栈顺序是和stdcall是一样的,参数首先由右向左压入堆栈。所不同的是,函数本身不清理堆栈,调用者负责清理堆栈。由于这种变化,C调用约定允许函数的参数的个数是不固定的,这也是C语言的一大特色。
GlobalUnlock函数解除锁定的内存块,使指向该内存块的指针无效,GlobalLock锁定的内存,一定要用GlobalUnlock解锁。
锁定内存中指定的内存块,并返回一个地址值,令其指向内存块的起始处。除非用 GlobalUnlock 函数将内存块解锁,否则地址会一直保持有效。Windows为每个内存对象都维持着一个锁定计数。对这个函数的每次调用都应有一个对应的 GlobalUnlock 调用返回值Long,如成功,返回内存块的地址;如出错,或者这是一个已被丢弃的“可丢弃”内存块,则返回零。
一般情况下我们在编程的时候,给应用程序分配的内存都是可以移动的或者是可以丢弃的,这样能使有限的内存资源充分利用,所以,在某一个时候我们分配的那块内存的地址是不确定的,因为他是可以移动的,所以得先锁定那块内存块,这儿应用程序需要调用API函数GlobalLock函数来锁定句柄。如下:>
FindDIBBits
取bmp灰度值FindDIBBits 是得到DIB图像象素起始位置 lpDIBBits = ::FindDIBBits(lpDIB); 得到指针后读取就可得到数据
// 得到各个灰度值
for (i = 0; i < m_lHeight; i ++)
{//m_lHeight为图像高
for (j = 0; j < m_lWidth; j ++)
{//m_lHeight为图像宽
lpSrc = (unsigned char *)lpDIBBits + lLineBytes * i + j; // // 计算图像每行的字节数 lLineBytes = WIDTHBYTES(m_lWidth * 8);
// 计数加1
// m_lCount[*(lpSrc)]++;
}
}
DIBNumColors
//获取图象的颜色数 wNumColors=::DIBNumColors(lpDIB);
DIB,全称Device Independent Bitmap,设备无关位图文件,这是一种文件格式,其目的是为了保证用某个应用程序创建的位图图形可以被其它应用程序装载或显示一样。
paintdib函数显示DIB
AssertValid / Dump 知识解析
http://blog.sina.com.cn/s/blog_4add390001000alo.html
Invalidate
Invalidate()函数的作用是使整个窗口客户区无效,窗口客户无效即需要重绘,这时Window系统会发送一WM_PAINT消息放在应用程序的消息队列中,WM_PAINT消息的优先级很低,所以不会立即重绘。
如果需要立即重绘,那么就使用UpdateWindow( )函数,该函数可使WM_PAINT被直接发送到目标窗口,从而导致窗口立即重绘。
C++头文件中的#ifndef _MAC 的含义
DIB 读取bmp 及jpg图像是如何判断的?文件头?