Problems with transparency behind a button over a wxFrame having a panel having an image as background

I am writing an application using wxWidgets and C++, this is a test program to show the problem:

#include <wx/wx.h>
#include <wx/dcbuffer.h>
#include <wx/graphics.h>
#include <wx/timer.h>
#include <wx/process.h>

// globals
wxString bkgPath = "C:/Dati/workspaces/codeblocks/ShapedButton/wallpaper.png";
wxString imgPath = "C:/Dati/workspaces/codeblocks/ShapedButton/Sample5.png";


class ImageButton : public wxControl
{
public:
ImageButton(wxWindow* parent, wxWindowID id, const wxBitmap& bitmap,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = 0,
const wxValidator& validator = wxDefaultValidator,
const wxString& name = wxControlNameStr)
: wxControl(parent, id, pos, size, style, validator, name),
m_bitmap(bitmap),
m_isDoubleClick(false),
m_isDragging(false),
m_lastMousePos(wxDefaultPosition),
m_capturedMouse(false)
{
SetSize(bitmap.GetWidth(), bitmap.GetHeight());
Bind(wxEVT_PAINT, &ImageButton::OnPaint, this);
Bind(wxEVT_LEFT_DOWN, &ImageButton::OnMouseDown, this);
Bind(wxEVT_LEFT_UP, &ImageButton::OnMouseUp, this);
#if 0
Bind(wxEVT_LEFT_DCLICK, &ImageButton::OnMouseDoubleClick, this);
#endif
Bind(wxEVT_MOTION, &ImageButton::OnMouseMove, this);
m_timer.Bind(wxEVT_TIMER, &ImageButton::OnTimer, this);
}
//------------------------------------------------------------------------

void OnPaint(wxPaintEvent& event)
{
wxBufferedPaintDC dc(this);
dc.DrawBitmap(m_bitmap, 0, 0, true);
}
//------------------------------------------------------------------------

void OnMouseDown(wxMouseEvent& event)
{
// Handle mouse down event
if(!m_capturedMouse && !m_isDragging) {
CaptureMouse();
m_isDragging = true;
}
m_lastMousePos = event.GetPosition();
}
//------------------------------------------------------------------------

void OnMouseUp(wxMouseEvent& event)
{
// Handle mouse up event
m_isDoubleClick = false;
if(m_capturedMouse) {
ReleaseMouse();
m_isDragging = false;
m_capturedMouse = false;
}
}
//------------------------------------------------------------------------

void OnMouseDoubleClick(wxMouseEvent& event)
{
// Handle double-click event
m_isDoubleClick = true;
wxCommandEvent evt(wxEVT_COMMAND_BUTTON_CLICKED, GetId());
evt.SetEventObject(this);
ProcessEvent(evt);

// Launch cmd.exe
wxExecute("cmd.exe", wxEXEC_ASYNC);
}
//------------------------------------------------------------------------

void OnMouseMove(wxMouseEvent& event)
{
if (m_isDragging && event.Dragging())
{
// Get the current button position relative to the parent
wxPoint oldPos = GetPosition();

// Calculate the new position based on the mouse movement relative to the button's last position
wxPoint newPos = oldPos + (event.GetPosition() - m_lastMousePos);

// Invalidate the background at the old position of the button
GetParent()->RefreshRect(wxRect(oldPos, GetSize()), true);

// Move the button to the new position
Move(newPos);

// Invalidate the new position to repaint the background under the button's new location
GetParent()->RefreshRect(wxRect(newPos, GetSize()), true);

// Update the parent panel to ensure the background refresh is immediate
GetParent()->Update();

// Update the last mouse position for the next drag event
m_lastMousePos = event.GetPosition();
}

// Allow further processing of the event
// event.Skip();
}

void OnTimer(wxTimerEvent& event)
{
if (!m_isDoubleClick)
{
wxCommandEvent evt(wxEVT_COMMAND_BUTTON_CLICKED, GetId());
evt.SetEventObject(this);
ProcessEvent(evt);
}
}
//------------------------------------------------------------------------

private:
wxBitmap m_bitmap;
wxTimer m_timer;
bool m_isDoubleClick;
bool m_isDragging;
wxPoint m_lastMousePos;
bool m_capturedMouse;
};
//------------------------------------------------------------------------
//------------------------------------------------------------------------

class ImagePanel : public wxPanel
{
public:
ImagePanel(wxWindow* parent, const wxBitmap& background)
: wxPanel(parent), m_background(background)
{
Bind(wxEVT_PAINT, &ImagePanel::OnPaint, this);
Bind(wxEVT_SIZE, &ImagePanel::OnSize, this);
}

void OnPaint(wxPaintEvent& event)
{
wxBufferedPaintDC dc(this);
wxSize panelSize = GetSize();

// First, draw the entire background, scaled to fit the panel size
wxImage scaledImage = m_background.ConvertToImage().Rescale(panelSize.GetWidth(), panelSize.GetHeight());
wxBitmap scaledBitmap(scaledImage);
dc.DrawBitmap(scaledBitmap, 0, 0, true);

// Now iterate over the children and handle ImageButton specifically
for (wxWindowList::Node* node = GetChildren().GetFirst(); node; node = node->GetNext())
{
wxWindow* child = node->GetData();

// Check if the child is an ImageButton
ImageButton* button = dynamic_cast<ImageButton*>(child);
if (button)
{
wxPoint childPos = child->GetPosition();
wxSize childSize = child->GetSize();

// Define the area of the background that needs to be redrawn beneath the child
wxRect backgroundRect(childPos, childSize);

// Ensure the backgroundRect is clipped to the panel bounds
backgroundRect.Intersect(wxRect(0, 0, panelSize.GetWidth(), panelSize.GetHeight()));

// Extract the part of the background image to be drawn behind the button
wxImage subImage = scaledImage.GetSubImage(backgroundRect);

// Draw the extracted background part at the correct position
dc.DrawBitmap(wxBitmap(subImage), childPos.x, childPos.y, true);
}
}
}

void OnSize(wxSizeEvent& event)
{
Refresh();
}

private:
wxBitmap m_background;
};


// Example usage
class MyFrame : public wxFrame
{
public:
MyFrame() : wxFrame(NULL, wxID_ANY, "Image Button Example", wxPoint(50, 50), wxSize(600, 400))
{
wxBitmap background(bkgPath, wxBITMAP_TYPE_PNG);
ImagePanel* panel = new ImagePanel(this, background);

wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
sizer->Add(panel, 1, wxEXPAND);
SetSizer(sizer);

wxBitmap buttonBitmap(imgPath, wxBITMAP_TYPE_PNG);
ImageButton* button = new ImageButton(panel, wxID_ANY, buttonBitmap, wxPoint(100, 100));
}
};
//------------------------------------------------------------------------

class MyApp : public wxApp
{
public:
virtual bool OnInit()
{
wxInitAllImageHandlers();
// Initialize image handlers
if(!wxImage::FindHandler(wxBITMAP_TYPE_PNG)) {
wxImage::AddHandler(new wxPNGHandler());
}
if(!wxImage::FindHandler(wxBITMAP_TYPE_JPEG)) {
wxImage::AddHandler(new wxJPEGHandler());
}
MyFrame* frame = new MyFrame();
frame->Show(true);
return true;
}
};
//------------------------------------------------------------------------

wxIMPLEMENT_APP(MyApp);
//------------------------------------------------------------------------
//------------------------------------------------------------------------

I have a button that can have its shape defined by an image and it has to be draggable around over a window that has an image as background on a panel extended to all the window that is a wxFrame descendant. When the program starts puts the button over the panel and the transparent part is painted with the background but starting from (0,0) of the panel independently by the button position and when I drag it the background of the button does not change remaining always the same. I am testing it on Windows 10, any suggestion or the solution?

This is my actual result:

…and this is I would like to have:

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật