流
中階會員
發表:36 回覆:142 積分:70 註冊:2003-07-24
發送簡訊給我
|
各位前輩好: 小弟參考了 http://delphi.ktop.com.tw/topic.php?TOPIC_ID=20816 這篇文章 進了連結的網址 http://www.bridgespublishing.com/articles/issues/0109/Custom_buttons__part_I.htm 小弟也想讓 Button 改變顏色,不過小弟試了 TColorButton 下的宣告
compile 都可以過,只是畫面 Show 出來什麼也沒有,跟網址上給的 Fig B 差很遠
小弟從網址上複製的 code 如下,希望前輩告知小弟哪裡疏忽了
然後才能順利的開啟有顏色的 Button
Unit.h 的部份 #ifndef Unit1H
#define Unit1H
#include
#include
#include
#include <Forms.hpp>
#include // 繼承 TButton 類別之 TColorButton 及函數宣告部份 class TColorButton : public TButton
{
public:
__fastcall TColorButton(TComponent* Owner); __published: __property TColor Color =
{read = GetColor, write = SetColor};
__property TColor ColorLo =
{read = ColorLo_, write = SetColorLo,
default = clBtnShadow};
__property TColor ColorHi =
{read = ColorHi_, write = SetColorHi,
default = clBtnHighlight}; protected:
// inherited member functions
virtual void __fastcall CreateParams(
TCreateParams& Params);
virtual void __fastcall SetButtonStyle(
bool ADefault); // introduced member functions
virtual void __fastcall DoDrawButtonFace(
const TOwnerDrawState& state);
virtual void __fastcall DoDrawButtonText(
const TOwnerDrawState& state); private:
TColor ColorLo_;
TColor ColorHi_;
std::auto_ptr Canvas_;
bool draw_as_default_; TColor __fastcall GetColor();
void __fastcall SetColor(TColor Value);
void __fastcall SetColorLo(TColor Value);
void __fastcall SetColorHi(TColor Value); MESSAGE void __fastcall CNDrawItem(
TMessage& Msg);
MESSAGE void __fastcall WMLButtonDblClk(
TMessage& Msg);
MESSAGE void __fastcall CMFontChanged(
TMessage& Msg);
MESSAGE void __fastcall CMEnabledChanged(
TMessage& Msg); public:
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(
CN_DRAWITEM, TMessage, CNDrawItem)
MESSAGE_HANDLER(
WM_LBUTTONDBLCLK, TMessage, WMLButtonDblClk)
MESSAGE_HANDLER(
CM_FONTCHANGED, TMessage, CMFontChanged)
MESSAGE_HANDLER(
CM_ENABLEDCHANGED, TMessage, CMEnabledChanged)
END_MESSAGE_MAP(TButton)
}; void __fastcall TColorButton::
CreateParams(TCreateParams& Params)
{
TButton::CreateParams(Params);
Params.Style |= BS_OWNERDRAW;
} void __fastcall TColorButton::
SetButtonStyle(bool ADefault)
{
if (draw_as_default_ != ADefault)
{
draw_as_default_ = ADefault;
InvalidateRect(Handle, NULL, FALSE);
}
} void __fastcall TColorButton::
CNDrawItem(TMessage& Msg)
{
// grab pointer to the DRAWITEMSTRUCT
const DRAWITEMSTRUCT* pDrawItem =
reinterpret_cast
(Msg.LParam); // store the current state of
// the target DC
SaveDC(pDrawItem->hDC);
// bind Canvas_ to the target DC
Canvas_->Handle = pDrawItem->hDC;
try
{
// extract the state flags...
TOwnerDrawState state;
// if the button has keyboard focus
if (pDrawItem->itemState & ODS_FOCUS)
{
state = state << odFocused;
}
// if the button is pushed
if (pDrawItem->itemState &
ODS_SELECTED)
{
state = state << odSelected;
}
// if the button is disabled
if (pDrawItem->itemState &
ODS_DISABLED)
{
state = state << odDisabled;
} // draw the button's face
DoDrawButtonFace(state); // draw the button's text
DoDrawButtonText(state);
}
catch (...)
{
// clean up
Canvas_->Handle = NULL;
RestoreDC(pDrawItem->hDC, -1);
}
// clean up
Canvas_->Handle = NULL;
RestoreDC(pDrawItem->hDC, -1); // reply TRUE
Msg.Result = TRUE;
} void __fastcall TColorButton::
DoDrawButtonFace(
const TOwnerDrawState& state
)
{
// draw a colored button...
Canvas_->Brush = Brush;
TRect RClient = ClientRect; // if the button is the default button
// or has keyboard focus...
if (draw_as_default_ ||
state.Contains(odFocused))
{
Canvas_->Pen->Color = clWindowFrame;
Canvas_->Rectangle(
RClient.Left, RClient.Top,
RClient.Right, RClient.Bottom
);
InflateRect(
reinterpret_cast(&RClient),
-1, -1
);
} // if the button is pushed...
if (state.Contains(odSelected))
{
Canvas_->Pen->Color = ColorLo_;
Canvas_->Rectangle(
RClient.Left, RClient.Top,
RClient.Right, RClient.Bottom
);
} // if the button isn't pushed...
else
{
Canvas_->FillRect(RClient);
Frame3D(
Canvas_.get(), RClient,
ColorHi_, clWindowFrame, 1
); POINT P[] = {
{1, RClient.Bottom - 1},
{RClient.Right - 1,
RClient.Bottom - 1},
{RClient.Right - 1,
RClient.Top - 1}
};
Canvas_->Pen->Color = ColorLo_;
Canvas_->Polyline(
reinterpret_cast(P), 2
);
}
} void __fastcall TColorButton::
DoDrawButtonText(
const TOwnerDrawState& state)
{
if (Caption.Length() == 0) return; RECT RText = {0, 0, Width, Height};
Canvas_->Font = Font;
Canvas_->Brush = Brush;
SetBkMode(
Canvas_->Handle, TRANSPARENT
); // if the button is pushed...
if (state.Contains(odSelected))
{
// offset the caption
OffsetRect(&RText, 1, 1);
}
// if the button is disabled...
if (!Enabled ||
state.Contains(odDisabled))
{ // render the caption
// in a disabled fashion
OffsetRect(&RText, 1, 1);
Canvas_->Font->Color = ColorHi_;
DrawText(
Canvas_->Handle, Caption.c_str(),
-1, &RText, DT_CENTER |
DT_VCENTER | DT_SINGLELINE
);
OffsetRect(&RText, -1, -1);
Canvas_->Font->Color = ColorLo_;
} // render the caption
DrawText(
Canvas_->Handle, Caption.c_str(), -1,
&RText, DT_CENTER | DT_VCENTER |
DT_SINGLELINE
); // if the button has keyboard focus...
if (state.Contains(odFocused))
{
// render the selection rectangle
TRect RFocus = ClientRect;
InflateRect(
reinterpret_cast(&RFocus),
-4, -4
);
Canvas_->DrawFocusRect(RFocus);
}
} TColor __fastcall TColorButton::
GetColor()
{
return Brush->Color;
} void __fastcall TColorButton::
SetColor(TColor Value)
{
if (Brush->Color != Value)
{
Brush->Color = Value;
InvalidateRect(Handle, NULL, TRUE);
}
} void __fastcall TColorButton::
SetColorLo(TColor Value)
{
if (ColorLo_ != Value)
{
ColorLo_ = Value;
InvalidateRect(Handle, NULL, TRUE);
}
} void __fastcall TColorButton::
SetColorHi(TColor Value)
{
if (ColorHi_ != Value)
{
ColorHi_ = Value;
InvalidateRect(Handle, NULL, TRUE);
}
} void __fastcall TColorButton::
CMFontChanged(TMessage& Msg)
{
TButton::Dispatch(&Msg);
InvalidateRect(Handle, NULL, TRUE);
} void __fastcall TColorButton::
CMEnabledChanged(TMessage& Msg)
{
TButton::Dispatch(&Msg);
InvalidateRect(Handle, NULL, TRUE);
} void __fastcall TColorButton::
WMLButtonDblClk(TMessage& Msg)
{
SNDMSG(
Handle, WM_LBUTTONDOWN,
Msg.WParam, Msg.LParam
);
} class TForm1 : public TForm
{
__published: // IDE-managed Components
private: // User declarations
public: // User declarations
__fastcall TForm1(TComponent* Owner); }; extern PACKAGE TForm1 *Form1;
#endif Unit1.cpp 的部份 #include
#pragma hdrstop
#include "Unit1.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1; __fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
} __fastcall TColorButton::TColorButton(TComponent* Owner)
: TButton(Owner), ColorLo_(clBtnShadow), ColorHi_(clBtnHighlight),
Canvas_(new TCanvas()),draw_as_default_(false)
{
} // end the declaration 程式看一看好像是小弟沒有給 TColorButton 的物件
可是小弟在 Button1OnClick中打上
TColorButton *CB1 = new TColorButton
compile 就不會過了,該是小弟沒某些觀念
所以小弟不知怎麼去使用這物件
懇請前輩指點一二 麻煩前輩了 發表人 - 流 於
|
AB
高階會員
發表:166 回覆:262 積分:125 註冊:2003-08-21
發送簡訊給我
|
http://delphi.ktop.com.tw/topic.php?topic_id=30161
也許可以參考看看
|
taishyang
站務副站長
發表:377 回覆:5490 積分:4563 註冊:2002-10-08
發送簡訊給我
|
流您好:
試試下面的code
void __fastcall TForm1::FormCreate(TObject *Sender)
{
TColorButton* Test = new TColorButton(Form1);
Test->Parent=Form1;
Test->Top=0;
Test->Left=0;
Test->Color=clBlue ;
Test->Caption="藍色按鈕";
}
//---------------------------------------------------------------------------
順心 <>~我也是在學習的階段,回答的不好請您多多見諒與指教~> 發表人 -
|
流
中階會員
發表:36 回覆:142 積分:70 註冊:2003-07-24
發送簡訊給我
|
AB 您好: 感謝您的回覆,小弟有試著安裝,不過卻在 compile 時就不成功
爬文的結果是跟 dclusr 有關,改來改去後還是不行
小弟認為怪怪的,於是又重灌了一次 BCB 6
離奇的是,重灌前 compile 出現一個錯誤
重灌後 compile 出現了好幾個錯誤,都是顯示 outline()... 這類訊息
參考了 ColorButton.pas 內容後,發現其實跟小弟貼的差不多說 現在有了 >
|
流
中階會員
發表:36 回覆:142 積分:70 註冊:2003-07-24
發送簡訊給我
|
taishyang 版主您好: 小弟想把這個元件 Install 為 Component
小弟剛剛參考手邊 文魁 C 與 RS232 這本書元件的 Install 過程
但是小弟從沒安裝過元件,又絕得怕怕的
生怕安裝不好小弟又會開始想重灌 BCB 6 希望 taishyang 版主您可以告訴小弟
有哪些 code 需要再加進去, cpp 檔裡要注意什麼
小弟是覺得這些內容好像還不能成為 VCL 元件 沒另開新題的原因是,也許以後有人也想要這個 ColorButton 時
也可以整篇的參考,要不要做成元件也有個選擇 謝謝
|
taishyang
站務副站長
發表:377 回覆:5490 積分:4563 註冊:2002-10-08
發送簡訊給我
|
流您好:
引言:
希望 taishyang 版主您可以告訴小弟
有哪些 code 需要再加進去, cpp 檔裡要注意什麼
小弟是覺得這些內容好像還不能成為 VCL 元件
沒另開新題的原因是,也許以後有人也想要這個 ColorButton 時
也可以整篇的參考,要不要做成元件也有個選擇
1.應該還需要製作一個圖示,也可以不做,會有內建的圖示,製作方式如下面連結
http://delphi.ktop.com.tw/topic.php?TOPIC_ID=38974
2.要安裝VCL的話接下來就如同安裝文魁C 與RS232 書中安裝TCOMM元件一樣
的步驟,[Component]->[Install Component]->[Unit File Name]
選擇該cpp即可,製作圖示方式這本書也有提到 順心 <>~我也是在學習的階段,回答的不好請您多多見諒與指教~> 發表人 -
|
流
中階會員
發表:36 回覆:142 積分:70 註冊:2003-07-24
發送簡訊給我
|
taishyang 版主您好: 小弟快昏倒了,試了四五個小時了
還是沒能將元件順利的安裝
金禾及文魁那本書小弟都有... 小弟安裝過程如下:
(1) New → Component :
Ancestor type → Tbutton [StdCtls]
Class Name → TColorButton
Palette Page → Standard
(2) 輸入 ColorButton.h 及 ColorButton.cpp 的相關函式 (a) ColorButton.h 的內容
//---------------------------------------------------------------------------
#ifndef ColorButtonH
#define ColorButtonH
//---------------------------------------------------------------------------
#include
#include
#include
#include
#include <Forms.hpp>
#include
//---------------------------------------------------------------------------
class PACKAGE TColorButton : public TButton
{
public:
__fastcall TColorButton(TComponent* Owner); __published:
__property TColor Color ={read = GetColor, write = SetColor};
__property TColor ColorLo ={read = ColorLo_, write = SetColorLo,default = clBtnShadow};
__property TColor ColorHi ={read = ColorHi_, write = SetColorHi,default = clBtnHighlight}; protected:
// inherited member functions
virtual void __fastcall CreateParams(TCreateParams& Params);
virtual void __fastcall SetButtonStyle(bool ADefault); // introduced member functions
virtual void __fastcall DoDrawButtonFace(const TOwnerDrawState& state);
virtual void __fastcall DoDrawButtonText(const TOwnerDrawState& state); private:
TColor ColorLo_;
TColor ColorHi_;
std::auto_ptr Canvas_;
bool draw_as_default_; TColor __fastcall GetColor();
void __fastcall SetColor(TColor Value);
void __fastcall SetColorLo(TColor Value);
void __fastcall SetColorHi(TColor Value); MESSAGE void __fastcall CNDrawItem(TMessage& Msg);
MESSAGE void __fastcall WMLButtonDblClk(TMessage& Msg);
MESSAGE void __fastcall CMFontChanged(TMessage& Msg);
MESSAGE void __fastcall CMEnabledChanged(TMessage& Msg); public:
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(CN_DRAWITEM, TMessage, CNDrawItem)
MESSAGE_HANDLER(WM_LBUTTONDBLCLK, TMessage, WMLButtonDblClk)
MESSAGE_HANDLER(CM_FONTCHANGED, TMessage, CMFontChanged)
MESSAGE_HANDLER(CM_ENABLEDCHANGED, TMessage, CMEnabledChanged)
END_MESSAGE_MAP(TButton)};
//---------------------------------------------------------------------------
#endif (b) ColorButton.cpp 的內容
#include
#pragma hdrstop
#include "ColorButton.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
// ValidCtrCheck is used to assure that the components created do not have
// any pure virtual functions.
// static inline void ValidCtrCheck(TColorButton *)
{
new TColorButton(NULL);
}
//---------------------------------------------------------------------------
__fastcall TColorButton::TColorButton(TComponent* Owner)
: TButton(Owner)
{
}
//---------------------------------------------------------------------------
namespace Colorbutton
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TColorButton)};
RegisterComponents("Standard", classes, 0);
}
}
//---------------------------------------------------------------------------
__fastcall TColorButton::TColorButton(TComponent* Owner)
: TButton(Owner), ColorLo_(clBtnShadow), ColorHi_(clBtnHighlight),
Canvas_(new TCanvas()),draw_as_default_(false)
{
// constructor
}
//---------------------------------------------------------------------------
void __fastcall TColorButton::CreateParams(TCreateParams& Params)
{
TButton::CreateParams(Params);
Params.Style |= BS_OWNERDRAW;
}
//---------------------------------------------------------------------------
void __fastcall TColorButton::SetButtonStyle(bool ADefault)
{
if (draw_as_default_ != ADefault)
{
draw_as_default_ = ADefault;
InvalidateRect(Handle, NULL, FALSE);
}
}
//---------------------------------------------------------------------------
void __fastcall TColorButton::CNDrawItem(TMessage& Msg)
{
// grab pointer to the DRAWITEMSTRUCT
const DRAWITEMSTRUCT* pDrawItem =
reinterpret_cast
(Msg.LParam); // store the current state of
// the target DC
SaveDC(pDrawItem->hDC);
// bind Canvas_ to the target DC
Canvas_->Handle = pDrawItem->hDC;
try
{
// extract the state flags...
TOwnerDrawState state;
// if the button has keyboard focus
if (pDrawItem->itemState & ODS_FOCUS)
{
state = state << odFocused;
}
// if the button is pushed
if (pDrawItem->itemState &
ODS_SELECTED)
{
state = state << odSelected;
}
// if the button is disabled
if (pDrawItem->itemState &
ODS_DISABLED)
{
state = state << odDisabled;
} // draw the button's face
DoDrawButtonFace(state); // draw the button's text
DoDrawButtonText(state);
}
catch (...)
{
// clean up
Canvas_->Handle = NULL;
RestoreDC(pDrawItem->hDC, -1);
}
// clean up
Canvas_->Handle = NULL;
RestoreDC(pDrawItem->hDC, -1); // reply TRUE
Msg.Result = TRUE;
}
//---------------------------------------------------------------------------
void __fastcall TColorButton::DoDrawButtonFace(const TOwnerDrawState& state)
{
// draw a colored button...
Canvas_->Brush = Brush;
TRect RClient = ClientRect; // if the button is the default button
// or has keyboard focus...
if (draw_as_default_ ||
state.Contains(odFocused))
{
Canvas_->Pen->Color = clWindowFrame;
Canvas_->Rectangle(
RClient.Left, RClient.Top,
RClient.Right, RClient.Bottom
);
InflateRect(
reinterpret_cast(&RClient),
-1, -1
);
} // if the button is pushed...
if (state.Contains(odSelected))
{
Canvas_->Pen->Color = ColorLo_;
Canvas_->Rectangle(
RClient.Left, RClient.Top,
RClient.Right, RClient.Bottom
);
} // if the button isn't pushed...
else
{
Canvas_->FillRect(RClient);
Frame3D(
Canvas_.get(), RClient,
ColorHi_, clWindowFrame, 1
); POINT P[] = {
{1, RClient.Bottom - 1},
{RClient.Right - 1,
RClient.Bottom - 1},
{RClient.Right - 1,
RClient.Top - 1}
};
Canvas_->Pen->Color = ColorLo_;
Canvas_->Polyline(
reinterpret_cast(P), 2
);
}
}
//---------------------------------------------------------------------------
void __fastcall TColorButton::DoDrawButtonText(const TOwnerDrawState& state)
{
if (Caption.Length() == 0) return; RECT RText = {0, 0, Width, Height};
Canvas_->Font = Font;
Canvas_->Brush = Brush;
SetBkMode(
Canvas_->Handle, TRANSPARENT
); // if the button is pushed...
if (state.Contains(odSelected))
{
// offset the caption
OffsetRect(&RText, 1, 1);
}
// if the button is disabled...
if (!Enabled ||
state.Contains(odDisabled))
{ // render the caption
// in a disabled fashion
OffsetRect(&RText, 1, 1);
Canvas_->Font->Color = ColorHi_;
DrawText(
Canvas_->Handle, Caption.c_str(),
-1, &RText, DT_CENTER |
DT_VCENTER | DT_SINGLELINE
);
OffsetRect(&RText, -1, -1);
Canvas_->Font->Color = ColorLo_;
} // render the caption
DrawText(
Canvas_->Handle, Caption.c_str(), -1,
&RText, DT_CENTER | DT_VCENTER |
DT_SINGLELINE
); // if the button has keyboard focus...
if (state.Contains(odFocused))
{
// render the selection rectangle
TRect RFocus = ClientRect;
InflateRect(
reinterpret_cast(&RFocus),
-4, -4
);
Canvas_->DrawFocusRect(RFocus);
}
}
//---------------------------------------------------------------------------
TColor __fastcall TColorButton::GetColor()
{
return Brush->Color;
}
//---------------------------------------------------------------------------
void __fastcall TColorButton::SetColor(TColor Value)
{
if (Brush->Color != Value)
{
Brush->Color = Value;
InvalidateRect(Handle, NULL, TRUE);
}
}
//---------------------------------------------------------------------------
void __fastcall TColorButton::SetColorLo(TColor Value)
{
if (ColorLo_ != Value)
{
ColorLo_ = Value;
InvalidateRect(Handle, NULL, TRUE);
}
}
//---------------------------------------------------------------------------
void __fastcall TColorButton::SetColorHi(TColor Value)
{
if (ColorHi_ != Value)
{
ColorHi_ = Value;
InvalidateRect(Handle, NULL, TRUE);
}
}
//---------------------------------------------------------------------------
void __fastcall TColorButton::CMFontChanged(TMessage& Msg)
{
TButton::Dispatch(&Msg);
InvalidateRect(Handle, NULL, TRUE);
}
//---------------------------------------------------------------------------
void __fastcall TColorButton::CMEnabledChanged(TMessage& Msg)
{
TButton::Dispatch(&Msg);
InvalidateRect(Handle, NULL, TRUE);
}
//---------------------------------------------------------------------------
void __fastcall TColorButton::WMLButtonDblClk(TMessage& Msg)
{
SNDMSG(
Handle, WM_LBUTTONDOWN,
Msg.WParam, Msg.LParam
);
}
//--------------------------------------------------------------------------- 再來小弟就點選 Component → Install Component
unit file name 就是剛剛 ColorButton.cpp compile 過程中出現一個錯誤:
[C Error] ColorButton.cpp(30): E2171 Body has already been defined for function '_fastcall TColorButton::TColorButton(TComponent *) 每次裝每次都出現,小弟一直找不到問題在哪
希望前輩指導,小弟真的是快...... 感謝回答 發表人 - 流 於
|
taishyang
站務副站長
發表:377 回覆:5490 積分:4563 註冊:2002-10-08
發送簡訊給我
|
流您好:
我放在下面連結供您參考
< href="http://delphi.ktop.com.tw/topic.php?TOPIC_ID=41578">http://delphi.ktop.com.tw/topic.php?TOPIC_ID=41578 順心
|
流
中階會員
發表:36 回覆:142 積分:70 註冊:2003-07-24
發送簡訊給我
|
謝謝taishyang 版主的幫忙 辛苦您了,再一次的感謝 發表人 - 流 於
|