场景:
1.现在的软件上的按钮都不是标准的按钮了,因为基本上是贴图上去的,正常情况下一种图片,鼠标移上去之后按钮显示另一种效果,按下去之后又是另一种效果。
2.wx的做法其实和mfc的按钮原理是一样的,就是给按钮贴图和重绘背景。
以下是源文件.
dh_bitmap_button.h
/* * File: dh_bitmap_button.h * Author: Sai * * Created on 2009年12月29日, 下午4:08 */ #ifndef _DH_BITMAP_BUTTON_H #define _DH_BITMAP_BUTTON_H #include "wx/wx.h" enum DhBitmapButtonStatus { kDhBitmapButtonNormal, kDhBitmapButtonEnter, kDhBitmapButtonDown, kDhBitmapButtonUp, kDhBitmapButtonLeave, kDhBitmapButtonDClick, kDhBitmapButtonDisable }; class DhBitmapButton : public wxControl { DECLARE_DYNAMIC_CLASS(DhBitmapButton) DECLARE_EVENT_TABLE() public: DhBitmapButton(); virtual ~DhBitmapButton(); DhBitmapButton(wxWindow* parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxBORDER_NONE, const wxValidator& validator = wxDefaultValidator); bool Create(wxWindow* parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxSUNKEN_BORDER, const wxValidator& validator = wxDefaultValidator); wxSize DoGetBestSize() const; void OnPaint(wxPaintEvent& event); virtual void OnEnter(wxMouseEvent& event); virtual void OnLeave(wxMouseEvent& event); virtual void OnDown(wxMouseEvent& event); virtual void OnDClick(wxMouseEvent& event); virtual void OnUp(wxMouseEvent& event); virtual bool Enable(bool enable = true); virtual bool Disable(); /** * 设置正常图片 * * @param bitmap */ DhBitmapButton* set_normal_bitmap(wxBitmap* bitmap); /** * 1.设置按钮按下时的切换图片 */ DhBitmapButton* set_down_bitmap(wxBitmap* bitmap); /** * 1.设置按钮按经过时的切换图片 */ DhBitmapButton* set_enter_bitmap(wxBitmap* bitmap); /** * 1.设置Disable图片. * * @param bitmap * @return this */ DhBitmapButton* set_disable_bitmap(wxBitmap* bitmap); DhBitmapButton* set_background(const wxBitmap& bitmap); bool SetBackgroundColour(const wxColour& colour); protected: void DrawExistBitmap(wxDC* dc,wxBitmap* image1,wxBitmap* exist_image); private: wxBitmap background_; bool is_used_bg_; wxBitmap* normal_bitmap_; wxBitmap* down_bitmap_; wxBitmap* enter_bitmap_; wxBitmap* disable_bitmap_; int button_status_; wxString text_; wxFont text_font_; void DrawBackground(wxDC* dc); }; #endif /* _DH_BITMAP_BUTTON_H */
/* * File: DhBitmapButton.cpp * Author: Sai * * Created on 2009年12月29日, 下午4:08 */ #include "dh_bitmap_button.h" BEGIN_EVENT_TABLE(DhBitmapButton, wxControl) EVT_PAINT(DhBitmapButton::OnPaint) EVT_ENTER_WINDOW(DhBitmapButton::OnEnter) EVT_LEAVE_WINDOW(DhBitmapButton::OnLeave) EVT_LEFT_DOWN(DhBitmapButton::OnDown) EVT_LEFT_DCLICK(DhBitmapButton::OnDClick) EVT_LEFT_UP(DhBitmapButton::OnUp) END_EVENT_TABLE() IMPLEMENT_DYNAMIC_CLASS(DhBitmapButton, wxControl) DhBitmapButton::DhBitmapButton() { } DhBitmapButton::DhBitmapButton(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxValidator& validator) : normal_bitmap_(NULL), down_bitmap_(NULL), enter_bitmap_(NULL) { Create(parent, id, pos, size, style, validator); } DhBitmapButton::~DhBitmapButton() { wxDELETE(normal_bitmap_); wxDELETE(enter_bitmap_); wxDELETE(down_bitmap_); } bool DhBitmapButton::Create(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxValidator& validator) { normal_bitmap_ = NULL; down_bitmap_ = NULL; enter_bitmap_ = NULL; disable_bitmap_ = NULL; if (!wxControl::Create(parent, id, pos, size, style, validator)) { return false; } SetBackgroundStyle(wxBG_STYLE_PAINT); is_used_bg_ = false; return true; } wxSize DhBitmapButton::DoGetBestSize() const { return GetSize(); } void DhBitmapButton::DrawExistBitmap(wxDC* dc, wxBitmap* image1, wxBitmap* exist_image) { if (image1) { dc->DrawBitmap(*image1, 0, 0, true); } else { dc->DrawBitmap(*exist_image, 0, 0, true); } } void DhBitmapButton::OnPaint(wxPaintEvent& event) { wxPaintDC dc(this); DrawBackground(&dc); //1.状态控制绘画,好处就是可以调用Refresh连背景一起刷新. switch (button_status_) { case kDhBitmapButtonNormal: dc.DrawBitmap(*normal_bitmap_, 0, 0, true); break; case kDhBitmapButtonEnter: if (!enter_bitmap_) { int width = DoGetBestSize().GetWidth(); int height = DoGetBestSize().GetHeight(); wxClientDC dc(this); dc.SetPen(*wxRED_PEN); dc.SetBrush(*wxTRANSPARENT_BRUSH); dc.DrawRectangle(0, 0, width, height); break; } dc.DrawBitmap(*enter_bitmap_, 0, 0, true); break; case kDhBitmapButtonDown: DrawExistBitmap(&dc,down_bitmap_,normal_bitmap_); break; case kDhBitmapButtonUp: dc.DrawBitmap(*normal_bitmap_, 0, 0, true); break; case kDhBitmapButtonLeave: dc.DrawBitmap(*normal_bitmap_, 0, 0, true); break; case kDhBitmapButtonDClick: DrawExistBitmap(&dc,down_bitmap_,normal_bitmap_); break; case kDhBitmapButtonDisable: DrawExistBitmap(&dc,disable_bitmap_,normal_bitmap_); break; default: dc.DrawBitmap(*normal_bitmap_, 0, 0, true); break; } } void DhBitmapButton::DrawBackground(wxDC* dc) { if (is_used_bg_) { dc->DrawBitmap(background_, 0, 0, true); } else { wxBrush brush(GetBackgroundColour()); wxPen pen(GetBackgroundColour()); dc->SetBrush(brush); dc->SetPen(pen); dc->DrawRectangle(0, 0, GetSize().x, GetSize().y); } } void DhBitmapButton::OnEnter(wxMouseEvent& event) { button_status_ = kDhBitmapButtonEnter; Refresh(); Update(); } void DhBitmapButton::OnLeave(wxMouseEvent& event) { if (!IsEnabled()) { return; } button_status_ = kDhBitmapButtonLeave; Refresh(); Update(); } void DhBitmapButton::OnDClick(wxMouseEvent& event) { button_status_ = kDhBitmapButtonDown; Refresh(false); Update(); } void DhBitmapButton::OnDown(wxMouseEvent& event) { button_status_ = kDhBitmapButtonDown; Refresh(); Update(); } void DhBitmapButton::OnUp(wxMouseEvent& event) { if (kDhBitmapButtonDown != button_status_) { return; } button_status_ = kDhBitmapButtonUp; Refresh(); Update(); wxCommandEvent myEvent(wxEVT_COMMAND_BUTTON_CLICKED, GetId()); myEvent.SetEventObject(this); GetEventHandler()->ProcessEvent(myEvent); } DhBitmapButton* DhBitmapButton::set_normal_bitmap(wxBitmap* bitmap) { normal_bitmap_ = bitmap; return this; } DhBitmapButton* DhBitmapButton::set_down_bitmap(wxBitmap* bitmap) { down_bitmap_ = bitmap; return this; } DhBitmapButton* DhBitmapButton::set_enter_bitmap(wxBitmap* bitmap) { enter_bitmap_ = bitmap; return this; } bool DhBitmapButton::Enable(bool enable) { if (enable) { button_status_ = kDhBitmapButtonNormal; } else { button_status_ = kDhBitmapButtonDisable; } Refresh(false); Update(); return wxControl::Enable(enable); } bool DhBitmapButton::Disable() { return Enable(false); } DhBitmapButton* DhBitmapButton::set_disable_bitmap(wxBitmap* bitmap) { disable_bitmap_ = bitmap; return this; } DhBitmapButton* DhBitmapButton::set_background(const wxBitmap& bitmap) { is_used_bg_ = true; background_ = bitmap; return this; } bool DhBitmapButton::SetBackgroundColour(const wxColour& colour) { is_used_bg_ = false; return wxControl::SetBackgroundColour(colour); }
1.先注册事件映射宏.
EVT_BUTTON(Minimal_StartSimplePopup, MyFrame::OnStartSimplePopup)
wxBitmap* normal = new wxBitmap("./resources/start/start_normal.png", wxBITMAP_TYPE_PNG); wxBitmap* down = new wxBitmap("./resources/start/start_pressed.png", wxBITMAP_TYPE_PNG); wxBitmap* enter = new wxBitmap("./resources/start/start_current.png", wxBITMAP_TYPE_PNG); wxBitmap* disable = new wxBitmap("./resources/start/stop_normal.png", wxBITMAP_TYPE_PNG); wxBitmap bg = GetPositionBackgroundBitmap(0,0,normal->GetWidth(),normal->GetHeight()); start = new DhBitmapButton(page,Minimal_StartSimplePopup,wxPoint(0,0), normal->GetSize()); start->set_normal_bitmap(normal)->set_down_bitmap(down)->set_enter_bitmap(enter); start->set_disable_bitmap(disable); start->set_background(bg);
wxBitmap MyFrame::GetPositionBackgroundBitmap(int x, int y, int width,int height) { wxRect rect; rect.x = x; rect.y = y; rect.width = width; rect.height = height; wxBitmap temp = this->bg.GetSubBitmap(rect); return temp; }
3.当然我觉得有更好的方式.
比如重载这个类.wxBitmapButton