【win32】day01-Windows程式設計

Windows程式設計基礎知識的介紹

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

     將原始碼編譯目的碼. OBJ檔案.

   2.1.2 連結器 Link.EXE

     將OBJ檔案和庫函式連結.生成EXE.

   2.1.3 資源編譯器 rc.exe

     將資源指令碼編譯成可以連結的檔案(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   

C:\Users\wuyq\Desktop>cl h.c
'cl' 不是內部或外部命令,也不是可執行的程式
或批處理檔案。
C:\Users\wuyq\Desktop>"C:\Program Files\Microsoft Visual Studio 12.0\VC\bin\vcv
rs32.bat"
C:\Users\wuyq\Desktop>cl h.c
用於 x86 的 Microsoft (R) C/C   優化編譯器 18.00.21005.1 版版權所有(C) Microsof
 Corporation。  保留所有權利。
h.c
Microsoft (R) Incremental Linker Version 12.00.21005.1
Copyright (C) Microsoft Corporation.  All rights reserved.
/out:h.exe
h.obj

或者藉助開發人員工具命令列:

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 執行

    正常執行或帶引數執行

helloworld.c

#include <windows.h>
int WINAPI WinMain( 
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR pszCmdLine,
int  nShowCmd )
{
MessageBox( NULL, pszCmdLine, 
"FirstWin32", MB_OK );
return 0;
}

Cl helloworld.c /c

Link helloworld.obj user32.lib

helloworld  

第一個視窗程式

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:傳送一個退出訊息。

Hellownd.c

#include <windows.h>
HINSTANCE g_hInst = NULL;
//2 視窗處理函式
LRESULT CALLBACK WndProc( HWND hWnd, 
UINT nMsg, 
WPARAM wParam,
LPARAM lParam )
{
//判斷訊息ID
switch( nMsg )
{
case WM_DESTROY: //視窗銷燬的訊息
PostQuitMessage( 0 ); //傳送退出訊息
return 0;
}
//呼叫預設的訊息處理程式
return DefWindowProc( hWnd, nMsg, 
wParam, lParam );	               
}
//3 註冊視窗型別
BOOL MyRegister( LPSTR pszClassName )
{
WNDCLASS wc = {0};
ATOM  nAtom = 0;
//構造註冊視窗的引數
wc.style         = CS_VREDRAW|CS_HREDRAW;
wc.lpfnWndProc   = WndProc;
wc.cbClsExtra    = 0;
wc.cbWndExtra    = 0;
wc.hInstance     = g_hInst;
wc.hIcon         = NULL;
wc.hCursor       = NULL;
wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE);
wc.lpszMenuName  = NULL;
wc.lpszClassName = pszClassName;
//註冊視窗
nAtom = RegisterClass( &wc );
if( 0 == nAtom )
{
MessageBox( NULL, "Register Failed",
"Error", MB_OK|MB_ICONWARNING );
return FALSE;
}
else
{
MessageBox( NULL, "Register Successed",
"Successed", MB_OK );
}
return TRUE;
}
//4 視窗建立
HWND MyCreate( LPSTR pszClassName )
{
HWND hWnd = NULL;
//建立視窗
hWnd = CreateWindow( pszClassName, 
"HelloWnd", WS_OVERLAPPEDWINDOW,
100, 100, 300, 500, NULL, NULL,
g_hInst,	NULL );
if( NULL == hWnd )
{
MessageBox( NULL, "CreateWnd Failed", 
"Error", MB_OK );
return NULL;
}
MessageBox( NULL, "CreateWnd Successed", 
"Successed", MB_OK );
return hWnd;
}
//5 顯示視窗
void DisplayWnd( HWND hWnd )
{
//顯示
ShowWindow( hWnd, SW_SHOW );
//重新整理
UpdateWindow( hWnd );
}
//6 訊息處理
void Message( )
{
MSG msg = { 0 };
//訊息迴圈處理,獲取訊息
while( GetMessage( &msg, NULL, 0, 0 ) )
{
//派發訊息
DispatchMessage( &msg );
}
}
//1 入口函式
int WINAPI WinMain( HINSTANCE hInst,
HINSTANCE hPrevInst,
LPSTR pszCmdLine,
int   nShowCmd )
{
HWND hWnd = NULL;
g_hInst = hInst;
//註冊視窗型別
MyRegister( "MyWnd" );
//建立註冊型別的視窗
hWnd = MyCreate( "MyWnd" );
//顯示視窗
DisplayWnd( hWnd );
//訊息處理
Message( );
return 0;
}

Cl hellownd.c /c

Link hellownd.obj user32.lib

hellownd

資源的處理

4.1 資源和資源指令碼

   資源:ICON/CUSRUR/BITMAP/MENU……

   資源指令碼: 副檔名為rc檔案。

4.2 編譯資源

   使用rc.exe編譯資源,生成RES檔案

4.3 連結資源

   使用link.exe將RES檔案連結到程式當中

4.4 ICON的使用

  LoadIcon從指定程式中載入ICON資源。

Hellownd.c

#include <windows.h>
HINSTANCE g_hInst = NULL;
//2 視窗處理函式
LRESULT CALLBACK WndProc( HWND hWnd, 
UINT nMsg, 
WPARAM wParam,
LPARAM lParam )
{
//判斷訊息ID
switch( nMsg )
{
case WM_DESTROY: //視窗銷燬的訊息
PostQuitMessage( 0 ); //傳送退出訊息
return 0;
}
//呼叫預設的訊息處理程式
return DefWindowProc( hWnd, nMsg, 
wParam, lParam );	               
}
//3 註冊視窗型別
BOOL MyRegister( LPSTR pszClassName )
{
WNDCLASS wc = {0};
ATOM  nAtom = 0;
//構造註冊視窗的引數
wc.style         = CS_VREDRAW|CS_HREDRAW;
wc.lpfnWndProc   = WndProc;
wc.cbClsExtra    = 0;
wc.cbWndExtra    = 0;
wc.hInstance     = g_hInst;
wc.hIcon         = LoadIcon( g_hInst, 
MAKEINTRESOURCE( 100 ) );//MAKEINTRESOURCE  將整數轉為字串 
wc.hCursor       = NULL;
wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE);
wc.lpszMenuName  = NULL;
wc.lpszClassName = pszClassName;
//註冊視窗
nAtom = RegisterClass( &wc );
if( 0 == nAtom )
{
MessageBox( NULL, "Register Failed",
"Error", MB_OK|MB_ICONWARNING );
return FALSE;
}
else
{
MessageBox( NULL, "Register Successed",
"Successed", MB_OK );
}
return TRUE;
}
//4 視窗建立
HWND MyCreate( LPSTR pszClassName )
{
HWND hWnd = NULL;
//建立視窗
hWnd = CreateWindow( pszClassName, 
"HelloWnd", WS_OVERLAPPEDWINDOW,
100, 100, 300, 500, NULL, NULL,
g_hInst,	NULL );
if( NULL == hWnd )
{
MessageBox( NULL, "CreateWnd Failed", 
"Error", MB_OK );
return NULL;
}
MessageBox( NULL, "CreateWnd Successed", 
"Successed", MB_OK );
return hWnd;
}
//5 顯示視窗
void DisplayWnd( HWND hWnd )
{
//顯示
ShowWindow( hWnd, SW_SHOW );
//重新整理
UpdateWindow( hWnd );
}
//6 訊息處理
void Message( )
{
MSG msg = { 0 };
//訊息迴圈處理,獲取訊息
while( GetMessage( &msg, NULL, 0, 0 ) )
{
//派發訊息
DispatchMessage( &msg );
}
}
//1 入口函式
int WINAPI WinMain( HINSTANCE hInst,
HINSTANCE hPrevInst,
LPSTR pszCmdLine,
int   nShowCmd )
{
HWND hWnd = NULL;
g_hInst = hInst;
//註冊視窗型別
MyRegister( "MyWnd" );
//建立註冊型別的視窗
hWnd = MyCreate( "MyWnd" );
//顯示視窗
DisplayWnd( hWnd );
//訊息處理
Message( );
return 0;
}

Hellownd.rc

100 ICON "window.ico"

hellownd.c

Window.ico 這個圖示可以自己進行製作

hellownd.rc

資源編號 資源型別資源的使用檔案

 

編譯的過程:

rc hellownd.rc

會生成hellownd.RES檔案

 

cl hellownd.c /c

 

link hellownd.obj hellownd.res user32.lib

此時會生成帶ico圖示的exe可執行檔案

NMAKE和Makefile

1.1 NMAKE – 命令直譯器,根據Makefile檔案中定義的指令碼,完成專案的編譯等操作。

 

1.2 Makefile – 定義編譯/連結等指令碼語言。

  

1.3 Makefile檔案的編寫

1.3.1 基本語法規則

      window.exe:window.obj // 依賴行

     cl.exe window.c /c    // 命令列

     link.exe window.obj user32.lib

  

    window.exe的依賴項是window.obj,如果window.obj被重新改寫,window.exe將重新生成.通過時間戳(time
stamp)判斷程式是否需要重新編譯連結,如果當檔案修改最後時間與時間戳不同,將會重新編譯連結.

1.3.2 執行過程

  1 NMAKE首先找到第一個依賴行,根據依賴行之間的關係,建立依賴樹。例如:

         A:B

         B:C

         C:D

      NMAKE會建立對應的依賴樹

         A

         |-B

           |-C

             |-D

  2 在樹建好後,NMAKE會首先執行D的命令列,然後依次執行父結點的命令列

  3 在A的命令執行結束後,退出NMAKE.

  4 如果需要執行指定依賴行,需要在執行NMAKE時增加依賴行的名稱。

        NMAKE /f Makefile.mak B <–指定從B執行

 

1.4 使用

  1.4.1 NAMKE指定檔名

NMAKE /f Makefile.mak

  1.4.2 使用預設檔名Makefile

NMAKE在執行時會自動查詢這個檔案.

 

Makefile資料夾下面新建一個windows.c,helloworld程式,makefile.mak

 

#nmake /f makefile.mak

Windows.c

#include <windows.h>
int WINAPI WinMain( HINSTANCE hInst,
HINSTANCE hPrevInst, 
LPSTR pszCmdLine,
int nShowCmd )
{
MessageBox( NULL, "Hello World", 
"Hello", MB_OKCANCEL );
return 0;
}

 Makefile.mak

window.exe:window.obj
cl.exe window.c /c
link.exe window.obj user32.lib

Makefile2.mak

CPP=cl.exe
CPP_FLAG="/c"
LINK32=link.exe
LINK_LIB=user32.lib
ALL:CLEAN
@echo Building....
$(CPP) $(CPP_FLAG) window.c
$(LINK32) $(LINK_LIB) window.obj /out:window.exe
CLEAN:
@echo Deleting....
del *.obj
del *.exe
INSTALL: