用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之后是vcxproj

上面介绍的是用VC2010建立Win32 Console Application,即win32控制台应用程序。

下面简要介绍用VC2010 建立Win32 Application(Win32应用程序):

在菜单栏中选择“文件 --> 新建 --> 项目

在“新建项目”对话框中:选择“Win32项目”,填写好项目名称(如winAppDemo),选择好存储路径,点击“确定”按钮

点击“确定”按钮后会弹“欢迎使用 Win32 应用程序向导”对话框

点击下一步”按钮,弹出新的“应用程序设置”对话框

勾选“空项目”,然后点击“完成”按钮

现在,就可以添加源文件

在“源文件”处右击鼠标,在弹出菜单中选择“添加 -> 新建项”出现“添加新项”对话框

在“代码”分类中选择C++文件(.cpp),填写文件名(注意文件名后缀改为.c),点击“添加”按钮就添加了一个新的源文件

将前面“(这段代码在本文的前面已出现过)”部分下的代码输入,编译运行,参见下图:

特别说明,所附代码肯定运行通过。断断续续写了几天,就到这儿吧。

用C语言进行Windows编程入门相关推荐

  1. windows程序设计 c语言,【教程】基于C语言的Windows编程入门

    (三) 窗口的创建与消息处理 原来那个程序是不是感觉有点简单?这里我们要制作一个复杂一点的Windows程序 - 显示一个空白窗口. 出于稳定性考量,Visual C++编译器中int.long等基本 ...

  2. Windows编程入门程序详解

    Windows编程入门程序详解 1.     程序 /************************************************************************* ...

  3. windows编程【c语言版】,C语言项目windows编程.docx

    C语言项目(windows编程)第1页 --------------------------------作者:--------------------------------日期:第2页 第一课. 1 ...

  4. 适合自学单片机c语言教材,单片机编程入门看什么书 盘点单片机初学者适合看的书...

    本篇文章盘点:单片机编程入门看什么书.其实学习单片机重点就是C语言,其次实践重要,学习单片机不光要看书,建议初学者多多实践,自己做一些尝试性的开发.话不多说,下面就来盘点,初学者单片机编程入门适合看什 ...

  5. C/C++教程 第九章 —— windows编程入门

    文章目录 前言 一.本章说明 二.什么是windows编程 三.从零写一个windows窗口 1.建立窗口的过程 2.建立项目 3.WinMain函数 4.注册窗口类 5.创建窗口 6.消息循环 7. ...

  6. 圣诞礼物c语言代码大全,windows编程入门二:圣诞节的礼物——从“屏幕飘雪”程序说起...

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 这段是定义全局变量和写一个窗口.大家注意ShowWindow(hwnd,SW_SHOWMINIMIZED),这说明当创建时是最小化的窗口. #includ ...

  7. 圣诞节程序c语言,windows编程入门二:圣诞节的礼物——从“屏幕飘雪”程序说起...

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 这段是定义全局变量和写一个窗口.大家注意ShowWindow(hwnd,SW_SHOWMINIMIZED),这说明当创建时是最小化的窗口. #includ ...

  8. c语言图形化编程入门_C语言C++新手入门,VS2013编程器安装教程

    C语言是面向过程的,而C++是面向对象的 C和C++的区别: C是一个结构化语言,它的重点在于算法和数据结构.C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到输出(或实现 ...

  9. C语言简单游戏编程入门之中国象棋

    运行截图 实现思路 老套路,二维数组存储棋盘,宏定义各种棋子,每次棋子的移动实质为二维数组的赋值. 重点是判断棋子是否可移动到目标位置,移动有两种可能,一是单纯移动,二是吃子移动.主要飞将的特殊规则. ...

最新文章

  1. 985 211 PHP,985 211是什么意思
  2. 洛谷 P1636 Einstein学画画
  3. Python高级特性(切片,迭代,列表生成式,生成器,迭代器)
  4. win10+vs2017+caffe(crnn)编译过程记录(验证成功)
  5. 打不开开php_(13)10个开源免费的PHP博客CMS
  6. mysql性能结构优化原理_MySQL性能管理及架构设计(二):数据库结构优化、高可用架构设计、数据库索引优化...
  7. java 数组冒泡排序、转置(降序)
  8. .NET Core快速入门教程 4、使用VS Code开发.NET Core控制台应用程序
  9. C++多态讲解以及常见面试题
  10. ----uni-app之解决HBuilderX安装less成功运行时提示未安装----
  11. 第一:MySQL安装和配置(超详细)
  12. 安装pattern出错mysql_config not found
  13. 如何判断一个类是无用的类?
  14. 阿里云ODPS升级为一体化大数据平台 满足用户多元化数据计算需求
  15. iOS在UIButton中换行
  16. java程序的执行流程
  17. PHP 生成随机号段的电话号码,PHP手机号正则(多号段)
  18. latex数字引用参考文献
  19. 微信小程序之微信登入
  20. Intel Quiet System Technology (QST) Support In ...

热门文章

  1. 中兴OLT ZXA10 C200 V1.1.3P2T6固件
  2. 上半年收入超耐克中国、大于两个李宁,安踏领跑背后的韧性
  3. protocol method: #method<connection.close>(reply-code=530, reply-text=NOTALLOWED - vhost / not found
  4. 洛谷 P1875 佳佳的魔法药水(最短路) 题解
  5. C++友元和运算符重载
  6. XiaoHu日志 7/29~8/9
  7. 力扣周赛310场题解
  8. 椭圆曲线:超级完整的椭圆曲线学习记录
  9. python离线翻译包下载_Python翻译
  10. 一键卸载,跟流氓软件说拜拜~