用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建立Win32 Console Application,即win32控制檯應用程序。
下面簡要介紹用VC2010 建立Win32 Application(Win32應用程序):
在菜單欄中選擇“文件 --> 新建 --> 項目
在“新建項目”對話框中:選擇“Win32項目”,填寫好項目名稱(如winAppDemo),選擇好存儲路徑,點擊“確定”按鈕
點擊“確定”按鈕後會彈“歡迎使用 Win32 應用程序嚮導”對話框
點擊下一步”按鈕,彈出新的“應用程序設置”對話框
勾選“空項目”,然後點擊“完成”按鈕
現在,就可以添加源文件
在“源文件”處右擊鼠標,在彈出菜單中選擇“添加 -> 新建項”出現“添加新項”對話框
在“代碼”分類中選擇C++文件(.cpp),填寫文件名(注意文件名後綴改爲.c),點擊“添加”按鈕就添加了一個新的源文件
將前面“(這段代碼在本文的前面已出現過)”部分下的代碼輸入,編譯運行,參見下圖:
特別說明,所附代碼肯定運行通過。斷斷續續寫了幾天,就到這兒吧。