83 lines
2.6 KiB
C++
83 lines
2.6 KiB
C++
///////////////////////////////////////////////////////////////////////////////
|
|
// Name: wx/msw/private/custompaint.h
|
|
// Purpose: Helper function for customizing the standard WM_PAINT handling.
|
|
// Author: Vadim Zeitlin
|
|
// Created: 2023-06-02
|
|
// Copyright: (c) 2023 Vadim Zeitlin <vadim@wxwidgets.org>
|
|
// Licence: wxWindows licence
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
#ifndef _WX_MSW_PRIVATE_CUSTOMPAINT_H_
|
|
#define _WX_MSW_PRIVATE_CUSTOMPAINT_H_
|
|
|
|
#include "wx/dcmemory.h"
|
|
#include "wx/image.h"
|
|
|
|
#include "wx/msw/dc.h"
|
|
|
|
namespace wxMSWImpl
|
|
{
|
|
|
|
// This function can be used as CustomPaint() callback to post process the
|
|
// bitmap by applying the specific functor to each of its pixels.
|
|
template <typename FuncProcessPixel>
|
|
wxBitmap
|
|
PostPaintEachPixel(const wxBitmap& bmp, FuncProcessPixel processPixel)
|
|
{
|
|
#if wxUSE_IMAGE
|
|
wxImage image = bmp.ConvertToImage();
|
|
|
|
unsigned char *data = image.GetData();
|
|
unsigned char *alpha = image.GetAlpha();
|
|
unsigned char alphaOpaque = wxALPHA_OPAQUE;
|
|
const int len = image.GetWidth()*image.GetHeight();
|
|
for ( int i = 0; i < len; ++i, data += 3 )
|
|
{
|
|
processPixel(data[0], data[1], data[2], alpha ? *alpha++ : alphaOpaque);
|
|
}
|
|
|
|
return wxBitmap(image);
|
|
#else // !wxUSE_IMAGE
|
|
return bmp;
|
|
#endif // wxUSE_IMAGE/!wxUSE_IMAGE
|
|
}
|
|
|
|
// This function uses the default WM_PAINT handler to paint the window contents
|
|
// into a bitmap and then the provided function to tweak the pixels of this
|
|
// bitmap.
|
|
//
|
|
// The first argument is a functor (typically a lambda) to paint the on the
|
|
// given HDC and the second one is another functor called to post process the
|
|
// bitmap before actually drawing it.
|
|
//
|
|
// It can only be called from WM_PAINT handler for a native control and assumes
|
|
// that this control handles WPARAM argument of WM_PAINT as HDC to paint on.
|
|
template <typename FuncDefPaint, typename FuncPostProcess>
|
|
void
|
|
CustomPaint(HWND hwnd, FuncDefPaint defPaint, FuncPostProcess postProcess)
|
|
{
|
|
const RECT rc = wxGetClientRect(hwnd);
|
|
const wxSize size{rc.right - rc.left, rc.bottom - rc.top};
|
|
|
|
// Don't bother doing anything with the empty windows.
|
|
if ( size == wxSize() )
|
|
return;
|
|
|
|
// Ask the control to paint itself on the given bitmap.
|
|
wxBitmap bmp(size);
|
|
{
|
|
wxMemoryDC mdc(bmp);
|
|
|
|
defPaint(hwnd, (WPARAM)GetHdcOf(mdc));
|
|
}
|
|
|
|
PAINTSTRUCT ps;
|
|
wxDCTemp dc(::BeginPaint(hwnd, &ps), size);
|
|
dc.DrawBitmap(postProcess(bmp), 0, 0);
|
|
::EndPaint(hwnd, &ps);
|
|
}
|
|
|
|
} // namespace wxMSWImpl
|
|
|
|
#endif // _WX_MSW_PRIVATE_CUSTOMPAINT_H_
|