Archive for the ‘BCB經典範例’ Category
問題描述:
為了讓BCB使用其他C++編譯器產生的DLL檔案,首先使用靜態調度DLL的方式,方法為產生BCB需要的Lib檔案(使用implib MainAlgorithm.lib MainAlgorithm.dll 來產生)
包入*.lib後,在檔案開頭用
extern "C" __declspec(dllimport) int SearchSolution(char* info);
宣告…
結果:當我們執行 迴圈: while(SearchSolution(info)){….} 時候,且執行的東西夠大,立刻就會產生Overflow!!該怎麼解決呢?
這個問題,我解了很久,今天終於在一個大陸的網站找到解答,有趣的是,對方是問另一個完全不相干的問題,我就在想,該不會這有影響吧!一試下去!果然就靈!只能說C++Builder…我真搞不懂你啊XD…
答案….使用動態調度DLL大法!!!!
改宣告
HANDLE hdDll;
int ( *Dll_SearchSolution)(char* info);
hdDll=LoadLibrary("MainAlgorithm.dll");//使用WinAPI
Dll_SearchSolution = (int( *)(char* info))GetProcAddress(hdDll,"SearchSolution");
接下來改使用Dll_SearchSolution 取代原先的函數!解決!
[BCB] 如何限制視窗最小大小
Posted 2011 年 06 月 10 日
on:- In: BCB經典範例
- 8 Comments
問題:
我用BCB設計了一個視窗,想讓使用者調整大小,但不希望樣式被破壞,因此想要限制使用者縮小視窗最小寬度或高度、我該怎麼設計?
笨的解法:
在FormResize事件當中限制能縮的大小,比方說:
if(Form1->Width<300) Form1->Width=300;
但這樣使用者縮視窗時後、會有震動的問題
聰明解法:
直接在初始化時後設定
Form1->Constraints->MinWidth=800;
就可以了!
昨天的方法,在輸入第一個字元為enter可能會導致出問題
另外要解的另個問題是,如果輸出超過兩行字、則會有行號判斷錯誤問題,幸好我們也找到解決方案
這邊設定字型為12,如果不是12,你在下面*19部分要調整一下
if(Key==13)
{
suiMemo_Input->Lines->Delete(LineNum++); //消去最後一行
suiMemo_Input->Lines->Append("> "+Edit_Simulation->Text);//將訊息印出
ToolButton1Click(Sender);
suiMemo_Input->Lines->Append("> "); //並增加下一個>記號
//if(Edit_Simulation->Top<19*10) Edit_Simulation->Top+=19; //改變Edit位置,讓使用者以為換行
if(suiMemo_Input->CaretPos.y<14) Edit_Simulation->Top = (suiMemo_Input->CaretPos.y-1) * 19 + 2;
Edit_Simulation->Clear(); //當然,要清除掉原先內容
}
if ( Shift.Contains(ssCtrl))//最重要的部份!偵測是否有按下CTRL!
{
if(Key==65)//A
Edit_Simulation->SelectAll();//當ctrl+A發生時候,使用全選
if(Key=='V')
{ //很無聊的bug….當第一個字元為換行,則會沒有反應
Memo1->PasteFromClipboard();
if(Memo1->Text.Pos("\r\n")==1) if(Memo1->Text.Pos("1."))
Edit_Simulation->Text = (Memo1->Text.SubString(Memo1->Text.Pos("1"), Memo1->Text.Length()));
Memo1->Clear();
}
}
[BCB] 如何寫一個模擬DOS輸入命令列的視窗
Posted 2011 年 06 月 06 日
on:問題:
在C++Builder中,我想寫一個類似(模擬) DOS視窗的組件,有以下特性:
每次我都只能在某一列輸入指令,指令最前面最好有個>提醒記號
按下Enter時候,會顯示在命令列上面,並自動換下一行
答案:
事實上BCB沒有提供這樣的元件,這的確是一種遺憾。.Net也沒有,看來使用Dos命令列來輸入指令大概只能當老人的喜好,
既然沒有我們就自己寫吧!基本原理是使用Memo搭配Edit來模擬。事實上我們是在Edit上輸入命令,並輸出在Memo中
具體做法:
拉一個Memo,一個Edit,將memo的enabled設為false讓使用者無法focured,拉一個Edit,擺在適當位置。
按一下Memo的Lines,改變內容為:
Please input your data at below:
>
當然你也可以根據你的喜好改變這段文字,重點是Edit要剛好在>後面,使用者以為在Memo裡,實際輸入都在Edit中,只是每次按下Enter,會輸出訊息在Memo中…
接著輸入以下程式碼,這邊都很白話,你應該要看得懂每一行在做甚麼
int LineNum=1;
//—————————————————————————
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
LineNum = 1;
}
//—————————————————————————
void __fastcall TForm1::FormShow(TObject *Sender)
{
Edit_Simulation->SetFocus(); //讓游標聚焦在edit,好像命令列一樣
}
//—————————————————————————
void __fastcall TForm1::Edit_SimulationKeyDown(TObject *Sender, WORD &Key,
TShiftState Shift)
{
if(Key==13)
{
suiMemo_Input->Lines->Delete(LineNum++); //消去最後一行
suiMemo_Input->Lines->Append(">"+Edit_Simulation->Text);//將訊息印出
suiMemo_Input->Lines->Append(">"); //並增加下一個>記號
if(Edit_Simulation->Top<100) Edit_Simulation->Top+=21; //改變Edit位置,讓使用者以為換行
Edit_Simulation->Clear(); //當然,要清除掉原先內容
}
}
//—————————————————————————
void __fastcall TForm1::Edit_SimulationKeyPress(TObject *Sender, char &Key)
{
if(Key==13 || Key==1) Key=0; //消除令人困擾的訊息聲音
}
//—————————————————————————
問題:
使用BCB,我拉了一個memo元件,並設計好ctrl+A就會全選的動作,結果只要我在memo元件上按下ctrl+任何按鍵,系統喇叭都會發出噁心的咚咚聲、警告聲,很像古早系統的BEEP,我該怎麼把她消除掉?
解答:
需要攔截系統事件、改系統廣播??太麻煩了,通通不用!
開啟KeyPress事件,加入一行Code就能解決!
void __fastcall TForm1::Memo1KeyPress(TObject *Sender, char &Key)
{
if(Key<10) Key=0;
}
//—————————————————————————
問題:
在BCB中,我拉了一個Speedbutton、並且放了圖案在上面,我要怎麼樣設計成按一下按鈕、就會陷下去,在按一下會彈回來呢?改變down屬性好像沒用!
解答:
使用 Speedbutton->down沒錯,但要記得把GroupIndex設為一個>0的值
- In: BCB經典範例
- 6 Comments
狀況分析
1. 在關閉BCB界面時會出現如下訊息:
An exception (C0000005) occurred during DllEntryPoint or DllMain in module:
c:\program files\borland\cbuilder6\Bin\idefilters60.bpl
2. 按ok後,就出現 "C++ Builder Development Environment發生問題,必須關閉,謹此致歉…"的資訊
這時有 "除錯"/"關閉" 兩個選項
3. 承2,如果選 "關閉",會出現 "Runtime error 216 at 40009009" 的 Error 提示,按下ok就又回到 2.
4. 承2,如果選 "除錯",再關掉除錯的BCB program,才能完全關掉
解決問題的方法:
下載C++Builder 6 Update Pack 4並更新完成
不過官方下載的網址似乎已經消失 ,因此我這邊提供自己下載點的備份檔案
http://www.box.net/shared/lx4hjx63qn
(2011.04.28重新上傳)
這個 UPDATE 主要修正,安裝 UPDATE 1 和 UPDATE 2 後會產生的一些錯誤,例如:關閉程式會出現存取錯誤的訊息:
An exception(C0000005)occurred during DllEntryPoint or DllMain in module:
c:\program files\borland\cbuilder6\Bin\idefilters60.bpl
Runtime error 216 at 40009009
另外這個修正檔也更新了一些 DEPHI 7 和 BCB6 共用的一些 DLL 檔,所以若要安裝 DELHI 請在安裝完後再更新一次程式。
如何用C程式語言擷取全螢幕,並輸出成BMP檔案
Posted 2010 年 07 月 08 日
on:問題:如何用C程式語言擷取全螢幕,並輸出成BMP檔案?
請別回答按下Print Scr XD!
解答:
void CaptureFullWindow(void)
{
HDC hScrDC,
hMemDC;
int width, height;
//the pointer will
save all pixel point's color value
BYTE *lpBitmapBits = NULL;
//creates a device context for the screen device
hScrDC =
CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
//get the screen
point size
width = GetDeviceCaps(hScrDC, HORZRES);
height =
GetDeviceCaps(hScrDC, VERTRES);
//creates a memory device
context (DC) compatible with the screen device(hScrDC)
hMemDC =
CreateCompatibleDC(hScrDC);
//initialise the struct
BITMAPINFO for the bimap infomation,
//in order to use the
function CreateDIBSection
// on wince os, each pixel stored by
24 bits(biBitCount=24)
//and no compressing(biCompression=0)
BITMAPINFO RGB24BitsBITMAPINFO;
ZeroMemory(&RGB24BitsBITMAPINFO, sizeof(BITMAPINFO));
RGB24BitsBITMAPINFO.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
RGB24BitsBITMAPINFO.bmiHeader.biWidth = width;
RGB24BitsBITMAPINFO.bmiHeader.biHeight = height;
RGB24BitsBITMAPINFO.bmiHeader.biPlanes = 1;
RGB24BitsBITMAPINFO.bmiHeader.biBitCount = 24;
//use the function
CreateDIBSection and SelectObject
//in order to get the bimap
pointer : lpBitmapBits
HBITMAP hBitmap = CreateDIBSection(hMemDC,
(BITMAPINFO*)&RGB24BitsBITMAPINFO,
DIB_RGB_COLORS, (void
**)&lpBitmapBits, NULL, 0);
HGDIOBJ hOldBitmap =
SelectObject(hMemDC, hBitmap);
// copy the screen dc to the
memory dc
BitBlt(hMemDC, 0, 0, width, height, hScrDC, 0, 0,
SRCCOPY);
//if you only want to get the every pixel color value,
//you can begin here and the following part of this function will be
unuseful;
//the following part is in order to write file;
//bimap file header in order to write bmp file
BITMAPFILEHEADER bmBITMAPFILEHEADER;
ZeroMemory(&bmBITMAPFILEHEADER, sizeof(BITMAPFILEHEADER));
bmBITMAPFILEHEADER.bfType = 0x4d42; //bmp
bmBITMAPFILEHEADER.bfOffBits = sizeof(BITMAPFILEHEADER) +
sizeof(BITMAPINFOHEADER);
bmBITMAPFILEHEADER.bfSize =
bmBITMAPFILEHEADER.bfOffBits + ((width*height)*3); ///3=(24 / 8)
DWORD dwNumBytes;
HANDLE hFile = CreateFile( L"\\Storage
Card\\capture.bmp",
GENERIC_WRITE,
(DWORD) 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hFile == INVALID_HANDLE_VALUE)
return ;
WriteFile(hFile, &bmBITMAPFILEHEADER, sizeof(BITMAPFILEHEADER),
&dwNumBytes, NULL); // Write the file header
WriteFile(hFile,
&(RGB24BitsBITMAPINFO.bmiHeader), sizeof(BITMAPINFOHEADER),
&dwNumBytes, NULL); // Write the DIB header
WriteFile(hFile,
lpBitmapBits, 3*width*height, &dwNumBytes, NULL); //Write DIB bits
FlushFileBuffers(hFile);
CloseHandle(hFile);
//delete
DeleteObject(hMemDC);
DeleteObject(hScrDC);
DeleteObject(hBitmap);
DeleteObject(hOldBitmap);
}
在bcb使用WinAPI函式撥放PCM資料
Posted 2010 年 01 月 24 日
on:問題:我有一個pcm檔案(純資料檔),我要如何使用BCB/VC++的WindowsAPI函式撥放這個PCM格式的資料?
解答:
char Example_Wave[]=
{
0x52,0x49,0x46,0x46,//RIFF標誌
0x44,0x93,0x6F,0x00,//文件長度,這邊是 7312196 byte
0x57,0x41,0x56,0x45,//Wave標誌
0x66,0x6D,0x74,0x20,//fmt標誌
0x10,0x00,0x00,0x00,//non
0x03,0x00, //格式類別
0x02,0x00, //channel 數量
0x80,0xBB,0x00,0x00,//取樣頻率,這邊是bb80h = 48000
0x00,0xDC,0x05,0x00,//波形音頻數據傳送速率,其值為通道數×每秒數據位數×每樣
//本的數據位數/8。播放軟件利用此值可以估計緩衝區的大小。
0x08,0x00, //數據塊的調整數(按字節算的),其值為通道數×每樣本的數據位值/8。
//播放軟件需要一次處理多個該值大小的字節數據,以便將其值用於緩衝區的調整。
0x20,0x00, //每樣本的數據位數,表示每個聲道中各個樣本的數據位數。這邊是32 bytes
//如果有多個聲道,對每個聲道而言,樣本大小都一樣。
0x64,0x61,0x74,0x61,//數據標記符”data”
0x20,0x93,0x6F,0x00 //語音數據的長度 7312160 byte
};
struct WaveForm
{
char szRiffID[4]; // 'R','I','F','F'
int dwRiffSize;
char szRiffFormat[4]; // 'W','A','V','E'
char szFmtID[4]; // 'f','m','t',' '
int dwFmtSize;
short wFormatTag;
short wChannels;
int dwSamplesPerSec;
int dwAvgBytesPerSec;
short wBlockAlign;
short wBitsPerSample;
char szDataID[4]; // 'd','a','t','a'
int dwDataSize;
}*Wave;
Wave = (struct WaveForm*) Example_Wave;
TMemoryStream *pcm = new TMemoryStream;
pcm->LoadFromFile(OpenDialog1->FileName);
Wave->dwDataSize = pcm->Size;
Wave->dwRiffSize = pcm->Size+36;
TMemoryStream *wav2 = new TMemoryStream;
wav2->Write(Wave,sizeof(struct WaveForm));
wav2->Write(pcm->Memory,pcm->Size);
PlaySound((char *)wav2->Memory, 0, SND_SYNC | SND_MEMORY);
delete pcm;
delete wav2;
如何設定ListView的其中一列被選取
Posted 2010 年 01 月 23 日
on:問題:
BCB中,我想在ListView元件上新增一列資料,並設定他被選取,我該怎麼做呢?
設定temp->Selected都沒反應啊!!
解答:
TListItem *temp = ListView1->Items->Add();
temp->Caption = ”Test”;
temp->Selected = true;
temp->Focused = true;
ListView1->SetFocus(); 即可
但要注意囉!如果你是把ListView1放到另外一個元件上,比方說PageControl,
則會出現BUG訊息,目前推估是bcb元件問題
解決方式:令此元件被focued,範例:(以PageControl為例)
suiPageControl1->ActivePageIndex = 1;
suiPageControl1->ActivePageIndex = 0;
(這邊ListView是放在suiPageControl1的第一個分頁)
近期迴響