文档库

最新最全的文档下载
当前位置:文档库 > MFC函数用法

MFC函数用法

DefWindowProc (1)

PostQuitMessage (2)

BeginPaint (2)

TextOut (3)

EndPaint (4)

InvalidateRect (4)

sprintf (5)

GetWindowText (12)

CreateWindow (12)

Wndproc (17)

WinMain (18)

LoadIcon (19)

LoadCursor (20)

GetStockObject (20)

RegisterClass (22)

MessageBox (22)

ShowWindow (26)

ShowWindow (27)

UpdateWindow (28)

GetMessage (29)

TranslateMessage (30)

DispatchMessage (31)

DefWindowProc

函数功能:该函数调用缺省的窗口过程来为应用程序没有处理的任何窗口消息提供缺省的处理。该函数确保每一个消息得到处理。调用DefWindowProc函数时使用窗口过程接收的相同参数。

函数原型:LRESULT DefWindowProc(HWND hWnd,UINT Msg,WPARA M wParam,LPARAM IParam);

参数:

hWnd:指向接收消息的窗口过程的句柄。

Msg:指定消息类型。

wParam:指定其余的、消息特定的信息。该参数的内容与Msg参数值有关。

IParam:指定其余的、消息特定的信息。该参数的内容与Msg参数值有关。

返回值:返回值就是消息处理结果,它与发送的消息有关。

备注:对于Windows CE;如果Msg为WM_SETTEXT那么返回0。

当DefWindowProc处理WM_DESTROY消息时,它不自动调用PostQutMessa ge。

速查:Windows NT 3.1以上版本;Windows:95以上版本:Windows CE以上版本;头文件;winuser.h;库文件:user32.lib;Unicode:在Windows NT环境中以Unicode和ANSI版本实现。

PostQuitMessage

函数功能:该函数向系统表明有个线程有终止请求。通常用来响应WM_DESTR OY消息。

函数原型:VOID PostQuitMessage(int nExitCode);

参数:

pExitCode:指定应用程序退出代码。此值被用作消息WM_QUIT的wParam参数。

返回值:无。

备注:PostQuitMessage寄送一个WM_QUIT消息给线程的消息队列并立即返回;此函数向系统表明有个线程请求在随后的某一时间终止。

当线程从消息队列里取得WM_QUIT消息时,应当退出消息循环并将控制返回给系统。返回给系统的退出值必须是消息WM_QUIT的wParam参数。

速查:Windows NT:3.1及以上版本;Windows:95及以上版本;Windows CE:1.0及以上版本;头文件:winuser.h;输入库:user32,lib:Uhicode:在Wi hdows NT环境下以Unicode和ANSI方式实现。

BeginPaint

BeginPaint函数准备指定的窗口来重绘并将绘画相关的信息放到一个PAINTST RUCT结构中。

HDC BeginPaint(

HWND hwnd, // 窗口的HANDLE

LPPAINTSTRUCT lpPaint // 绘画信息

);

参数:

hWnd:[输入]被重绘的窗口HANDLE

lpPaint:[输出]指向一个用来接收绘画信息的PAINTSTRUCT结构

返回值:

如果函数成功,返回值是指定窗口的显示设备内容HANDLE

如果函数失败,返回值是NULL,指示没有得到显示设备内容

Windows NT/2000/XP: 使用GetLastError得到更多的错误信息。

备注:

BeginPaint函数自动设置显示设备内容的剪切区域而排除任何更新区域外的区

域更新区域通过InalidateRect或InalidateRgn函数和系统的改变大小、移动、创建、滚动或其他的影响客户区操作来设置的。如果更新区域被标记为可擦除的,BeginPa int发送一个WM_ERASEBKGND消息给窗口。

一个应用程序除了响应WM_PAINT消息外,不应该调用BeginPaint。每次调用BeginPaint都应该有相应的EndPaint函数。

如果被绘画的客户区中有一个^符号,BeginPaint自动隐藏该符号,而保证它不被擦除。

如果窗口类有一个背景刷,BeginPaint使用这个刷子来擦除更新区域的背景。

例子代码:

你使用BeginPaint和EndPaint函数来准备和完成客户区的绘画。BeginPaint返回一个用来绘画的客户区的显示设备内容的HANDLE,EndPaint终止绘画请求,并释放设备内容。

TextOut

函数功能:该函数用当前选择字符、背景颜色和正文颜色将一个字符串写到指定位置。

函数原型:BOOL TextOut (HDC hdc, int nXStart, int nYStart, LPCTSTR l pString, int cbString);

参数:

hdc:设备环境句柄。

nXStart:指定用于字符串对齐的基准点的逻辑X坐标。

nYStart:指定用于字符串对齐的基准点的逻辑Y坐标。

lpString:指向将被绘制字符串的指针。此字符串不必为以\0结束的,因为cbSt ring中指定了字符串的长度。

cbString:字符串的字符数。

返回值:如果函数调用成功,返回值非零;如果函数调用失败,返回值是0。

Windows NT:若想获得更多错误信息,请调用GetLastError函数。

备注:对基准点的解释依赖于当前字符对齐模式,一个应用程序可以调用GetTe xtAlign来获得该模式,调用SetTextAlign来更改该模式。

缺省地,此函数不能使用和修改当前位置,但一个应用程序可以在每次在指定设备环境中调用TextOut之前,通过将参数fMode设为TA_UPDATECP值来调用Set TextAlign,以允许系统在调用TextOut时修改当前位置,当上述标志设置时,系统会忽略随后调用TextOut中的nXStart和nYStart值。

当把函数TextOut放入一个路径括号内时,系统为包含每一个字符并加上字符值的TrueType正文产生一个路径,产生的区域是字符框加上正文,而不是正文本身,可以在把TextOut放入路径括号之前设置背景模式为透明的,这样就能得到由TrueT ype正文的轮廓封闭而成的区域。下面是说明这个过程的例程代码:GetClientRect(hwnd, &r); BeginPath(hdc); TextOut(hdc, r.left, r.top, "Defen estration can be hazardous", 4); EndPath(hdc); SelectClipPath(hdc, RGN_AN D); FillRect(hdc, &r, GetStockObject(GRAY_BRUSH))。

速查:Windows NT:3.1及以上版本;Windows:95及以上版本;Windows CE:不支持;头文件:wingdi.h;库文件:gdi32.lib;Unicode:在Windows NT环境下实现为Unicode和ANSI两种版本。

EndPaint

EndPaint函数标记指定窗口的绘画过程结束;这个函数在每次调用BeginPaint 函数之后被请求,但仅仅在绘画完成以后。

BOOL EndPaint(

HWND hWnd, // 窗口句柄

CONST PAINTSTRUCT *lpPaint // 绘制窗口的数据

);

参数:

hWnd:[输入]已经被重画的窗口的HANDLE

lpPaint:[输入]指向一个PAINTSTRUCT结构,该结构包含了绘画信息,是Be ginPaint函数返回的返回值:

返回值:

返回值始终是非0

备注:

PAINTSTRUCT 结构体包含了用于绘制窗口客户区的信息。

PAINTSTRUCT定义:

typedef struct tagPAINTSTRUCT {

HDC hdc;

BOOL fErase;

RECT rcPaint;

BOOL fRestore;

BOOL fIncUpdate;

BYTE rgbReserved[32];

} PAINTSTRUCT, *PPAINTSTRUCT;

hdc是用于绘制的句柄,fErase如果为非零值则擦除背景,否则不擦除背景,rc Paint 通过制定左上角和右下角的坐标确定一个要绘制的矩形范围,该矩形单位相对于客户区左上角,后面三个参数都是系统预留的,编程一般用不到。InvalidateRect

该函数向指定的窗体添加一个矩形,然后窗口客户区域的这一部分将被重新绘制。

BOOL InvalidateRect(

HWND hWnd, // handle of window with changed update region

CONST RECT *lpRect, // address of rectangle coordinates

BOOL bErase // erase-background flag

);

参数:

hWnd:要更新的客户区所在的窗体的句柄。如果为NULL,则系统将在函数返回前重新绘制所有的窗口, 然后发送WM_ERASEBKGND和WM_NCPAINT给窗口过程处理函数。

lpRect:无效区域的矩形代表,它是一个结构体指针,存放着矩形的大小。如果为NULL,全部的窗口客户区域将被增加到更新区域中。

bErase:指出无效矩形被标记为有效后,是否重绘该区域的背景。

返回值:

函数成功则返回非零值,否则返回零值。

说明:被标记为无效矩形的区域直到WM_PAINT消息被处理完之后才会消失,或者使用ValidateRect(),ValidateRgn()函数来使之有效。当应用程序的消息队列中为空时,并且窗体要更新的区域非空时,系统会发送一个WM_PAINT消息到窗体。

需要:

Windows NT/2000/XP/Vista: 包含Windows NT 3.1以及之后版本。

Windows 95/98/Me: 包含Windows 95 以及之后版本。

Header:声名在Winuser.h中;包含在Windows.h中。

Library: Use User32.lib.

atof(将字串转换成浮点型数)

相关函数atoi,atol,strtod,strtol,strtoul

表头文件#include

定义函数double atof(const char *nptr);

函数说明atof()会扫描参数nptr字符串,跳过前面的空格字符,直到遇上数字或正负符号才开始做转换,而再遇到非数字或字符串结束时('\0')才结束转换,并将结果返回。参数nptr字符串可包含正负号、小数点或E(e)来表示指数部分,如123.456或123e-2。

返回值返回转换后的浮点型数。

附加说明atof()与使用strtod(nptr,(char**)NULL)结果相同。

sprintf

sprintf 将字串格式化。

在头文件#include

语法: string sprintf(string format, mixed [args]...);

传回值: 字串

1. 处理字符方向。-负号时表时从后向前处理。

2. 填空字元。0 的话表示空格填0;空格是内定值,表示空格就放着。

3. 字符总宽度。为最小宽度。

4. 精确度。指在小数点后的浮点数位数。

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

转换字符

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

% 印出百分比符号,不转换。

b 整数转成二进位。

c 整数转成对应的ASCII 字元。

d 整数转成十进位。

f 倍精确度数字转成浮点数。

o 整数转成八进位。

s 整数转成字串。

x 整数转成小写十六进位。

X 整数转成大写十六进位。

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

$money = 123.1

$formatted = sprintf ("%06.2f", $money); // 此时变数$ formatted 值为"1 23.10"

$formatted = sprintf ("%08.2f", $money); // 此时变数$ formatted 值为"0 0123.10"

$formatted = sprintf ("%-08.2f", $money); // 此时变数$ formatted 值为" 123.1000"

$formatted = sprintf ("%.2f%%", 0.95 * 100); // 格式化为百分比

?>

¢%08.2f 解释:

%开始符

0是"填空字元" 表示,如果长度不足时就用0来填满。

6格式化后总长度

2f小数位长度,即2位

¢第4行值为"00123.10" 解释:

因为2f是(2位)+小数点符号(1)+前面123(3位)=6位,总长度为8位,故前面用[填空字元]0表示,即00123.10

¢第4行值为"-123.1000" 解释:

-号为反向操作,然后填空字元0添加在最后面了

/********************************************************

以下选自《CSDN 社区电子杂志——C/C++杂志》

*********************************************************/

在将各种类型的数据构造成字符串时,sprintf 的强大功能很少会让你失望。由于sprintf 跟printf 在用法上几乎一样,只是打印的目的地不同而已,前者打印到字符串中,后者则直接在命令行上输出。这也导致sprintf 比printf 有用得多。

sprintf 是个变参函数,定义如下:

int sprintf( char *buffer, const char *format [, argument] ... );

除了前两个参数类型固定外,后面可以接任意多个参数。而它的精华,显然就在第二个参数:

格式化字符串上。

printf 和sprintf 都使用格式化字符串来指定串的格式,在格式串内部使用一些以“%”开头的格式说明符(format specifications)来占据一个位置,在后边的变参列表中提供相应的变量,最终函数就会用相应位置的变量来替代那个说明符,产生一个调用者想要的字符串。

格式化数字字符串

sprintf 最常见的应用之一莫过于把整数打印到字符串中,所以,spritnf 在大多数场合可以替代

itoa。

如:

//把整数123 打印成一个字符串保存在s 中。

sprintf(s, "%d", 123); //产生"123"

可以指定宽度,不足的左边补空格:

sprintf(s, "%8d%8d", 123, 4567); //产生:" 123 4567"

当然也可以左对齐:

sprintf(s, "%-8d%8d", 123, 4567); //产生:"123 4567"

也可以按照16 进制打印:

sprintf(s, "%8x", 4567); //小写16 进制,宽度占8 个位置,右对齐

sprintf(s, "%-8X", 4568); //大写16 进制,宽度占8 个位置,左对齐

这样,一个整数的16 进制字符串就很容易得到,但我们在打印16 进制内容时,通常想要一种左边补0 的等宽格式,那该怎么做呢?很简单,在表示宽度的数字前面加个0 就可以了。

sprintf(s, "%08X", 4567); //产生:"000011D7"

上面以”%d”进行的10 进制打印同样也可以使用这种左边补0 的方式。

这里要注意一个符号扩展的问题:比如,假如我们想打印短整数(short)-1 的内存16 进制表示形式,在Win32 平台上,一个short 型占2 个字节,所以我们自然希望用4 个16 进制数字来打印它:

short si = -1;

sprintf(s, "%04X", si);

产生“FFFFFFFF”,怎么回事?因为spritnf 是个变参函数,除了前面两个参数之外,后面的参数都不是类型安全的,函数更没有办法仅仅通过一个“%X”就能得知当初函数调用前参数压栈时被压进来的到底是个4 字节的整数还是个2 字节的短整数,所以采取了统一4 字节的处理方式,导致参数压栈时做了符号扩展,扩展成了32

位的整数-1,打印时4 个位置不够了,就把32 位整数-1 的8 位16 进制都打印出来了。

如果你想看si 的本来面目,那么就应该让编译器做0 扩展而不是符号扩展(扩展时二进制左边补0 而不是补符号位):

sprintf(s, "%04X", (unsigned short)si);

就可以了。或者:

unsigned short si = -1;

sprintf(s, "%04X", si);

sprintf 和printf 还可以按8 进制打印整数字符串,使用”%o”。注意8 进制和1 6 进制都不会打

印出负数,都是无符号的,实际上也就是变量的内部编码的直接的16 进制或8 进制表示。

控制浮点数打印格式

浮点数的打印和格式控制是sprintf 的又一大常用功能,浮点数使用格式符”%f”控制,默认保

留小数点后6 位数字,比如:

sprintf(s, "%f", 3.1415926); //产生"3.141593"

但有时我们希望自己控制打印的宽度和小数位数,这时就应该使用:”%m.nf”格式,其中m 表

示打印的宽度,n 表示小数点后的位数。比如:

sprintf(s, "%10.3f", 3.1415626); //产生:" 3.142"

sprintf(s, "%-10.3f", 3.1415626); //产生:"3.142 "

sprintf(s, "%.3f", 3.1415626); //不指定总宽度,产生:"3.142"

注意一个问题,你猜

int i = 100;

sprintf(s, "%.2f", i);

会打出什么东东来?“100.00”?对吗?自己试试就知道了,同时也试试下面这个:sprintf(s, "%.2f", (double)i);

第一个打出来的肯定不是正确结果,原因跟前面提到的一样,参数压栈时调用者并不知道跟i相对应的格式控制符是个”%f”。而函数执行时函数本身则并不知道当年被压入栈里的是个整数,于是可怜的保存整数i 的那4 个字节就被不由分说地强行作为浮点数格式来解释了,整个乱套了。不过,如果有人有兴趣使用手工编码一个浮点数,那么倒可以使用这种方法来检验一下你手工编排的结果是否正确。

字符/Ascii 码对照

我们知道,在C/C++语言中,char 也是一种普通的scalable 类型,除了字长之外,它与short,

int,long 这些类型没有本质区别,只不过被大家习惯用来表示字符和字符串而已。(或许当年该把

这个类型叫做“byte”,然后现在就可以根据实际情况,使用byte 或short 来把c har 通过typedef 定义出来,这样更合适些)于是,使用”%d”或者”%x”打印一个字符,

便能得出它的10 进制或16 进制的ASCII 码;反过来,使用”%c”打印一个整数,便可以看到它所对应的ASCII 字符。以下程序段把所有可见字符的ASCII 码对照表打印到屏幕上(这里采用printf,注意”#”与”%X”合用时自动为16 进制数增加”0X”前缀):for(int i = 32; i < 127; i++) {

printf("[ %c ]: %3d 0x%#04X\n", i, i, i);

}

连接字符串

sprintf 的格式控制串中既然可以插入各种东西,并最终把它们“连成一串”,自然也就能够连

接字符串,从而在许多场合可以替代strcat,但sprintf 能够一次连接多个字符串(自然也可以同时

在它们中间插入别的内容,总之非常灵活)。比如:

char* who = "I";

char* whom = "CSDN";

sprintf(s, "%s love %s.", who, whom); //产生:"I love CSDN. "

strcat 只能连接字符串(一段以’’结尾的字符数组或叫做字符缓冲,null-termina ted-string),但有时我们有两段字符缓冲区,他们并不是以’’结尾。比如许多从第三方库函数中返回的字符数组,从硬件或者网络传输中读进来的字符流,它们未必每一段字符序列后面都有个相应的’’来结尾。如果直接连接,不管是sprintf 还是strcat

肯定会导致非法内存操作,而strncat 也至少要求第一个参数是个null-terminated-st ring,那该怎么办呢?我们自然会想起前面介绍打印整数和浮点数时可以指定宽度,字符串也一样的。比如:

char a1[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};

char a2[] = {'H', 'I', 'J', 'K', 'L', 'M', 'N'};

如果:

sprintf(s, "%s%s", a1, a2); //Don't do that!

十有八九要出问题了。是否可以改成:

sprintf(s, "%7s%7s", a1, a2);

也没好到哪儿去,正确的应该是:

sprintf(s, "%.7s%.7s", a1, a2);//产生:"ABCDEFGHIJKLMN"

这可以类比打印浮点数的”%m.nf”,在”%m.ns”中,m 表示占用宽度(字符串长度不足时补空格,超出了则按照实际宽度打印),n 才表示从相应的字符串中最多取用的字符数。通常在打印字符串时m 没什么大用,还是点号后面的n 用的多。自然,也可以前后都只取部分字符:

sprintf(s, "%.6s%.5s", a1, a2);//产生:"ABCDEFHIJKL"

在许多时候,我们或许还希望这些格式控制符中用以指定长度信息的数字是动态的,而不是静态指定的,因为许多时候,程序要到运行时才会清楚到底需要取字符数组中的几个字符,这种动态的宽度/精度设置功能在sprintf 的实现中也被考虑到了,

sprintf 采用”*”来占用一个本来需要一个指定宽度或精度的常数数字的位置,同样,而实际的宽度或精度就可以和其它被打印的变量一样被提供出来,于是,上面的例子可以变成:

sprintf(s, "%.*s%.*s", 7, a1, 7, a2);

或者:

sprintf(s, "%.*s%.*s", sizeof(a1), a1, sizeof(a2), a2);

实际上,前面介绍的打印字符、整数、浮点数等都可以动态指定那些常量值,比如:

sprintf(s, "%-*d", 4, 'A'); //产生"65 "

sprintf(s, "%#0*X", 8, 128); //产生"0X000080","#"产生0X

sprintf(s, "%*.*f", 10, 2, 3.1415926); //产生" 3.14"

打印地址信息

有时调试程序时,我们可能想查看某些变量或者成员的地址,由于地址或者指针也不过是个32 位的数,你完全可以使用打印无符号整数的”%u”把他们打印出来:sprintf(s, "%u", &i);

不过通常人们还是喜欢使用16 进制而不是10 进制来显示一个地址:

sprintf(s, "%08X", &i);

然而,这些都是间接的方法,对于地址打印,sprintf 提供了专门的”%p”:

sprintf(s, "%p", &i);

我觉得它实际上就相当于:

sprintf(s, "%0*x", 2 * sizeof(void *), &i);

利用sprintf 的返回值

较少有人注意printf/sprintf 函数的返回值,但有时它却是有用的,spritnf 返回了本次函数调用

最终打印到字符缓冲区中的字符数目。也就是说每当一次sprinf 调用结束以后,你无须再调用一次

strlen 便已经知道了结果字符串的长度。如:

int len = sprintf(s, "%d", i);

对于正整数来说,len 便等于整数i 的10 进制位数。

下面的是个完整的例子,产生10 个[0, 100)之间的随机数,并将他们打印到一个字符数组s 中,

以逗号分隔开。

#include

#include

#include

int main() {

srand(time(0));

char s[64];

int offset = 0;

for(int i = 0; i < 10; i++) {

offset += sprintf(s + offset, "%d,", rand() % 100);

}

s[offset - 1] = '\n';//将最后一个逗号换成换行符。

printf(s);

return 0;

}

设想当你从数据库中取出一条记录,然后希望把他们的各个字段按照某种规则连接成一个字

符串时,就可以使用这种方法,从理论上讲,他应该比不断的strcat 效率高,因为strcat 每次调用

都需要先找到最后的那个’’的位置,而在上面给出的例子中,我们每次都利用sp rintf 返回值把这

个位置直接记下来了。

使用sprintf 的常见问题

sprintf 是个变参函数,使用时经常出问题,而且只要出问题通常就是能导致程序崩溃的内存访

问错误,但好在由sprintf 误用导致的问题虽然严重,却很容易找出,无非就是那么几种情况,通

常用眼睛再把出错的代码多看几眼就看出来了。

?? 缓冲区溢出

第一个参数的长度太短了,没的说,给个大点的地方吧。当然也可能是后面的参数的问

题,建议变参对应一定要细心,而打印字符串时,尽量使用”%.ns”的形式指定最大字符数。

?? 忘记了第一个参数

低级得不能再低级问题,用printf 用得太惯了。//偶就常犯。:。(

?? 变参对应出问题

通常是忘记了提供对应某个格式符的变参,导致以后的参数统统错位,检查检查吧。尤

其是对应”*”的那些参数,都提供了吗?不要把一个整数对应一个”%s”,编译器会觉得你

欺她太甚了(编译器是obj 和exe 的妈妈,应该是个女的,:P)。

strftime

sprnitf 还有个不错的表妹:strftime,专门用于格式化时间字符串的,用法跟她表哥很像,也

是一大堆格式控制符,只是毕竟小姑娘家心细,她还要调用者指定缓冲区的最大长度,可能是为

了在出现问题时可以推卸责任吧。这里举个例子:

time_t t = time(0);

//产生"YYYY-MM-DD hh:mm:ss"格式的字符串。

char s[32];

strftime(s, sizeof(s), "%Y-%m-%d %H:%M:%S", localtime(&t));

sprintf 在MFC 中也能找到他的知音:CString::Format,strftime 在MFC 中自然也有她的同道:

CTime::Format,这一对由于从面向对象哪里得到了赞助,用以写出的代码更觉优雅。

GetWindowText

函数功能:该函数将指定窗口的标题条文本(如果存在)拷贝到一个缓存区内。如果指定的窗口是一个控制,则拷贝控制的文本。但是,GetWindowTeXt不能接收在其他应用程序中的控制文本。

函数原型:Int GetWindowText(HWND hWnd,LPTSTR lpString,Int nMax Count);

参数:

hWnd:带文本的窗口或控制的句柄。

IpString:指向接收文本的缓冲区的指针。

nMaxCount:指定要保存在缓冲区内的字符的最大个数,其中包含NULL字符。如果文本超过界限,它就被截断。

返回值:如果函数成功,返回值是拷贝的字符串的字符个数,不包括中断的空字符;如果窗口无标题栏或文本,或标题栏为空,或窗口或控制的句柄无效,则返回值为零。若想获得更多错误信息,请调用GetLastError函数。

函数不能返回在其他应用程序中的编辑控制的文本。

备注:如果目标窗口属于当前进程,GetWindowText函数给指定的窗口或控制发送WM_GETTEXT消息。如果目标窗口属于其他进程,并且有一个窗口标题,则G etWindowTeXt返回窗口的标题文本,如果窗口无标题,则函数返回空字符串。

速查:Windows NT:3.1以上版本;Windows:95以上版本:Windows CE:1.0以上版本;头文件:Winuser.h;库文件:user32.lib:Unicode:在Windows NT上实现为Unicode和ANSI两种版本。

CreateWindow

函数功能:该函数创建一个重叠式窗口、弹出式窗口或子窗口。它指定窗口类,窗口标题,窗口风格,以及窗口的初始位置及大小(可选的)。该函数也指定该窗口的父窗口或所属窗口(如果存在的话),及窗口的菜单。若要使用除CreateWindow

函数支持的风格外的扩展风格,则使用CreateWindowEx函数代替CreateWindow函数。

函数原型:HWND CreateWindow(LPCTSTR lpClassName,LPCTSTR lpWind owName,DWORD dwStyle,int x,int y,int nWidth,int nHeight,HWND hWndPar ent,HMENU hMenu,HANDLE hlnstance,LPVOID lpParam);

参数:

lpClassName:指向一个空结束的字符串或整型数atom。如果该参数是一个整型量,它是由此前调用theGlobalAddAtom函数产生的全局量。这个小于0xC000的1 6位数必须是lpClassName参数字的低16位,该参数的高位必须是0。

如果lpClassName是一个字符串,它指定了窗口的类名。这个类名可以是任何用函数RegisterClassEx注册的类名,或是任何预定义的控制类名。请看说明部分的列表。

LPWindowName:指向一个指定窗口名的空结束的字符串指针。

如果窗口风格指定了标题条,由lpWindowName指向的窗口标题将显示在标题条上。当使用Createwindow函数来创建控制例如按钮,选择框和静态控制时,可使用lpWindowName来指定控制文本。

dwStyle:指定创建窗口的风格。该参数可以是下列窗口风格的组合再加上说明部分的控制风格。风格意义:

WS_BORDER:创建一个单边框的窗口。

WS_CAPTION:创建一个有标题框的窗口(包括WS_BODER风格)。

WS_CHILD:创建一个子窗口。这个风格不能与WS_POPUP风格合用。

WS_CHLDWINDOW:与WS_CHILD相同。

WS_CLIPCHILDREN:当在父窗口内绘图时,排除子窗口区域。在创建父窗口时使用这个风格。

WS_CLlPBLINGS;排除子窗口之间的相对区域,也就是,当一个特定的窗口接收到WM_PAINT消息时,WS_CLIPSIBLINGS 风格将所有层叠窗口排除在绘图之外,只重绘指定的子窗口。如果未指定WS_CLIPSIBLINGS风格,并且子窗口是层叠的,则在重绘子窗口的客户区时,就会重绘邻近的子窗口。

WS_DISABLED:创建一个初始状态为禁止的子窗口。一个禁止状态的窗日不能接受来自用户的输入信息。

WS_DLGFRAME:创建一个带对话框边框风格的窗口。这种风格的窗口不能带标题条。

WS_GROUP:指定一组控制的第一个控制。这个控制组由第一个控制和随后定义的控制组成,自第二个控制开始每个控制,具有WS_GROUP风格,每个组的第一个控制带有WS_TABSTOP风格,从而使用户可以在组间移动。用户随后可以使用光标在组内的控制间改变键盘焦点。

WS_HSCROLL:创建一个有水平滚动条的窗口。

WS_ICONIC:创建一个初始状态为最小化状态的窗口。与WS_MINIMIZE风格相同。

WS_MAXIMIZE:创建一个具有最大化按钮的窗口。该风格不能与WS_EX_CO NTEXTHELP风格同时出现,同时必须指定WS_SYSMENU风格。

WS_OVERLAPPED:产生一个层叠的窗口。一个层叠的窗口有一个标题条和一个边框。与WS_TILED风格相同。

WS_OVERLAPPEDWINDOW:创建一个具有WS_OVERLAPPED,WS_CAPT ION,WS_SYSMENU WS_THICKFRAME,WS_MINIMIZEBOX,WS_MAXMIZEB OX风格的层叠窗口,与WS_TILEDWINDOW风格相同。

WS_POPUP;创建一个弹出式窗口。该风格不能与WS_CHLD风格同时使用。

WS_POPUWINDOW:创建一个具有WS_BORDER,WS_POPUP,WS_SYSME NU风格的窗口,WS_CAPTION和WS_POPUPWINDOW必须同时设定才能使窗口某单可见。

WS_SIZEBOX:创建一个可调边框的窗口,与WS_THICKFRAME风格相同。

WS_SYSMENU:创建一个在标题条上带有窗口菜单的窗口,必须同时设定WS _CAPTION风格。

WS_TABSTOP:创建一个控制,这个控制在用户按下Tab键时可以获得键盘焦点。按下Tab键后使键盘焦点转移到下一具有WS_TABSTOP风格的控制。

WS_THICKFRAME:创建一个具有可调边框的窗口,与WS_SIZEBOX风格相同。

WS_TILED:产生一个层叠的窗口。一个层叠的窗口有一个标题和一个边框。与WS_OVERLAPPED风格相同。

WS_TILEDWINDOW:创建一个具有WS_OVERLAPPED,WS_CAPTION,WS _SYSMENU MS_THICKFRAME.

WS_MINIMIZEBOX,WS_MAXMIZEBOX风格的层叠窗口。与WS_OVERLAP PEDWINDOW风格相同。

WS_VISIBLE:创建一个初始状态为可见的窗口。WS_VSCROLL:创建一个有垂直滚动条的窗口。

X:指定窗口的初始水平位置。对一个层叠或弹出式窗口,X参数是屏幕坐标系的窗口的左上角的初始X坐标。对于子富口,x是子窗口左上角相对父窗口客户区左上角的初始X坐标。如果该参数被设为CW_UCEDEFAULT则系统为窗口选择缺省的左上角坐标并忽略Y参数。CW_USEDEFAULT只对层叠窗口有效,如果为弹出式窗口或子窗口设定,则X和y参数被设为零。

Y:指定窗口的初始垂直位置。对一个层叠或弹出式窗日,y参数是屏幕坐标系的窗口的左上角的初始y坐标。对于子窗口,y是子窗口左上角相对父窗口客户区左上角的初始y坐标。对于列表框,y是列表框客户区左上角相对父窗口客户区左上角的初始y坐标。如果层叠窗口是使用WS_VISIBLE风格位创建的并且X参数被设为CW_USEDEFAULT,则系统将忽略y参数。

nWidth:以设备单元指明窗口的宽度。对于层叠窗口,nWidth或是屏幕坐标的窗口宽度或是CW_USEDEFAULT。若nWidth是CW_USEDEFAULT,则系统为窗口选择一个缺省的高度和宽度:缺省宽度为从初始X坐标开始到屏幕的右边界,缺省高度为从初始X坐标开始到目标区域的顶部。CW_USEDEFAULT只参层叠窗口有效;如果为弹出式窗口和子窗口设定CW_USEDEFAULT标志则nWidth和nHeight被设为零。

nHelght:以设备单元指明窗口的高度。对于层叠窗口,nHeight是屏幕坐标的窗口宽度。若nWidth被设为CW_USEDEFAULT,则系统忽略nHeight参数。

hWndParent:指向被创建窗口的父窗口或所有者窗口的旬柄。若要创建一个子窗口或一个被属窗口,需提供一个有效的窗口句柄。这个参数对弹出式窗日是可选的。Windows NT 5.0;创建一个消息窗口,可以提供HWND_MESSAGE或提供一个己存在的消息窗口的句柄。

hMenu:菜单句柄,或依据窗口风格指明一个子窗口标识。对于层叠或弹出式窗口,hMenu指定窗口使用的菜单:如果使用了菜单类,则hMenu可以为NULL。对于子窗口,hMenu指定了该子窗口标识(一个整型量),一个对话框使用这个整型值将事件通知父类。应用程序确定子窗口标识,这个值对于相同父窗口的所有子窗口必须是唯一的。

hlnstance:与窗口相关联的模块事例的句柄。

lpParam:指向一个值的指针,该值传递给窗口WM_CREATE消息。该值通过在IParam参数中的CREATESTRUCT结构传递。如果应用程序调用CreateWindow创建一个MDI客户窗口,则lpParam必须指向一个CLIENTCREATESTRUCT结构。

返回值:如果函数成功,返回值为新窗口的句柄:如果函数失败,返回值为NU LL。若想获得更多错误信息,请调用GetLastError函数。

备注:在返回前,CreateWindow给窗口过程发送一个WM_CREATE消息。对于层叠,弹出式和子窗口,CreateWindow给窗口发送WM_CREATE,WM_GETMI NMAXINFO和WM_NCCREATE消息。消息WM_CREATE的IParam参数包含一个指向CREATESTRUCT结构的指针。如果指定了WS_VISIBLE风格,CreateWindo w向窗口发送所有需要激活和显示窗口的消息。

获取有关任务条是否为创建的窗口显示一个按钮的控制信息,参看Taskbar按钮的Visbility。

以下预定义的控制类可以在lpClassName参数中指定。注意在dwStyle参数中可以使用的相应的控制风格。

BUTTON按钮按钮是一个小矩形子窗口,用户可以点击来打开或关闭。按钮控制可以单独使用或包含在组中使用,可以为控制写标签或不写标签。当用户点击按钮控制时按钮的外观有明显的改变。请参看Button。查看dwStyle参数中指定的按钮风格表请参考Button Style。

COMBOBOX组合框由一个列表框和一个类似于编辑控制的选择域组成。在使用这个风格控制时,应用程序或者使列表框一直显示或者是作成一个下拉列表。如果列

表框可见,则在编辑域中输入字符将使列表框中与字符一致的第一个域高亮。反之,在列表框中选择的项将显示在编辑域中。请参看Combo Boxes。

查看dwStyle参数中指定的组合框风格表请参考Combo Boxes Style。

EDIT编辑框一个小的矩形子窗口用户可以使用键盘向其中输入文本。用户可以通过点击或按Tab键来选中编辑框控制并且使控制获得焦点。当编辑框中显示一个闪烁的插入记号时,用户可以输入文本。使用鼠标移动光标,选择被替换的字符或设置插入字符的位置或使用回退键删除字符。请参看Edit。controls。

查看dwStyle参数中指定的编辑框风格的表格请参考Edit Control Style。

LISTBOX列表框字符串的列表。当应用程序必须显示名称的列表,例如文件名列表等,使用户可以从中选择时就可指定列表框。用户可以通过单击来选择名称。选择时,被选择名高亮,同时传递给父窗口一个通知消息。请参看LiSt Box Style。查看dwStyle参数中指定的列表风格表请参考List BOX Control Style。

MDICLIENT MDI客户设计出MDI客户窗口。窗口接收控制MDI应用程序子窗口的消息。建议使用两种控制风格位:WS_CLIPCHILDREN和WS_CHILD。指定了WS_HSCROLL和WS_VSCROLL风格的MDI客户窗口允许用户将MDI子窗口滑动进入视窗。请参看MDI。

RiChEdit设计一个Rich Editl.0版的控制。该控制使用户可以以字符和段落格式测览和编辑文本,并且可以包含嵌入的COM对象。请参看Rich Edit Controls。查看dwStyle参数中指定的RichEdit风格表请参考LiSt Box Control Style。

RICHEDIT CLASS设计一个Rich Edik2.0版的控制。该控制使用户可以以字符和段落格式测览和编辑文本,并且可以包含嵌入的COM对象。请参看RichEditCont rols。查看dwStyle参数中指定的RichEdit风格表请参考RichEditControIStyle。

SCROLLBAR 滚动条设计的一个包含着一个滚动盒和两端有方向箭头的矩形。只要用户点击了控制,滚动条就给父窗口发送一个通知消息。如有必要,父窗口负责更新滚动条的位置。请参看ScrollBars。查看dwStyle参数中指定的滚动条风格表请参考Scroll Bars Style。

STATIC一个简单的静态文本域,文本盒或矩形用于给控制加标签,组合控制或将控制与其他控制分开。

静态控制不提供输入和也不提供输出。请参看Static Control Styles。查看dwS tyle参数中指定的静态文本风格表请参考Scroll Bars Style。

Windows95:系统可以支持最大16,364个窗口句柄。

备注:如果在链接应用程序时指明是Windows 4.x版本,除非应用程序的窗口有窗口某单,否则窗口控制没有标题控制。对Windows3.x版本没有这种要求。

Windows CE:CreateWindow是以“宏”方式完成的。它被定义为CreateWindo wEX,并且dwExStyle参数被置为长整数0。不支持菜单条控制,除非被声明为子窗口标志否则hMenu参数必须为NULL。不支持MDICLIENT窗口类。dwStyle参数可以是对话框(Dialogue Box),窗口(Windows),控制(Controls)文件中的窗口风格和控制风格的组合。

下列dwStyle标志在窗口中不支持:

WS_CHILDWINDOW WS_ICONC;WS_MAXMIZE WS_MAXIMIZEBOX;WS _MINIMIZE WS_MINIMIZEBOX;

WS_OVERLAPPEDWINDOW WS_POPUPWINDOW;WS_SIZEBOXWS_THI CKFRAME WS_TILED WS_TILEDWINDOW

下列dwStyle标志在控制和对话框中不支持:

不支持的按钮风格和静态控制风格:

BS_LEFTTEXT SS_BLACKFRAME;BS_MULTILINE SS_GRAYFRAME BS_ TEXT SS_METAPICT;BS_USERBUTTON SS_SIMPLE

不支持组合框SS_WHITERECT风格。

CBS_OWNERDRAWFIXED SS_BLACKRECT;CBS_OWNWEDRAWVARIAB LE SS_GRAYRECT;CBS_SIMPLE8R旧HTrIMAGE

不支持列表框控制SS_WHITEFRAME风格。

LBS_NODATA

不支持的对话框风格:

LBS_OWNERDRAWFIXED DS_ABSALIGN;LBS_OWNERDRAWVARIABLE DS_CENTERMOUSE;LBS_STANDARD DS_CONTEXTHELP

不支持滚动条的DS_FIXEDSYS风格

SBS_BOTTOMALIGN DS_NOFAILCREATE;SBS_RIGHTALIGN DS_NOIDL EMSG;

SBS_SlZEBOXBOTT0MRIHTALIGN DS_SYSMODAL;SBS_SIZEGRIP

可使用BS_OWNERDRAW风格来代替BS_USERBUTTON风格。

可使用SS_LEFT或SS_LEFTNOWORDWRAP风格来代替静态控制的SS_SI MPLE风格。

不支持MDICLIENT窗口类。

所有窗口都隐含WS_CLIPSIBLINGS和WS_CLIPCHILDREN风格。

Windows CE1.0版除对话框外不支持被属窗口。如果hwndParent参数不为NU LL,则窗口隐含给出WS_CHILD风格。Windows CE1.0不支持菜单条。

速查:Windows NT:3.1以上版本;Windows:95以上版本;Windows CE:1.0以上版本;头文件:winuser.h;库文件:user32.lib;Unicode:在Windows NT上实现为Unicode和ANSI两种版本。

Wndproc

1. 窗口过程

操作系统向应用程序发送一系列消息,如左键按下和左键抬起,应用程序将通过GetMessage等方法最终将消息提交到窗口过程(WndProc)

2. 指向一个应用程序定义的窗口过程的指针

3. 回调函数

每个窗口会有一个称为窗口过程的回调函数(WndProc),它带有四个参数,分别为:窗口句柄(Window Handle),消息ID(Message ID),和两个消息参数(wParam, lP aram)

4. 窗口程序

pOldProc:Pointer; //子类化前的窗口程序(WndProc)指针WinMain

函数功能:该函数被系统调用,作为一个32位应用程序的入口点。

函数原型:

int WINAPI WinMain(

HINSTANCE hInstance,

HINSTANCE hPrevInstance,

LPSTR lpCmdLine,

int nCmdShow

);

参数;

hInstance:应用程序当前事例的句柄。

hPrelnstance:应用程序的先事例的句柄。对于同一个程序打开两次,出现两个窗口第一次打开的窗口就是先前实例的窗口。对于一个32的位程序,该参数总为N ULL。

如果需要检测另外一个事例是否已经存在,则使用CreateMutex函数创建一个独一无二的名字。即使互斥名已经存在,CreateMutex函数也是成功的,但是GetLast Error函数将返回ERROR_ALREADY_EXISTS,这就表明在应用程序中有另外一个事例存在,因为它首先创建了互斥名。

lpCmdLine:指向应用程序命令行的空字符串的指针,不包括函数名。获得整个命令行,参看GetCommandLine。

第三个参数lpCmdLine是一个以空终止的字符串,指定传递给应用程序的命令行参数。例如:在D盘下有一个sunxin.txt文件,当我们用鼠标双击这个文件时将启动记事本程序(notepad.exe),此时系统会将D:\sunxin.txt作为命令行参数传递给记事本程序的WinMain函数,记事本程序在得到这个文件的全路径名后,就在窗口中显示该文件的内容。要在VC++开发环境中向应用程序传递参数,可以单击菜单【P roject】→【Settings】,选择“Debug”选项卡,在“Program arguments”编辑框中输入你想传递给应用程序的参数。

nCmdShow:指明窗口如何显示。该参数可以是下列值之一:

SW_HIOE:隐藏窗口并且激活另外一个窗口。

SW_MINIMIZE:最小化指定的窗口,并且激活在系统表中的顶层窗口。

SW_RESTORE:激活并显示窗口。如果窗口已经最小化或最大化,系统将以恢复到原来的尺寸和位置显示窗口(与SW_SHOWNORMAL相同)。

SW_SHOW:激活一个窗口并以原来的尺寸和位置显示窗口。

SW_SHOWMAXIMIZED:激活窗口并且将其最大化。

SW_SHOWMINIMIZED:激活窗口并将其目标化。

SW_SHOWMINNOACTIVE:将一个窗口显示为图标。激活窗口维持活动状态。

SW_SHOWNA:以窗口的当前状态显示窗口。激活窗口保持活动状态。

SW_SHOWNOACTIVATE:以窗口的最近一次的尺寸和位置显示窗口。激活窗口维持激活状态。

SW_SHOWNORMAL:激活并显示窗口。如果窗口最大化或最小化,系统将其恢复到原来的尺寸和位置(与SW_RESTORE相同)。

返回值:如果函数成功,当它接收到一个WM_QUIT消息时就中止,函数应该返回在该消息的wParam参数的退出值。如果函数在进入消息循环时退出,应该返回零。

备注:WinMain函数应初始化应用程序,显示主窗口,进入一个消息接收一发送循环,这个循环是应用程序执行的其余部分的顶级控制结构。当接收到一个WM_QU IT消息时,程序就中止。这时,WinMain函数应退出应用程序,并且返回传递给W M_QUIT消息的wParam参数的值。如果由于调用PostQuitMessage函数而接收到WM_QUIT消息,wParam的值是PostQuiMessage函数的nExitCode的值。请参看“创建一个窗口循环”。

ANSI应用程序可以使用WinMain函数的lpCmdLine参数进入命令行字符串(除了程序名之外)。WinMain不能返回Unicode字符串的原因是IpCmdLine使用的是LPSTR数据类型,而不是LPTSTR类型。GetCommandLine函数可以用于进入命令行的Unicode字符串,因为它使用的是LPTSTR类型。

Windows CE:Windows CE不支持下列nCmdLine参数值:

SW_MINIMIZE;SW_RESTORE;SW_RESTORE;SW_SHOWMAXMIZED SW_SHOWMINIMIZED;SW_SHOWMINNOACTIVE

速查:Windows NT:3.1以上版本;Windows:95以上版本:Windows CE:1.0以上版本;头文件:Winbase.h库文件:用户自定义。

LoadIcon

HICON LoadIcon(HINSTANCE hInstance,LPCTSTR lpIconName);

1.函数说明:

该函数从与hInstance模块相关联的可执行文件中装入lpIconName指定的图标资源,仅当图标资源还没有被装入时该函数才执行装入操作,否则只获取装入的资源句柄

2.参数说明:lpIconName是指向NULL字符结尾的字符串的指针,它包含图标名.如果要使用windows预定义的图标,这是hInstance必须设置成NULL,lpIconName则可以是下列值:

IDI_APPLICATION:32512 IDI_QUESTION:332514

IDI_HAND:32513 IDI_EXCLAMATION:32515

IDI_ASTERISK :32516 IDI_WINLOGO:32517