2010年10月25日

[C++學習筆記]Windows 程式設計模型

在傳統的作業系統裡,程式採用的是程序設計模型(procedural programming model),什麼是程序設計模型呢?程序設計模型指的是程式會按照順序由上而下的執行。例如在傳統的C語言裡,程式會從main函式的第一行開始執行到main的最後一行,雖然中間有可能會因為user輸入的東西不同,進入不同的function,但是我們還是可以大概了解程式的執行過程。在傳統的這種C程式裡,呼叫函式是由這個程式的main來決定的。


 

Windows 程式的運作程式和傳統的方法不一樣,Windows程式的運作是採用事件驅動(event-driven)的模型,「事件」(event)就是敲一下鍵盤或是按一下滑鼠這些動作。

我們可以把WinMain當成Windows程式的main function ,WinMain會先建立視窗之後進入訊息迴圈(message loop),訊息迴圈會不斷的收取訊息,再把訊息分配給視窗程式裡,再由視窗程式來負責處理送到視窗的訊息。


 

什麼是訊息呢?訊息從哪裡來?又代表什麼意義呢?Windows定義了許多不同的訊息型態,大部分的訊息名稱,都是由「WM_」開頭的,如下表:

訊息

意義

WM_CHAR

從鍵盤輸入字元

WM_CREATE

建立視窗的時候

WM_DESTROY

視窗被摧毀的時候

WM_LBUTTONDOWN

按下滑鼠左鍵

WM_LBUTTONUP

放開滑鼠左鍵

WM_MOUSEMOVE

移動滑鼠時

WM_PAINT

重新繪製視窗

WM_QUIT

結束應用程式時

WM_SIZE

視窗大小改變時


 

舉個例子來說,當我們按下視窗程式右上角的「X」時,就會產生WM_QUIT的訊息。

訊息產生之後,就會被留在一個訊息佇列中,直到訊息被收取為止。

當視窗程式收取到WM_QUIT這個訊息的時候(代表應用程式應該要結束),因此訊息迴圈會結束,訊息迴圈結束之後應用程式也會跟著結束。


 

視窗程式怎麼處理收到的訊息呢?通常視窗程式會呼叫其他的函式來處理收到的訊息,例如:Windows提供的API 函式或是程式裡的其他函式。

而Win32 API提供了很多函式,像是建立視窗、畫圖或是處理檔案等等。

2010年10月21日

[C++學習筆記]程式碼與介面

Windows程式可以分成兩個部分,「程式碼」和「介面」(UI, User Interface),這兩部分會被整合為一個exe檔。

介面

介面是指工作列、警告視窗、程式的圖示,或是滑鼠指標的外觀等等,它們是.bmp、.ico等等的檔案,而成式的開發者會在一個「資源描述檔」(.rc)裡描述這些檔案,然後透過「RC編譯器」讀取這個「資源描述檔」(.rc檔),把這些UI檔案(.bmp等)製作成一個.RES檔。

程式碼

程式碼則是透過C編譯器,致做出一個.OBJ檔。


 

最後將程式碼和介面結合,最後產生一個執行檔(.exe),才是一個完整的Windows 程式。

2010年10月20日

[C++學習筆記]MFC常用基礎類別


CWnd

CWnd是許多類別的基礎類別,如:Cbutton和CDialog。

因此button、對話框、scroll bar等等,其實都算是一個「視窗」。



CWinApp

CWinApp這個類別是MFC程式的骨架,開始執行程式的時候,CWinApp就存在程式中。

而建構CWinApp時,會呼叫InitInstance()這個function,我們可以把這個function想像成C程式的main() function。



CSring

用於字串,可以讓許多操作變得更容易。

[C++學習筆記]用->還是用.


假設我們有一個類別Cbox


1 class Cbox 
2 { 
3  int length; 
4  int width; 
5  int height; 
6 public: 
7 draw();
8}


使用draw()函式的方法:

1 Cbox *pbox;
2 Cbox candyBox;
3 pbox->draw();
4 candyBox.draw();


使用指標時必須使用間接成員存取運算子"->"

使用物件必須使用直接成員存取運算子"."

[C++學習筆記]Messages 和Handles


Message

視窗程式是以Message為基礎的,依靠Message的傳送和回應使得視窗程式能夠運作。

Message是一個32位元的數字。

當我們移動滑鼠時,Message (WM_MOUSEMOVE)就會被傳送到目前的視窗;當我們改變視窗位置時,Message(WM_MOVE)就會被傳送到目前的視窗。

這些Message會被排入Queue(佇列)中,視窗會將他們從Queue中取出,並進行對應的動作,若是視窗得到了WM_SIZE(改變視窗大小)的Message,視窗就會在螢幕上重新繪製。



Handles

視窗程式要使用Handles來判斷各個不同的視窗。

Handles是一個參考不同視窗物件的方法,我們可以將Handles想像成指向各個視窗的一種指標,Handles必須要在使用完之後銷毀,否則會使程式及系統當機。



Messages 和Handles的運作

假設我們擁有一個視窗,我們擁有視窗的Handles,我們將這個Handles命名為My_HWND。

如果作業系統要告知要重新繪製視窗,系統就會傳送一個Message



PostMessage(My_HWND, WM_PAINT, 0, 0);
這個function會傳出Handles和Message給視窗程式,而視窗程式則是一個巨大的switch….case,處理各種不同的訊息。

void HandleMessage(long Message)

{

switch(Message)

  {

  case WM_PAINT:

    DrawWindows();

    break;

  case WM_SIZE:

    //do something

    break;

  }

}

2010年10月15日

[C++學習筆記]範圍解析運算子(scope resolution operator ::)



當區域變數名稱和全域變數名稱相同時,在區域變數名稱的範圍之內,全域變數會被隱藏,而我們可以透過範圍解析運算子: : (兩個冒號)來存取全域變數。



1#include<iostream>
  
2using std::cout;
3using std::endl;
  
4int num=100;
  
5int main()
6{
7int num = 1;
8 cout <<"inner num: " <<num <<endl;
9 cout <<"global num: " <<::num <<endl;
10 return 0;
 
11}


執行的結果是

inner num: 1

global num: 100

[C++學習筆記]2種標準的C++



ISO/ANSIC++/CLI
程式特性 可直接編譯成機器碼並在本機執行的程式碼。

未受控管的C++程式,因程式並沒有受到CLR的控制,必須自行處理記憶體的配置與釋放。
在CLR中執行的視窗程式,user必須安裝.NET Framework

在CLR中執行的程式碼,是
受控管的C++(managed C++),因為CLR會控制程式碼和資料,例如釋放自動配置的記憶體,這樣可以消除某些原生C++(native C++)程式產生的錯誤。
GUI開發
  1. 使用微軟機處類別(MFC)來開發式窗應用程式的圖形使用者介面,MFC封裝了Windows作業系統的圖形使用者介面,簡短了程式開發的步驟。
  2. 若是考慮到執行效能,也可以在程式碼中直接使用Windows API,但Windows API比C++還要更早發展,因此他不具有物件導向特性
可以使用由.NET Framework函式庫提供的Windows Froms做為GUI的基礎。若使用Windows Froms,程式開發者就可以使用圖形化的介面,快速的開發GUI,而程式碼則是自動產出的,開發者只須對自動產生的程式碼進行增修。

[C++學習筆記].NET Framework是什麼?

簡單來說,.NET Framework是一個能夠執行、開發.NET程式的平臺,如同軟體建構於硬體之上,.NET程式也必須依靠.NET Framework來執行。

.NET Framework包含兩個元素:
    1. CLR(Common Language Runtime):可以提供VB、C#和C++等等高階語言撰寫、執行的標準化環境
    2. 類別函式庫:支援各種程式碼所需的功能,也就是不需要考慮程式碼的語言是什麼,都可以使用相同的類別函式庫。因此只要是.NET程式都可以使用一樣的函式庫