MySQL的C语言API接口
1、首先当然是连接数据库,函数原型如下:
MYSQL * STDCALL mysql_real_connect(MYSQL *mysql, const char *host,const char *user,const char *passwd,const char *db,unsigned int port,const char *unix_socket,unsigned long clientflag);第一个参数 MYSQL是 C api中一个非常重要的变量,里面内存非常丰富,有port,dbname,charset等连接基本参数。它也包含了一个叫 st_mysql_methods的结构体变量,该变量里面保存着很多函数指针,这些函数指针将会在数据库连接成功以后的各种数据操作中被调用。mysql_real_connect函数中各参数,基本都是顾名思意。
2、连接数据库成功之后就可以执行sql语句了使用mysql_query
int STDCALL mysql_query(MYSQL *mysql, const char *q);第一个参数上面已经介绍过,第二个参数为要执行的sql语句。这个函数总体就两步:(1)发送sql语句,其实就一个socket发送sql 语句,加上mysql固定的协议头。懒的去看源码了,抓了下包,如下:0000 19 00 00 00 0373 65 6c 65 63 74 20 61 70 70 5f .....select app_0010 6e 61 6d 65 20 66 72 6f 6d 20 61 70 70 name from app红色部分是协议,前面两位其实就是包的长度。具体协议没研究过。(2)然后就是接受结果,这里将会调用MYSQL变量中的st_mysql_methods中的read_query_result函数指针
3、获取结果
sql执行完以后,如果是查询语句,我们当然还要读取数据,如果update,insert等语句,那么就看下操作成功与否即可。我们来看看如何获取查询结果: 如果mysql_query返回成功,那么我们就通过mysql_store_result这个函数来读取结果。原型如下:MYSQL_RES * STDCALL mysql_store_result(MYSQL *mysql);该函数会调用MYSQL变量中的st_mysql_methods中的 read_rows函数指针来获取查询的结果。同时该函数会返回MYSQL_RES 这样一个变量,该变量主要用于保存查询的结果。同时该函数malloc了一片内存空间来存储查询过来的数据,所以我们一定要记的 free(result),不然是肯定会造成内存泄漏的。 执行完mysql_store_result以后,其实数据都已经在MYSQL_RES 变量中了,下面的api基本就是读取MYSQL_RES 中的数据。例如mysql_fetch_row这个函数,就是读去查询结果的一行。函数原型如下MYSQL_ROW STDCALL mysql_fetch_row(MYSQL_RES *result);它会返回一个MYSQL_ROW变量,MYSQL_ROW其实就是char **.就当成一个二维数组来用吧。还有很多api,不再一一介绍,大部分信息都在MYSQL_RES MYSQL这两个结构体中。具体可以参考mysql官方网站: http://dev.mysql.com/doc/refman/5.1/en/c.html 突然发现官方网站资料好全面,貌似比任何书都要好。下面来个例子:#include<stdio.h>#include<stdlib.h>#include<string.h>#include<mysql/mysql.h>#define MAX_COLUMN_LEN 32int main(int argc , char *argv[]){ MYSQL my_connection; MYSQL_RES *result; MYSQL_ROW sql_row; MYSQL_FIELD *fd; char column[MAX_COLUMN_LEN][MAX_COLUMN_LEN]; int res; mysql_init(&my_connection); if(mysql_real_connect(&my_connection,"127.0.0.1","用户","密码","数据名称",3306,NULL,0)) { perror("connect"); res=mysql_query(&my_connection,"select * from app");//查询 if(!res) { result=mysql_store_result(&my_connection);//保存查询到的数据到result if(result) { int i,j; printf("the result number is %lu\n ",(unsigned long)mysql_num_rows(result)); for(i=0;fd=mysql_fetch_field(result);i++)//获取列名 { bzero(column[i],sizeof(column[i])); strcpy(column[i],fd->name); } j=mysql_num_fields(result); for(i=0;i<j;i++) { printf("%s\t",column[i]); } printf("\n"); while(sql_row=mysql_fetch_row(result))//获取具体的数据 { for(i=0;i<j;i++) { printf("%s\t",sql_row[i]); } printf("\n"); } } } else { perror("select"); } } else { perror("connect:error"); } mysql_free_result(MYSQL_RES *result);//释放结果资源 mysql_close(&my_connection);//断开连接}上面这个例子就是从一个表中查数据,然后输出。 如果要insert或者update,只需要修改具体的sql既可。具体的操作都是通过mysql_query这个函数来搞定。 现在来讲编译的方法吧,这里我们需要.h以及.so库。我们可以在 http://dev.mysql.com/downloads/connector/c/6.0.html 下载Connector/C。简单的方法就是: 把里面include的东西拷贝到/usr/include/mysql/下面去,这样编译的时候就不需要加-I了,然后把lib下面的东西拷贝的/usr/lib/下去。gcc具体的编译方法:gcc ***.c -o *** -lmysqlclient
C语言日志和事务API—libjio
libjio是一个C库做日志,交易为导向的I/O它提供了一个类UNIX的文件操作功能(如打开,读取和写入) ,这是装在一个交易框架,以使文件操作可以提交或回滚是必要的。这是非侵入性,原子,和线程安全的,具有快速崩溃恢复。示例代码:#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <errno.h>#include <string.h>#include <libjio.h>#define FILENAME "test1"#define TEXT "Hello world!\n"int main(void){ int r; struct jfs file; struct jtrans trans; struct jfsck_result result; /* check the file is OK */ jfsck(FILENAME, NULL, &result); jfsck_cleanup(FILENAME, NULL); /* and open it */ r = jopen(&file, FILENAME, O_RDWR | O_CREAT | O_TRUNC, 0600, 0); if (r < 0) { perror("jopen"); return 1; } /* write two "Hello world"s next to each other */ jtrans_init(&file, &trans); jtrans_add(&trans, TEXT, strlen(TEXT), 0); jtrans_add(&trans, TEXT, strlen(TEXT), strlen(TEXT)); r = jtrans_commit(&trans); if (r < 0) { perror("jtrans_commit"); return 1; } /* at this point the file has "Hello world!\nHello world!\n" */ /* now we rollback */ r = jtrans_rollback(&trans); if (r < 0) { perror("jtrans_rollback"); return 1; } /* and now the file is empty! */ jtrans_free(&trans); jclose(&file); return 0;}
sqlite-C语言API介绍
在这一部分我将展示一些简单的应用程序来说明SQLite的众多特性。这些应用程序将在下面的一些子部分中展示,让我们通过学习一个很简单的应用程序来开始我们SQLite大陆的探险吧。下面的例子展示了一个典型的SQLite应用程序。它是一个使用SQLite API来处理一个SQLite数据库文件的C程序。
这是一个典型的SQLite应用程序:#include <stdio.h>#include "sqlite3.h"int main(void){ sqlite3* db = 0; sqlite3_stmt* stmt = 0; int retcode; retcode = sqlite3_open("MyDB", &db); if (retcode != SQLITE_OK){ sqlite3_close(db); fprintf(stderr, "Could not open MyDB/n"); return retcode; } retcode = sqlite3_prepare(db, "select SID from Students order by SID", -1, &stmt, 0); if (retcode != SQLITE_OK){ sqlite3_close(db); fprintf(stderr, "Could not execute SELECT/n"); return retcode; } while (sqlite3_step(stmt) == SQLITE_ROW){ int i = sqlite3_column_int(stmt, 0); printf("SID = %d/n", i); } sqlite3_finalize(stmt); sqlite3_close(db); return SQLITE_OK;}你可以编译上面的例子并且执行它。在这个文档中显示的示例输出是在一个linux机器上获得的,但是这些例子能够在SQLite运行的其他的平台上工作。这些例子假定你已经准备了可执行的sqlite3,libsqlite3.so(windows上是sqlite3.dll而Mac OS X上是libsqlite3.dylib)共享库,和sqlite3.h接口定义文件。你可以从http://www.sqlite.org上获取这些源代码或二进制形式的文件。你会发现如果你将所有这三个(sqlite3, the shared library, 和sqlite3.h)和范例放在同一个目录下处理该范例会比较容易。举个例子,假设你在一个Linux系统上,并且你将app1.c示例程序保存在libsqlite3.so , sqlite3和sqlite3.h同一个目录下。你能够通过执行这条命令编译文件:gcc app1.c -o ./app1 -lsqlite3 -L.它将会在当前工作的目录下产生一个名为app1的二进制文件。你可以执行这个二进制文件来查看输出。注:SQLite源代码和应用程序必须在同一个编译器下编译。如果你已经将SQLite作为一个包安装了,或者如果你的操作系统预安装了SQlite,你可能需要使用一组不同的编译参数。例如,在Ubuntu上,你可以通过命令sudo aptitude install sqlite3 libsqlite3-dev安装SQLite,并且你可以使用命令cc app1.c -o ./app1 -lsqlite3来编译应用程序。因为在现行的Mac OS X版本中包含SQLite,上述的相同的编译命令也能工作。这个应用程序打开了在当前工作目录下的MyDB数据库文件。这个数据库需要至少一个表,命名为Students;这个表必须至少有一个整型列名为SID。在下一个例子中,你将会学习如何在数据库中创建新的表,和如何在表中插入行(也被称为元组和记录),但是在目前,你可以使用这些命令创建并落户表:sqlite3 MyDB "create table students (SID integer)"sqlite3 MyDB "insert into students values (200)"sqlite3 MyDB "insert into students values (100)"sqlite3 MyDB "insert into students values (300)"如果你现在运行app1(在linux系统下要引入SQLite库,,你可能需要在LD_LIBRARY_PATH环境变量中加入你的工作目录名字,你将会看到下面的输出:SID = 100SID = 200SID = 300注:在Linux,Unix和Mac OS X中,在命令提示符中键入app1的名字时,你可能需要前缀./应用程序首先做好准备工作,接着执行SQL语句:select SID from Students order by SID。然后它进阶到作为结果的行集,一个接一个的获取SID的值,并且打印各个值。最后关闭数据库。SQLite是一个调用级别上的接口库,它能够嵌入到应用程序中。该库将所有的SQLite API函数实现为C函数。所有的API函数都是以sqlite3_前缀命名,并且在sqlite3.h中声明。在示例应用程序中使用了他们中的一部分,他们是sqlite3_open, sqlite3_prepare, sqlite3_step, sqlite3_column_int, sqlite3_finalize, 和 sqlite3_close。应用程序也采用了助记符常量,即用于API的返回比较值的SQLITE_OK 和 SQLITE_ROW。这些助记符在sqlite3.h中被定义。1.1.1.1 sqlite3_open 通过执行sqlite3_open函数,应用程序经由SQLite库打开了一个到数据库文件的新连接。(该应用程序可能有其他到相同的或者不同的数据库的开放连接。SQLite清楚地处理这些连接,并且他们在SQLite注意前是相互间独立的)。如果文件还不存在,SQLite将自动的创建数据库文件。注:在打开或创建一个文件时,SQLite遵守一个懒惰策略:知道该文件被阅读访问时才真正的打开或者创建。sqlite3_open函数经由一个形参(db,在前面的例子中)返回一个连接句柄(一个指向sqlite3类型的对象的指针),而句柄被用来支持在数据库连接(因为这次打开连接)上的进一步操作。句柄表示了这次连接的完整情况。1.1.1.2 sqlite3_preparesqlite3_prepare函数编译了一个SQL语句,并且产生了一个等价的内部对象。这个对象在数据库文法中作为一个准备语句被普遍的提及,在SQLite中他被实现为一个字节编码程序。字节编码程序是在虚拟机或者解释器上运行的SQL语言的一个抽象表示。想要得到更多的信息,看后面的部分字节编码编程语言。在本书中,我将交替使用条件字节编码程序和准备语句。sqlite3_prepare函数经由一个形参(在前面例子中的stmt)返回一个状态句柄(指向sqlite3_stmt类型对象的指针),该句柄被用来支持进一步的操作来操纵准备状态。在这个示例程序中,我准备了select SID from Students order by SID语句作为stmt句柄。这个句柄动作起来就像一个开放的光标并且他被用来获取SELECT语句返回的作为结果的行集,一次一行。1.1.1.3 sqlite3_stepsqlite3_step函数将执行字节编码程序直到它遇到折点(因为它已经计算了新的一行),或者直到它停止(没有剩下的行了)。在之前的例子中,他返回了SQLITE_ROW,而在之后的例子中是SQLITE_DONE。因为有的SQL语句不返回行(例如UPDATE,INSERT,DELETE,和CREATE),当没有行要处理时,他总是返回SQLITE_DONE。Step函数移动指针的位置来获得SELECT语句的结果。初始的,指针指向输出行集的第一行的前一位置。执行一次step函数,指针移动到了输出行集的下一行。该指针只能向前移动。1.1.1.4 sqlite3_column_int如果step函数返回了SQLITE_ROW,你能够通过执行sqlite3_column_*API函数来检索每一列(也被认为是属性或域)的值。SQL/SQLite和C语言中的阻抗(数据类型)的不匹配能够被自动的处理:API在两种语言间,将数据进行从存储类型到请求类型的转换。在示例应用中,每个输出行是一个整型值,我们通过执行返回整型值的sqlite3_column_int函数来读取的SID的值。1.1.1.5 sqlite3_finalizesqlite3_finalize函数销毁准备好的状态。也就是说,擦除字节编码程序,并且释放分配给状态句柄的所有资源。句柄变为不可用。1.1.1.6 sqlite3_closesqlite3_close函数关闭数据库连接,并且释放了分配给该连接的所有资源。该连接句柄变为不可用。1.1.1.7 其他有用的函数其它被广泛使用的API是sqlite3_bind_*和sqlite3_reset。在一个SQL语句字符串(输入到sqlite3_prepare),一个或者多个文本值能够被SQL参数标识?(或者?NNN,:AAA,@AAA或者$AAA,其中NNN是一个数字,而AAA是一个标示符)来代替。他们成为准备语句的输入参数这些参数的值可以通过使用bind API函数来设置。如果一个参数没有值约束,那么它不是取默认值,就是在没有默认值被声明的时候取SQL NULL。reset API函数通过一个异常将状态句柄(例如,准备状态)重置回它的初始状态:所有有制约值的参数保持他们的原值。状态准备被应用程序再一次的执行,并且在再执行过程中重用这些值。然而,应用程序可能会在它开始重新执行的前再一次的执行bind API获得新值来代替前值。1.1.1.8 返回值 所有的API函数返回0或者负整数值。SQLite推荐使用助记符来核对返回值。返回值SQLITE_OK表示成功。SQLITE_ROW表示sqlite3_step函数在SELECT语句返回的行集中找到了新的一行;SQLITE_DONE表示语句执行完成了。
c语言+API实现恶作剧程序
恶作剧一:鼠标禁锢:#include<windows.h>#pragma comment(linker,"/subsystem:\"Windows\" /entry:\"mainCRTStartup\"")void main(){ int x,y; while(1) { x=1; y=1; SetCursorPos(x,y); } return ;}恶作剧二:鼠标乱抖:#include<windows.h>#include<stdio.h>#pragma comment(linker,"/subsystem:\"Windows\" /entry:\"mainCRTStartup\"")void main(){ int x,y; while(1) {x=rand()%801; y=rand()%601; SetCursorPos(x,y); }return ;}
C语言API之文本和字体函数
C中与图形有关的在#include "graphics.h"里面setcolor 颜色,可以用数字表示色彩。AddFontResource:在Windows系统中添加一种字体资源CreateFont :用指定的属性创建一种逻辑字体CreateFontIndirect: 用指定的属性创建一种逻辑字体CreateScalableFontResource:为一种TureType字体创建一个资源文件,以便能用API函数AddFontResource将其加入Windows系统DrawText:将文本描绘到指定的矩形中DrawTextEx与DrawText相似,只是加入了更多的功能EnumFontFamilies:列举指定设备可用的字体EnumFontFamiliesEx:列举指定设备可用的字体EnumFonts:列举指定设备可用的字体ExtTextOut:经过扩展的文本描绘函数。也请参考SetTextAlign函数GetAspectRatioFilterEx用SetMapperFlags要求Windows只选择与设备当前纵横比相符的光栅字体时,本函数可判断纵横比大小GetCharABCWidths:判断TureType字体中一个或多个字符的A-B-C大小GetCharABCWidthsFloat:查询一种字体中一个或多个字符的A-B-C尺寸GetCharacterPlacement:该函数用于了解如何用一个给定的字符显示一个字串GetCharWidth:调查字体中一个或多个字符的宽度GetFontData:接收一种可缩放字体文件的数据GetFontLanguageInfo:返回目前选入指定设备场景中的字体的信息GetGlyphOutline:取得TureType字体中构成一个字符的曲线信息GetKerningPairs:取得指定字体的字距信息GetOutlineTextMetrics:接收与TureType字体内部特征有关的详细信息GetRasterizerCaps:了解系统是否有能力支持可缩放的字体GetTabbedTextExtent:判断一个字串占据的范围,同时考虑制表站扩充的因素GetTextAlign:接收一个设备场景当前的文本对齐标志GetTextCharacterExtra 判断额外字符间距的当前值GetTextCharset 接收当前选入指定设备场景的字体的字符集标识符GetTextCharsetInfo 获取与当前选定字体的字符集有关的详细信息GetTextColor 判断当前字体颜色。通常也称为“前景色”GetTextExtentExPoint 判断要填入指定区域的字符数量。也用一个数组装载每个字符的范围信息GetTextExtentPoint 判断一个字串的大小(范围)GetTextFace 获取一种字体的字样名GetTextMetrics 获取与选入一种设备场景的物理字体有关的信息GrayString 描绘一个以灰色显示的字串。通常由Windows用于标识禁止状态PolyTextOut 描绘一系列字串RemoveFontResource 从Windows系统中删除一种字体资源SetMapperFlags Windows对字体进行映射时,可用该函数选择与目标设备的纵横比相符的光栅字体SetTextAlign 设置文本对齐方式,并指定在文本输出过程中使用设备场景的当前位置SetTextCharacterExtra 描绘文本的时候,指定要在字符间插入的额外间距SetTextColor 设置当前文本颜色。这种颜色也称为“前景色”SetTextJustification 通过指定一个文本行应占据的额外空间,可用这个函数对文本进行两端对齐处理TabbedTextOut 支持制表站的一个文本描绘函数TextOut 文本绘图函数 一.C语言中字体的问题 C语言中有两种显示方式,即文本方式和图形方式。就我所知,只能在图形方式下控制字体. 先看一下C中定义的几种字体 名称 索引值 字体说明 DEFAULT_FONT 0 8x8 bit-mapped font TRIPLEX_FONT 1 Stroked triplex font SMALL_FONT 2 Stroked small font SANS_SERIF_FONT 3 Stroked sans-serif font GOTHIC_FONT 4 Stroked gothic font
C语言API—sqlite3的速度问题
在这里:http://web.utk.edu/~jplyon/sqlite/SQLite_optimization_FAQ.html#timing大拿说道:The first thing you should know is that most of the time spent by SQLite (and most other DB systems) is on disk access, which is slow compared to memory operations.我写了个测试程序,意外的看到读写只是运行时占用资源的一个小头,大头被sqlite3_get_table()占了,请教是怎么回事?/* 纯净版, 无出错处理 */ 头文件 /#include <stdio.h>#include <sqlite3.h>#include <time.h> /* for time */#include <stdlib.h> /* for system */#include <string.h> /* for memset strcpy */// 宏及结构体定义 ///#define DB_FILE "test_0.1.db"struct s_table1{ int id; int mark; char name[33]; unsigned char type; char con[513];}; 全局变量 /sqlite3 *db = NULL;int ret = -1; /* 各函数返回值 */ 函数声明 /void way01(); // 打开、关闭的影响int createdb();int insertdb();int getdatas_no_oc1 ( sqlite3 *db, struct s_table1 *tb1 );/ 代码 /int main ( void ){ int c = 0; ret = createdb(); ret = insertdb(); printf ( "createdb() -> createtable() -> insertdb() over\n" ); printf ( "\n" ); printf ( "1 : 打开、关闭的影响 ///\n" ); while ( (c=getchar()) != 'q' ) { switch (c) { case '1': way01(); // 打开、关闭的影响 break; default: break; } } system ( "rm -rf test_0.1.db" ); return 0;}///// 打开、关闭的影响void way01(){ time_t tick1, tick2; int i = 0; int num = 100000; struct s_table1 tb_data; time ( &tick1 ); for ( i=0; i<num; i++ ) { ret = sqlite3_open ( DB_FILE, &db ); sqlite3_close (db); } time ( &tick2 ); printf("单纯打开、关闭数据库文件 100000 次, 时间为: %4ld s\n", tick2 - tick1 ); time ( &tick1 ); for ( i=0; i<num; i++ ) { ret = sqlite3_open ( DB_FILE, &db ); ret = getdatas_no_oc1 ( db, &tb_data ); sqlite3_close (db); } time ( &tick2 ); printf("打开、关闭并操作数据库文件 100000 次, 时间为: %4ld s\n", tick2 - tick1 );}///int createdb(){ system ( "rm -rf test_0.1.db" ); char *sql1 = "CREATE TABLE table1 (id INTEGER, m INTEGER, n VARCHAR(32), t CHAR(1), con VARCHAR(512))"; ret = sqlite3_open ( DB_FILE, &db ); ret = sqlite3_exec ( db, sql1, NULL, NULL, NULL ); sqlite3_close (db); return 0;}int insertdb(){ time_t ticks1, ticks2; int i = 0; int num = 1000; ret = sqlite3_open ( DB_FILE, &db ); char *qf1 = "INSERT INTO table1 VALUES (%d, %d, %Q, %d, %Q)"; char *sql = NULL; time ( &ticks1 ); //下面是对所以插入进行手动提交, 这样可以加快插入速度, 大于200倍 sqlite3_exec ( db, "BEGIN", NULL, NULL, NULL ); //插入num条记录 for (i=0;i<num;i++) { sql = sqlite3_mprintf ( qf1, i, i*2, "goodc", i%(num/10), "test - varcharvarcharvarchar" ); ret = sqlite3_exec(db, sql, NULL, NULL, NULL); sqlite3_free (sql); } sqlite3_exec(db,"COMMIT",NULL,NULL,NULL); time ( &ticks2 ); //printf ( "the time of insertdb is: %ld s\n", ticks2-ticks1 ); sqlite3_close (db); return 0;}int getdatas_no_oc1 ( sqlite3 *db, struct s_table1 *tb1 ){ char *sql = "SELECT * FROM table1 WHERE id=500;"; int row = 0; int column = 0; char **resultp = NULL; ret = sqlite3_get_table ( db, sql, &resultp, &row, &column, NULL ); sqlite3_free_table(resultp); return 0;}
利用win32 API写文件
void WriteLog(CHAR csMsg[], DWORD dwSize ){ HANDLE hFile;DWORD dwNumberOfBytesWritten;// 必须指定 OPEN_ALWAYS 标志, 否则不会在原文件内容上添加hFile = CreateFile( _szFileName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_HIDDEN,NULL );if (hFile == INVALID_HANDLE_VALUE ){ return ;}// 设置文件指针到文件结尾, 在 当前位置 FILE_END, 向后移动 0 字节SetFilePointer( hFile , 0, NULL, FILE_END );// 这个 API 是设置当前的位置为文件的结尾// SetEndOfFile( hFile);BOOL BRet = WriteFile( hFile, csMsg, dwSize , &dwNumberOfBytesWritten, NULL);CloseHandle( hFile );}
简要的Windows API函数大全(1)
1. API之网络函数
WNetAddConnection 创建同一个网络资源的永久性连接WNetAddConnection2 创建同一个网络资源的连接WNetAddConnection3 创建同一个网络资源的连接WNetCancelConnection 结束一个网络连接WNetCancelConnection2 结束一个网络连接WNetCloseEnum 结束一次枚举操作WNetConnectionDialog 启动一个标准对话框,以便建立同网络资源的连接WNetDisconnectDialog 启动一个标准对话框,以便断开同网络资源的连接WNetEnumResource 枚举网络资源WNetGetConnection 获取本地或已连接的一个资源的网络名称WNetGetLastError 获取网络错误的扩展错误信息WNetGetUniversalName 获取网络中一个文件的远程名称以及/或者UNC(统一命名规范)名称WNetGetUser 获取一个网络资源用以连接的名字WNetOpenEnum 启动对网络资源进行枚举的过程
2. API之消息函数
BroadcastSystemMessage 将一条系统消息广播给系统中所有的顶级窗口GetMessagePos 取得消息队列中上一条消息处理完毕时的鼠标指针屏幕位置GetMessageTime 取得消息队列中上一条消息处理完毕时的时间PostMessage 将一条消息投递到指定窗口的消息队列PostThreadMessage 将一条消息投递给应用程序RegisterWindowMessage 获取分配给一个字串标识符的消息编号ReplyMessage 答复一个消息SendMessage 调用一个窗口的窗口函数,将一条消息发给那个窗口SendMessageCallback 将一条消息发给窗口SendMessageTimeout 向窗口发送一条消息SendNotifyMessage 向窗口发送一条消息
3. API之文件处理函数
CloseHandle 关闭一个内核对象。其中包括文件、文件映射、进程、线程、安全和同步对象等CompareFileTime 对比两个文件的时间CopyFile 复制文件CreateDirectory 创建一个新目录CreateFile 打开和创建文件、管道、邮槽、通信服务、设备以及控制台CreateFileMapping 创建一个新的文件映射对象DeleteFile 删除指定文件DeviceIoControl 对设备执行指定的操作DosDateTimeToFileTime 将DOS日期和时间值转换成一个 win32 FILETIME 值FileTimeToDosDateTime 将一个 win32 FILETIME 值转换成DOS日期和时间值FileTimeToLocalFileTime 将一个FILETIME结构转换成本地时间FileTimeToSystemTime 根据一个FILETIME结构的内容,装载一个SYSTEMTIME结构FindClose 关闭由FindFirstFile函数创建的一个搜索句柄FindFirstFile 根据文件名查找文件FindNextFile 根据调用FindFirstFile函数时指定的一个文件名查找下一个文件FlushFileBuffers 针对指定的文件句柄,刷新内部文件缓冲区FlushViewOfFile 将写入文件映射缓冲区的所有数据都刷新到磁盘GetBinaryType 判断文件是否可以执行GetCompressedFileSize 判断一个压缩文件在磁盘上实际占据的字节数GetCurrentDirectory 在一个缓冲区中装载当前目录GetDiskFreeSpace 获取与一个磁盘的组织有关的信息,以及了解剩余空间的容量GetDiskFreeSpaceEx 获取与一个磁盘的组织以及剩余空间容量有关的信息GetDriveType 判断一个磁盘驱动器的类型GetExpandedName 取得一个压缩文件的全名GetFileAttributes 判断指定文件的属性GetFileInformationByHandle 这个函数提供了获取文件信息的一种机制GetFileSize 判断文件长度GetFileTime 取得指定文件的时间信息GetFileType 在给出文件句柄的前提下,判断文件类型GetFileVersionInfo 从支持版本标记的一个模块里获取文件版本信息GetFileVersionInfoSize 针对包含了版本资源的一个文件,判断容纳文件版本信息需要一个多大的缓冲区GetFullPathName 获取指定文件的完整路径名GetLogicalDrives 判断系统中存在哪些逻辑驱动器字母GetLogicalDriveStrings 获取一个字串,其中包含了当前所有逻辑驱动器的根驱动器路径GetOverlappedResult 判断一个重叠操作当前的状态GetPrivateProfileInt 为初始化文件(.ini文件)中指定的条目获取一个整数值GetPrivateProfileSection 获取指定小节(在.ini文件中)所有项名和值的一个列表GetPrivateProfileString 为初始化文件中指定的条目取得字串GetProfileInt 取得win.ini初始化文件中指定条目的一个整数值GetProfileSection 获取指定小节(在win.ini文件中)所有项名和值的一个列表GetProfileString 为win.ini初始化文件中指定的条目取得字串GetShortPathName 获取指定文件的短路径名GetSystemDirectory 取得Windows系统目录(即System目录)的完整路径名GetTempFileName 这个函数包含了一个临时文件的名字,它可由应用程序使用GetTempPath 获取为临时文件指定的路径GetVolumeInformation 获取与一个磁盘卷有关的信息GetWindowsDirectory 获取Windows目录的完整路径名hread 参考lreadhwrite 参考lwrite函数lclose 关闭指定的文件lcreat 创建一个文件llseek 设置文件中进行读写的当前位置LockFile 锁定文件的某一部分,使其不与其他应用程序共享LockFileEx 与LockFile相似,只是它提供了更多的功能lopen 以二进制模式打开指定的文件lread 将文件中的数据读入内存缓冲区lwrite 将数据从内存缓冲区写入一个文件LZClose 关闭由LZOpenFile 或 LZInit函数打开的一个文件LZCopy 复制一个文件LZInit 这个函数用于初始化内部缓冲区LZOpenFile 该函数能执行大量不同的文件处理,而且兼容于压缩文件LZRead 将数据从文件读入内存缓冲区LZSeek 设置一个文件中进行读写的当前位置MapViewOfFile 将一个文件映射对象映射到当前应用程序的地址空间MoveFile 移动文件OpenFile 这个函数能执行大量不同的文件操作OpenFileMapping 打开一个现成的文件映射对象QueryDosDevice 在Windows NT中,DOS设备名会映射成NT系统设备名。该函数可判断当前的设备映射情况ReadFile 从文件中读出数据ReadFileEx 与ReadFile相似,只是它只能用于异步读操作,并包含了一个完整的回调RegCloseKey 关闭系统注册表中的一个项(或键)RegConnectRegistry 访问远程系统的部分注册表RegCreateKey 在指定的项下创建或打开一个项RegCreateKeyEx 在指定项下创建新项的更复杂的方式。在Win32环境中建议使用这个函数RegDeleteKey 删除现有项下方一个指定的子项RegDeleteValue 删除指定项下方的一个值RegEnumKey 枚举指定项的子项。在Win32环境中应使用RegEnumKeyExRegEnumKeyEx 枚举指定项下方的子项RegEnumValue 枚举指定项的值RegFlushKey 将对项和它的子项作出的改动实际写入磁盘RegGetKeySecurity 获取与一个注册表项有关的安全信息RegLoadKey 从以前用RegSaveKey函数创建的一个文件里装载注册表信息RegNotifyChangeKeyValue 注册表项或它的任何一个子项发生变化时,用这个函数提供一种通知机制RegOpenKey 打开一个现有的注册表项RegOpenKeyEx 打开一个现有的项。在win32下推荐使用这个函数RegQueryInfoKey 获取与一个项有关的信息RegQueryValue 取得指定项或子项的默认(未命名)值RegQueryValueEx 获取一个项的设置值RegReplaceKey 用一个磁盘文件保存的信息替换注册表信息;并创建一个备份,在其中包含当前注册表信息RegRestoreKey 从一个磁盘文件恢复注册表信息RegSaveKey 将一个项以及它的所有子项都保存到一个磁盘文件RegSetKeySecurity 设置指定项的安全特性RegSetValue 设置指定项或子项的默认值RegSetValueEx 设置指定项的值RegUnLoadKey 卸载指定的项以及它的所有子项RemoveDirectory 删除指定目录SearchPath 查找指定文件SetCurrentDirectory 设置当前目录SetEndOfFile 针对一个打开的文件,将当前文件位置设为文件末尾SetFileAttributes 设置文件属性SetFilePointer 在一个文件中设置当前的读写位置SetFileTime 设置文件的创建、访问及上次修改时间SetHandleCount 这个函数不必在win32下使用;即使使用,也不会有任何效果SetVolumeLabel 设置一个磁盘的卷标(Label)SystemTimeToFileTime 根据一个FILETIME结构的内容,载入一个SYSTEMTIME结构UnlockFile 解除对一个文件的锁定UnlockFileEx 解除对一个文件的锁定UnmapViewOfFile 在当前应用程序的内存地址空间解除对一个文件映射对象的映射VerFindFile 用这个函数决定一个文件应安装到哪里VerInstallFile 用这个函数安装一个文件VerLanguageName 这个函数能根据16位语言代码获取一种语言的名称VerQueryValue 这个函数用于从版本资源中获取信息WriteFile 将数据写入一个文件WriteFileEx 与WriteFile类似,只是它只能用于异步写操作,并包括了一个完整的回调WritePrivateProfileSection 为一个初始化文件(.ini)中指定的小节设置所有项名和值WritePrivateProfileString 在初始化文件指定小节内设置一个字串WriteProfileSection 为Win.ini初始化文件中一个指定的小节设置所有项名和值WriteProfileString 在Win.ini初始化文件指定小节内设置一个字串
4. API之打印函数
AbortDoc 取消一份文档的打印AbortPrinter 删除与一台打印机关联在一起的缓冲文件AddForm 为打印机的表单列表添加一个新表单AddJob 用于获取一个有效的路径名,以便用它为作业创建一个后台打印文件。它也会为作业分配一个作业编号AddMonitor 为系统添加一个打印机监视器AddPort 启动"添加端AddPort 启动"添加端口"对话框,允许用户在系统可用端口列表中加入一个新端口AddPrinter 在系统中添加一台新打印机AddPrinterConnection 连接指定的打印机AddPrinterDriver 为指定的系统添加一个打印驱动程序AddPrintProcessor 为指定的系统添加一个打印处理器AddPrintProvidor 为系统添加一个打印供应商AdvancedDocumentProperties 启动打印机文档设置对话框ClosePrinter 关闭一个打开的打印机对象ConfigurePort 针对指定的端口,启动一个端口配置对话框ConnectToPrinterDlg 启动连接打印机对话框,用它同访问网络的打印机连接DeleteForm 从打印机可用表单列表中删除一个表单DeleteMonitor 删除指定的打印监视器DeletePort 启动"删除端口"对话框,允许用户从当前系统删除一个端口DeletePrinter 将指定的打印机标志为从系统中删除DeletePrinterConnection 删除与指定打印机的连接DeletePrinterDriver 从系统删除一个打印机驱动程序DeletePrintProcessor 从指定系统删除一个打印处理器DeletePrintProvidor 从系统中删除一个打印供应商DeviceCapabilities 利用这个函数可获得与一个设备的能力有关的信息DocumentProperties 打印机配置控制函数EndDocAPI 结束一个成功的打印作业EndDocPrinter 在后台打印程序的级别指定一个文档的结束EndPage 用这个函数完成一个页面的打印,并准备设备场景,以便打印下一个页EndPagePrinter 指定一个页在打印作业中的结尾EnumForms 枚举一台打印机可用的表单EnumJobs 枚举打印队列中的作业EnumMonitors 枚举可用的打印监视器EnumPorts 枚举一个系统可用的端口EnumPrinterDrivers 枚举指定系统中已安装的打印机驱动程序EnumPrinters 枚举系统中安装的打印机EnumPrintProcessorDatatypes 枚举由一个打印处理器支持的数据类型EnumPrintProcessors 枚举系统中可用的打印处理器Escape 设备控制函数FindClosePrinterChangeNotification 关闭用FindFirstPrinterChangeNotification函数获取的一个打印机通告对象FindFirstPrinterChangeNotification 创建一个新的改变通告对象,以便我们注意打印机状态的各种变化FindNextPrinterChangeNotification 用这个函数判断触发一次打印机改变通告信号的原因FreePrinterNotifyInfo 释放由FindNextPrinterChangeNotification函数分配的一个缓冲区GetForm 取得与指定表单有关的信息GetJob 获取与指定作业有关的信息GetPrinter 取得与指定打印机有关的信息GetPrinterData 为打印机设置注册表配置信息GetPrinterDriver 针对指定的打印机,获取与打印机驱动程序有关的信息GetPrinterDriverDirectory 判断指定系统中包含了打印机驱动程序的目录是什么GetPrintProcessorDirectory 判断指定系统中包含了打印机处理器驱动程序及文件的目录OpenPrinter 打开指定的打印机,并获取打印机的句柄PrinterMessageBox 在拥有指定打印作业的系统上显示一个打印机出错消息框PrinterProperties 启动打印机属性对话框,以便对打印机进行配置ReadPrinter 从打印机读入数据ResetDC 重设一个设备场景ResetPrinter 改变指定打印机的默认数据类型及文档设置ScheduleJob 提交一个要打印的作业SetAbortProc 为Windows指定取消函数的地址SetForm 为指定的表单设置信息SetJob 对一个打印作业的状态进行控制SetPrinter 对一台打印机的状态进行控制SetPrinterData 设置打印机的注册表配置信息StartDoc 开始一个打印作业StartDocPrinter 在后台打印的级别启动一个新文档StartPage 打印一个新页前要先调用这个函数StartPagePrinter 在打印作业中指定一个新页的开始WritePrinter 将发送目录中的数据写入打印机
5. API之文本和字体函数
AddFontResource 在Windows系统中添加一种字体资源CreateFont 用指定的属性创建一种逻辑字体CreateFontIndirect 用指定的属性创建一种逻辑字体CreateScalableFontResource 为一种TureType字体创建一个资源文件,以便能用API函数AddFontResource将其加入Windows系统DrawText 将文本描绘到指定的矩形中DrawTextEx 与DrawText相似,只是加入了更多的功能EnumFontFamilies 列举指定设备可用的字体EnumFontFamiliesEx 列举指定设备可用的字体EnumFonts 列举指定设备可用的字体ExtTextOut 经过扩展的文本描绘函数。也请参考SetTextAlign函数GetAspectRatioFilterEx 用SetMapperFlags要求Windows只选择与设备当前纵横比相符的光栅字体时,本函数可判断纵横比大小GetCharABCWidths 判断TureType字体中一个或多个字符的A-B-C大小GetCharABCWidthsFloat 查询一种字体中一个或多个字符的A-B-C尺寸GetCharacterPlacement 该函数用于了解如何用一个给定的字符显示一个字串GetCharWidth 调查字体中一个或多个字符的宽度GetFontData 接收一种可缩放字体文件的数据GetFontLanguageInfo 返回目前选入指定设备场景中的字体的信息GetGlyphOutline 取得TureType字体中构成一个字符的曲线信息GetKerningPairs 取得指定字体的字距信息GetOutlineTextMetrics 接收与TureType字体内部特征有关的详细信息GetRasterizerCaps 了解系统是否有能力支持可缩放的字体GetTabbedTextExtent 判断一个字串占据的范围,同时考虑制表站扩充的因素GetTextAlign 接收一个设备场景当前的文本对齐标志GetTextCharacterExtra 判断额外字符间距的当前值GetTextCharset 接收当前选入指定设备场景的字体的字符集标识符GetTextCharsetInfo 获取与当前选定字体的字符集有关的详细信息GetTextColor 判断当前字体颜色。通常也称为"前景色"GetTextExtentExPoint 判断要填入指定区域的字符数量。也用一个数组装载每个字符的范围信息GetTextExtentPoint 判断一个字串的大小(范围)GetTextFace 获取一种字体的字样名GetTextMetrics 获取与选入一种设备场景的物理字体有关的信息GrayString 描绘一个以灰色显示的字串。通常由Windows用于标识禁止状态PolyTextOut 描绘一系列字串RemoveFontResource 从Windows系统中删除一种字体资源SetMapperFlags Windows对字体进行映射时,可用该函数选择与目标设备的纵横比相符的光栅字体SetTextAlign 设置文本对齐方式,并指定在文本输出过程中使用设备场景的当前位置SetTextCharacterExtra 描绘文本的时候,指定要在字符间插入的额外间距SetTextColor 设置当前文本颜色。这种颜色也称为"前景色"SetTextJustification 通过指定一个文本行应占据的额外空间,可用这个函数对文本进行两端对齐处理TabbedTextOut 支持制表站的一个文本描绘函数TextOut 文本绘图函数
6. API之菜单函数
AppendMenu 在指定的菜单里添加一个菜单项CheckMenuItem 复选或撤消复选指定的菜单条目CheckMenuRadioItem 指定一个菜单条目被复选成"单选"项目CreateMenu 创建新菜单CreatePopupMenu 创建一个空的弹出式菜单DeleteMenu 删除指定的菜单条目DestroyMenu 删除指定的菜单DrawMenuBar 为指定的窗口重画菜单EnableMenuItem 允许或禁止指定的菜单条目GetMenu 取得窗口中一个菜单的句柄GetMenuCheckMarkDimensions 返回一个菜单复选符的大小GetMenuContextHelpId 取得一个菜单的帮助场景IDGetMenuDefaultItem 判断菜单中的哪个条目是默认条目GetMenuItemCount 返回菜单中条目(菜单项)的数量GetMenuItemID 返回位于菜单中指定位置处的条目的菜单IDGetMenuItemInfo 取得(接收)与一个菜单条目有关的特定信息GetMenuItemRect 在一个矩形中装载指定菜单条目的屏幕坐标信息GetMenuState 取得与指定菜单条目状态有关的信息GetMenuString 取得指定菜单条目的字串GetSubMenu 取得一个弹出式菜单的句柄,它位于菜单中指定的位置GetSystemMenu 取得指定窗口的系统菜单的句柄HiliteMenuItem 控制顶级菜单条目的加亮显示状态InsertMenu 在菜单的指定位置处插入一个菜单条目,并根据需要将其他条目向下移动InsertMenuItem 插入一个新菜单条目IsMenu 判断指定的句柄是否为一个菜单的句柄LoadMenu 从指定的模块或应用程序实例中载入一个菜单LoadMenuIndirect 载入一个菜单MenuItemFromPoint 判断哪个菜单条目包含了屏幕上一个指定的点ModifyMenu 改变菜单条目RemoveMenu 删除指定的菜单条目SetMenu 设置窗口菜单SetMenuContextHelpId 设置一个菜单的帮助场景IDSetMenuDefaultItem 将一个菜单条目设为默认条目SetMenuItemBitmaps 设置一幅特定位图,令其在指定的菜单条目中使用,代替标准的复选符号(√)SetMenuItemInfo 为一个菜单条目设置指定的信息TrackPopupMenu 在屏幕的任意地方显示一个弹出式菜单TrackPopupMenuEx 与TrackPopupMenu相似,只是它提供了额外的功能
简要的Windows API函数大全(2)
7. API之位图、图标和光栅运算函数
BitBlt 将一幅位图从一个设备场景复制到另一个CopyIcon 制作指定图标或鼠标指针的一个副本。这个副本从属于发出调用的应用程序CopyImage 复制位图、图标或指针,同时在复制过程中进行一些转换工作CreateBitmap 按照规定的格式创建一幅与设备有关位图CreateBitmapIndirect 创建一幅与设备有关位图CreateCompatibleBitmap 创建一幅与设备有关位图,它与指定的设备场景兼容CreateCursor 创建一个鼠标指针CreateDIBitmap 根据一幅与设备无关的位图创建一幅与设备有关的位图CreateDIBSection 创建一个DIBSectionCreateIcon 创建一个图标CreateIconIndirect 创建一个图标DestroyCursor 清除指定的鼠标指针,并释放它占用的所有系统资源DestroyIcon 清除图标DrawIcon 在指定的位置画一个图标DrawIconEx 描绘一个图标或鼠标指针。与DrawIcon相比,这个函数提供了更多的功能ExtractAssociatedIcon 判断一个可执行程序或DLL中是否存在图标,或是否有图标与系统注册表中指定的文件存在关联并提取之ExtractIcon 判断一个可执行文件或DLL中是否有图标存在,并将其提取出来GetBitmapBits 将来自位图的二进制位复制到一个缓冲区GetBitmapDimensionEx 取得一幅位图的宽度和高度GetDIBColorTable 从选入设备场景的DIBSection中取得颜色表信息GetDIBits 将来自一幅位图的二进制位复制到一幅与设备无关的位图里GetIconInfo 取得与图标有关的信息GetStretchBltMode 判断StretchBlt 和 StretchDIBits函数采用的伸缩模式LoadBitmap 从指定的模块或应用程序实例中载入一幅位图LoadCursor 从指定的模块或应用程序实例中载入一个鼠标指针LoadCursorFromFile 在一个指针文件或一个动画指针文件的基础上创建一个指针LoadIcon 从指定的模块或应用程序实例中载入一个图标LoadImage 载入一个位图、图标或指针MaskBlt 执行复杂的图象传输,同时进行掩模(MASK)处理PatBlt 在当前选定的刷子的基础上,用一个图案填充指定的设备场景PlgBlt 复制一幅位图,同时将其转换成一个平行四边形。利用它可对位图进行旋转处理SetBitmapBits 将来自缓冲区的二进制位复制到一幅位图SetBitmapDimensionEx 设置一幅位图的宽度。以一毫米的十分之一为单位SetDIBColorTable 设置选入设备场景的一个DIBSection的颜色表信息SetDIBits 将来自与设备无关位图的二进制位复制到一幅与设备有关的位图里SetDIBitsToDevice 将一幅与设备无关位图的全部或部分数据直接复制到一个设备SetStretchBltMode 指定StretchBlt 和 StretchDIBits函数的伸缩模式StretchBlt 将一幅位图从一个设备场景复制到另一个StretchDIBits 将一幅与设备无关位图的全部或部分数据直接复制到指定的设备场景
8. API之绘图函数
AbortPath 抛弃选入指定设备场景中的所有路径。也取消目前正在进行的任何路径的创建工作AngleArc 用一个连接弧画一条线Arc 画一个圆弧BeginPath 启动一个路径分支CancelDC 取消另一个线程里的长时间绘图操作Chord 画一个弦CloseEnhMetaFile 关闭指定的增强型图元文件设备场景,并将新建的图元文件返回一个句柄CloseFigure 描绘到一个路径时,关闭当前打开的图形CloseMetaFile 关闭指定的图元文件设备场景,并向新建的图元文件返回一个句柄CopyEnhMetaFile 制作指定增强型图元文件的一个副本(拷贝)CopyMetaFile 制作指定(标准)图元文件的一个副本CreateBrushIndirect 在一个LOGBRUSH数据结构的基础上创建一个刷子CreateDIBPatternBrush 用一幅与设备无关的位图创建一个刷子,以便指定刷子样式(图案)CreateEnhMetaFile 创建一个增强型的图元文件设备场景CreateHatchBrush 创建带有阴影图案的一个刷子CreateMetaFile 创建一个图元文件设备场景CreatePatternBrush 用指定了刷子图案的一幅位图创建一个刷子CreatePen 用指定的样式、宽度和颜色创建一个画笔CreatePenIndirect 根据指定的LOGPEN结构创建一个画笔CreateSolidBrush 用纯色创建一个刷子DeleteEnhMetaFile 删除指定的增强型图元文件DeleteMetaFile 删除指定的图元文件DeleteObject 删除GDI对象,对象使用的所有系统资源都会被释放DrawEdge 用指定的样式描绘一个矩形的边框DrawEscape 换码(Escape)函数将数据直接发至显示设备驱动程序DrawFocusRect 画一个焦点矩形DrawFrameControl 描绘一个标准控件DrawState 为一幅图象或绘图操作应用各式各样的效果Ellipse 描绘一个椭圆,由指定的矩形围绕EndPath 停止定义一个路径EnumEnhMetaFile 针对一个增强型图元文件,列举其中单独的图元文件记录EnumMetaFile 为一个标准的windows图元文件枚举单独的图元文件记录EnumObjects 枚举可随同指定设备场景使用的画笔和刷子ExtCreatePen 创建一个扩展画笔(装饰或几何)ExtFloodFill 在指定的设备场景里,用当前选择的刷子填充一个区域FillPath 关闭路径中任何打开的图形,并用当前刷子填充FillRect 用指定的刷子填充一个矩形FlattenPath 将一个路径中的所有曲线都转换成线段FloodFill 用当前选定的刷子在指定的设备场景中填充一个区域FrameRect 用指定的刷子围绕一个矩形画一个边框GdiComment 为指定的增强型图元文件设备场景添加一条注释信息GdiFlush 执行任何未决的绘图操作GdiGetBatchLimit 判断有多少个GDI绘图命令位于队列中GdiSetBatchLimit 指定有多少个GDI绘图命令能够进入队列GetArcDirection 画圆弧的时候,判断当前采用的绘图方向GetBkColor 取得指定设备场景当前的背景颜色GetBkMode 针对指定的设备场景,取得当前的背景填充模式GetBrushOrgEx 判断指定设备场景中当前选定刷子起点GetCurrentObject 获得指定类型的当前选定对象GetCurrentPositionEx 在指定的设备场景中取得当前的画笔位置GetEnhMetaFile 取得磁盘文件中包含的一个增强型图元文件的图元文件句柄GetEnhMetaFileBits 将指定的增强型图元文件复制到一个内存缓冲区里GetEnhMetaFileDescription 返回对一个增强型图元文件的说明GetEnhMetaFileHeader 取得增强型图元文件的图元文件头GetEnhMetaFilePaletteEntries 取得增强型图元文件的全部或部分调色板GetMetaFile 取得包含在一个磁盘文件中的图元文件的图元文件句柄GetMetaFileBitsEx 将指定的图元文件复制到一个内存缓冲区GetMiterLimit 取得设备场景的斜率限制(Miter)设置GetNearestColor 根据设备的显示能力,取得与指定颜色最接近的一种纯色GetObjectAPI 取得对指定对象进行说明的一个结构GetObjectType 判断由指定句柄引用的GDI对象的类型GetPath 取得对当前路径进行定义的一系列数据GetPixel 在指定的设备场景中取得一个像素的RGB值GetPolyFillMode 针对指定的设备场景,获得多边形填充模式GetROP2 针对指定的设备场景,取得当前的绘图模式GetStockObject 取得一个固有对象(Stock)GetSysColorBrush 为任何一种标准系统颜色取得一个刷子GetWinMetaFileBits 通过在一个缓冲区中填充用于标准图元文件的数据,将一个增强型图元文件转换成标准windows图元文件InvertRect 通过反转每个像素的值,从而反转一个设备场景中指定的矩形LineDDA 枚举指定线段中的所有点LineTo 用当前画笔画一条线,从当前位置连到一个指定的点MoveToEx 为指定的设备场景指定一个新的当前画笔位置PaintDesk 在指定的设备场景中描绘桌面墙纸图案PathToRegion 将当前选定的路径转换到一个区域里Pie 画一个饼图PlayEnhMetaFile 在指定的设备场景中画一个增强型图元文件PlayEnhMetaFileRecord 回放单独一条增强型图元文件记录PlayMetaFile 在指定的设备场景中回放一个图元文件PlayMetaFileRecord 回放来自图元文件的单条记录PolyBezier 描绘一条或多条贝塞尔(Bezier)曲线PolyDraw 描绘一条复杂的曲线,由线段及贝塞尔曲线组成Polygon 描绘一个多边形Polyline 用当前画笔描绘一系列线段PolyPolygon 用当前选定画笔描绘两个或多个多边形PolyPolyline 用当前选定画笔描绘两个或多个多边形Rectangle 用当前选定的画笔描绘矩形,并用当前选定的刷子填充RoundRect 用当前选定的画笔画一个圆角矩形,并用当前选定的刷子在其中填充SelectClipPath 将设备场景当前的路径合并到剪切区域里SelectObject 为当前设备场景选择图形对象SetArcDirection 设置圆弧的描绘方向SetBkColor 为指定的设备场景设置背景颜色SetBkMode 指定阴影刷子、虚线画笔以及字符中的空隙的填充方式SetBrushOrgEx 为指定的设备场景设置当前选定刷子的起点SetEnhMetaFileBits 用指定内存缓冲区内包含的数据创建一个增强型图元文件SetMetaFileBitsEx 用包含在指定内存缓冲区内的数据结构创建一个图元文件SetMiterLimit 设置设备场景当前的斜率限制SetPixel 在指定的设备场景中设置一个像素的RGB值SetPixelV 在指定的设备场景中设置一个像素的RGB值SetPolyFillMode 设置多边形的填充模式SetROP2 设置指定设备场景的绘图模式。与vb的DrawMode属性完全一致SetWinMetaFileBits 将一个标准Windows图元文件转换成增强型图元文件StrokeAndFillPath 针对指定的设备场景,关闭路径上打开的所有区域StrokePath 用当前画笔描绘一个路径的轮廓。打开的图形不会被这个函数关闭UnrealizeObject 将一个刷子对象选入设备场景之前,如刷子的起点准备用SetBrushOrgEx修改,则必须先调用本函数WidenPath 根据选定画笔的宽度,重新定义当前选定的路径
9. API之设备场景函数
CombineRgn 将两个区域组合为一个新区域CombineTransform 驱动世界转换。它相当于依顺序进行两次转换CreateCompatibleDC 创建一个与特定设备场景一致的内存设备场景CreateDC 为专门设备创建设备场景CreateEllipticRgn 创建一个椭圆CreateEllipticRgnIndirect 创建一个内切于特定矩形的椭圆区域CreateIC 为专用设备创建一个信息场景CreatePolygonRgn 创建一个由一系列点围成的区域CreatePolyPolygonRgn 创建由多个多边形构成的区域。每个多边形都应是封闭的CreateRectRgn 创建一个矩形区域CreateRectRgnIndirect 创建一个矩形区域CreateRoundRectRgn 创建一个圆角矩形DeleteDC 删除专用设备场景或信息场景,释放所有相关窗口资源DPtoLP 将点阵从设备坐标转换到专用设备场景逻辑坐标EqualRgn 确定两个区域是否相等ExcludeClipRect 从专用设备场景的剪裁区中去掉一个矩形区。矩形内不能进行绘图ExcludeUpdateRgn 从专用设备场景剪裁区去掉指定窗口的刷新区域ExtCreateRegion 根据世界转换修改区域ExtSelectClipRgn 将指定区域组合到设备场景的当前剪裁区FillRgn 用指定刷子填充指定区域FrameRgn 用指定刷子围绕指定区域画一个外框GetBoundsRect 获取指定设备场景的边界矩形GetClipBox 获取完全包含指定设备场景剪裁区的最小矩形GetClipRgn 获取设备场景当前剪裁区GetDC 获取指定窗口的设备场景GetDCEx 为指定窗口获取设备场景。相比GetDC,本函数提供了更多的选项GetDCOrgEx 获取指定设备场景起点位置(以屏幕坐标表示)GetDeviceCaps 根据指定设备场景代表的设备的功能返回信息GetGraphicsMode 确定是否允许增强图形模式(世界转换)GetMapMode 为特定设备场景调入映象模式GetRegionData 装入描述一个区域信息的RgnData结构或缓冲区GetRgnBox 获取完全包含指定区域的最小矩形GetUpdateRgn 确定指定窗口的刷新区域。该区域当前无效,需要刷新GetViewportExtEx 获取设备场景视口(viewport)范围GetViewportOrgEx 获取设备场景视口起点GetWindowDC 获取整个窗口(包括边框、滚动条、标题栏、菜单等)的设备场景GetWindowExtEx 获取指定设备场景的窗口范围GetWindowOrgEx 获取指定设备场景的逻辑窗口的起点GetWindowRgn 获取窗口区域GetWorldTransform 如果有世界转换,为设备场景获取当前世界转换IntersectClipRect 为指定设备定义一个新的剪裁区InvalidateRgn 使窗口指定区域不活动,并将它加入窗口刷新区,使之可随后被重画InvertRgn 通过颠倒每个像素值反转设备场景指定区域LPtoDP 将点阵从指定设备场景逻辑坐标转换为设备坐标ModifyWorldTransform 根据指定的模式修改世界转换OffsetClipRgn 按指定量平移设备场景剪裁区OffsetRgn 按指定偏移量平移指定区域OffsetViewportOrgEx 平移设备场景视口区域OffsetWindowOrgEx 平移指定设备场景窗口起点PaintRgn 用当前刷子背景色填充指定区域PtInRegion 确定点是否在指定区域内PtVisible 确定指定点是否可见(即,点是否在设备场景剪裁区内)RectInRegion 确定矩形是否有部分在指定区域内RectVisible 确定指定矩形是否有部分可见(是否在设备场景剪裁区内)ReleaseDC 释放由调用GetDC或GetWindowDC函数获取的指定设备场景RestoreDC 从设备场景堆栈恢复一个原先保存的设备场景SaveDC 将指定设备场景状态保存到Windows设备场景堆栈ScaleViewportExtEx 缩放设备场景视口的范围ScaleWindowExtEx 缩放指定设备场景窗口范围ScrollDC 在窗口(由设备场景代表)中水平和(或)垂直滚动矩形SelectClipRgn 为指定设备场景选择新的剪裁区SetBoundsRect 设置指定设备场景的边界矩形SetGraphicsMode 允许或禁止增强图形模式,以提供某些支持(包括世界转换)SetMapMode 设置指定设备场景的映射模式SetRectRgn 设置区域为指定的矩形SetViewportExtEx 设置设备场景视口范围SetViewportOrgEx 设置设备场景视口起点SetWindowExtEx 设置指定设备场景窗口范围SetWindowOrgEx 设置指定设备场景窗口起点SetWindowRgn 设置窗口区域SetWorldTransform 设置世界转换ValidateRgn 激活窗口中指定区域,把它从刷新区移走WindowFromDC 取回与某一设备场景相关的窗口的句柄
10. API之硬件与系统函数
ActivateKeyboardLayout 激活一个新的键盘布局。键盘布局定义了按键在一种物理性键盘上的位置与含义Beep 用于生成简单的声音CharToOem 将一个字串从ANSI字符集转换到OEM字符集ClipCursor 将指针限制到指定区域ConvertDefaultLocale 将一个特殊的地方标识符转换成真实的地方IDCreateCaret 根据指定的信息创建一个插入符(光标),并将它选定为指定窗口的默认插入符DestroyCaret 清除(破坏)一个插入符EnumCalendarInfo 枚举在指定"地方"环境中可用的日历信息EnumDateFormats 列举指定的"当地"设置中可用的长、短日期格式EnumSystemCodePages 枚举系统中已安装或支持的代码页EnumSystemLocales 枚举系统已经安装或提供支持的"地方"设置EnumTimeFormats 枚举一个指定的地方适用的时间格式ExitWindowsEx 退出windows,并用特定的选项重新启动ExpandEnvironmentStrings 扩充环境字串FreeEnvironmentStrings 翻译指定的环境字串块GetACP 判断目前正在生效的ANSI代码页GetAsyncKeyState 判断函数调用时指定虚拟键的状态GetCaretBlinkTime 判断插入符光标的闪烁频率GetCaretPos 判断插入符的当前位置GetClipCursor 取得一个矩形,用于描述目前为鼠标指针规定的剪切区域GetCommandLine 获得指向当前命令行缓冲区的一个指针GetComputerName 取得这台计算机的名称GetCPInfo 取得与指定代码页有关的信息GetCurrencyFormat 针对指定的"地方"设置,根据货币格式格式化一个数字GetCursor 获取目前选择的鼠标指针的句柄GetCursorPos 获取鼠标指针的当前位置GetDateFormat 针对指定的"当地"格式,对一个系统日期进行格式化GetDoubleClickTime 判断连续两次鼠标单击之间会被处理成双击事件的间隔时间GetEnvironmentStrings 为包含了当前环境字串设置的一个内存块分配和返回一个句柄GetEnvironmentVariable 取得一个环境变量的值GetInputState 判断是否存在任何待决(等待处理)的鼠标或键盘事件GetKBCodePage 由GetOEMCP取代,两者功能完全相同GetKeyboardLayout 取得一个句柄,描述指定应用程序的键盘布局GetKeyboardLayoutList 获得系统适用的所有键盘布局的一个列表GetKeyboardLayoutName 取得当前活动键盘布局的名称GetKeyboardState 取得键盘上每个虚拟键当前的状态GetKeyboardType 了解与正在使用的键盘有关的信息GetKeyNameText 在给出扫描码的前提下,判断键名GetKeyState 针对已处理过的按键,在最近一次输入信息时,判断指定虚拟键的状态GetLastError 针对之前调用的api函数,用这个函数取得扩展错误信息GetLocaleInfo 取得与指定"地方"有关的信息GetLocalTime 取得本地日期和时间GetNumberFormat 针对指定的"地方",按特定的格式格式化一个数字GetOEMCP 判断在OEM和ANSI字符集间转换的windows代码页GetQueueStatus 判断应用程序消息队列中待决(等待处理)的消息类型GetSysColor 判断指定windows显示对象的颜色GetSystemDefaultLangID 取得系统的默认语言IDGetSystemDefaultLCID 取得当前的默认系统"地方"GetSystemInfo 取得与底层硬件平台有关的信息GetSystemMetrics 返回与windows环境有关的信息GetSystemPowerStatus 获得与当前系统电源状态有关的信息GetSystemTime 取得当前系统时间,这个时间采用的是"协同世界时间"(即UTC,也叫做GMT)格式GetSystemTimeAdjustment 使内部系统时钟与一个外部的时钟信号源同步GetThreadLocale 取得当前线程的地方IDGetTickCount 用于获取自windows启动以来经历的时间长度(毫秒)GetTimeFormat 针对当前指定的"地方",按特定的格式格式化一个系统时间GetTimeZoneInformation 取得与系统时区设置有关的信息GetUserDefaultLangID 为当前用户取得默认语言IDGetUserDefaultLCID 取得当前用户的默认"地方"设置GetUserName 取得当前用户的名字GetVersion 判断当前运行的Windows和DOS版本GetVersionEx 取得与平台和操作系统有关的版本信息HideCaret 在指定的窗口隐藏插入符(光标)IsValidCodePage 判断一个代码页是否有效IsValidLocale 判断地方标识符是否有效keybd_event 这个函数模拟了键盘行动LoadKeyboardLayout 载入一个键盘布局MapVirtualKey 根据指定的映射类型,执行不同的扫描码和字符转换MapVirtualKeyEx 根据指定的映射类型,执行不同的扫描码和字符转换MessageBeep 播放一个系统声音。系统声音的分配方案是在控制面板里决定的mouse_event 模拟一次鼠标事件OemKeyScan 判断OEM字符集中的一个ASCII字符的扫描码和Shift键状态OemToChar 将OEM字符集的一个字串转换到ANSI字符集SetCaretBlinkTime 指定插入符(光标)的闪烁频率SetCaretPos 指定插入符的位置SetComputerName 设置新的计算机名SetCursor 将指定的鼠标指针设为当前指针SetCursorPos 设置指针的位置SetDoubleClickTime 设置连续两次鼠标单击之间能使系统认为是双击事件的间隔时间SetEnvironmentVariable 将一个环境变量设为指定的值SetKeyboardState 设置每个虚拟键当前在键盘上的状态SetLocaleInfo 改变用户"地方"设置信息SetLocalTime 设置当前地方时间SetSysColors 设置指定窗口显示对象的颜色SetSystemCursor 改变任何一个标准系统指针SetSystemTime 设置当前系统时间SetSystemTimeAdjustment 定时添加一个校准值使内部系统时钟与一个外部的时钟信号源同步SetThreadLocale 为当前线程设置地方SetTimeZoneInformation 设置系统时区信息ShowCaret 在指定的窗口里显示插入符(光标)ShowCursor 控制鼠标指针的可视性SwapMouseButton 决定是否互换鼠标左右键的功能SystemParametersInfo 获取和设置数量众多的windows系统参数SystemTimeToTzSpecificLocalTime 将系统时间转换成地方时间ToAscii 根据当前的扫描码和键盘信息,将一个虚拟键转换成ASCII字符ToUnicode 根据当前的扫描码和键盘信息,将一个虚拟键转换成Unicode字符UnloadKeyboardLayout 卸载指定的键盘布局VkKeyScan 针对Windows字符集中一个ASCII字符,判断虚拟键码和Shift键的状态
11. API之进程和线程函数
CancelWaitableTimer 这个函数用于取消一个可以等待下去的计时器操作CallNamedPipe 这个函数由一个希望通过管道通信的一个客户进程调用ConnectNamedPipe 指示一台服务器等待下去,直至客户机同一个命名管道连接CreateEvent 创建一个事件对象CreateMailslot 创建一个邮路。返回的句柄由邮路服务器使用(收件人)CreateMutex 创建一个互斥体(MUTEX)CreateNamedPipe 创建一个命名管道。返回的句柄由管道的服务器端使用CreatePipe 创建一个匿名管道CreateProcess 创建一个新进程(比如执行一个程序)CreateSemaphore 创建一个新的信号机CreateWaitableTimer 创建一个可等待的计时器对象DisconnectNamedPipe 断开一个客户与一个命名管道的连接DuplicateHandle 在指出一个现有系统对象当前句柄的情况下,为那个对象创建一个新句柄ExitProcess 中止一个进程FindCloseChangeNotification 关闭一个改动通知对象FindExecutable 查找与一个指定文件关联在一起的程序的文件名FindFirstChangeNotification 创建一个文件通知对象。该对象用于监视文件系统发生的变化FindNextChangeNotification 重设一个文件改变通知对象,令其继续监视下一次变化FreeLibrary 释放指定的动态链接库GetCurrentProcess 获取当前进程的一个伪句柄GetCurrentProcessId 获取当前进程一个唯一的标识符GetCurrentThread 获取当前线程的一个伪句柄GetCurrentThreadId 获取当前线程一个唯一的线程标识符GetExitCodeProces 获取一个已中断进程的退出代码GetExitCodeThread 获取一个已中止线程的退出代码GetHandleInformation 获取与一个系统对象句柄有关的信息GetMailslotInfo 获取与一个邮路有关的信息GetModuleFileName 获取一个已装载模板的完整路径名称GetModuleHandle 获取一个应用程序或动态链接库的模块句柄GetPriorityClass 获取特定进程的优先级别GetProcessShutdownParameters 调查系统关闭时一个指定的进程相对于其它进程的关闭早迟情况GetProcessTimes 获取与一个进程的经过时间有关的信息GetProcessWorkingSetSize 了解一个应用程序在运行过程中实际向它交付了多大容量的内存GetSartupInfo 获取一个进程的启动信息GetThreadPriority 获取特定线程的优先级别GetTheardTimes 获取与一个线程的经过时间有GetTheardTimes 获取与一个线程的经过时间有关的信息GetWindowThreadProcessId 获取与指定窗口关联在一起的一个进程和线程标识符LoadLibrary 载入指定的动态链接库,并将它映射到当前进程使用的地址空间LoadLibraryEx 装载指定的动态链接库,并为当前进程把它映射到地址空间LoadModule 载入一个Windows应用程序,并在指定的环境中运行MsgWaitForMultipleObjects 等侯单个对象或一系列对象发出信号。如返回条件已经满足,则立即返回SetPriorityClass 设置一个进程的优先级别SetProcessShutdownParameters 在系统关闭期间,为指定进程设置他相对于其它程序的关闭顺序SetProcessWorkingSetSize 设置操作系统实际划分给进程使用的内存容量SetThreadPriority 设定线程的优先级别ShellExecute 查找与指定文件关联在一起的程序的文件名TerminateProcess 结束一个进程WinExec 运行指定的程序
12. API之控件与消息函数
AdjustWindowRect 给定一种窗口样式,计算获得目标客户区矩形所需的窗口大小AnyPopup 判断屏幕上是否存在任何弹出式窗口ArrangeIconicWindows 排列一个父窗口的最小化子窗口AttachThreadInput 连接线程输入函数BeginDeferWindowPos 启动构建一系列新窗口位置的过程BringWindowToTop 将指定的窗口带至窗口列表顶部CascadeWindows 以层叠方式排列窗口ChildWindowFromPoint 返回父窗口中包含了指定点的第一个子窗口的句柄ClientToScreen 判断窗口内以客户区坐标表示的一个点的屏幕坐标CloseWindow 最小化指定的窗口CopyRect 矩形内容复制DeferWindowPos 该函数为特定的窗口指定一个新窗口位置DestroyWindow 清除指定的窗口以及它的所有子窗口DrawAnimatedRects 描绘一系列动态矩形EnableWindow 指定的窗口里允许或禁止所有鼠标及键盘输入EndDeferWindowPos 同时更新DeferWindowPos调用时指定的所有窗口的位置及状态EnumChildWindows 为指定的父窗口枚举子窗口EnumThreadWindows 枚举与指定任务相关的窗口EnumWindows 枚举窗口列表中的所有父窗口EqualRect 判断两个矩形结构是否相同FindWindow 寻找窗口列表中第一个符合指定条件的顶级窗口FindWindowEx 在窗口列表中寻找与指定条件相符的第一个子窗口FlashWindow 闪烁显示指定窗口GetActiveWindow 获得活动窗口的句柄GetCapture 获得一个窗口的句柄,这个窗口位于当前输入线程,且拥有鼠标捕获(鼠标活动由它接收)GetClassInfo 取得WNDCLASS结构(或WNDCLASSEX结构)的一个副本,结构中包含了与指定类有关的信息GetClassLong 取得窗口类的一个Long变量条目GetClassName 为指定的窗口取得类名GetClassWord 为窗口类取得一个整数变量GetClientRect 返回指定窗口客户区矩形的大小GetDesktopWindow 获得代表整个屏幕的一个窗口(桌面窗口)句柄GetFocus 获得拥有输入焦点的窗口的句柄GetForegroundWindow 获得前台窗口的句柄GetLastActivePopup 获得在一个给定父窗口中最近激活过的弹出式窗口的句柄GetParent 判断指定窗口的父窗口GetTopWindow 搜索内部窗口列表,寻找隶属于指定窗口的头一个窗口的句柄GetUpdateRect 获得一个矩形,它描叙了指定窗口中需要更新的那一部分GetWindow 获得一个窗口的句柄,该窗口与某源窗口有特定的关系GetWindowContextHelpId 取得与窗口关联在一起的帮助场景IDGetWindowLong 从指定窗口的结构中取得信息GetWindowPlacement 获得指定窗口的状态及位置信息GetWindowRect 获得整个窗口的范围矩形,窗口的边框、标题栏、滚动条及菜单等都在这个矩形内GetWindowText 取得一个窗体的标题(caption)文字,或者一个控件的内容GetWindowTextLength 调查窗口标题文字或控件内容的长短GetWindowWord 获得指定窗口结构的信息InflateRect 增大或减小一个矩形的大小IntersectRect 这个函数在lpDestRect里载入一个矩形,它是lpSrc1Rect与lpSrc2Rect两个矩形的交集InvalidateRect 屏蔽一个窗口客户区的全部或部分区域IsChild 判断一个窗口是否为另一窗口的子或隶属窗口IsIconic 判断窗口是否已最小化IsRectEmpty 判断一个矩形是否为空IsWindow 判断一个窗口句柄是否有效IsWindowEnabled 判断窗口是否处于活动状态IsWindowUnicode 判断一个窗口是否为Unicode窗口。这意味着窗口为所有基于文本的消息都接收Unicode文字IsWindowVisible 判断窗口是否可见IsZoomed 判断窗口是否最大化LockWindowUpdate 锁定指定窗口,禁止它更新MapWindowPoints 将一个窗口客户区坐标的点转换到另一窗口的客户区坐标系统MoveWindow 改变指定窗口的位置和大小OffsetRect 通过应用一个指定的偏移,从而让矩形移动起来OpenIcon 恢复一个最小化的程序,并将其激活PtInRect 判断指定的点是否位于矩形内部RedrawWindow 重画全部或部分窗口ReleaseCapture 为当前的应用程序释放鼠标捕获ScreenToClient 判断屏幕上一个指定点的客户区坐标ScrollWindow 滚动窗口客户区的全部或一部分ScrollWindowEx 根据附加的选项,滚动窗口客户区的全部或部分SetActiveWindow 激活指定的窗口SetCapture 将鼠标捕获设置到指定的窗口SetClassLong 为窗口类设置一个Long变量条目SetClassWord 为窗口类设置一个条目SetFocusAPI 将输入焦点设到指定的窗口。如有必要,会激活窗口SetForegroundWindow 将窗口设为系统的前台窗口SetParent 指定一个窗口的新父SetRect 设置指定矩形的内容SetRectEmpty 将矩形设为一个空矩形SetWindowContextHelpId 为指定的窗口设置帮助场景(上下文)IDSetWindowLong 在窗口结构中为指定的窗口设置信息SetWindowPlacement 设置窗口状态和位置信息SetWindowPos 为窗口指定一个新位置和状态SetWindowText 设置窗口的标题文字或控件的内容SetWindowWord 在窗口结构中为指定的窗口设置信息ShowOwnedPopups 显示或隐藏由指定窗口所有的全部弹出式窗口ShowWindow 控制窗口的可见性ShowWindowAsync 与ShowWindow相似SubtractRect 装载矩形lprcDst,它是在矩形lprcSrc1中减去lprcSrc2得到的结果TileWindows 以平铺顺序排列窗口UnionRect 装载一个lpDestRect目标矩形,它是lpSrc1Rect和lpSrc2Rect联合起来的结果UpdateWindow 强制立即更新窗口ValidateRect 校验窗口的全部或部分客户区WindowFromPoint 返回包含了指定点的窗口的句柄。忽略屏蔽、隐藏以及透明窗口
定制与开发应用之二: 可扩展编程(一)
相比于COM组件编程,可编程性扩展虽然比不上COM组件操作简单,但是由于可编程性扩展提供了底层的C语言编程接口,使得扩展编程拥有更高的运行效率和更稳定的执行能力,而且还使JAVA等其他编程语言调用SPSS进行分析成为可能。SPSS公司近年来着力加强了SPSS统计软件包对可编程性扩展的支持。从支持编程的多样性来看,SPSS的最新版本Statistics 17支持Python语言、SAS、R语言和.NET(C++、C#、VB)的集成开发,并提供了C语言的API(Application Programming Interface,应用程序编程接口)。从编程灵活性来看,SPSS既可基于Script下的Saxbasic调用外部的Python、SAS、R及.NET程序,又可以被这些语言编写的程序所调用。从支持的操作系统来看,它既支持UNIX环境,又支持Windows环境。从运行特性来讲,既可以在后台调用SPSS处理器来完成指定任务得到输出的分析结果,又可以构建前端界面,实现与用户的窗×××互。可见,SPSS为用户提供了越来越灵活的编程技术支持,而且可编程性扩展已经成为SPSS高级用户自定制应用的良好选择。用户基于SPSS使用可编程性扩展,可以构建灵活、综合、与现有系统高度集成的企业级应用。SPSS的可编程性扩展最权威的资料是SPSS的官方文档,对版本Statistics 17.0而言,主要是《Programming and Data Management for SPSS Statistics 17.0》、《SPSS Statistics Programmability Extension Developer's Guide for Windows》和《SPSS Statistics Programmability Extension Developer's Guide for UNIX》。此外,SPSS还在可编程性扩展包中发布了相关的简单编程实例,可谓是周到。上述这些资料都可以在SPSS的官方网站开发人员中心下载栏目免费获取。使用SPSS的可编程性扩展来进行开发和应用,首先要很好的理解SPSS Statistics的基础是什么,以及它如何工作。SPSS支持三种应用方式下的开发:
SPSS统计应用(SPSS Statistics),它有图形化用户界面,但是编程扩展不适用GUI(图形化用户界面)。
SPSS服务器(SPSS Server),它是一个分布式的应用,拥有一个客户端/服务器架构。它为资源密集型操作分发客户端请求到一个强大的分析服务软件。请求由客户端提交,被SPSS统计服务器处理。
SPSS统计批处理工具(SPSS Statistics Batch Facility),它包含在SPSS统计服务器里。它的任务是自动的数据管理和统计结果输出。自动生产提供了无须人为干预的命令提交。批量处理工具把输入的命令语言文件作为数据操作和统计的请求。它也没有图形用户界面。
可编程性扩展包含在SPSS的基本系统里,提供扩展SPSS与需要独立集成插件的外部程序语言交互的基本的支持。SPSS实现与外部语言的集成主要是通过两个动态链接库文件,第一个是SPSSXD API,它包括C语言应用编程接口(API)实现内部处理(spssxd.dll)和外部处理(spssxd_p.dll),该API允许外部处理器控制SPSS统计应用。第二个是通用接口spssdx.dll,它使SPSS可以执行写在命令语句“BEGIN PROGRAM-END PROGRAM”语句块间的外部语言代码。通常,一个插件包含两种库文件,第一种是MyLanguageInvokeSPSSXD,负责装载spssxd.dll或者spssxd_p.dll,并且使外部语言可以使用SPSSXD API。第二种是InvokeMyLanguage,它通过spssdx.dll为SPSS激活外部处理器,是一个插件的备选组件。
定制与开发应用之二:可扩展编程C语言API
上次讲到了两种库文件MyLanguageInvokeSPSSXD和InvokeMyLanguage。本节重点解析一下MyLanguageInvokeSPSSXD。SPSS的C语言应用编程接口(SPSSXD API)在动态链接库spssxd.dll中包含两个方面的底层功能:第一种是提交操作请求给SPSS,请求的典型返回结果为错误码,通过错误码,可以得出操作结果是成功还是出现其他异常和错误。第二种是提交信息请求给SPSS,请求的典型返回结果是所请求的信息。这些底层功能实现对SPSS的功能操作,变量字典的获取,输出结果XML工作区信息的读取,对SPSS活动数据集的操作。SPSS的C语言应用编程接口帮助文档可以在SPSS提供的可扩展性编程spssxdAPI文件夹下找到。外部语言程序直接调用SPSS C语言应用编程接口的基本工作过程可以描述为以下步骤:
外部语言准备调用SPSS。
检查SPSS后台程序是否运行,没有运行则装载MyLanguageInvokeSPSSXD,如果运行则进入下一步。
获得SPSS后台程序句柄。成功则继续,否则中断。
初始化相关功能指针。成功则完整SPSS调用准备,否则中断。
启动SPSS通讯。成功则进入下一步,否则中断。
检查SPSS后台状态正常时,操作SPSS功能,输出分析结果。
调用任务完成,终止SPSS通讯。
卸载动态链接库。
外部语言程序调用SPSS结束。
以下为SPSS提供的官方样例程序。C语言程序的主入口:int _tmain(int argc, _TCHAR* argv[]){ //初始化传入参数个数为1int count = 1; if (argc >1) count = atoi(argv[1]);__time64_t stime; //time.h time类中定义的结构 _time64( &stime );//the start time of the test//装载DLLint load = LoadLib();//判断是否成功 if ( load != 0 ){ std::cout << "load failure, exitcode = " << load << std::endl; return -1; }//创建暂存结果的文件std::string tempfile = "d:/temp/result.txt"; std::string tempresult("-out "); tempresult = tempresult + tempfile; //申明状态检查int err = 0;//启动SPSS通信err = StartSpss(tempresult.c_str());if( err != 0 ){ std::cout << "start spss failed, exitcode = " << err << std::endl; return -1; }//To Do Workfor (int i=0; i<count; i++){ //判断是否就绪 int ready = IsBackendReady(); if( ready != 1 ){ std::cout << "backend is not ready, exitcode = " << ready << std::endl; return -1; } //确定要处理的文件 std::vector<std::string> fList; //data file list filelist(fList); //检验并打开文件 int index=i%(int)fList.size(); err = getfile(fList[index].c_str()); if (err !=0 ){ std::cout << "get file error: filename=>" << fList[index] << " err=" << err << std::endl; return -1; } //测试XPath和通用功能 XPathAndGeneralFunctions(fList[index].c_str()); int iPosition = 0; Displayresult(tempfile.c_str(), iPosition); std::cout <<"The end of XPATH result output! \n"<<endl; //开始一个用户的过程 StartProcedure("UserProc1"); //操作数据库 DataSourceFunctions(); Displayresult(tempfile.c_str(), iPosition); //测试转轴表 PivotTableFunctions(); Displayresult(tempfile.c_str(), iPosition); //结束过程 EndProcedure(); //测试数据数据集 DataStepFunctions(); Displayresult(tempfile.c_str(), iPosition); }//终止SPSS通信StopSpss();//卸载DLLFreeLib();return 0;}进一步深入LoadLib(),该方法由load.cpp提供,源代码如下:/*** load.c -* load and unload spssxd.dll dynamically.* COPYRIGHT* Copyright 2005 by SPSS Inc. All rights reserved.*/#include "load.h"#include <iostream>using namespace std;//declare the function pointer.FP_IsBackendReady IsBackendReady = NULL;FP_IsXDriven IsXDriven = NULL;FP_StartSpss StartSpss = NULL;FP_StopSpss StopSpss = NULL;FP_Submit Submit = NULL;FP_QueueCommandPart QueueCommandPart = NULL;FP_PostSpssOutput PostSpssOutput = NULL;FP_GetVariableCount GetVariableCount = NULL;FP_GetRowCount GetRowCount = NULL;FP_GetVariableName GetVariableName = NULL;FP_GetVariableLabel GetVariableLabel = NULL;FP_GetVariableType GetVariableType = NULL;FP_GetVariableFormat GetVariableFormat = NULL;FP_GetVariableMeasurementLevel GetVariableMeasurementLevel = NULL;FP_CreateXPathDictionary CreateXPathDictionary = NULL;FP_RemoveXPathHandle RemoveXPathHandle = NULL;FP_EvaluateXPath EvaluateXPath = NULL;FP_GetStringListLength GetStringListLength = NULL;FP_GetStringFromList GetStringFromList = NULL;FP_RemoveStringList RemoveStringList = NULL;FP_GetXmlUtf16 GetXmlUtf16 = NULL;FP_GetHandleList GetHandleList = NULL;FP_GetNumericValue GetNumericValue = NULL;FP_GetStringValue GetStringValue = NULL;FP_MakeCaseCursor MakeCaseCursor = NULL;FP_NextCase NextCase = NULL;FP_RemoveCaseCursor RemoveCaseCursor = NULL;FP_GetVariableFormatType GetVariableFormatType = NULL;FP_GetCursorPosition GetCursorPosition = NULL;FP_StartPivotTable StartPivotTable = NULL; FP_AddDimension AddDimension = NULL; FP_AddStringCategory AddStringCategory = NULL; FP_SetFormatSpecCount SetFormatSpecCount = NULL; FP_SetNumberCell SetNumberCell = NULL; FP_AddCellFootnotes AddCellFootnotes = NULL; FP_AddTextBlock AddTextBlock = NULL;FP_StartProcedure StartProcedure = NULL; FP_EndProcedure EndProcedure = NULL;FP_StartDataStep StartDataStep = NULL; FP_CreateDataset CreateDataset = NULL; FP_GetCaseCountInDS GetCaseCountInDS = NULL;FP_InsertCase InsertCase = NULL;FP_DeleteCase DeleteCase = NULL; FP_GetVarTypeInDS GetVarTypeInDS = NULL;FP_GetNCellValue GetNCellValue = NULL;FP_GetCCellValue GetCCellValue = NULL;FP_SetNCellValue SetNCellValue = NULL;FP_SetCCellValue SetCCellValue = NULL;FP_EndDataStep EndDataStep = NULL;HMODULE pLib = NULL; //初始化一个句柄const char libName[] = "spssxd_p.dll"; //SPSS的动态链接库const int LOAD_FAIL = 1011;const int LOAD_SUCCESS = 0;//Initialize the function pointervoid InitializeFP(){ //GetProcAddress函数检索指定的动态链接库(DLL)中的输出库函数地址,参数为句柄加函数名,返回的是动态链接库的空间地址IsBackendReady = (FP_IsBackendReady)GetProcAddress(pLib,"IsBackendReady"); //上句检查动态链接库后台已经准备就绪,设置后台准备状态为就绪布尔型//下句设置动态链接库驱动正确布尔型IsXDriven = (FP_IsXDriven)GetProcAddress(pLib,"IsXDriven");//设置动态链接库为SPSS开始的命令行字符串 StartSpss = (FP_StartSpss)GetProcAddress(pLib,"StartSpss");//设置动态链接库为SPSS结束整型 StopSpss = (FP_StopSpss)GetProcAddress(pLib,"StopSpss");//设置动态链接库为SPSS提交的命令行包括提交命令及其长度返回整型 Submit = (FP_Submit)GetProcAddress(pLib,"Submit");//设置动态链接库为SPSS提交的队列命令包括提交行命令及其长度返回整型 QueueCommandPart = (FP_QueueCommandPart)GetProcAddress(pLib,"QueueCommandPart");//设置动态链接库为SPSS返回结构的文本返回整型 PostSpssOutput = (FP_PostSpssOutput)GetProcAddress(pLib,"PostSpssOutput");//设置动态链接库为SPSSF能取得的变量个数返回整型 GetVariableCount = (FP_GetVariableCount)GetProcAddress(pLib,"GetVariableCount");//设置动态链接库为SPSSF能取得的记录行数返回整型 GetRowCount = (FP_GetRowCount)GetProcAddress(pLib,"GetRowCount");//设置动态链接库为SPSS能取得的变量名称返回字符型 GetVariableName = (FP_GetVariableName)GetProcAddress(pLib,"GetVariableName");//设置动态链接库为SPSS能取得的变量标签返回字符型 GetVariableLabel = (FP_GetVariableLabel)GetProcAddress(pLib,"GetVariableLabel");//设置动态链接库为SPSS能取得的变量类型返回字符型 GetVariableType = (FP_GetVariableType)GetProcAddress(pLib,"GetVariableType");//设置动态链接库为SPSS能取得的变量格式返回字符型 GetVariableFormat = (FP_GetVariableFormat)GetProcAddress(pLib,"GetVariableFormat");//设置动态链接库为SPSS能取得的变量评价层次返回整型 GetVariableMeasurementLevel = (FP_GetVariableMeasurementLevel)GetProcAddress(pLib,"GetVariableMeasurementLevel"); //设置动态链接库为SPSS创建的XPATH字典返回整型CreateXPathDictionary = (FP_CreateXPathDictionary)GetProcAddress(pLib,"CreateXPathDictionary"); //设置动态链接库为SPSS删除的XPATH处理返回整型RemoveXPathHandle = (FP_RemoveXPathHandle)GetProcAddress(pLib,"RemoveXPathHandle"); //设置动态链接库为SPSS评估的XPATH处理(包括处理,上下文,表达式)无返回EvaluateXPath =(FP_EvaluateXPath)GetProcAddress(pLib,"EvaluateXPath"); //设置动态链接库为SPSS处理的列表返回整型GetStringListLength = (FP_GetStringListLength)GetProcAddress(pLib,"GetStringListLength"); //设置动态链接库为SPSS处理的字符列表返回字符GetStringFromList = (FP_GetStringFromList)GetProcAddress(pLib,"GetStringFromList"); //设置动态链接库为SPSS删除处理的字符列表返回字符RemoveStringList = (FP_RemoveStringList)GetProcAddress(pLib,"RemoveStringList"); //设置动态链接库为SPSS处理的XML返回字符GetXmlUtf16 = (FP_GetXmlUtf16)GetProcAddress(pLib,"GetXmlUtf16"); //设置动态链接库为SPSS处理的列表无返回GetHandleList = (FP_GetHandleList)GetProcAddress(pLib,"GetHandleList"); //设置动态链接库为SPSS结果和变量索引返回整型GetNumericValue = (FP_GetNumericValue)GetProcAddress(pLib,"GetNumericValue"); //设置动态链接库为SPSS结果、缓冲长度和变量索引返回整型GetStringValue = (FP_GetStringValue)GetProcAddress(pLib,"GetStringValue");//创建游标 返回整型MakeCaseCursor = (FP_MakeCaseCursor)GetProcAddress(pLib,"MakeCaseCursor");//移动到下一个案例 返回整型NextCase = (FP_NextCase)GetProcAddress(pLib,"NextCase");//移除案例游标返回整型RemoveCaseCursor = (FP_RemoveCaseCursor)GetProcAddress(pLib,"RemoveCaseCursor");//由格式类型拿到变量格式类型返回整型GetVariableFormatType = (FP_GetVariableFormatType)GetProcAddress(pLib,"GetVariableFormatType"); //得到游标位置GetCursorPosition = (FP_GetCursorPosition)GetProcAddress(pLib,"GetCursorPosition");// StartPivotTable = (FP_StartPivotTable)GetProcAddress(pLib,"StartPivotTable"); AddDimension = (FP_AddDimension)GetProcAddress(pLib,"AddDimension"); AddStringCategory = (FP_AddStringCategory)GetProcAddress(pLib,"AddStringCategory"); SetFormatSpecCount = (FP_SetFormatSpecCount)GetProcAddress(pLib,"SetFormatSpecCount"); SetNumberCell = (FP_SetNumberCell)GetProcAddress(pLib,"SetNumberCell"); AddCellFootnotes = (FP_AddCellFootnotes)GetProcAddress(pLib,"AddCellFootnotes"); AddTextBlock = (FP_AddTextBlock)GetProcAddress(pLib,"AddTextBlock");StartProcedure = (FP_StartProcedure)GetProcAddress(pLib,"StartProcedure"); EndProcedure = (FP_EndProcedure)GetProcAddress(pLib,"EndProcedure");StartDataStep = (FP_StartDataStep)GetProcAddress(pLib,"StartDataStep");CreateDataset = (FP_CreateDataset)GetProcAddress(pLib,"CreateDataset");GetCaseCountInDS = (FP_GetCaseCountInDS)GetProcAddress(pLib,"GetCaseCountInDS");InsertCase = (FP_InsertCase)GetProcAddress(pLib,"InsertCase");DeleteCase = (FP_DeleteCase)GetProcAddress(pLib,"DeleteCase");GetVarTypeInDS = (FP_GetVarTypeInDS)GetProcAddress(pLib,"GetVarTypeInDS");GetNCellValue = (FP_GetNCellValue)GetProcAddress(pLib,"GetNCellValue");GetCCellValue = (FP_GetCCellValue)GetProcAddress(pLib,"GetCCellValue");SetNCellValue = (FP_SetNCellValue)GetProcAddress(pLib,"SetNCellValue");SetCCellValue = (FP_SetCCellValue)GetProcAddress(pLib,"SetCCellValue");EndDataStep = (FP_EndDataStep)GetProcAddress(pLib,"EndDataStep");}int LoadLib(){ //判断是否得到句柄pLib if(NULL == pLib){ //libName = "spssxd.dll" //find out spssxd.dll module, it will success when spss drive pLib = GetModuleHandle(libName);//如果SPSS是运行的,这里获得名为spssxd.dll的句柄 //find out spssxd.dll module failure, load it. if(NULL == pLib) {//SPSS程序此时没有运行,所以这里句柄为Null pLib = LoadLibrary(libName);//重新载入名为spssxd.dll的链接库道地址空间,进而访问该资源 } //load spssxd.dll module success, initialize the function pointer这里成功载入动态链接库 if (pLib) {//载入动态链接库spssxd.dll,并开始初始化功能指针 InitializeFP(); } //load failure else { return LOAD_FAIL;//装载失败 } } return LOAD_SUCCESS;//装载成功}void FreeLib(){ FreeLibrary(pLib); pLib= NULL; IsBackendReady = NULL; IsXDriven = NULL; StartSpss = NULL; StopSpss = NULL; Submit = NULL; QueueCommandPart = NULL; PostSpssOutput = NULL; GetVariableCount = NULL; GetRowCount = NULL; GetVariableName = NULL; GetVariableLabel = NULL; GetVariableType = NULL; GetVariableFormat = NULL; GetVariableMeasurementLevel = NULL; CreateXPathDictionary = NULL; RemoveXPathHandle = NULL; EvaluateXPath = NULL; GetStringListLength = NULL; GetStringFromList = NULL; RemoveStringList = NULL; GetXmlUtf16 = NULL; GetHandleList = NULL; GetNumericValue = NULL; GetStringValue = NULL; MakeCaseCursor = NULL; NextCase = NULL; RemoveCaseCursor = NULL; GetVariableFormatType = NULL; GetCursorPosition = NULL; StartPivotTable = NULL; AddDimension = NULL; AddStringCategory = NULL; SetFormatSpecCount = NULL; SetNumberCell = NULL; AddCellFootnotes = NULL; AddTextBlock = NULL; StartProcedure = NULL; EndProcedure = NULL; StartDataStep = NULL; CreateDataset = NULL; GetCaseCountInDS = NULL; InsertCase = NULL; DeleteCase = NULL; GetVarTypeInDS = NULL; GetNCellValue = NULL; GetCCellValue = NULL; SetNCellValue = NULL; SetCCellValue = NULL; EndDataStep = NULL;}
Python的C语言扩展
C-Python,或者CPython,指C实现的Python虚拟机的基础API。最通用的Python就是是基于C实现的,它的底层API称为C-Python API,所有Python代码的最终变成这些API以及数据结构的调用,才有了Python世界的精彩。Cython,准确说Cython是单独的一门语言,专门用来写在Python里面import用的扩展库。实际上Cython的语法基本上跟Python一致,而Cython有专门的“编译器”先将 Cython代码转变成C(自动加入了一大堆的C-Python API),然后使用C编译器编译出最终的Python可调用的模块。GIL:Global Interpreter Lock,是Python虚拟机的多线程机制的核心机制,翻译为:全局解释器锁。其实Python线程是操作系统级别的线程,在不同平台有不同的底层实现(如win下就用win32_thread, posix下就用pthread等),Python解释器为了使所有对象的操作是线程安全的,使用了一个全局锁(GIL)来同步所有的线程,所以造成“一个时刻只有一个Python线程运行”的伪线程假象。GIL是个颗粒度很大的锁,它的实现跟性能问题多年来也引起过争议,但到今天它还是经受起了考验,即使它让Python在多核平台下CPU得不到最大发挥。
什么是BIOS?
BIOS即基本输入输出系统,它是PC机的操作的基础。当计算机上电时,BIOS是第一个被执行的程序,DOS和其它程序都通过BIOS来存取计算机内部的各种硬件设备。然而,引导程序并不是计算机内唯一被称为BIOS的代码。实际上,PC机上电时要执行的BIOS通常被称为主板BIOS,因为它被存放在主板上。直到不久之前,这个BIOS还被固化在一块ROM芯片上,因而无法为了修改错误和扩充功能而重新编写它。现在,主板BIOS被存放在一块叫做Flash EPROM的可重新编程的存储器芯片中,但它还是原来的BIOS。不管怎样。主板BIOS会读遍系统内存,从而找到系统中其它一些硬件设备,这些设备都带有自身要使用的一些基础代码(即其它的BIOS代码)。例如,VGA卡就有其自身的BIOS,通常被称为Video BIOS或VGA BIOS;硬盘和软盘控制器也有一个BIOS,并且也在系统引导时被执行。当人们提及BIOS时,或者是指这些程序的集合,或者是指其中单独的一个BIOS,这两种说法部对。根据上述介绍,你应该知道BIOS并不是DOS——BIOS是PC机中最底层的功能软件。DOS刚好位于BIOS上面的一层,并且经常调用BIOS来完成一些基本操作,而这些操作可能会被你误认为是"DOS"函数。例如,你可能会用DOS函数40H来把数据写到硬盘上的一个文件中,而DOS最终还是要通过调用硬盘BIOS的函数03来把数据写到硬盘上。mso-bidi-font-family:宋体; mso-font-kerning:0pt'>正在执行重要的代码时,把这一情况通知DOS。然而,该标志对程序员也是很有用的,因为他们能由此知道什么时候DOS处于忙状态。尽管从DOS 2.0版开始就有这个函数了,但因为Microsoft最近已经公开了这个函数,所以从技术角度上讲它已不再是一个未公开的函数。有几本很不错的书介绍了已公开和未公开的DOS函数,对这个问题有兴趣的读者可以去阅读这些书。
什么是中断?
首先,中断分硬件中断和软件中断两种。中断为计算机的硬件设备和软件"部件"提供了一种相互交流的途径,这就是它的作用。那么,都有哪些中断呢?它们又是怎样实现这种交流的呢?PC机中的CPU通常都是Intel 80x86处理器,它有几条引脚用来中断CPU的当前工作,并使它转去进行其它工作。每条中断引脚上都连接着一些硬件设备(例如定时器),其作用是为这条引脚提供一个特定的电压。当中断事件发生时,处理器会停止执行当前正在执行的软件,保存当前的操作状态·然后去“处理”中断。处理器中事先已经装有一张中断向量表,其中列出了每个中断号以及当某个特定中断发生时所应执行的程序。以系统定时器为例——作为要完成的许多任务中的一部分,PC机需要维持一天的计时工作,其具体工作过程为:(1)一个硬件计时器每秒钟向CPU发出18次中断;(2)CPU停止当前的工作并在中断向量表中查找负责维持系统计时器数据的程序(这种程序叫做中断处理程序(interrupt handler),因为它的工作就是在中断发生时处理中断);(3)CPU执行该程序(将新的定时器数据存入系统内存),然后返回到刚才被中断的地方继续往下执行。当你的程序要求使用当前时间时,定时器数据就会按照你要求的格式被组织好并传给程序。以上的解释大大简化了定时器中断的工作情况,但它是一个很好的硬件中断的例子。系统定时器只是通过中断机制发生的数百个事件(有时被称为中断)中的一个。在很多时候,硬仵并不参与到中断处理过程中去。换句话说,软件经常会通过中断来调用其它软件,并且可以不需要硬件的参与。DOS和BIOS就是这方面的两个主要例子。当一个程序打开一个文件,读/写一个文件,把字符写到屏幕上,从键盘那里得到一个字符,甚至询问当前时间时,都需要有一个软件中断来完成这项任务。你可能不知道发生了这些事情,因为这些中断都深藏在你所调用的那些无足轻重的小函数(例如getch(),fopen()和ctime())的后面。在C中,你可以通过int86()和int86x()函数产生中断。int86()和int86x()函数要求用你想产生的中断号作为它们的一个参数。当你调用其中的一个函数时,CPU将象前面所讲的那样被中断,并俭查中断向量表,以找到需要执行的那个程序。在调用这两个函数时,通常将执行的是一个DOS或BIOS程序。表14.6列出了一些常见的中断,你可以通过它们设置或检索计算机的有关信息。注意这并不是一张完整的表,并且其中的每个中断都可以服务于数百种不同的函数。 表14.6 常见的PC中断————————————————————————————————————— 中断(hex) 描述————一———————————————————————————————— 5 屏幕打印服务 10 视频显示服务(MDA,CGA,EGA,VGA) 11 获得设备清单 12 获得内存大小 13 磁盘服务 14 串行口服务 15 杂项功能服务 16 键盘服务 17 打印机服务 1A 时钟服务 21 DOS函数 2F DOS多路共享服务 33 鼠标器服务 67 EMS服务--------------------------------------------------------------------------当你知道了什么是中断后,你就会认识到:当计算机处于空闲状态时,它每秒可能要处理几十个中断;而当计算机紧张工作时,它每秒经常要处理数百个中断。在20.12中有一个例子程序,你可以参照该程序写出自己的中断处理程序,从而使两个程序通过中断进行交流。如果你觉得有意思,不妨试一下。
在C语言中应该使用ANSI函数还是BIOS函数,哪种方式更好?
两种方式各有利弊。你必须先回答几个问题,然后才能确定哪种方式适合你需要创建的那种应用。例如:你需要很快地实现你的应用吗?你的应用仅仅是用来“证实有关概念”,还是一个“真正的应用”呢?速度对你的应用重要吗?下面比较了使用ANSI函数和使用BIOS函数的基本优点:使用ANSI函数的优点:
只需要printf()语句就可完成任务
改变文本的颜色和属性很方便
不管系统如何配置,都可以在所有PC机上工作
无需记忆BIOS iN数
使用BIOS函数的优点:
运行速度快
用BIOS可以做更多的事
不需要设备驱动程序(使用ANSI iN数需要ANSI.SYS)
无需记忆ANSI命令
刚开始时,你会发现用ANSI函数编程是很不错的,并且能使你写出一些漂亮的程序。然而,不久你就可能会发现ANSI函数“有些碍事”,此时你就会想用BIOS函数。当然,以后你又发现BIOS函数有时也会“碍事”,此时你就想使用一种更快的方式。例如,14.4中的一个例子甚至不通过BIOS来把文本打印到屏幕上,你也许会发现这种方法比使用ANSI或BIOS函数更有趣。
可以通过BIOS把显示模式改为VGA图形模式吗?
当然可以。中断10H,即Video BIOS,负责处理文本模式和图形模式之间的转换。当你所运行的程序要进行文本模式和图形模式之间的相互转换时(即使该程序是Microsoft Windows),就需要通过Video BIOS来实现这种转换。每一种不同的设置都被称作一种显示模式。要改变显示模式,你必须通过int 10H服务来调用Video BIOS。这就是说,你必须向中断10H的中断处理程序发出中断请求。除中断号不同之外,这与实现DOS调用(int 21H)没有什么区别。下面的一段程序通过调用Video BIOS函数0,先从标准文本模式(模式3)切换到一个由命令行输入的模式号,然后再切换回来:# include <stdlib. h># include <dos. h>main(int argc, char * * argv){ union REGS regs; int mode; / * accept Mode number in hex * / sscanf (argv[1] , " %x" , &mode) ; regs. h. ah = 0; /* AH = 0 means "change display mode" */ regs.h.al = (char)mode; /* AL = ??, where ?? is the Mode number * regs. x. bx = 0; /* Page number, usually zero */ int86(0xl0, ®s, ®s); /* Call the BIOS (intlO) * / printf("Mode 0x%X now active\n" , mode); printf ("Press any key to return. . . ") ; getch(); regs. h. al = 3; / * return to Mode 3 * / int86(0xl0, ®s, ®s);}有一个有趣的特点并没有在这个程序中表现出来,即该程序可以在不清屏的情况下改变显示模式。在某些场合,这一特点极为有用。要想改变显示模式,而又不影响屏幕内容,只需把存放在AI.寄存器中的显示模式值和80H或一下。例如,如果你要切换到模式13H,你只需把93H存入AL中,而程序中其余的代码可以保持不变。今天,在VESA Video BIOS标准中已经加入了VGA卡对扩充显示模式(见下文中的补充说明)的支持。然而,需要有一个新的“改变显示模式”函数来支持这些扩充模式。按照VESA标准,在切换VESA模式时,应该使用函数4FH,而不是前文例子中的函数O。下面的程序改进了前文中的例子,以切换VESA模式:# include <stdlib. h>#include <dos. h>main(int argc, char * * argv){ union REGS regs; int mode; / * accept Mode number in hex * / sscanf (argv[1], " %x" , &mode); regs. x. ax = 0x4F02; /* change display mode * / regs. x. bx = (short )mode; / * three-digit mode number * / int86(0x10, ®s, ®s); /* Call the BIOS (intlO) * / if(regs.h.al !=0x4F){ printf("VESA modes NOT supported! \n" ); } else { printf("Mode Ox%X now active\n" , mode); printf ("Press any key to return. . . " ) ; getch() ; } regs. h. al = 3; / * return to Mode 3 * / int86(0x10,®s, ®s) ;}注意,在切换VESA模式时,不能通过把模式号和80H或一下来达到不清屏的目的。但是。只要把原来两位的(十六进制)模式号的最高位往前移一位,就得到了VESA模式号(所有VESA模式号的长度都是三位(十六进制),见下文中的补充说明)。因此,为了切换到VESA模式101H并且保留屏幕上的内容,你只需把VESA模式号换为901H。关于显示模式的补充说明:IBM推出了一种显示模式标准,该标准试图定义所有可能会用到的显示模式,其中包括所有可能的像素层次(颜色的数目)。因此,IBM创建了19种显示模式(从OH到13H)。表14.8a给出了这种显示模式标准。 14.8a 标准显示模式------------------------------------------------------------------------------- 模式(H) 分辨率 图形/文本 颜色------------------------------------------------------------------------------- 0 40X 25 文本 单色 1 40 X 25 文本 16 2 80X 25 文本 单色 3 80X 25 文本 16 4 320X 200 图形 4 5 320X 200 图形 4级灰度 6 640X 200 图形 单色 7 80 X 25 文本 单色 8 160X 200 图形 16 9 320X 200 图形 16 A 640 x 200 图形 4 B 保留给EC-A BIOS使用 C 保留给EGA BIOS使用 D 320×200 图形 16 E 640×200 图形 16 F 640×350 图形 单色 10 640×350 图形 4 11 640×480 图形 单色 12 640×480 图形 16 13 320×200 图形 256-------------------------------------------------------------------------------那么,你见过其中的某些模式吗?模式3是80×25彩色文本模式,也就是PC机上电时你所看到的模式。当你把"VGA"(随Windows提供的一个驱动程序)选为Microsoft Windows3.x的驱动程序时,你所看到的就是模式12(H)。注意,上表中并没有一种颜色多于256色或分辨率高于640×480的模式。多年以来,模式4,9和D一直是DOS游戏开发者喜欢用的模式,它们拥有“高”达320×200的分辨率和足够的颜色(4或16种),足以显示一些“象样”的图形。所有流行的动画游戏几乎都使用模式13,例如DOOM(一代和二代),id软件公司的new Heretic,Apogee公司的Rise of the Triad,Interplay公司的Descent,等等。实际上,许多动画游戏在VGA卡上耍了个小花招,即把模式13的分辨率改为320×240 这种模式被称为模式x,它有更多的内存页。可以提高图形质量和显示速度。那么,其它一些常见的显示模式又是从哪里来的呢?它们是由VGA卡的制造商提供的。这些你可能已经熟悉的显示模式来自各种各样的渠道,但不管它们来自何处,VGA卡的制造商们都把它们加到了自己的VGA卡中,以增加这些VGA卡的价值。这些模式通常被称为扩充显示模式(extended display mode)。由于竞争和资本积累的原因,VGA卡的制造商们逐步转向了这些更高级的显示模式。有人还试过其它一些显示模式(听说过1152×900吗?),但并不象上述模式那样受欢迎。那么。什么是VESA呢?它与VGA卡有什么关系呢?尽管VGA卡的制造商们都选择了支持同样的一组显示模式(包括扩充模式),但他们都按自己的专用方式去实现其中的扩充模式,而游戏厂商和其它软件厂商不得不去支持市场上每一种VGA卡的每一种专用方式。因此,一些制造商和其它方面的一些代表一起组成了一个委员会,以尽可能地使这些卡的设置和编程标准化,这个委员会就是VESA(Video Electronic Standards Association)。VESA委员会采用了一种扩充显示模式的标准,从而使软件可以通过普通的BIOS调用来设置和初始化所有符合该标准的VGA卡。基本上可以这样说,在美国出售的所有的VGA卡都支持某种VESA标准。所有的VESA模式(即VESA标准所包含的那些显示模式)都采用宽度为9位(bit)的模式号,而不是标准模式的8位(hit)模式号。使用了9位(bit)的模式号后,就可以用三位十六进制数来表示VESA模式了,而IBM标准模式只能用两位十六进制数(在表14.8a中,从0到13H)来表示,这样就避免了模式号的冲突。因此,所有的VESA模式号都大于100H。VESA模式是这样起作用的:假设你想让你的VGA卡以1024×768和256色这样的模式显示,而这种模式就是VESA模式105,因此你要用模式号105作一次BIOS调用。Video BIOS(有时叫做VESA BIOS)会把VESA模式号翻译成内部专用号,以完成实际的模式切换工作。VGA卡的制造商们在每一块VGA卡上都提供了一种可以完成上述翻译工作的Video BIOS,因此你只需要搞清楚VESA模式号就行了。表14.8b列出了最新的VESA显示模式(VESA是一个不断发展的标准。) 表14.8b VESA显示模式---------------------------------------------------------------------------- 分辨率 颜色 VESA模式---------------------------------------------------------------------------- 640X400 256 100 640X480 256 101 640X480 32768 110 640X480 65536 111 640X480 16. 7M 112 800X600 16 102 800X600 256 103 800X600 32768 113 800X600 65536 114 800X600 16. 7M 115 1024X768 16 104 1024X768 256 105 1024X768 32768 116 1024X768 65536 117 1024X768 16. 7M 118 1280X1024 16 106 1280X1024 256 107 1280X1024 32768 119 1280X1024 65536 11A 1280X1024 16. 7M 11B-----------------------------------------------------------------------------注意,这些都是人们熟悉的显示模式,特别是在使用Microsoft Windows时,这些模式更为常见。
可以通过BIOS控制鼠标吗?
可以。你可以通过中断33H调用鼠标服务程序。表14.13列出了中断33H中最常用的鼠标服务程序。 表14.13鼠标中断服务-------------------------------------------------------------------------- 功能号 描 述-------------------------------------------------------------------------- 0 初始化鼠标;当前可见则隐藏它 1 显示鼠标 2 隐藏鼠标 3 获得鼠标位置 4 设置鼠标位置 6 检查鼠标按钮是否被按下 7 设置鼠标的水平限制值 8 设置鼠标的垂直限制值 9 设置图形模式鼠标形状 10 设置文本模式鼠标风格 11 获得鼠标的移动步值---------------------------------------------------------------------------下面的例子通过上表中的一些鼠标服务程序来控制一个文本模式的鼠标:# include <stdlib. h># include <dos. h>main(){ union REGS regs; printf("Initializing Mouse. . . ") ; regs. x. ax = 0; int86(0x33, ®s, ®s); printf("\nShowing Mouse. . . ") ; regs. x.ax = 1; int86(0x33, ®s, ®s); printf ("\nMove mouse around. Press any key to quit. . . ") ; getch() ; printf ("\nHiding Mouse. . . " ) ; regs. x. ax = 2; int86(0x33, ®s, ®s); printf("\nDone\n"); }当运行这个程序时,屏幕上会出现一个闪烁的可以移动的块状光标。无论什么时候,你都可以通过函数3向鼠标处理程序询问鼠标的位置。实际上,笔者用表14.13中的函数编写了一整套鼠标库函数,并且在笔者的许多使用文本模式鼠标的程序中使用了这套函数。为了使用上表中的函数,你必须安装一种鼠标驱动程序。通常可以通过AUTOEXEC.BAT文件来安装鼠标驱动程序。然而,现在运行Windows时通常只安装一种Windows鼠标驱动程序,在这种情况下,你必须先运行在DOS shell下,然后才能调用这些鼠标函数。