線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:2323
推到 Plurk!
推到 Facebook!

按鈕連接圖片反白 疑問

答題得分者是:herbert2
nba2005mt
一般會員


發表:5
回覆:9
積分:2
註冊:2012-09-03

發送簡訊給我
#1 引用回覆 回覆 發表時間:2012-09-11 18:30:52 IP:125.224.xxx.xxx 訂閱
 請教各位
我現在做了6個按鈕(假設)
我點擊任一個按鈕 對應的圖片就會反白
讓使用者知道 現在選擇到的功能是哪一個
在點擊一次 反白就會取消

請問 要怎麼才可以讓點擊別的按鈕後 原先點擊的反白的圖片 取消反白
舉個例子

其中兩個按鈕 A , B 對應圖片為 a , b

點A按鈕時 圖片a反白
點b按鈕時 圖片a反白取消 圖片b反白

以下為按鈕 click的程式碼

Byte* ptr;
Graphics::TBitmap *TheBitmap;
//------------------------------------------------
TheBitmap=Image1->Picture->Bitmap;
//------------------------------------------------
for(int y=0; yHeight; y )
{
ptr = (Byte*)TheBitmap->ScanLine[y];
for (int x=0; xWidth; x )
ptr[x]=(Byte)(255-ptr[x]);
}
Repaint();




請各位大哥大姐幫幫忙
noodlejay
一般會員


發表:8
回覆:18
積分:10
註冊:2011-08-10

發送簡訊給我
#2 引用回覆 回覆 發表時間:2012-09-13 21:47:18 IP:120.107.xxx.xxx 訂閱
 每個按鈕,對應設一個全域變數,

按A→ A=1; B=0;

按B→A=0;B=1;

然後用條件式去判斷
nba2005mt
一般會員


發表:5
回覆:9
積分:2
註冊:2012-09-03

發送簡訊給我
#3 引用回覆 回覆 發表時間:2012-09-14 09:29:13 IP:125.224.xxx.xxx 訂閱
 不知 能否再多說明一些
小弟對這 實在了解的很淺

感謝你的回覆
herbert2
尊榮會員


發表:58
回覆:632
積分:878
註冊:2004-04-16

發送簡訊給我
#4 引用回覆 回覆 發表時間:2012-09-14 10:40:46 IP:202.39.xxx.xxx 訂閱
每個 VCL 元件,都有一個 int 的 Property 叫做 Tag,初值都是 0,可任憑自己運用。
每個按鈕的 OnClick ,都使用同一個 Event。
假設共有9個 BitBtn,在 .h 宣告 Btn[9], 在 .cpp 的 Constructor 段,設 Btn[0] = BitBtn1; .... Btn[8] = BitBtn9;
則:


[code cpp]

// .h 檔
//-----------------------------------------------------------
....
private:
....
TBitBtn *Btn[9]; // 宣告
....

//-----------------------------------------------------------
// .cpp 檔
void __fastcall TForm1::TForm1(TComponent *Owner) : TForm(Owner)
{
// Constructor 段
Btn[0] = BitBtn1; // 給值
Btn[1] = BitBtn2;
Btn[2] = BitBtn3;
Btn[3] = BitBtn4;
Btn[4] = BitBtn5;
Btn[5] = BitBtn6;
Btn[6] = BitBtn7;
Btn[7] = BitBtn8;
Btn[8] = BitBtn9;
/*
// 或先宣告一個 local TBitBtn 陣列 TmpBtn[9] 並填值(必須一個 Statement 完成)
TBitBtn *TmpBtn[9] = {BitBtn1,BitBtn2,BitBtn3,BitBtn4,BitBtn5,BitBtn6,BitBtn7,BitBtn8,BitBtn9};
// 再轉入 private 的 Btn[9]
for (int i = 0; i < 9) {
Btn[i] = TmpBtn[i];
}
*/
}
//-----------------------------------------------------------
void __fastcall TForm1::BitBtn1Click(TObject *Sender)
{
// 將 Sender 轉成目前 Click 的 BitBtn,記錄下其 Name 供後面程式使用
AnsiString sxName;
sxName = ((TBitBtn *)Sender)->Name;
for (int i = 0; i < 9; i) {
if (Btn[i]->Name == sxName) {
// 0...8 中之第 i 個 TBitBtn 為目前 Click 者
if (Btn[i]->Tag == 0) {
Btn[i]->Tag = 1;
// Btn[i] 的圖形反白的處理
}
}
else {
if (Btn[i]->Tag == 1) {
Btn[i]->Tag = 0;
// Btn[i] 的圖形恢復正常的處理
}
}
}
// 最後,Btn[i] 的 Tag 尚可做其他用途的判斷
}
//-----------------------------------------------------------

[/code]


編輯記錄
herbert2 重新編輯於 2012-09-13 20:42:11, 註解 無‧
herbert2 重新編輯於 2012-09-13 20:44:13, 註解 無‧
herbert2 重新編輯於 2012-09-13 20:44:52, 註解 無‧
herbert2 重新編輯於 2012-09-13 20:45:34, 註解 無‧
herbert2 重新編輯於 2012-09-13 20:47:12, 註解 程式碼區的縮格不正常,怎麼改都不對?!‧
herbert2 重新編輯於 2012-09-14 00:08:47, 註解 無‧
herbert2 重新編輯於 2012-09-14 00:10:04, 註解 無‧
herbert2 重新編輯於 2012-09-15 09:54:14, 註解 無‧
herbert2 重新編輯於 2012-09-15 09:57:06, 註解 無‧
noodlejay
一般會員


發表:8
回覆:18
積分:10
註冊:2011-08-10

發送簡訊給我
#5 引用回覆 回覆 發表時間:2012-09-14 15:49:41 IP:120.107.xxx.xxx 訂閱
  herbert2 處理的方式更為簡潔進階。

只是不太懂,這一段的作法
假設共有9個 BitBtn,在 .h 宣告 Btn[9], 在 .cpp 的 Constructor 段,設 Btn[0] = BitBtn1; .... Btn[8] = BitBtn9;

我原先想說是用String來判斷,Btn[i]->Name 代表這是存取到原件?
nba2005mt
一般會員


發表:5
回覆:9
積分:2
註冊:2012-09-03

發送簡訊給我
#6 引用回覆 回覆 發表時間:2012-09-14 17:32:04 IP:125.224.xxx.xxx 訂閱
 不好意思  小弟對這段  不太了解
在.h 檔裡面宣告 Btn[9] 該怎麼寫 (> < 我這個也不會)




在 .h 宣告 Btn[9], 在 .cpp 的 Constructor 段,設 Btn[0] = BitBtn1; .... Btn[8] = BitBtn9;
noodlejay
一般會員


發表:8
回覆:18
積分:10
註冊:2011-08-10

發送簡訊給我
#7 引用回覆 回覆 發表時間:2012-09-14 21:41:02 IP:120.107.xxx.xxx 訂閱
 但你還是可以用String,

宣告 AnsiString Btn[9]; 然把後個別Button的Name打進去,Btn[0]="BitBtn1"; .....


後面條件式在做一點修改
...

(Btn[i]== sxNamer)
..
..

我想也是可以的。
herbert2
尊榮會員


發表:58
回覆:632
積分:878
註冊:2004-04-16

發送簡訊給我
#8 引用回覆 回覆 發表時間:2012-09-16 23:23:28 IP:202.39.xxx.xxx 訂閱
再舉另一種寫法供參考:

每個 VCL 元件,都有一個 int 的 Property 叫做 Tag,初值都是 0,可任憑自己運用。
每個按鈕的 OnClick ,都使用同一個 Event。
假設共有5個 BitBtn,在 .h 宣告 Btn[5], 在 .cpp 的 Constructor 段,設 Btn[0] = BitBtn1; .... Btn[4] = BitBtn5;
(因9個在本論壇之程式碼區會折到下一列,故改成5個做示範)
我把這5個 BitBtn->Tag 分別先填上 0~4 代表其在陣列中的 Index。
則:

[code cpp]

// .h 檔
//-----------------------------------------------------------
....
private:
....
TBitBtn *Btn[5]; // 宣告
int igHi;
....
//-----------------------------------------------------------
// .cpp 檔
void __fastcall TForm1::TForm1(TComponent *Owner) : TForm(Owner)
{
// 此為 Constructor 段
// 先宣告一個 local TBitBtn 陣列 TmpBtn[5] 並填值(必須一個 Statement 完成)
TBitBtn *TmpBtn[5] = {BitBtn1,BitBtn2,BitBtn3,BitBtn4,BitBtn5};
// 再轉入 private 的 Btn[5]
for (int i = 0; i < 5) {
Btn[i] = TmpBtn[i]; // 註: Btn[i]->Tag = i;
}
igHi = -1; // 目前5個 BitBtn 皆未反白
}
//-----------------------------------------------------------
void __fastcall TForm1::BitBtn1Click(TObject *Sender)
{
// 將 Sender 轉成目前 Click 的 BitBtn,記錄下其 Index 供後面程式使用
int ixTag;
ixTag = ((TBitBtn *)Sender)->Tag;
for (int i = 0; i < 5; i) {
if (Btn[i]->Tag != ixTag) {
// 非目前 Click 者
if (i == igHi) {
// Btn[i] 的圖形恢復正常的處理
}
}
}
// 0...4 中之第 ixTag 個 TBitBtn 為目前 Click 者
if (ixTag != igHi) {
// Btn[ixTag] 的圖形反白的處理
}
igHi = ixTag;
// 最後,igHi 尚可做其他用途的判斷
}
//-----------------------------------------------------------

[/code]

為了縮格位置正確,縮格用一個全型空白取代兩個半型空白,真正的程式須改回半型空白。

編輯記錄
herbert2 重新編輯於 2012-09-16 09:27:54, 註解 無‧
herbert2 重新編輯於 2012-09-16 09:29:20, 註解 無‧
herbert2 重新編輯於 2012-09-18 03:37:10, 註解 無‧
nba2005mt
一般會員


發表:5
回覆:9
積分:2
註冊:2012-09-03

發送簡訊給我
#9 引用回覆 回覆 發表時間:2012-09-17 18:34:01 IP:125.224.xxx.xxx 訂閱
 不好意思  我照著你的方法去做  但將圖片恢復正常處理   我試不出來  可以在請教你該怎麼下手嗎?
感謝兩位的幫忙

感恩感恩
herbert2
尊榮會員


發表:58
回覆:632
積分:878
註冊:2004-04-16

發送簡訊給我
#10 引用回覆 回覆 發表時間:2012-09-18 17:43:23 IP:202.39.xxx.xxx 訂閱
圖形反白的處理與圖形恢復正常的處理應該都是您寫的同一個函式可處理吧!
原始圖一個點 13: 255 - 13 = 242 // 變反白
反白圖一個點242: 255 - 242 = 13 // 恢復原值
nba2005mt
一般會員


發表:5
回覆:9
積分:2
註冊:2012-09-03

發送簡訊給我
#11 引用回覆 回覆 發表時間:2012-09-18 18:41:07 IP:125.224.xxx.xxx 訂閱
 不好意思  
我也是這樣想
不過 我試不出結果
ptr[x] =(Byte)(255-ptr[x]); // 這是我參考書籍得來的

我在設一個optr

這樣在RUN的時沒有error
在執行按鈕Click的時 就會跳出錯誤視窗
noodlejay
一般會員


發表:8
回覆:18
積分:10
註冊:2011-08-10

發送簡訊給我
#12 引用回覆 回覆 發表時間:2012-09-19 13:34:40 IP:120.107.xxx.xxx 訂閱
 你使用的圖片格式為何? 

我猜測是記憶體跟指標方面的問題,

你可能需要貼出比較完整的程式。
nba2005mt
一般會員


發表:5
回覆:9
積分:2
註冊:2012-09-03

發送簡訊給我
#13 引用回覆 回覆 發表時間:2012-09-24 14:40:51 IP:125.224.xxx.xxx 訂閱
 Byte *iptr, *optr, *ptr;
Graphics::TBitmap *TheBitmap, *OrgBitmap, *TempBitmap;
AnsiString sxName;
sxName = ((TBitBtn *)Sender)->Name;
for (int i = 0; i < 2; i)
{
if (Btn[i]->Name == sxName)
{
if (Btn[i]->Tag == 0)
{
Btn[i]->Tag = 1;
TheBitmap=Image1->Picture->Bitmap;
for(int y=0; yHeight; y )
{
ptr = (Byte*)TheBitmap->ScanLine[y];
for (int x=0; xWidth; x )
ptr[x]=(Byte)(255-ptr[x]);
}
Repaint();
}
}
else
{
if (Btn[i]->Tag == 1)
{
Btn[i]->Tag = 0;
}
}
}
}


不好意思 這是按鈕程式 這樣執行結果 會是(兩個按鈕 A B)
點擊案扭會反白 不過 兩個按鈕以上 反白動作會變成怪怪的
nba2005mt
一般會員


發表:5
回覆:9
積分:2
註冊:2012-09-03

發送簡訊給我
#14 引用回覆 回覆 發表時間:2012-09-24 14:57:16 IP:125.224.xxx.xxx 訂閱
  TheBitmap=Image1->Picture->Bitmap;
for(int y=0; yHeight; y )
{
optr = (Byte*)TheBitmap->ScanLine[y];
for (int x=0; xWidth; x )
optr[x]=(Byte)(255-ptr[x]);
}
Repaint();
}
nba2005mt
一般會員


發表:5
回覆:9
積分:2
註冊:2012-09-03

發送簡訊給我
#15 引用回覆 回覆 發表時間:2012-09-25 16:49:15 IP:125.224.xxx.xxx 訂閱
 不好意思  感謝兩位的大力幫忙與協助
小弟 找到解決方法了

TheBitmap=Image1->Picture->Bitmap;
for(int y=0; yHeight; y )
{
ptr = (Byte*)TheBitmap->ScanLine[y];
for (int x=0; xWidth; x )
ptr[x]=(Byte)(255-ptr[x]);
}
Repaint();
}

恢復反白 程式碼 與反白程式碼相同
我只改紅色字體 部分 就可以兩個切換
兩個以上 就沒去試了
系統時間:2017-12-13 9:32:18
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!