第一個手寫Win32窗口程序


第一個手寫Win32窗口程序

 

一 Windows編程基礎

1 Win32應用程序的基本類型

1.1 控制台程序
不需要完善的Windows窗口,可以使用DOS窗口
的方式顯示。
1.2 Win32窗口程序
包含窗口的程序。可以通過窗口與程序進行交互。
1.3 Win32庫程序
提供已有的代碼,供其他程序使用。
動態庫:DLL 是在執行的時候可以加載的程序。
靜態庫:LIB 是在編譯鏈接是使用的程序。
1.4 對比
1.4.1 程序的入口函數不同
控制台:main
Win32窗口程序:WinMain
動態庫DLL:DllMain
靜態庫LIB:無

1.4.2 編譯鏈接后存在的形式不同
控制台和Win32窗口程序:EXE文件,可以執行
動態庫DLL:DLL文件,無法執行
靜態庫LIB:LIB文件,無法執行

1.4.3 執行結果不同
控制台:使用DOS窗口,自己沒有窗口。
Win32窗口程序:會產生自己的窗口,
可以將結果輸出或者從窗口接受輸入。
動態庫DLL:自己無法執行,提供可以執行
的代碼,當EXE等程序執行時,可以使用
這些代碼.執行時,該庫必須在指定的路徑.
靜態庫LIB: 自己無法執行,提供給程序在
編譯鏈接時使用,將庫中的代碼嵌入到
程序當中.執行時,不需要該庫存在.

二 Win32窗口程序和編譯環境

2.1 開發和編譯環境
VC1.5 - VC6.0(2008) - VC10.0(2010)

2.1.1 編譯器 CL.EXE(在VC安裝目錄的VC98/Bin目錄下)
將原代碼編譯目標代碼. OBJ文件.
2.1.2 鏈接器 Link.EXE(在VC安裝目錄的VC98/Bin目錄下)
將OBJ文件和庫函數鏈接.生成EXE.
2.1.3 資源編譯器 rc.exe(在VC安裝目錄的MSDev98\Bin目錄下)
將資源腳本編譯成可以鏈接的文件(RES).

2.2 頭文件和庫
2.2.1 頭文件 windows.h包含了windows
常用的定義等.其他,還包含了一些其他的
頭文件:
windef.h - 定義了各種的數據類型
winbase.h- 定義了kernel的相關函數
wingdi.h - 定義了繪圖和文字
winuser.h- 窗口 控件等函數
winnt.h - 提供Unicode支持

2.2.2 庫
kernel32.lib - 提供進程/線程/內存等等
API函數支持
user32.lib - 包括窗戶/界面等等.
gdi32.lib - 提供繪圖/文字等。

2.3 Hello World程序

2.3.1 入口函數
int WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR pszCmdLine,
int nShowCmd )
hInstance - 應用程序的實例句柄
hPrevInstance - 該應用程序的前一個實例句柄
pszCmdLine - 命令行參數
nShowCmd - 窗口的顯示方式

2.3.2 MessageBox

2.4 編譯環境的准備

在VC98的BIN目錄下VCVARS32.BAT

2.5 編譯CL.EXE
CL的常用選項
/c 只編譯不鏈接
/TC 編譯C文件
/TP 編譯C++文件
如果不指定,CL會根據文件類型自動區分
/I 頭文件所在路徑
字符大小寫敏感
2.6 鏈接LINK.EXE
LINK常用選項:
/out:文件名,鏈接成指定文件名的程序
/LIBPATH:LIB文件存放的路徑, /LIBPATH:"E:\XXX"
/SUBSYSTEM: CONSOLE/WINDOW
字符大小寫不敏感

2.7 執行
正常執行或帶參數執行

三 第一個窗口程序

3.1 入口函數WinMain
3.2 窗口處理函數
當窗口處理消息事件時,系統調用該函數
LRESULT CALLBACK WindowProc(
HWND hwnd, // 窗口的句柄
UINT uMsg, // 消息的ID號
WPARAM wParam, // 消息所對應的參數
LPARAM lParam // 消息所對應的參數
);
3.3 注冊窗口類型
typedef struct _WNDCLASS {
UINT style; //窗口類的風格
WNDPROC lpfnWndProc; //窗口處理函數
int cbClsExtra; //窗口類附加數據大小
int cbWndExtra; //窗口附加數據大小
HANDLE hInstance; //當前應用程序的實例句柄
HICON hIcon; //窗口圖標
HCURSOR hCursor; //窗口的鼠標
HBRUSH hbrBackground; //窗口的背景畫刷
LPCTSTR lpszMenuName; //菜單
LPCTSTR lpszClassName; //類型名稱
} WNDCLASS;

注冊函數 RegisterClass
3.4 創建窗口
HWND CreateWindow(
LPCTSTR lpClassName, //窗口類型名稱
LPCTSTR lpWindowName, //窗口名稱
DWORD dwStyle, //窗口類型
int x, //窗口的左上角X坐邊
int y, //窗口的左上角X坐邊
int nWidth, //窗口的寬度
int nHeight, //窗口的高度
HWND hWndParent, //父窗口句柄
HMENU hMenu, //窗口菜單句柄
HANDLE hInstance, //應用程序的實例句柄
LPVOID lpParam //創建的參數,一般為NULL
);

3.5 顯示窗口
ShowWindow 顯示窗口
BOOL ShowWindow(
HWND hWnd, //顯示的窗口句柄
int nCmdShow //顯示的方式
);
UpdateWindow 刷新窗口
3.6 消息處理
GetMessage 獲取消息
DispatchMessage 派發消息

3.7 程序退出
窗口銷毀時,退出程序。在WndProc中實現。
WM_DESTROY: 當窗口銷毀時,會調用WndProc
傳遞給使用者。
PostQuitMessage:發送一個退出消息。

四 資源的處理

4.1 資源和資源腳本
資源:ICON/CUSRUR/BITMAP/MENU......
資源腳本: 擴展名為rc文件。
4.2 編譯資源
使用rc.exe編譯資源,生成RES文件
4.3 鏈接資源
使用link.exe將RES文件鏈接到程序當中
4.4 ICON的使用
LoadIcon從指定程序中加載ICON資源。

 

HelloWorld.c代碼如下:

  1 #include <windows.h>
  2 
  3 
  4 // 2、窗口過程函數
  5 LRESULT CALLBACK WindowProc(  HWND hwnd,
  6                               UINT uMsg,
  7                               WPARAM wParam,
  8                               LPARAM lParam )
  9 {
 10     //判斷消息ID
 11     switch (uMsg)
 12     {
 13         case WM_DESTROY:    // 窗口銷毀消息
 14             PostQuitMessage( 0 );   //  發送退出消息
 15             return 0;
 16     }
 17     // 其他的消息調用缺省的消息處理程序
 18     return DefWindowProc( hwnd, uMsg, wParam, lParam );
 19 }
 20 
 21 // 3、注冊窗口類型
 22 BOOL RegisterWindow( LPCSTR lpcWndName, HINSTANCE hInstance )
 23 {
 24     ATOM nAtom = 0;
 25 
 26     // 構造創建窗口參數
 27     WNDCLASS wndClass = { 0 };
 28     
 29     wndClass.style = CS_HREDRAW | CS_VREDRAW;
 30     wndClass.lpfnWndProc = WindowProc;      // 指向窗口過程函數
 31     wndClass.cbClsExtra = 0;
 32     wndClass.cbWndExtra = 0;
 33     wndClass.hInstance = hInstance;
 34     wndClass.hIcon = LoadIcon( hInstance, MAKEINTRESOURCE( 100 ) );// 100為在HelloWorld.rc文件中定義的ID號
 35     wndClass.hCursor = NULL;
 36     wndClass.hbrBackground = (HBRUSH)COLOR_GRAYTEXT;
 37     wndClass.lpszMenuName = NULL;
 38     wndClass.lpszClassName = lpcWndName;    // 注冊的窗口名稱,並非標題,以后創建窗口根據此注冊的名稱創建
 39     
 40     nAtom = RegisterClass( &wndClass );
 41     if( 0 == nAtom)
 42     {
 43         MessageBox( NULL, "Register Failed",
 44                     "Error", MB_OK|MB_ICONERROR );
 45         return FALSE;
 46     }
 47     else
 48     {
 49         MessageBox( NULL, "Register Successed",
 50                     "Sucessed", MB_OK );
 51     }
 52     return TRUE;
 53 }
 54 
 55 // 4、創建窗口(lpClassName 一定是已經注冊過的窗口類型)
 56 HWND CreateMyWindow( LPCTSTR lpClassName, HINSTANCE hInstance )
 57 {
 58     HWND hWnd = NULL;
 59     // 創建窗口
 60     hWnd = CreateWindow( lpClassName, "Hello World",
 61                   WS_OVERLAPPEDWINDOW,
 62                   0, 0, 500, 300,
 63                   NULL, NULL, hInstance, NULL );
 64     if( NULL == hWnd )
 65     {
 66         MessageBox( NULL, "Create Window Failed",
 67                     "Error", MB_OK|MB_ICONERROR );
 68         return NULL;
 69     }
 70     else
 71     {
 72         MessageBox( NULL, "Create Window Successed",
 73                     "Sucessed", MB_OK );
 74     }
 75     return hWnd;
 76 }
 77 
 78 // 5、 顯示窗口
 79 void DisplayMyWnd( HWND hWnd )
 80 {
 81     ShowWindow( hWnd, SW_SHOW );
 82     UpdateWindow( hWnd );
 83 }
 84 
 85 void doMessage()        // 消息循環處理函數
 86 {
 87     MSG msg = { 0 };
 88     // 獲取消息
 89     while( GetMessage( &msg, NULL, 0, 0 ) ) // 當接收到WM_QIUT消息時,GetMessage函數返回0,結束循環
 90     {
 91         DispatchMessage( &msg ); // 派發消息,到WindowPro函數處理
 92     }
 93 }
 94 
 95 
 96 // 1、 入口函數
 97 int WINAPI WinMain( HINSTANCE hInstance,
 98                     HINSTANCE hPrevInstance,
 99                     LPWSTR lpCmdLine,
100                     int nShowCmd )
101 {
102     HWND hWnd = NULL;
103     LPCTSTR lpClassName = "MyWnd";  // 注冊窗口的名稱
104     RegisterWindow( lpClassName, hInstance );
105     hWnd = CreateMyWindow( lpClassName, hInstance );
106 
107     DisplayMyWnd( hWnd );
108     doMessage();
109     
110     return 0;
111 }

HelloWorld.rc資源腳本如下:

其中 100:表示資源的ID號

       ICON:表示資源的類型

     ”resources/ICO.ico“ 表示資源Ico圖標的路徑

1 100 ICON "resources/ICO.ico"

 

運行方法:(首先運行VC98/bin/VCVARS32.bat配置好運行環境)

1、在Cmd控制台中找到代碼當前路徑,使用CL HelloWorld.c /c  命令只編譯不鏈接文件,會生成一個HelloWorld.obj的目標文件

2、使用 rc HelloWorld.rc 命令編譯HelloWorld.rc 資源腳本文件,會生成一個HelloWorld.RES的編譯過的資源腳本文件

3、使用 link HelloWorld.obj user32.lib HelloWorld.res 鏈接這幾個文件,會生成一個帶圖標的HelloWorld.exe文件

4、可以在 cmd 窗口中繼續使用 HelloWorld 命令運行該程序,也可以點擊生成的HelloWorld.exe運行改程序

 

運行結果如下:

(1)                                                  (2)    

                                

(3)可以看到左上角的圖標也改變了

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM