2015年12月13日 星期日

Windows視窗程式常用物件介紹


基本上這裡並不講解這些元件要如何使用,如要學習請上網查,

例如TEDIT這個元件,您可以googletedit c++ builder,會有一些相關的使用方法,總之這些元件基本上都是一個指標

假設您在畫面上拉一個TEdit元件(edit1)
輸入Edit1->會有一堆屬性,選擇您要的屬性,並照他的使用方法使用

例如我要使它顯示123
Edit1->Text = L“123”;
當您執行完該指令時,它就會顯示123在欄位上

這裡值得注意的是C++ builderXE以後,所有欄位都是UnicodeString(預設)
所以您要給他一個寬字元,例如剛剛的(L“123”)L的意思代表是寬字元,
基本上如果您下這行指令Edit1->Text = “123”;,它會回報錯誤,因為您給他的不是寬字元

總之這些教程,基本上不一一教學,我只會講一些比較重要和粗略的東西,基本上我假設看的人會寫一些基本的程式了,並且對常用元件已經熟悉了,

因為基本上寫C++ builder要靠自己上網查,他從bcb5就存在了,因此應該是有足夠的資料,寫這些基本的東西,不如有空錄製一個教學影片,大概展示一下,效果會比較好,所以就看看有沒有空我再來做

以下進入正題
其實您在他Tool Palette那邊的Search找下面的關鍵子,點擊並把她拉到Form上就可以看到了,所以我就不截圖

我列舉他幾個比較重要的元件
1.      TLabel(標籤)
2.      TEdit(輸入欄位)
3.      TCheckBox(確認框)
4.      TComboBox(多選框)
5.      TPanel(容器)
6.      TScrollBox(有拉霸的容器)
7.      TProgressBar(進度條)
8.      TScrollBar(拉霸)
9.      TTrackBar(另一種拉霸)
10.  TPageControl(頁籤)
11.  TMemo(文本)
12.  TImage(影像)
13.  TRadioBox(單選多選框)
14.  TOpenDialog(開啟對話框)
15.  TBitBtn(圖示按鈕)
16.  TMenu(選單)

基本上建置UI使用這些就可以千變萬化了,不太需要一些新元件(當然新的也是有用拉),
到後期原則上是使用這些來完成

當然它有一些其他的元件也是可以用拉
例如TNoteBook,一些其他收納容器,我並沒說不可以用,但是基本上後期,很多元件都是自己兜的,

例如我要一個進度條
我可以使用一個TImageTPanel組合,TImage載入一張圖,調整TImage的長度來代表,進度到哪裡了,亙別說您的TImage可以載影像,就變成一個動態的進度條了,這就不在這裡討論範圍,其實它的元件太多了,您要是全部學完會發瘋的,

例如我要一個不一樣的Menu,您可以用不同容器或按鈕拚一拚,手動設計它的切換顯示,也可以做出一個不一樣的東西,如一直使用它的基本元件,基本上來說沒有不行,不過老實講就是太死了,缺乏彈性,會抹煞很多創意及想法

就像一個TPanel,您可以經由設計它的MouseMoveMouseDown來切換它的顏色,當作一個按鈕,總之可以千變萬化,這需要知道一些技巧,往後我會提供一個陽村的模組供參考,您會看到TPanel也可以當作按鈕

總之我上面列的那些元件基本上搞懂,其實您UI就足夠了,要兜啥功能都可以,基本上不太需要知道其他東西,當然也是可以使用拉

不過要寫一個軟體還有很多東西要學,您其實如果有需要寫演算法或設計模組使用,其實時間就不夠了,所以還是將基本的弄熟,有空再使用其他元件

軟體說難也很難,當您要設計些什麼的時候很難,說簡單也很簡單,其實您去上班後會發現,一般員工就拉拉按鈕寫寫功能爾以,不會動到設計這塊,給沒有經驗的人家做個一個禮拜,有經驗的可能兩三天就完成了

基本上要是只是拉拉按鈕,假設您公司有一個產品已經持續在賣了,您會發現那個維護的工程師很閒,拉一兩個按鈕跟您收好幾千,根本是賺死了,

但是其實那樣隨便拉幾個按鈕,您用久其實會發現使用者體驗很差(就很難用就是了)

總之軟體就是設計在設計,這樣也才看得出,誰是比較有功力的,而且設計完後,要是設計得好,使用起來是絕對有感的(但是不能否認比較後段的或者是小間公司的作法,都是求方便,簡單做一做,是不太摸設計這一塊的)

當然不能否認您的製作過程時間的考量,有時候很趕時又或者收不到錢時的狀況要考量,很多事情並不是絕對的,但是再次強調,一個好的設計會讓您做起來更快速,並且更易維護,不要太小看有意義的設計,這些都需要經過長久思考及歷練的

Windows視窗程式的一些知識


基本上傳統的程式叫Console(主控台),也就是它是一個執行檔,會一行一行的執行,

windows視窗程式基本上它是一個圖形介面,基本上您靠滑鼠點一點,他就可以執行程式設計師設計好的程式功能,

您只要打開windows,桌面其實就是一個應用程式,也就是explorer.exe,如果您會用DOS開機,您可以故意把explorer.exe殺掉或改名子,您重新登入windows時你會發現進不到桌面,應該是一片藍藍的(這是XP時的知識,我不確定之後的版本是否還是一樣,我沒有試過)

其實您有看過嵌入式板子的視窗程式是如何執行的,舉個例來說,QT程式,他會有一個基本框架,當您進入那個環境時,他背景全部是藍色的,如果您有開啟QT程式,您會發現他跟windows只差在沒有下面的工具列,就是一個藍藍的背景,然後沒有任何作用,如果您有開啟程式,就是藍藍的背景上有一個應用程式顯示

說起來windows程式算是一個block的程式,他會根據您的動作,去執行相對應的動作,做完會繼續block住,總之您把她想成是人家設計好的框架,您只要會利用編程(例如C++ builder or Visual C#)拉一拉介面,編譯完就會出現圖形程式就對了,一開始時不需要知道太多知識

Windows程式啟動時,其實他也是執行一個Main(),我舉C++ builder的例子
您開啟一個project,可以在裡面找tWinMain

///////////////////////////////////////////////////////////
int WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int)
{
        try
        {
                Application->Initialize();
                Application->MainFormOnTaskBar = true;
                Application->CreateForm(__classid(TForm2), &Form2);
                Application->Run();
        }
        catch (Exception &exception)
        {
                Application->ShowException(&exception);
        }
        catch (...)
        {
                try
                {
                        throw Exception("");
                }
                catch (Exception &exception)
                {
                        Application->ShowException(&exception);
                }
        }
        return 0;
}

///////////////////////////////////////////////////////////

其實他就是一個執行續跑tWinMain,他會建立一個Form,並執行他(Application->Run();),他會再開另一個執行緒跑您的應用程式,然後程式就停在Application->Run();,直到您關閉程式時,他會繼續執行下去,直到return 0;

這裡是初始化過程,進去就是所謂的windows programming那套了,初學者大概知道到這邊就好,您只要會拉幾個Button照他的寫法寫,CompilerLink過就會動了,並不難理解

基本上C++ builder開發速度很快,比Visual C++ MFC好寫太多了,入門門檻比較低,到目前為止我還不知道Visual C++ MFC要如何寫,而且C++ Builder畫面可以做比較多的設計,如果您要用C++寫視窗程式,就目前而言,大概就是C++ Builder,而C#就是Visual C#,沒別的寫法了,總之就是使用他們來寫您要的桌機應用程式就對了

大概就介紹到這裡,下面講一些重點,

基本上現在程式都往多執行緒的方式開發,因為如果您將所有程式片段都在主執行緒執行,你的應用程式在跑時會卡卡的,有時候會動彈不得,例如您建一個Button,在按下Button時您執行Sleep(100)或者是while(1);您程式就無法控制了,不會動了,以上是模擬當您執行很長一段程式(while(1);),程式就當掉了,

這基本上多執行緒程式已經成為寫視窗程式主流的寫法了,您不那樣寫,不知道哪個時候您程式就出錯當掉了,或者是沒辦法利用到多核心能力,快速處理掉您要做的事情

當然,這是寫到後期,必須具備的技能,一開始就是拉一拉Button,設計一個有功能程式就很棒了,所以也是急不得的,多執行緒程式基本上要用到一些底層的函式,例如CreateThread,並把它弄成一個函式,可以rework(就是所謂的Msgthread,他接受不同的Msg執行不同的動作),這基本上外面是沒得學的,

要自學只能使用tthread,或者PPL的東西(XE7以後才有)所以就是會基本的程式撰寫,基本上要進一些有基礎的公司,慢慢地重新學,不然是學不起來的,

很像是你只有一歲,您知道如何騎機車嗎,就算是轉轉把手,也要有人教您,是吧

總之在沒基礎時
基本上您的活動範圍在主執行緒,要功能的話要會演算法,不然就是要會使用他的元件

有基礎時,
您必須開始會Windows消息傳遞這項技術,並嘗試使用TThread

當您比較能掌握時
要開始接觸Windows Programming的函式庫,並熟用他,如果不會的話,想辦法進入會的公司學吧,這是唯一道路,其實他並不陌生,例如FileExists他就是一個Windows Programming的函式

一般再來就是進公司,
就是想辦法把Windows Programming熟悉(其實也不用全會,因為那很多你的領域不見得會用到,學有用到的即可),並將您那領域的演算法攻破,並會優化技術,利用公司已有的基礎,向上發展,這是唯一解

 

 

C++物件導向的基本知識(物件間的關係.o)


http://hatsukiakio.blogspot.tw/2009/04/c-static.html

基本上物件(.o)之間是獨立的,也就是說compiler只會將一個一個的CPP,編譯成獨立的.o檔,在最後使用linker將物件連結起來

連結的意思是,假設我在a.cpp時做一個void sum(){};當我在a.h前置宣告void sum()b.cpp要是includea.h,並且執行sum();

他在link的時候會去所有的物件裡面找void sum()實作的地方,也就是a.cpp,並把他做一個關聯,在執行程式時,就會執行a.cppvoid sum(){}

如前面所說,.o之間是互相獨立的,也就是說可以實作兩個void sum(){}在不同.cpp,如:
///////////////////////////////////

a.cpp
#include “c.h”
void sum()
{
        Int a = 0;
}

b.cpp
#include “c.h”
void sum()
{
        Int a = 1;
}

c.cpp

#include “c.h”
void main()
{
        Sum();
}

c.h
#ifndef cH
#define cH
void sum();
#endif

///////////////////////////////////

這在compiler是會過的,並且可以連結起來成exe檔,
問題來了,兩個相同的函式,您怎麼知道他會執行哪一個函式呢

這就牽涉到linker的程式了,基本上我們不可能知道他linker實際上是如何做的,

就我了解並且測試過,
基本上它會跑你專案裡面第一個有void sum(){}的程式碼,也就是a.cpp

要是您將a.cpp從專案移除,然後再加入a.cpp進入專案,也就是b.cpp會在第一個,您會發現再次link執行它會執行b.cpp的程式裡的void sum(){}

這您可以自己寫個小專案測試看看,就是三個.cpp一個.h,並在軟體程式裡面執行sum();,下中斷點觀察您的程式是如何執行的

這很有趣,所以在寫程式時,要是有所謂的lib函式庫,裡面的cpp你又將他重複加到專案裡,造成有相同的函式,

這時候要是兩個函式是不同程式內容,您要注意.lib.cpp加入專案裡的順序,不然有時候您會查了半天,發現結果都不是您要的,一直出錯,

最好是將他們用不同的namespace區隔,並命名成不同名子,做一些修改,然後您在使用函式時,假設有兩個namespace,一個是namespace hahaha,一個是namespace hehehe

假設您要執行namespace hahaha的程式,您就執行hahaha::sum();,這樣就不會錯亂了,

當然您要注意您lib裡用的.h,和您複製一份加到專案裡的.h,他下面這地方也要改,例如原來的是

#ifndef heheheH
#define heheheH
Namespace hehehe
{

}
#endif

加入專案相同的.h

#ifndef hahahaH
#define hahahaH
Namespace hahaha
{

}
#endif

總之要做一點區隔,不然會容易有問題,
省了一點點時間,卻花您很多時間在找這個問題