用C语言进行Windows编程入门
本文对一般教程或网上有的(如C语言语法等基础)不深入介绍,对初学者易造成疑惑误解或难以找到的内容进行较详尽的介绍。
学习C语言很久了,一直面对控制台应用程序(Win32 Console Application),没有漂亮的界面,是不是不爽呀。用C开发图形界面程序,有多种技术方案,本文希望用简单的例子,深入浅出的介绍一种方案——用C和SDK进行图形界面编程。
图形界面又叫图形用户接口(GUI = Graphical User Interface),这样的程序的窗口包含最大化、最小化、关闭按钮,也包含菜单、单选框、图像等组成。
本文主题是用C语言进行Windows编程。
一般而言,基于 Windows 的编程方式有两种。一种是使用 Windows 的 API(Application Programming Interface ,应用程序编程接口)函数,通常用 C/C++ 语言按相应的程序框架进行编程。这些程序框架往往就程序应用提供相应的文档、范例和软件开发工具包(Software Development Kit ,SDK ),所以这种编程方式有时又称为 SDK 方式。另一种是使用“封装”方式,例如Visual C++ 的MFC方式,它是将 SDK 中的绝大多数函数、 数据等按 C++“类”的形式进行封装,并提供相应的应用程序框架和编程操作,简单地说,MFC 是对 API 的封装,隐藏了许多复杂的情节。
C语言源代码文件的后缀是.c,C++语言源代码文件的后缀是.cpp。
要进行Windows编程,需要先对Windows 有一个初步认识
Windows 的 3 个主要子系统:内核(kernel),用户(user),GDI。
内核 负责操作系统的传统工作:如 内存管理,文件输入/输出 以及任务管理等。
用户 指的是用户界面,负责所有的窗口管理。
GDI 就是图形设备接口,负责在屏幕或打印机上显示文本与图形。
在 Windows 程序中,调用 Windows 函数与调用 C 语言的库函数没有什么两样。
最主要的区别就是 C 语言库函数的机器代码会直接链接到你的程序代码中去,而 Windows 函数则是放到你的程序之外的 DLL 里。
关于这些,作为初学者可以大体了解之,不必深究,随着深入学习实线,经过一段时间,才会有清晰的认识。
下面开发实验,先使用Dev-C++开发环境,然后在再介绍VC++开发环境。
所谓开发环境,也就是安装编译器或者 IDE(集成开发环境)。Windows 下的C语言 IDE 众多,本人使用的是 Dev C++5.11。Dev C++ 是一款免费开源的 C/C++ IDE,内嵌 GCC 编译器(Linux GCC 编译器的 Windows 移植版),是 NOI、NOIP 等比赛的指定工具。Dev C++ 的优点是体积小(只有几十兆)、安装卸载方便、学习成本低,适合于初学者使用,缺点是调试功能弱,功能并不完善,不易用来开发商业级的软件。
VC++开发环境,讲了两种VC6.0(VC++6.0)和Microsoft Visual C++ 2010 Express。
微软公司的VC6.0(VC++6.0)完整版在Win7、Win10中存在兼容问题,故使用VC++ 6.0第三方修改版本,在网上也容易找到。微软新版 Visual Studio(简称 VS,包含VC++),如VS2010、VS2015等,目前最新版式VS2019,功能越来越全面,但越来越庞大。全国计算机等级考试组委会决定,2018年全国计算机二级 C、C++两个科目的应用软件由 Visual C++6.0 改为 Visual C++ 2010 学习版(即 Visual C++ 2010 Express)。综合看来,C语言初学者,可以考虑VC++6.0第三方修改的版本,或者使用Microsoft Visual C++ 2010 Express。
为了便于学习者,我给出开发工具(C_C++实验学习环境合集)的下载地址:C及C++实验学习环境合集.rar_c++实验环境-C++工具类资源-CSDN下载
所提的三种工具,对每一种都先演示控制台程序,再演示带界面的Windows程序。
不带图形用户界面(Graphical User Interface,简称 GUI,又称图形用户接口)的程序是控制台程序(Console Application)。带界面的Windows程序(Windows Application),也称为GUI程序(GUI Application)。
Dev-C++开发使用
下面简要介绍一下Dev C++的安装:
下载完成后,就像安装其他软件一样,点击安装包,出现如下图,语言先默认选择English,不要改变(安装完成后会选择中文简体的选项设置)。点ok!
接下来的安装界面点“I agree”按钮,之后,一路默认点击“next”按钮,直至“finish”,此时出现:
此时你就可以选择 中文简体。
控制台程序以 main() 为入口函数,Windows程序以 WinMain() 为入口函数,动态链接库(DLL)以 DllMain() 为入口函数(请查看 动态链接库DLL教程),不同的入口函数决定了不同类型的程序。
从main 到WinMain
学习编程一般从简单的例子入手,例如一个 C 程序常有下列简单的框架代码:
#include <stdio.h>
int main()
{
printf("Hello World!\n"); /*输出*/
return 0; /*指定返回值*/
}
该程序已包括 C 程序中最常用的 #include 指令、必须的程序入口 main 函数、库函数 printf 调用和 return 语句。由于此程序是在早期的DOS(Disk Operating System ,磁盘操作系统)环境的字符模型下运行的,因而 printf 函数所输出的都是字符流,也就是说,它在屏幕上输出一行文本“ Hello World! ”。基于 Windows的上述 C 程序代码框架肯定是有所不同的。等价的 Windows 程序可以写成:
#include <windows.h>
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int nCmdShow)
{
MessageBox (NULL, TEXT("Hello, World!"), TEXT("Hello"), 0) ;
return 0 ;
}
使用C和Win32 SDK开发Windows图形界面程序,运行时会显示黑乎乎的CMD窗口。原因是控制台(CONSOLE)程序,必然出现cmd窗口。如何不显示CMD窗口后面再说。
该程序的 #include<windows.h> 就是像 C 语言的 #include<stdio.h> 一样重要的头文件。这些头文件定义了Windows的所有数据类型、函数原型、数据结构和符号常量,也就是说,所有的Windows API都在这些头文件中声明。
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow),就像 C 语言的 int main(void) 一样,都是程序的入口。C 程序的入口是 main,Windows 程序的入口是 WinMain。WinMain() 函数的原型为:
int WINAPI WinMain(
HINSTANCE hInstance, // 当前窗口句柄
HINSTANCE hPrevInstance, // 前一个窗口句柄,Win32下为NULL(Win16留下的废物,目前已弃用)
LPSTR lpCmdLine, // 命令行参数
int nCmdShow // 窗口显示方式
);
WinMain的第一个参数叫做"实例句柄"(Instance Handle)。句柄就是一个数值,用它来标识某些东西。句柄是一个 4byte 的数值,可用来标识 窗口,按钮,图标,滚动条,输出设备,控件或者文件等等。
第二个参数通常是 NULL。
第三个参数是用来运行程序的命令行(CommandLine)。
第四个参数是用来指明程序最初如何显示。(最大化到全屏,正常显示,最小化到任务栏)。
MessageBox函数:
函数原型:int WINAPI MessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType);
第一个参数通常是一个窗口句柄。
第二个参数是在信息框里出现的文本字符串。
第三个参数是标题栏上显示的文本字符串。
第四个参数是以前缀MB_开头的一些常量组合。用以对话框中的按钮,图标等等。
在输入代码时,一个好的习惯是创建了一个新程序后,在还未输入代码之前先将该程序保存到硬盘某个目录下,然后在程序的编辑过程中经常性地保存程序,以防止机器突然断电或者死机。要保存程序,只需从主菜单选择“File—〉Save”,此时会将程序重新保存到之前指定的目录下,如F:\temp ;如果想将程序保存到其他的硬盘路径下,可以选择“File—〉Save As…”
【 插入一个话题,跳过这部分不影响理解本文:在Dev-C++上使用自己写头文件
1.新建--源代码。注意:删去不必要的函数尤其是主函数,删去多余的定义,避免出现重复定义。数据类型用typedef定义。
2.保存:在保存类型的下拉列表中选择Header Files
3.写入函数,定义等
4.别忘了保存
5.引用:例:#include<路径\文件名.后缀>
#include<C:\Users\lair\Desktop\hello.h>
Dev C++安装第三方库(.h文件、头文件)
注意兼容的才能使用。
初学者容易被这些坑搞得心灰意冷。
打开Dev-C++,点击工具栏,工具栏选择编译选项找到目录,C++包含文件,在C++包含文件中可以找到头文件添加的位置
第三步 :电脑中找到这个位置,把第三方库(.h文件、头文件)复制粘贴过去:
注意:不同系列编辑器(如TC++、DEV-C++、Visual C++)的头文件(.h文件、库)一般不兼容,使用时要注意。】
如何不显示CMD窗口呢?参见下图:
如此,可由Dev-C++自动生成一些代码——Windows图形界面框架代码 ,如下图:
你可以将代码区的内容替换为:
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
PSTR szCmdLine,
int iCmdShow
){
static TCHAR szClassName[] = TEXT("HelloWin"); //窗口类名
HWND hwnd; //窗口句柄
MSG msg; //消息
WNDCLASS wndclass; //窗口类
/**********第①步:注册窗口类**********/
//为窗口类的各个字段赋值
wndclass.style = CS_HREDRAW | CS_VREDRAW; //窗口风格
wndclass.lpfnWndProc = WndProc; //窗口过程
wndclass.cbClsExtra = 0; //暂时不需要理解
wndclass.cbWndExtra = 0; //暂时不需要理解
wndclass.hInstance = hInstance; //当前窗口句柄
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION); //窗口图标
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); //鼠标样式
wndclass.hbrBackground= (HBRUSH) GetStockObject (WHITE_BRUSH); //窗口背景画刷
wndclass.lpszMenuName = NULL ; //窗口菜单
wndclass.lpszClassName= szClassName; //窗口类名
//注册窗口
RegisterClass(&wndclass);
/*****第②步:创建窗口(并让窗口显示出来)*****/
hwnd = CreateWindow(
szClassName, //窗口类的名字
TEXT("Welcome"), //窗口标题(出现在标题栏)
WS_OVERLAPPEDWINDOW, //窗口风格
CW_USEDEFAULT, //初始化时x轴的位置
CW_USEDEFAULT, //初始化时y轴的位置
500, //窗口宽度
300, //窗口高度
NULL, //父窗口句柄
NULL, //窗口菜单句柄
hInstance, //当前窗口的句柄
NULL //不使用该值
);
//显示窗口
ShowWindow (hwnd, iCmdShow);
//更新(绘制)窗口
UpdateWindow (hwnd);
/**********第③步:消息循环**********/
while( GetMessage(&msg, NULL, 0, 0) ){
TranslateMessage(&msg); //翻译消息
DispatchMessage (&msg); //分派消息
}
return msg.wParam;
}
/**********第④步:窗口过程**********/
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){
HDC hdc; //设备环境句柄
PAINTSTRUCT ps;
RECT rect;
switch (message){
//窗口绘制消息
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ;
GetClientRect (hwnd, &rect) ;
DrawText(
hdc,
TEXT("你好,Windows世界"),
-1,
&rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER
);
EndPaint (hwnd, &ps) ;
return 0 ;
//窗口销毁消息
case WM_DESTROY:
PostQuitMessage(0) ;
return 0 ;
}
return DefWindowProc(hwnd, message, wParam, lParam) ;
}
编译运行结果如下:
这是一个简单Windows程序,Dev C++同时自动生成了其它几个文件,参见下图:
为了便于管理使用,建议为每个用Dev-C++建立C项目(Project:工程,项目)建立一个文件夹(目录)。
这是一个用Dev-C++的C语言开发最简单的Windows应用程序,有点吓人,显然不像控制台应用程序那么简单,几行代码搞定。这显然不是短时间就学透头,本文的目的是说明C语言是可以开发Windows应用程序的。
上面例子代码,是一个Windows程序的基本框架,从中可以了Windows应用程序文件主要包括如下部分:
第①部分、注册窗口类
第②部分、根据窗口类来创建窗口
第③部分、进入无休止的消息循环
第④部分、编写窗口过程
大部分代码一样,直接拿来当作代码模板用,主要不同是在第④部分。
下面是一个像样点的程序,同时作为上述文字的印证:
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HINSTANCE hInst; //HINSTANCE 是“句柄型”数据类型。---------
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
PSTR szCmdLine,
int iCmdShow
){
static TCHAR szClassName[] = TEXT("Win32Demo"); //窗口类名
HWND hwnd; //窗口句柄
MSG msg; //消息
WNDCLASS wndclass; //窗口类
hInst = hInstance; //------------
/**********第①步:注册窗口类**********/
//为窗口类的各个字段赋值
wndclass.style = CS_HREDRAW | CS_VREDRAW; //窗口风格
wndclass.lpfnWndProc = WndProc; //窗口过程
wndclass.cbClsExtra = 0; //暂时不需要理解
wndclass.cbWndExtra = 0; //暂时不需要理解
wndclass.hInstance = hInstance; //当前窗口句柄
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION); //窗口图标
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); //鼠标样式
wndclass.hbrBackground= (HBRUSH) GetStockObject (WHITE_BRUSH);; //窗口背景画刷(白色)
wndclass.lpszMenuName = NULL ; //窗口菜单
wndclass.lpszClassName= szClassName; //窗口类名
//注册窗口
RegisterClass(&wndclass);
/*****第②步:创建窗口(并让窗口显示出来)*****/
hwnd = CreateWindow(
szClassName, //窗口名字
TEXT("Welcome"), //窗口标题(出现在标题栏)
WS_OVERLAPPEDWINDOW, //窗口风格
CW_USEDEFAULT, //初始化时x轴的位置
CW_USEDEFAULT, //初始化时y轴的位置
500, //窗口宽度
300, //窗口高度
NULL, //父窗口句柄
NULL, //窗口菜单句柄
hInstance, //当前窗口的句柄
NULL //不使用该值
);
//显示窗口
ShowWindow (hwnd, iCmdShow);
//更新(绘制)窗口
UpdateWindow (hwnd);
/**********第③步:消息循环**********/
while( GetMessage(&msg, NULL, 0, 0) ){
TranslateMessage(&msg); //翻译消息
DispatchMessage (&msg); //分派消息
}
return msg.wParam;
}
/**********第④步:消息循环**********/
//------------
LRESULT CALLBACK WndProc(
HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam
){
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
static HFONT hFont;
static HWND hBtn;
static HWND hStatic;
switch (message){
case WM_CREATE:
//创建逻辑字体
hFont = CreateFont(
-15/*高度*/, -7.5/*宽度*/, 0, 0, 400 /*一般这个值设为400*/,
FALSE/*不带斜体*/, FALSE/*不带下划线*/, FALSE/*不带删除线*/,
DEFAULT_CHARSET, //使用默认字符集
OUT_CHARACTER_PRECIS, CLIP_CHARACTER_PRECIS, //这行参数不用管
DEFAULT_QUALITY, //默认输出质量
FF_DONTCARE, //不指定字体族*/
TEXT("微软雅黑") //字体名
);
//创建静态文本控件
hStatic = CreateWindow(
TEXT("static"), //静态文本框的类名
TEXT("你好,欢迎来到C语言中文网"), //控件的文本
WS_CHILD /*子窗口*/ | WS_VISIBLE /*创建时显示*/ | WS_BORDER /*带边框*/,
30 /*X坐标*/, 20/*Y坐标*/, 150/*宽度*/, 80/*高度*/, hWnd/*父窗口句柄*/,
(HMENU)1, //为控件指定一个唯一标识符
hInst, //当前实例句柄
NULL
);
//创建按钮控件
hBtn = CreateWindow(
TEXT("button"), //按钮控件的类名
TEXT("点击这里试试"),
WS_CHILD | WS_VISIBLE | WS_BORDER | BS_FLAT/*扁平样式*/,
30 /*X坐标*/, 110 /*Y坐标*/, 150 /*宽度*/, 50/*高度*/,
hWnd, (HMENU)2 /*控件唯一标识符*/, hInst, NULL
);
SendMessage(hStatic,WM_SETFONT,(WPARAM)hFont,NULL);//设置文本框字体
SendMessage(hBtn, WM_SETFONT, (WPARAM)hFont, NULL);//设置按钮字体
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch (wmId){
case 2: //按下按钮
//更改文本框的内容
SetWindowText(hStatic, TEXT("你点击了下面的按钮"));
break;
default:
//不处理的消息一定要交给 DefWindowProc 处理。
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: 在此添加任意绘图代码...
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
//请做好善后工作
DeleteObject(hFont);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
运行结果如下:
现在介绍VC++6.0的使用
先简要介绍VC6.0的使用, 微软原版的 VC6.0 已经不容易找到,网上提供的都是经过第三方修改的版本,删除了一些使用不到的功能,增强了和win10的兼容性。
打开VC6.0,按下图所示操作新建工程(Project:工程,项目):
提示:选择“An empty project”项将生成一个空的工程,工程内不包括任何东西。选择“A simple application”项将生成包含一个空的main函数和一个空的头文件的工程。选“A "Hello World!" application”项与选“A simple application”项没有什么本质的区别,只是包含有显示出“Hello World!”字符串的输出语句。选择“An application that supports MFC”项的话,可以利用VC6.0所提供的类库来进行编程。
点击“Finish”按钮完成工程的创建。再按下图所示建立C源文件:
提示:微软的VC++(Visual C++)是在C语言的基础上进行的扩展,C++已经包含了C语言的所有内容,所以大部分的 IDE 只有创建C++文件的选项,没有创建C语言文件的选项。但是这并不影响使用,我们在填写源文件名称时把后缀改为.c即可,编译器会根据源文件的后缀来判断代码的种类。
再单击工具栏上的保存 按钮,在工作空间中可以看到刚才创建的工程和源文件,如下图所示:
现在可以按下图所示编译并运行代码:
注意:编译生成的 .exe 文件在工程(Project)目录下的Debug文件夹内。打开看到有一个Debug文件夹,进入可以看到 cDemo.exe。除了 hello.c,还会看到很多其他文件,它们是VC6.0自动创建的,用来支持当前工程,如下图:
其中,dsp文件:DeveloperStudio Project,是VC6.0的工程文件,用来保存当前工程的信息,例如编译参数、包含的源文件等,不建议手动改动。当需要打开一个已存在的工程时,打开该文件即可。
上面介绍的是用VC++6.0建立Win32 Console Application,即win32控制台应用程序,没有漂亮的界面,运行时会显示黑乎乎的CMD窗口。Win32 Application(Win32应用程序) 是普通的常见的窗口应用程序,是所谓的GUI(Graphics User Interface图形用户接口),我们可以通过鼠标点击来完成控制。两者有明显的不同:
控制台应用程序:
入口函数为main,一般写C和C++计算类代码常用,如计算水仙花数、冒泡排序等一类程序。程序运行结果以命令行窗口显示。
window应用程序:
入口函数为WinMain,一般用于写桌面应用程序,强大之处在于能够作出用户操作界面,并与操作系统配合捕获并响应用户的各种操作,如鼠标移动、按钮形状及点击等基本上要用win32 api自己写代码实现,比较繁杂。
顺便提及,MFC(微软基础类库)应用程序,也有界面,饭界面里的控件不需要自己去实现了,常用的控件都已经在MFC库内写好,直接拖动即可。
只强调实用与开发效率,用MFC;强调用户体验与软件细节及灵活性,使用WIN32。MFC可以实现的,WIN32都可以实现,反之不可。
VC++ 6.0可创建的工程类型还有一些,说实话我也知道的不多,就不提了。
为了切合本文主题,下面介绍 用VC++ 6.0建立Win32 Application(Win32应用程序)。
首先创建项目,选择File->New,出现如下对话框,并参见下图设置:
添加C源文件,选择File->New,出现如下对话框,并参见下图设置
输入如下代码(这段代码在本文的前面已出现过):
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HINSTANCE hInst; //HINSTANCE 是“句柄型”数据类型。---------
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
PSTR szCmdLine,
int iCmdShow
){
static TCHAR szClassName[] = TEXT("Win32Demo"); //窗口类名
HWND hwnd; //窗口句柄
MSG msg; //消息
WNDCLASS wndclass; //窗口类
hInst = hInstance; //------------
/**********第①步:注册窗口类**********/
//为窗口类的各个字段赋值
wndclass.style = CS_HREDRAW | CS_VREDRAW; //窗口风格
wndclass.lpfnWndProc = WndProc; //窗口过程
wndclass.cbClsExtra = 0; //暂时不需要理解
wndclass.cbWndExtra = 0; //暂时不需要理解
wndclass.hInstance = hInstance; //当前窗口句柄
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION); //窗口图标
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); //鼠标样式
wndclass.hbrBackground= (HBRUSH) GetStockObject (WHITE_BRUSH);; //窗口背景画刷(白色)
wndclass.lpszMenuName = NULL ; //窗口菜单
wndclass.lpszClassName= szClassName; //窗口类名
//注册窗口
RegisterClass(&wndclass);
/*****第②步:创建窗口(并让窗口显示出来)*****/
hwnd = CreateWindow(
szClassName, //窗口名字
TEXT("Welcome"), //窗口标题(出现在标题栏)
WS_OVERLAPPEDWINDOW, //窗口风格
CW_USEDEFAULT, //初始化时x轴的位置
CW_USEDEFAULT, //初始化时y轴的位置
500, //窗口宽度
300, //窗口高度
NULL, //父窗口句柄
NULL, //窗口菜单句柄
hInstance, //当前窗口的句柄
NULL //不使用该值
);
//显示窗口
ShowWindow (hwnd, iCmdShow);
//更新(绘制)窗口
UpdateWindow (hwnd);
/**********第③步:消息循环**********/
while( GetMessage(&msg, NULL, 0, 0) ){
TranslateMessage(&msg); //翻译消息
DispatchMessage (&msg); //分派消息
}
return msg.wParam;
}
/**********第④步:消息循环**********/
//------------
LRESULT CALLBACK WndProc(
HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam
){
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
static HFONT hFont;
static HWND hBtn;
static HWND hStatic;
switch (message){
case WM_CREATE:
//创建逻辑字体
hFont = CreateFont(
-15/*高度*/, -7.5/*宽度*/, 0, 0, 400 /*一般这个值设为400*/,
FALSE/*不带斜体*/, FALSE/*不带下划线*/, FALSE/*不带删除线*/,
DEFAULT_CHARSET, //使用默认字符集
OUT_CHARACTER_PRECIS, CLIP_CHARACTER_PRECIS, //这行参数不用管
DEFAULT_QUALITY, //默认输出质量
FF_DONTCARE, //不指定字体族*/
TEXT("微软雅黑") //字体名
);
//创建静态文本控件
hStatic = CreateWindow(
TEXT("static"), //静态文本框的类名
TEXT("你好,欢迎来到C语言中文网"), //控件的文本
WS_CHILD /*子窗口*/ | WS_VISIBLE /*创建时显示*/ | WS_BORDER /*带边框*/,
30 /*X坐标*/, 20/*Y坐标*/, 150/*宽度*/, 80/*高度*/, hWnd/*父窗口句柄*/,
(HMENU)1, //为控件指定一个唯一标识符
hInst, //当前实例句柄
NULL
);
//创建按钮控件
hBtn = CreateWindow(
TEXT("button"), //按钮控件的类名
TEXT("点击这里试试"),
WS_CHILD | WS_VISIBLE | WS_BORDER | BS_FLAT/*扁平样式*/,
30 /*X坐标*/, 110 /*Y坐标*/, 150 /*宽度*/, 50/*高度*/,
hWnd, (HMENU)2 /*控件唯一标识符*/, hInst, NULL
);
SendMessage(hStatic,WM_SETFONT,(WPARAM)hFont,NULL);//设置文本框字体
SendMessage(hBtn, WM_SETFONT, (WPARAM)hFont, NULL);//设置按钮字体
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch (wmId){
case 2: //按下按钮
//更改文本框的内容
SetWindowText(hStatic, TEXT("你点击了下面的按钮"));
break;
default:
//不处理的消息一定要交给 DefWindowProc 处理。
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: 在此添加任意绘图代码...
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
//请做好善后工作
DeleteObject(hFont);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
注意,这里是用VC++ 6.0的C语言进行Windows编程, VC++ 6.0功能很多,如可以用C++和MFC(微软基础类库)进行Windows编程,并且可创建的工程类型很多,为符合本文主题未提及。
Microsoft Visual C++ 2010 Express的使用
打开 Microsoft Visual C++ 2010 Express,在菜单栏中选择“文件 --> 新建 --> 项目,参见下图:
在“新建项目”对话框中:选择“Win32控制台应用程序”,填写好项目名称(如cDemo),选择好存储路径,点击“确定”按钮
点击“确定”按钮后会弹“欢迎使用 Win32 应用程序向导”对话框
点击下一步”按钮,弹出新的“应用程序设置”对话框
先取消“预编译头”,再勾选“空项目”,然后点击“完成”按钮
现在,就可以添加源文件参见下图:
在“源文件”处右击鼠标,在弹出菜单中选择“添加 -> 新建项”出现“添加新项”对话框
在“代码”分类中选择C++文件(.cpp),填写文件名(注意文件名后缀改为.c),点击“添加”按钮就添加了一个新的源文件
输入如下代码
#include <stdio.h>
#include <stdlib.h>
int main()
{
puts("你好!世界");
system("pause"); //此句的作用就是让程序暂停一下
return 0;
}
编译运行,参见下图:
VC++2010开发的用应用程所在文件夹(目录)情况,如下图所示:
其中:
vcxproj是Visual C++ 2010(VC2010)的工程(Project:工程,项目)文件的后缀。 .vcxproj文件是自动生成生成的工程文件, 它包含生成该文件的 Visual C++ 的版本信息,以及有关使用应用程序向导选择的平台、配置和项目功能的信息。 对于工程来说,是非常重要的。这个文件在转移工程时,不要删除。我们打开别人的项目,一些设置已经保存于此,如果只是拷贝代码文件,这些信息就不见了,就可能导致工程无法正常打开编译运行。
sln是解决方案配置(solution)文件的后缀,Visual Studio开发套装进入.net时代后,使用解决方案文件(后缀为sln的文件)表示一个项目组,他通常包含一个项目中所有的工程文件信息。
打开已存在的VC工程时,可以打开vcxproj文件或sln文件。打开sln文件是可以启动工程的,那是因为sln文件有工程文件的入口,sln是以解决方案的方式启动,打开vcxproj文件,则是以工程的名义启动的。
顺便说明:关于MS VC++的工程文件的后缀
vc6的工程文件是.dsp
vc2002-2008工程文件是vcproj
上面介绍的是用VC2010建立Win32 Console Application,即win32控制台应用程序。
下面简要介绍用VC2010 建立Win32 Application(Win32应用程序):
在菜单栏中选择“文件 --> 新建 --> 项目
在“新建项目”对话框中:选择“Win32项目”,填写好项目名称(如winAppDemo),选择好存储路径,点击“确定”按钮
点击“确定”按钮后会弹“欢迎使用 Win32 应用程序向导”对话框
点击下一步”按钮,弹出新的“应用程序设置”对话框
勾选“空项目”,然后点击“完成”按钮
现在,就可以添加源文件
在“源文件”处右击鼠标,在弹出菜单中选择“添加 -> 新建项”出现“添加新项”对话框
在“代码”分类中选择C++文件(.cpp),填写文件名(注意文件名后缀改为.c),点击“添加”按钮就添加了一个新的源文件
将前面“(这段代码在本文的前面已出现过)”部分下的代码输入,编译运行,参见下图:
特别说明,所附代码肯定运行通过。断断续续写了几天,就到这儿吧。