I found a similar thread here: viewtopic.php?f=1&t=38262&sid=1c68f38d6 ... 65e69f2a5f
And I downloaded the shapedtest example that T-Rex posted back in 2014. I incorporated his code that allows him to have shaped bitmap buttons however I ran into some problems.
1. I encounter an error if I try to pass the wxRegion to the SetShape function as a reference. "Initial value of reference to non-const must be Ivalue"
https://pasteboard.co/kLLQO9Wumo90.png
2. If I pass the wxRegion by value I clear the error, however the alpha channel of the bitmap button is still clickable.
Code: Select all
class MyFrame : public wxFrame
{
public:
MyFrame();
};
class MyApp : public wxApp
{
MyFrame* frame = new MyFrame();
wxImagePanel* drawPane;
public:
bool OnInit()
{
wxInitAllImageHandlers();
wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
drawPane = new wxImagePanel(frame, wxT("board321x440.jpg"), wxBITMAP_TYPE_JPEG);
sizer->Add(drawPane, 1, wxEXPAND);
frame->SetSizer(sizer);
frame->SetBackgroundColour(wxColour(192, 192, 192));
frame->Show();
return true;
}
};
DECLARE_APP(MyApp)
IMPLEMENT_APP(MyApp)
class wxBitmappedButton : public wxButton
{
wxBitmap m_holdOrg;
wxBitmap m_holdStartHold;
bool m_IsPushed;
public:
bool SetShape(wxWindow* victim, wxRegion& region);
wxBitmappedButton(wxWindow* parent, wxWindowID id, wxBitmap holdOrg, wxBitmap holdStartHold, wxPoint pos);
DECLARE_EVENT_TABLE()
void OnMouseDown(wxMouseEvent& event);
void OnPaint(wxPaintEvent& event);
};
BEGIN_EVENT_TABLE(wxBitmappedButton, wxButton)
EVT_LEFT_DOWN(wxBitmappedButton::OnMouseDown)
EVT_PAINT(wxBitmappedButton::OnPaint)
END_EVENT_TABLE()
wxBitmappedButton::wxBitmappedButton(wxWindow* parent, wxWindowID id, wxBitmap holdOrg, wxBitmap holdStartHold, wxPoint pos) : wxButton(parent, id, wxEmptyString, pos), m_IsPushed(false), m_holdOrg(holdOrg), m_holdStartHold(holdStartHold)
{
SetSize(m_holdOrg.GetWidth(), m_holdOrg.GetHeight());
SetShape(this, wxRegion(m_holdOrg));
}
void wxBitmappedButton::OnMouseDown(wxMouseEvent& event)
{
m_IsPushed = true;
Refresh();
}
void wxBitmappedButton::OnPaint(wxPaintEvent& event)
{
wxPaintDC dc(this);
m_IsPushed ? dc.DrawBitmap(m_holdOrg, 0, 0, false):dc.DrawBitmap(m_holdStartHold, 0, 0, false);
}
MyFrame::MyFrame() : wxFrame(NULL, wxID_ANY, "", wxPoint(0, 0), wxSize(800, 480), wxNORESIZE_FRAME_STYLE)
{
wxImage::AddHandler(new wxPNGHandler);
wxBitmap holdOrg;
wxBitmap holdStartHold;
holdOrg.LoadFile(wxT("holdOrg.png"), wxBITMAP_TYPE_PNG);
holdStartHold.LoadFile(wxT("holdStartHold.png"), wxBITMAP_TYPE_PNG);
wxBitmappedButton* btn = new wxBitmappedButton(this, wxID_CLOSE, holdOrg, holdStartHold, wxPoint(0,0));
}
bool wxBitmappedButton::SetShape(wxWindow* victim, wxRegion& region)
{
DWORD noBytes = ::GetRegionData((HRGN)region.GetHRGN(), 0, NULL);
RGNDATA* rgnData = (RGNDATA*) new char[noBytes];
::GetRegionData((HRGN)region.GetHRGN(), noBytes, rgnData);
HRGN hrgn = ::ExtCreateRegion(NULL, noBytes, rgnData);
delete[](char*) rgnData;
RECT rect;
DWORD dwStyle = ::GetWindowLong((HWND)victim->GetHandle(), GWL_STYLE);
DWORD dwExStyle = ::GetWindowLong((HWND)victim->GetHandle(), GWL_EXSTYLE);
::GetClientRect((HWND)victim->GetHandle(), &rect);
::AdjustWindowRectEx(&rect, dwStyle, FALSE, dwExStyle);
::OffsetRgn(hrgn, -rect.left, -rect.top);
return true;
}
default Visual Studio 2019 C++ compiler
wxWidgets 3.1.5