C语言也能干大事第三节
一、 给程序添加图标
把一个ico图标放到工程文件夹下;使用ResEd在工程文件夹下新建一个资源文件(工程),然后点击【工程】→【资源】,添加一个ICON类型的资源,名称加前缀IDI_(命名习惯),文件名文件名为所选ico图标文件名;然后保存这个资源文件,保证这个资源的ID为最小(一般设置为0就可以)。在C-Free里的OtherFiles中点右键,选择“添加文件到文件夹”,将rc文件加入,重新编译即可。
二、 结构体及指针复习(这部分内容具体请参考C语言的教材)
1. 结构体的定义和声明
struct MyStruct
{
int f1;
int f2;
} //最常用的定义结构体的方式
typedef int MYInt; //使用typedef定义类型别名
typedef MyStruct JSJ321Struct; //结构体别名的声明
typedef MyStruct *PMyStruct; //PMyStruct是MyStruct指针的声明
typedef struct MyStruct
{
int f1;
int f2;
} JSJ321Struct; //把MyStruct的定义和定义MyStruct的别名为JSJ321Struct结合到了一起。
typedef struct MyStruct
{
int f1;
int f2;
} *PMyStruct; //把MyStruct的定义和定义MyStruct的指针别名PMyStruct的定义结合到了一起。
typedef struct MyStruct
{
int f1;
int f2;
} JSJ321Struct ,*PMyStruct; //把MyStruct的定义和定义MyStruct的别名为JSJ321Struct以及定义MyStruct的指针别名PMyStruct的定义结合到了一起。
MyStruct s1; //最普通的结构体声明
2. 给结构体所有字段置零
复习一下C语言中memset以及结构体的应用。
C语言中声明一个结构体变量之后,在使用这个变量之前要首先用memset来把各个位清零。使用C语言内置的函数memset来完成:memset(&s1, 0, sizeof(s1));
在下面,我们使用ZeroMemory“函数”。ZeroMemory其实并不是函数,看一下ZeroMemory的定义:
#define ZeroMemory RtlZeroMemory
其实编译的时候ZeroMemory会宏展开为RtlZeroMemory。再看RtlZeroMemory的定义:
#define RtlZeroMemory(d, l) RtlFillMemory((d), (l), 0)
而RtlZeroMemory又是RtlFillMemory的一个宏定义,而且是带参数的宏定义:
#define RtlFillMemory(d,l,f) memset((d), (f), (l))
可见RtlFillMemory其实是memset的宏定。所以ZeroMemory其实就是memset,纸老虎而已,不是一个全新的函数。
三、 GetOpenFileName之打开文件对话框的使用
实例:
OPENFILENAME ofn;
char szFile[MAX_PATH];
ZeroMemory(&ofn,sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.lpstrFile = szFile;
ofn.lpstrFile[0] = TEXT(" ");
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFilter = TEXT("ALL *.* Text *.TXT ");
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_EXPLORER |OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
if (GetOpenFileName(&ofn))
{
MessageBox(NULL,szFile,"",MB_OK);
}
下面将对这段代码作解释:
ZeroMemory
含义见上边;
char szFile[MAX_PATH];
定义一个长度为MAX_PATH的char数组。MAX_PATH是系统定义的一个宏,260。为Windows操作系统文件路径的最大长度。
ofn.lpstrFile = szFile;
szFile是一个字符数组, szFile这个名字代表这个字符数组的首地址。这是一个指针的应用,把接收选择文件名的数组的地址传递到GetOpenFileName函数中。
ofn.lpstrFile[0] = TEXT(" ");
效果等价于ZeroMemory(szFile, sizeof(szFile)/sizeof(char));
ofn.lpstrFilter = TEXT("ALL *.* Text *.TXT ");
文件类型过滤器:
(*.*就表示所有文件,*.txt就表示所有文本文件,abc*.*就表示所有以abc开头的文件,abc*.txt就表示所有以abc开头的文本文件。)
用“ ”分割出几个字段,每两个字段是一组过滤器,每组的第一个字段代表过滤器显示的值,而第二段表示真正的过滤器。
ofn.nFilterIndex = 1;
默认选择第几个过滤器,是从1开始的,不是0。这是试验出来的。
ofn.lpstrInitialDir = NULL;
表示指定初始打开文件的所在目录全路径,若为NULL则表示为程序当前目录。
ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
用于指定对话框的一些特性,其中:
OFN_EXPLORER表示对话框提供了与Windows Explorer相似的用户界面特征;
OFN_PATHMUSTEXIST表示指定的路径必须是存在的;
OFN_FILEMUSTEXIST表示指定的文件必须是存在的。
windows的一个惯例:结构体的指针类型别名一般是LP+结构体的名字。
GetOpenFileName(&ofn)而不是GetOpenFileName(ofn),因为GetOpenFileName函数要的是OPENFILENAME的指针。
只要用户还没关闭对话框,那么GetOpenFileName函数是停住的,同步模式的PlaySound以及getchar、scanf也是一样的。当用户关闭对话框,GetOpenFileName函数返回,返回值是BOOL类型的,等于TRUE表示用户选择了文件,如果等于FALSE就表示用户选择了【取消】按钮。