Showing posts with label basic. Show all posts
Showing posts with label basic. Show all posts

Wednesday, February 15, 2012

XE2: 儲存 Project

除了 Form/Unit 必須儲存之外, 每一個應用程式的專案也要儲存起來, 從功能表中選取 File | Save Project As.. 就可以將專案的內容儲存起來。



在你儲存的目錄中, 你一共可以看到關於專案的 3 個不同的副檔名。

1. Project1.cbproj

  副檔名是 cbproj, 指的是 C++ Builder 的 Project File, 儲存的內容是關於整個專案內容的描述。

2. Project1.cbproj.local

  在副檔名是 cbproj 的後面加加上 .local, 用記事本打開看, 可以看到專案儲存在這台電腦(local)的相關目錄。

3. Project1.cpp

  副檔名是 cpp, 因此是整個專案能夠在視窗環境下執行的 C++ 語言指令的相關部分。

如下圖的三個檔案。

XE2: 儲存 Form/Unit

當我們完成一個 Form 的設計與其對應的 Unit 的程式撰寫後, 或是想要休息一下, 下次再繼續寫程式, 就要先將 Form/Unit 先儲存起來, 可以從功能表中選取 File | Save 或 Save as... 來進行第一次的儲存, 如果已經儲存過了, 那就可以直接選 File | Save 進行儲存。



如果沒有對 Unit1 進行重新命名, 就會看到 Unit1 一共被儲存成下列三個檔案:

 1. Unit1.cpp

   副檔名為 cpp, 類型為 C++ Source File, 內容就是你在撰寫程式時, 所看到的程式內容。

 2. Unit1.dfm

   副檔名為 dfm, 內容其實就是對你所設計的 Form 之描述, 如果你用記事本開啟 Unit1.dfm, 你就可以看到 C++ Builder 是如何描述一個 Form 的。



  由於上圖中的 Form1 並沒有任何元件, 所以描述內容僅有對 object Form1 的描述。

 3. Unit1.h
 
   副檔名為 h, 表示為一個 C 語言的標頭檔(header file), 每一個 Unit 都會搭配一個標頭檔, 在 Unit1.cpp 中, 你也可以找到一行 #include "Unit1.h" 的指令。

 在你儲存的目錄中, 你一共可以看到如下圖的三個檔案。

XE2: Object Inspector

在 C++ Builder 中, 可以用 Object Inspector 來觀看與設定所有元件的 Properties, 也可以從 Events 中設定 Object 的所有事件處理程序。

XE2: 開啟一個 VCL Form 應用

進入 C++ Builder XE2 的整合開發環境後, 如果你要開始寫一個全新的應用程式, 你可以從功能列中選擇 File | New | VCL Forms Application (如下圖),
 

 
C++ Builder 就會幫你產生一個 Form, 讓你開始規劃你的 Form 上要放哪些元件。


要修改 Form1 物件 Properties 的內容, 可以直接在位於左下角的 Object Inspector 中直接更改。

Tuesday, February 14, 2012

XE2: 工具盤 Tool Palette

C++ Builder XE2 的工具盤(Tool Palette) 其實就是 BCB6 中的元件盤(Component Palette), 可以從這邊找到想要的元件, 直接拉到 Form 上就可以了。

Tuesday, March 24, 2009

使用者自定之副程式如何存取物件之相關資料

在 C++ Builder 中撰寫副程式, 如果要存取物件中的相關資料, 必須從 Form1 開始描述起, 不可以直接寫物件之名稱, 否則會有 Undefined symbol 的錯誤訊息。

Example:

Form1->StatusBar1->Panels->Items[0]->Text = AnsiString(iFrameCount);

Thursday, December 20, 2007

如何取得系統時間

#include time.h

A = clock();

Wednesday, November 21, 2007

% operator

我們知道 % operator 就是除法取其餘數的運算子。
例如:

Q = A % 2;

一般來說, Q 值不是 0 就是 1。

不過, 我一直沒有想過如果被除數 A 是負數的時候, 會發生什麼情形? 今天下午我在寫程式時, 就發生了這樣的例子, 害我 debug 很久, 把程式一堆變數的值一一顯示出來看, 才發現這個有趣的問題。原來, 如果被除數 A 是負數的時候, 餘數也會是負數的!
例如:
 
-3 % 2 = -1
 

Monday, November 13, 2006

如何讓 Label 顯示實數值

在程式中, 我們常會遭遇到要顯示實數(real number)的問題, 早期我會直接寫一個小程式把實數中每一個 digit 都算出來, 然後轉換成 AnsiString, 再把字串接起來, 再顯示到 Label 上。

後來, 我的作法就簡單多了, 直接用 sprintf 的方式, 將實數輸出到某一個字串中, 然後再顯示到某個 Label 上。例如:

//宣告部份
char Message[10];

//程式部份
RMS = sqrt(SquareErrorSum/(MH*MW*3));
sprintf(Message,"%6.3f",RMS);
lblRMS->Caption = "RMS="+AnsiString(Message);
 

Saturday, November 04, 2006

將布林值轉成字串 BoolToStr

運用在邏輯運算的 Boolean 型態值有 true or false 兩個。因此, 這兩個字在 C++ 屬於 specific keywords。換句話說, 你不可以用這兩個字當變數名稱, 它們是有特定意義的。

我們再深入一點探討, 電腦是怎麼儲存這個形態的變數呢? 我們看看 BCB 中的 Help 是怎麼說的:
bool, true, false

Category

C++-Specific Keywords

Syntax
bool ;

Description
Use bool and the literals false and true to perform Boolean logic tests.

The bool keyword represents a type that can take only the value false or true. The keywords false and true are Boolean literals with predefined values. false is numericallly zero and true is numerically one. These Boolean literals are rvalues; you cannot make an assignment to them.

You can convert an rvalue that is of type bool to an rvalue that is int type. The numerical conversion sets false to zero and true becomes one.

You can convert arithmetic, enumeration, pointer, or pointer to member rvalue types to an rvalue of type bool. A zero value, null pointer value, or null member pointer value is converted to false. Any other value is converted to true.

很顯然地, 這些 Boolean 值在電腦中, 也是用電腦基本的 0, 1 數值來儲存。"The keywords false and true are Boolean literals with predefined values. false is numericallly zero and true is numerically one." 此外, 我們也可以把一些其他型態的值轉換成布林值, 像 0, null pointer value, null member pointer value 會被轉換成 false, 其餘則是通通轉換成 true

在 BCB 中, 還提供了一個 BoolToStr 將布林值轉換成字串。
BoolToStr(bool B, bool UseBoolStrs)
Converts a Boolean value to an AnsiString.

Unit
SysUtils

Category
type conversion routines

extern PACKAGE AnsiString __fastcall BoolToStr(bool B, bool UseBoolStrs = false);

Description
BoolToStr converts the given Boolean value to a string as follows:

B UseBoolStrs  Returned string
true  false    "-1"
true  true    The first string in TrueBoolStrs (default, "TRUE");
false  false    "0"
false  true    The first string in FalseBoolStrs (default, "FALSE");

 

Monday, September 25, 2006

Component Palette


BCB 的核心除了以 C++ 程式語言為基礎之外, 最重要的就是 Visual Component Library 了。BCB 把在視窗應用程式 ( window application ) 中常用的一些功能, 包裝成一個個的元件 ( component ), 這些元件通通被放到上圖的 Component Palette 中, 由於元件太多了, 因此 BCB 用分頁選單的方式, 將性質相近的元件放到同一個標籤頁中, 方便我們使用。

你可以比較出畫家用的調色盤 ( palette ) 和 BCB 中的 component palette 之間的異同嗎?

Sunday, September 24, 2006

Visual Component Library (VCL)

視覺化元件程式庫( Visual Component Library, VCL ) 是 Borland 所發展出來的, 包含 Objects, Components, Routines, Types, Constants and Variables 等五大部分。底下的說明是從 Borland C++ Builder Help 所寫的說明文字。
Objects
An object consists of methods, and in many cases, properties, and events. Properties represent the data contained in the object. Methods are the actions the object can perform. Events are conditions the object can react to. All objects descend from the ancestor object TObject.

Components
Components are visual objects that you can manipulate at design time. All components descend from TComponent.

Routines
Global routines are the procedures and functions from the runtime library and from the VCL. These routines are not part of a class, but can be called either directly or from within class methods.

Types
The types described in the Help are used as return types and parameter types for object methods, properties and events, and for global routines. In many cases, types are documented in the entry for the method, property, event or global routine in which they are used.

Constants and Variables
The constants and variables defined in the Help are declared in the runtime library and in the VCL. Some of these are instantiations of objects. Examples are the Application and Screen variables. Others represent routines that provide the underlying implementation of other methods or global routines. Examples include the AnsiResemblesProc and RegisterComponentsProc variables. Still other variables and constants represent information that can vary with the system or platform, such as the DateSeparator variable and PathDelim constant.
Borland C++ Builder 是 Borland 針對 C++ 程式語言所開發的快速應用程式開發工具 ( Rapid Application Development, RAD ), Borland 為 C++ 加入了許多的視覺化元件, 配合整合開發環境 ( Integrated Development Environment, IDE ), 推出了 Borland C++ Builder 這個產品, 加速了一個視窗應用程式的開發。

Wednesday, September 13, 2006

動態宣告二維陣列

寫程式時, 『變數宣告』指的是請作業系統分配 (allocate) 一塊大小合適的記憶體, 讓我們作為儲存資料之用。因此, 我們必須告訴作業系統, 我們要儲存的資料是什麼型態, 然後, 根據程式設計師所提供的變數型態, 作業系統就會知道該分配多大的記憶體給我們使用。因此, 變數宣告通常會寫在程式的最前面, 希望程式一開始執行時, 就把需要用到的記憶體通通分配好。

標題中『動態宣告』指的是當程式設計師在寫程式時, 並無法確實知道程式在執行時需要用的多大的記憶體, 必須等到程式真正執行時(run time), 才會知道確實的大小。為了解決這樣的問題, 就必須允許程式設計師在執行程式時, 才臨時去宣告, 要求分配記憶體, 這就是『動態』兩個字的意義由來。

用二維陣列來儲存數位影像是非常直覺的想法, 不過, 需要用動態宣告方式的原因則是因為我們不知道要事先宣告一個多大的二維陣列才夠儲存你所開啟的影像。這邊就是要介紹 BCB 中, 要動態宣告一個二維陣列的作法。

#include <iostream.h>
// 注意: 必須加入這一行到程式最前面, 否則我們後面用到的 std::bad_alloc 會沒有定義

unsigned char **ucMatrix;
/* 說明:
1. ucMatrix 就是我們要宣告的二維陣列的名稱, 為了讓我們在寫程式時, 一看到這個名稱就知道其資料型態為何, 我們在名稱之前加入了小寫的 uc, 代表 unsigned char 的縮寫,
2. 這邊用 unsigned char 當例子的原因是影像的色彩值範圍為 0 ~ 255, 剛好就是 unsigned char 可以表示的數值範圍。
3. 名稱之前, 我們放了兩個 star 符號 ( ** ), 就是要告訴 BCB 的編譯器, 這個名稱本身是一個指到二維陣列的名稱。
結束說明 */

int iImageHeight=0, iImageWidth=0;

// 說明: 這兩個變數是用來儲存影像 ( image ) 的高 ( height ) 與寬 ( width ) 的, 至於變數名稱最前面的小寫 i, 也是用來指出其資料型態為 int

 try
  {
  ucMatrix = new unsigned char *[iImageHeight];
  for (j=0;j<iImageHeight;j++)
   ucMatrix[j] = new unsigned char [iImageWidth];
  }
 catch (std::bad_alloc)
  {
  ShowMessage("Could not allocate memory...Bye");
  exit(-1);
  }
 
/* 說明:
1. 如果有一段程式 ( 用大括號 {}, 括起來) 有可能發生一些特殊例外的情況, 以上面的例子來說, 要求系統給予一塊記憶體, 在一般情況下, 這段程式可以順利要到記憶體繼續執行; 可是, 當系統已經沒有多餘的記憶體分配給你的時候, 程式該怎麼辦呢? 這種情況就是可能發生的例外情況。在 C++ (BCB) 中, 你可以將這段程式碼的前面加上 try 這個 keyword, 讓系統知道可能會發生例外情況, 需要例外處理程序支援。
2. 至於不同的例外情況, 要做不同的例外處理, 我們必須用 catch 這個 keyword 來加以分別。以我們的例子來說, 當發生了 std::bad_alloc 這種情況時, 請秀出 "Could not allocate memory... Bye" 字串, 然後程式結束 exit(-1);
3. new 就是提供動態記憶體配置 (dynamic storage allocation) 的指令。如果成功配置到記憶體, new 這個 operator 就會傳回一個指標 (pointer), 指向所配置到的記憶體位置。如果失敗了, new operator 就會呼叫 new_handler 函數。這個函數內定的處理方式就是指出發生了一個 bad_alloc 的例外情況。然後再由程式設計師透過例外處理指令 catch 來接手該如何處理這個例外情況。
4. 由於我們要宣告的是一個二維陣列, 因此整個步驟分成兩部份, 首先要求配置 iImageHeight 個一維陣列的指標, 每一個指標都是指向一個資料型態為 unsigned char 的變數。如果成功了, 就將這個陣列的指標存到 ucMatrix 這個變數中。接著, 再利用for 迴圈要求 iImageHeight 個陣列, 每個陣列都有 iImageWidth 個元素 (elements), 每一個元素的資料型態都是 unsigned char。
結束說明 */

注意: 上述程式為了程式的可讀性, 用了全型的空白" "來控制部落格文章的內縮顯示。因此, 如果你要直接複製上述程式到 C++ Builder 執行, 請務必將全型空白" "改成半型空白" ", 否則, 編譯時發出現以下的錯誤訊息。:
[C++ Error] Unit1.cpp(40): E2206 Illegal character ' ' (0xa140)

Monday, September 11, 2006

開啟 JPEG 影像

BCB Professional 版本並不提供直接開啟 JPEG 影像的功能, 要開啟 JPEG 影像, 要自己寫 JPEG 的 decoder, 這個有點難度, 不然就是直接上網找別人寫的程式, 弄懂後, 想辦法和自己的程式結合起來。不過, 如果是 BCB Enterprise 版本, 要開啟 JPEG 影像就容易多了, 只要在程式最前面宣告的部份, 加入:

#include "jpeg.hpp"

至於其他的步驟, 則都和 開啟 BMP 影像 相同。

如果你想要看看 jpeg.hpp 這個檔案的內容, 你可以在

C:\Program Files\Borland\CBuilder6\Include\Vcl\

這個目錄中找到這個檔案。如果你沒有安裝 BCB Enterprise 版, 你可以按這邊 一賭為快

開啟與儲存 BMP 影像

BCB 中, 要寫程式開啟一張 BMP 影像, 非常的簡單, 主要步驟有二:

1. 利用 OpenPictureDialog1->Execute() 來選定你所希望開啟的影像。
OpenPictureDialog 這個對話方塊專門設計用來開啟一張影像的, Execute() 這個method 並不需要任何的傳入值, 當我們用對話視窗選定一個影像檔後, 則會傳回一個 boolean 值 ( true or false), 來表示是否執行成功。如果傳回值是 true, Execute() 就會把你所選擇的檔案名稱 (包刮路徑), 存在FileName 這個字串中。

2. 再利用 Image1->Picture->LoadFromFile(OpenPictureDialog1->FileName)
將影像顯示到 Image1 這個影像物件中。
LoadFromFile 這個 method 的輸入值就是你要開啟的路徑與檔案名稱。

同樣地, 要將影像物件的內容儲存成 BMP 影像檔案, 也是有兩個步驟:

1. 利用 SavePictureDialog1->Execute() 來選定你所希望開啟的影像。

2.
利用 Image1->Picture->SaveToFile(SavePictureDialog1->FileName)
 將影像內容儲存成檔名為 SavePictureDialog1->FileName 的 BMP 檔案中