用C语言进行Windows编程入门

用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++实验学习环境合集)的下载地址:https://download.csdn.net/download/cnds123/11609117

所提的三种工具,对每一种都先演示控制台程序,再演示带界面的Windows程序。

不带图形用户界面(Graphical User Interface,简称 GUI,又称图形用户接口)的程序是控制台程序(Console Application)。带界面的Windows程序(Windows Application),也称为GUI程序(GUI Application)。

 

Dev-C++开发使用

下面简要介绍一下Dev C++的安装:

下载完成后,就像安装其他软件一样,点击安装包,出现如下图,语言先默认选择English,不要改变(安装完成后会选择中文简体的选项设置)。点ok!

用C语言进行Windows编程入门_第1张图片

接下来的安装界面点“I agree”按钮,之后,一路默认点击“next”按钮,直至“finish”,此时出现:

用C语言进行Windows编程入门_第2张图片

此时你就可以选择 中文简体。

 

控制台程序以 main() 为入口函数,Windows程序以 WinMain() 为入口函数,动态链接库(DLL)以 DllMain() 为入口函数(请查看 动态链接库DLL教程),不同的入口函数决定了不同类型的程序。

 

从main  到WinMain

    学习编程一般从简单的例子入手,例如一个 C 程序常有下列简单的框架代码:

    #include

    int main()

    {

      printf("Hello World!\n");                  /*输出*/

      return 0;                               /*指定返回值*/

      }

用C语言进行Windows编程入门_第3张图片

该程序已包括  C 程序中最常用的 #include  指令、必须的程序入口  main 函数、库函数 printf  调用和 return 语句。由于此程序是在早期的DOS(Disk Operating System ,磁盘操作系统)环境的字符模型下运行的,因而 printf 函数所输出的都是字符流,也就是说,它在屏幕上输出一行文本“ Hello World!  ”。基于 Windows的上述 C 程序代码框架肯定是有所不同的。等价的 Windows  程序可以写成:

 

       #include

       int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int nCmdShow)

       {

         MessageBox (NULL, TEXT("Hello, World!"), TEXT("Hello"), 0) ;

         return 0 ;

       } 

 

用C语言进行Windows编程入门_第4张图片

使用C和Win32 SDK开发Windows图形界面程序,运行时会显示黑乎乎的CMD窗口。原因是控制台(CONSOLE)程序,必然出现cmd窗口。如何不显示CMD窗口后面再说。

 

该程序的 #include 就是像 C 语言的 #include 一样重要的头文件。这些头文件定义了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

 

Dev C++安装第三方库(.h文件、头文件)

 

注意兼容的才能使用。

初学者容易被这些坑搞得心灰意冷。

 

打开Dev-C++,点击工具栏,工具栏选择编译选项找到目录,C++包含文件,在C++包含文件中可以找到头文件添加的位置

用C语言进行Windows编程入门_第5张图片

 

第三步  :电脑中找到这个位置,把第三方库(.h文件、头文件)复制粘贴过去:

 

 

注意:不同系列编辑器(如TC++、DEV-C++、Visual C++)的头文件(.h文件、库)一般不兼容,使用时要注意。】

 

如何不显示CMD窗口呢?参见下图:

用C语言进行Windows编程入门_第6张图片

如此,可由Dev-C++自动生成一些代码——Windows图形界面框架代码 ,如下图:

用C语言进行Windows编程入门_第7张图片

你可以将代码区的内容替换为:

#include

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) ;
}

编译运行结果如下:

用C语言进行Windows编程入门_第8张图片

这是一个简单Windows程序,Dev C++同时自动生成了其它几个文件,参见下图:

用C语言进行Windows编程入门_第9张图片

为了便于管理使用,建议为每个用Dev-C++建立C项目(Project:工程,项目)建立一个文件夹(目录)。

这是一个用Dev-C++的C语言开发最简单的Windows应用程序,有点吓人,显然不像控制台应用程序那么简单,几行代码搞定。这显然不是短时间就学透头,本文的目的是说明C语言是可以开发Windows应用程序的。

上面例子代码,是一个Windows程序的基本框架,从中可以了Windows应用程序文件主要包括如下部分:

第①部分、注册窗口类

第②部分、根据窗口类来创建窗口

第③部分、进入无休止的消息循环

第④部分、编写窗口过程

大部分代码一样,直接拿来当作代码模板用,主要不同是在第④部分。

下面是一个像样点的程序,同时作为上述文字的印证:

#include

 

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;

}

运行结果如下:

用C语言进行Windows编程入门_第10张图片

 

 

现在介绍VC++6.0的使用

先简要介绍VC6.0的使用, 微软原版的 VC6.0 已经不容易找到,网上提供的都是经过第三方修改的版本,删除了一些使用不到的功能,增强了和win10的兼容性。

打开VC6.0,按下图所示操作新建工程(Project:工程,项目)

用C语言进行Windows编程入门_第11张图片

提示:选择“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源文件:

用C语言进行Windows编程入门_第12张图片

提示:微软的VC++(Visual C++)是在C语言的基础上进行的扩展,C++已经包含了C语言的所有内容,所以大部分的 IDE 只有创建C++文件的选项,没有创建C语言文件的选项。但是这并不影响使用,我们在填写源文件名称时把后缀改为.c即可,编译器会根据源文件的后缀来判断代码的种类。

再单击工具栏上的保存 按钮,在工作空间中可以看到刚才创建的工程和源文件,如下图所示:

用C语言进行Windows编程入门_第13张图片

 

现在可以按下图所示编译并运行代码:

用C语言进行Windows编程入门_第14张图片

 

注意:编译生成的 .exe 文件在工程(Project)目录下的Debug文件夹内。打开看到有一个Debug文件夹,进入可以看到 cDemo.exe。除了 hello.c,还会看到很多其他文件,它们是VC6.0自动创建的,用来支持当前工程,如下图:

用C语言进行Windows编程入门_第15张图片

 

其中,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语言进行Windows编程入门_第16张图片

 

添加C源文件,选择File->New,出现如下对话框,并参见下图设置

用C语言进行Windows编程入门_第17张图片

 

输入如下代码(这段代码在本文的前面已出现过):

#include

 

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;

}

 

 

用C语言进行Windows编程入门_第18张图片

 

 

注意,这里是用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语言进行Windows编程入门_第19张图片

 

现在,就可以添加源文件参见下图:

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

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

用C语言进行Windows编程入门_第20张图片

输入如下代码

#include

#include

int main()

{

    puts("你好!世界");

system("pause");  //此句的作用就是让程序暂停一下

    return 0;

}

编译运行,参见下图:

用C语言进行Windows编程入门_第21张图片

 

 

VC++2010开发的用应用程所在文件夹(目录)情况,如下图所示:

用C语言进行Windows编程入门_第22张图片

其中:

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),选择好存储路径,点击“确定”按钮

用C语言进行Windows编程入门_第23张图片

 

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

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

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

用C语言进行Windows编程入门_第24张图片

 

现在,就可以添加源文件

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

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

用C语言进行Windows编程入门_第25张图片

 

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

用C语言进行Windows编程入门_第26张图片

 

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

 

 

 

 

 

 

你可能感兴趣的:(软件开发)