
C 语言的学习,一般的方法是,先学 C,然后是 C++,最好还要有汇编语言跟微机原理基础, 然后才是 Visual C++。这样的方法,对学习者来说,要耗费太多时间跟耐力。而在大学教 学中,也没有时间深入学习 Windows 编程的实用科技了。 其实,具有了 C 语言基础后,再有一些基本的 C++类的概念,就可以直接学习 Windows C 编程了。 一、走近 Windows C 语言 很多语言都把显示一个“Hello,World!”做为第一个入门程序, C 语言的第一个程序 是这种的:#include<stdio.h> main() { printf(“Hello,World!”); }如果把 main 函数写成带参数的 main 函数,应该是:#include<stdio.h> main(int arge,char *argv[]) { printf(“Hello,World!”); }Windows C 的第一个程序跟这个程序在方式和原理上都是一致的,只是有两点不同: 1. 主变量接收的实参不仅仅命令行中的字符串的个数跟字符串的首地址。 2. C 语言的这些函数在 Windows C 中都可以再次使用,但像 printf()屏幕显示等函 数就不能继续使用了。
因为 Windows 是多任务操作系统, 屏幕已不再为某一个应用程序所独 有,Windows C 应用程序要显示字符串,需要使用 Windows 提供的 API 函数,开自己的窗口 下面是一个最简单的,显示“Hello,World!”的 Windows C 程序:#include<windows.h> APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, LPSTR lpCmdLine,int nCmdShow) { MessageBox(NULL,"Hello,World!","第一个 Windows C 程序 ",MB_OK|MB_ICONASTERISK);}主函数的实参有四个: 1) 2) 3) 4) Hinstance:接收程序运行时当前实例的类库; HprivInstance:前一个实例的句柄; LpCmdLine:程序命令行指针; NcmdShow:一个用来指定窗口显示模式的整数。这几个参数的使用我们会在深入的学习中介绍的。 显示 Hello,Word!字符串,我们使用了一个 MessageBox 函数,这个函数会在屏幕上显 示一个对话框,它的原型是:int MessageBox(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UNIT uType)四个参数分别是: 1) 2) 3) 4) HWnd:父窗口的赋值; LpText:要显示字符串的指针; LpCaption:对话框标题字符串的指针; UType:显示在对话框上的小图标的类型。

使用这个变量要成个好习惯,指明函数的返回值 类型c 网络编程基础,因为在 C++中,函数返回值类别是不可以缺省的。而我们在 Windows C 编程时,还是 会用到 C++的一些概念,这样做,有利于以后深入地学习。 规范一点的程序需要是这种的:#include<windows.h> int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, LPSTR lpCmdLine,int nCmdShow) { MessageBox(NULL,"Hello,World!","第一个 Windows C 程序 ",MB_OK|MB_ICONASTERISK); return 0; }这里,我们声明的类别为 int 型,并且返回一个值 0,这样的变量就可以使用在复杂 一点的变量调用中了。
在这一节中,我们有几处都看到了句柄的概念,句柄和指针的概念不同,它是成为操 作平台外部索引表中的一个值来使用的,这样可以避免应用程序直接访问名对象的外部结 构,体现了 Windows 资源管理的优越性。譬如说,一个窗口找开以后,好对应内存中的一个 内存块, 这个窗口所在的内存快地址通常会由操作系统做动态的调整, 但其仍不会随之变化。 不过,通过它可以访问这个窗口,所以在使用的之后,可以把它当作指针一样看待。 二、 获取本地计算机的主机名和 IP 地址 和 C 语言一样,函数是 Windows C 编程的更基本的单位。不过,Windows C 主要使用 API 函数,而网络编程则主要使用 Winsock 提供的 API 函数。 Winsock 是 90 年代初,为了便于网络编程,由 Microsoft 联合了其它几家公司一同制 定的一套 WINDOWS 下的网络编程接口, 它是借助 C 语言的动态链接库模式提供给客户及工具 开发者的,主要由 winsock.h 头文件和动态链接库 winsock.dll 组成,目前有两个版本: Winsock1.1 和 Winsock2.0。 在 Win32 平台上,访问很多的基层网络协议,Winsock 是首选接口。

用 Visual C++6.0 编译 Windows C 程序,使用 Winsock API 函数时,首先应把 wsock32.lib 添加至它的库模块中,否刚在链接的之后,会出现“error LNK2001”错误。 添加 wsock32.lib 的详细方法是:打开工程菜单,选择更改,在跳出的 Project settings 对话框中,点击 link 选项卡,然后在对象/库模块文本框中添加 wsock32.lib。 最简单的网络编程是获得本机的主机名和 IP 地址,这个程序使用了 WSAStart()、 WSAClenaup()、gethostname()、gethostbyname()四个 winsock API 函数,这四个函数 的用途跟使用方式介绍如下: 1. WSAStartup(): 【函数原型】int PASCAL FAR WSAStartup(WORD wVersionRequired, LPWSADATA lpWSAData);【使用说明】 每一个使用 winsock 的应用程序, 都需要进行 WSAStart 函数调用, 并且只有在调用成 功以后才会使用其他的 winsock 网络操作函数。
WVersionRequired:<输入>表示欲使用的Winsock 版本,这是一个 WORD 类型的整数, 它的高位字节定义的是次版本号,低位字节定义的是主版本号。 LpWSAData:<输出>是一个指向 WSADATA 资料的指针。这个资料我们通常不使用。 返回值:调用成功返回 0;否则,返回错误信息。 2. WSAClenaup(): 【函数原型】int PASCAL FAR WSACleanup(void);【使用说明】 winsock 使用后,要读取WSACleanup 函数关闭网络设施,以便释放其占用的资源。 3.gethostname() 【函数原型】int PASCAL FAR gethostname (char FAR * name, int namelen);【使用表明】 该变量可以获得本地主机的主机名,其中: name:<输出>用于指向所获得的主机名的缓冲区的指针。 Namelen:<输入>缓冲区的大小,以字符为单位。 返回值:若无出错,返回 0;否则,返回错误代吗。4.gethostbyname() 【函数原型】struct hostent FAR * PASCAL FAR gethostbyname(const char FAR * name);【使用表明】 该变量可以从主机名中受到对应的“主机”。

该变量唯一的参数 name 就是前面调用函数 gethostname()得到的主机名。若无错误, 刚返回一个指向 hostent 结构的批针,它可以标志一个“主机”列表。 Hostent 结构定义如下:Struct hostent { char FAR * h_name; char FAR FAR ** h_aliases; short h_addrtype; char FAR FAR ** h_addr_list; }其中: h_name:<输入>主机名地址(PC)。 h_aliases:一个由主机备用名构成的空中止字符。 H_addrtype:返回地址的类别,对于 Winsock,这个域总是 PF_INET。 H_lenth:每个地址的长度(字节数),对应于 PF_INET 域必须为 4。 H_addr_list: 应该以空指针结尾的主机地址的列表, 返回的地址是以网络顺序排列的。 其中,h_addr_list[0]存放的就是本地主机的 4 个字节的 IP 地址,即: h_addr_list[0][0].h_addr_list[0][1].h_addr_list[0][2].h_addr_list[0][3] 一个简单的用消息框显示主机名和 IP 地址的源程序如下:#include<winsock.h> int WSA_return; WSADATA WSAData;HOSTENT *host_entry; char host_name[256]; char host_address[256]; int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, LPSTR lpCmdLine,int nCmdShow) { WSA_return=WSAStartup(0x0101,&WSAData); if(WSA_return==0) { gethostname(host_name,256); host_entry=gethostbyname(host_name); if(host_entry!=0) { wsprintf(host_address,"%d.%d.%d.%d", (host_entry->h_addr_list[0][0]&0x00ff), (host_entry->h_addr_list[0][1]&0x00ff), (host_entry->h_addr_list[0][2]&0x00ff), (host_entry->h_addr_list[0][3]&0x00ff)); MessageBox(NULL,host_address,host_name,MB_OK); } } WSACleanup(); return 0; }深入编程: 前面显示 IP 地址的之后,我们使用的是消息框,规范一点的编程需要使用对话框,如 何编辑一个对话框,很多书中都有介绍,编辑的对话框可参考图 5 的运行界面。
头文件 Get_IP.h 如下:BOOL APIENTRY Hostname_ipDlgPro(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam);这个程序只使用了一个对话框过程,一般把这个过程的声明放在头文件中。源程序 Get_IP.c:#include<winsock2.h> #include"Get_IP.h" #include"resource.h" //这个头文件在建立资源的之后会自动生成, //并会在插入资源时手动生成控件标识号. int WSA_return; WSADATA WSAData; HOSTENT *host_entry; char host_name[256]; char host_address[256]; int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, LPSTR lpCmdLine,int nCmdShow) { WSA_return=WSAStartup(0x0101,&WSAData); if(WSA_return==0) { gethostname(host_name,256); host_entry=gethostbyname(host_name); if(host_entry!=0) { wsprintf(host_address,"%d.%d.%d.%d", (host_entry->h_addr_list[0][0]&0x00ff), (host_entry->h_addr_list[0][1]&0x00ff), (host_entry->h_addr_list[0][2]&0x00ff), (host_entry->h_addr_list[0][3]&0x00ff)); } } WSACleanup(); DialogBox(hInstance,"DIALOG1",NULL,(DLGPROC)Hostname_ipDlgPro); return 0; } BOOL APIENTRY Hostname_ipDlgPro(HWND hDlg,UINT message, WPARAM wParam,LPARAM lParam) { switch(message) { case WM_INITDIALOG: return(TRUE);case WM_COMMAND: if(LOWORD(wParam)==IDOK) { SetDlgItemText(hDlg,IDC_EDIT1,host_name); SetDlgItemText(hDlg,IDC_EDIT2,host_address); SetDlgItemText(hDlg,IDCANCEL,"确定"); } if(LOWORD(wParam)==IDCANCEL) EndDialog(hDlg,TRUE); return(TRUE); break; } return(FALSE); }三、利用 VisualC++6.0 编译 Windows C 程序 利用 Visual C++6.0 编译 Windows C 程序通常应经过下列四个步骤:新建工程、添加代 码、 添加资源和编译链接。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-142942-1.html
已成即成事实
中国现在的教授实在无法令人尊敬