String str = "C:\\Program Files\\Borland\\CBuilder6\\Projects\\Project1.exe";
Label1->Caption = ExtractFileName(str);
// Project1.exe
Label2->Caption = ExtractFilePath(str);
// C:\Program Files\Borland\CBuilder6\Projects\
Label3->Caption = ExtractFileDir(str);
// C:\Program Files\Borland\CBuilder6\Projects
Label4->Caption = ExtractFileDrive(str);
// C:
Label5->Caption = ExtractFileExt(str);
// .exe
2010年10月15日 星期五
2010年8月20日 星期五
2010年8月5日 星期四
[BCB] Memo 與 RichEdit
Memo 無法對每一行文字做不同的顏色,
用 RichEdit 則可以透過設定,RichEdit1->SelAttributes->Color = clBlue
來變換文字的顏色。
用 RichEdit 則可以透過設定,RichEdit1->SelAttributes->Color = clBlue
來變換文字的顏色。
2010年8月3日 星期二
[BCB] 設定 OpenDialog 開啟資料夾的起始位置
只透過設定 InitialDir ,每次開啟時還是會回到上次開啟檔案的目錄下,
還必須將 Options 下的 ofNoChangeDir 設成 true 才會每次都開啟設定好的位置。
2010年6月29日 星期二
[BCB] 定義自己的鼠標圖示
到 Tools -> Image Editor 就可以直接修改 res 檔的鼠標圖案,
更改完後存檔就可以使用,如果沒有更新,就把 res 檔從 project 從移除,
再 add 一次就行了。(不 add,也可以使用 )
0xfffffff0 ~ 0xffffffff 的位址已有內建的滑鼠圖示,
所以可以從 0x1 開始定義自己要對應的滑鼠圖示,
如下的範例 :
#pragma resource "Project1.res" //使用前要先引入 res
const int crDraw = 6;
HINSTANCE HInst;
HInst = reinterpret_cast<HINSTANCE>(HInstance);
// Load custom cursors for tools from extrares.res
// ABC 是 cusor 的名稱
Screen->Cursors[crDraw] = LoadCursor(HInst, "ABC");
Cursor = TCursor(crDraw);
0xfffffff0 ~ 0xffffffff 的位址已有內建的滑鼠圖示,
所以可以從 0x1 開始定義自己要對應的滑鼠圖示,
如下的範例 :
#pragma resource "Project1.res" //使用前要先引入 res
const int crDraw = 6;
HINSTANCE HInst;
HInst = reinterpret_cast<HINSTANCE>(HInstance);
// Load custom cursors for tools from extrares.res
// ABC 是 cusor 的名稱
Screen->Cursors[crDraw] = LoadCursor(HInst, "ABC");
Cursor = TCursor(crDraw);
2010年5月28日 星期五
[BCB] TStringList 的排序
TStringList *list = new TStringList();
// 原始內容 {"22", "211", "222", "33"};
list->Sort();
// Sort() 後的結果, 是依序比較字串開頭的大小 {211, 22, 222, 33};
// 想按數字大小排序 {22, 33, 211, 222};, 需用 CustomSort()
list->CustomSort(compare);
// 並自訂 compare function
int __fastcall compare(TStringList* List, int Index1, int Index2)
{
if (StrToInt(List->Strings[Index1]) > StrToInt(List->Strings[Index2]))
return 1;
else if (StrToInt(List->Strings[Index1]) == StrToInt(List->Strings[Index2]))
return 0;
else
return -1;
}
// 原始內容 {"22", "211", "222", "33"};
list->Sort();
// Sort() 後的結果, 是依序比較字串開頭的大小 {211, 22, 222, 33};
// 想按數字大小排序 {22, 33, 211, 222};, 需用 CustomSort()
list->CustomSort(compare);
// 並自訂 compare function
int __fastcall compare(TStringList* List, int Index1, int Index2)
{
if (StrToInt(List->Strings[Index1]) > StrToInt(List->Strings[Index2]))
return 1;
else if (StrToInt(List->Strings[Index1]) == StrToInt(List->Strings[Index2]))
return 0;
else
return -1;
}
2010年4月24日 星期六
[BCB] 連結 MySQL 資料庫
想用 BCB 連結 MySQL 資料庫,可以到網路下載 SQLAPI++ 試用版,
藉由 SQLAPI++ 就不需要透過 ODBC 來連接,方便很多。
官網現在最新的版本是 2010/3/24 發佈的 3.7.31 版,
網路上有比較舊 2007/12/11 發佈的 3.7.23 破解版,
不過舊的版本要先執行 "SET NAMES big5" 指令,不然中文印出來會是亂碼。
另外,若要連線到遠端的 MySQL 資料庫,要注意兩點 :
1. 必須在 Server 端的防火牆,新增 MySQL 的連接埠 (MySQL 的預設值為 3306)。
2. 無法用帳號 root 遠端連線,必須另開帳號給予權限。
2010年3月9日 星期二
[BCB] 手動觸發 Event 事件
觸發按下 Button 有兩種方法,
// deffine 在 ComCtrls.hpp// enum TUDBtnType { btNext, btPrev };
1. UpDown1->OnClick(UpDown1, btNext);
1. Button1->Click();
2. Button1->OnClick(Button1);
觸發按下 UpDown 則需要多一個參數,用來辨別是下一頁還是上一頁,
// deffine 在 ComCtrls.hpp
1. UpDown1->OnClick(UpDown1, btNext);
2010年1月17日 星期日
[BCB] ScrollBar 的 Enable
用 Property 視窗把 ScrollBar 的 Enable 設為 false,
好像只有在 Position 為 0 的時候可以,真怪。
只好在程式裡在寫一次 ScrollBar1->Enable = false;
2010年1月16日 星期六
[BCB] 三種方法讀取 pixel 中的 RGB
我用了一張 640x480 的圖片作測試。
// 方法一 : 0.016s
for (int i = 0; i < h; i++)
{
ptr1 = (Byte*)Image1->Picture->Bitmap->ScanLine[i];
for (int j = 0; j < w; j++)
{
b = ptr1[3*j];
g = ptr1[3*j+1];
r = ptr1[3*j+2];
}
}
// 方法二 : 0.172s
for (int i = 0; i < h; i++)
for (int j = 0; j < w; j++)
{
color = Image1->Canvas->Pixels[j][i];
b = (color&0xFF0000) >> 16;
g = (color&0x00FF00) >> 8;
r = (color&0x0000FF);
}
// 方法三 : 0.515s
for (int i = 0; i < h; i++)
for (int j = 0; j < w; j++)
{
b = GetBValue(Image1->Canvas->Pixels[j][i]);
g = GetGValue(Image1->Canvas->Pixels[j][i]);
r = GetRValue(Image1->Canvas->Pixels[j][i]);
}
結論是,最好是用指標作,要不然就自己切,絕對不要用內建的 GetRValue() !
後記 :
TheBitmap->PixelFormat = pf32bit;
不論給多少,最好先給值,否則預設為 pfDevice ,這是依據顯卡目前的設定來處理,
而這會使得圖片處理的較慢
// 方法一 : 0.016s
for (int i = 0; i < h; i++)
{
ptr1 = (Byte*)Image1->Picture->Bitmap->ScanLine[i];
for (int j = 0; j < w; j++)
{
b = ptr1[3*j];
g = ptr1[3*j+1];
r = ptr1[3*j+2];
}
}
// 方法二 : 0.172s
for (int i = 0; i < h; i++)
for (int j = 0; j < w; j++)
{
color = Image1->Canvas->Pixels[j][i];
b = (color&0xFF0000) >> 16;
g = (color&0x00FF00) >> 8;
r = (color&0x0000FF);
}
// 方法三 : 0.515s
for (int i = 0; i < h; i++)
for (int j = 0; j < w; j++)
{
b = GetBValue(Image1->Canvas->Pixels[j][i]);
g = GetGValue(Image1->Canvas->Pixels[j][i]);
r = GetRValue(Image1->Canvas->Pixels[j][i]);
}
結論是,最好是用指標作,要不然就自己切,絕對不要用內建的 GetRValue() !
後記 :
TheBitmap->PixelFormat = pf32bit;
不論給多少,最好先給值,否則預設為 pfDevice ,這是依據顯卡目前的設定來處理,
而這會使得圖片處理的較慢
2009年11月2日 星期一
[BCB] TImage 和 TBitmap
在 BCB 裡,讀取 TImage 的像素和 TBitmap 的像素時間是差不多的,
但是寫入的時間卻是差很多,我用四種方法對同一個位置寫了 100000 次,
// 執行時間: 0.125s
for (int i = 0; i < 100000; i++)
TheBitmap->Canvas->Pixels[0][0] = TColor(RGB(0, 0, 0));
// 執行時間: 0.125s
for (int i = 0; i < 100000; i++)
TheBitmap->Canvas->Pixels[0][0] = clBlack;
// 執行時間: 0.969s
for (int i = 0; i < 100000; i++)
Image1->Canvas->Pixels[0][0] = TColor(RGB(0, 0, 0));
// 執行時間: 0.969s
for (int i = 0; i < 100000; i++)
Image1->Picture->Bitmap->Canvas->Pixels[0][0] = TColor(RGB(0, 0, 0));
結果發現,TBitmap 的寫入時間較快,此外搭配 ScanLine[] 和指標會比直接設
Pixels 快上 50 倍以上,所以要畫圖最好用間接的方式 :
Pixels 快上 50 倍以上,所以要畫圖最好用間接的方式 :
Graphics::TBitmap *TheBitmap;
TheBitmap = new Graphics::TBitmap();
TheBitmap->Height = h;
TheBitmap->Width = w;
對 TBitmap 寫值...
Image1->Picture->Bitmap = TheBitmap;
這樣會有較好的執行效率,也可以避免畫面閃爍。
訂閱:
文章 (Atom)