用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!

接下來的安裝界面點“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都在這些頭文件中聲明。

nt 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),點擊“添加”按鈕就添加了一個新的源文件

 

將前面“(這段代碼在本文的前面已出現過)”部分下的代碼輸入,編譯運行,參見下圖:

 

特別說明,所附代碼肯定運行通過。斷斷續續寫了幾天,就到這兒吧。

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章