initial commit

Signed-off-by: Peter Siegmund <mars3142@noreply.mars3142.dev>
This commit is contained in:
2025-10-31 23:37:30 +01:00
commit 7228269764
9653 changed files with 4034514 additions and 0 deletions

View File

@@ -0,0 +1,76 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/msw/private/button.h
// Purpose: helper functions used with native BUTTON control
// Author: Vadim Zeitlin
// Created: 2008-06-07
// Copyright: (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_MSW_PRIVATE_BUTTON_H_
#define _WX_MSW_PRIVATE_BUTTON_H_
// define some standard button constants which may be missing in the headers
#ifndef BS_PUSHLIKE
#define BS_PUSHLIKE 0x00001000L
#endif
#ifndef BST_UNCHECKED
#define BST_UNCHECKED 0x0000
#endif
#ifndef BST_CHECKED
#define BST_CHECKED 0x0001
#endif
#ifndef BST_INDETERMINATE
#define BST_INDETERMINATE 0x0002
#endif
namespace wxMSWButton
{
// returns BS_MULTILINE if the label contains new lines or 0 otherwise
inline int GetMultilineStyle(const wxString& label)
{
return label.find(wxT('\n')) == wxString::npos ? 0 : BS_MULTILINE;
}
// update the style of the specified HWND to include or exclude BS_MULTILINE
// depending on whether the label contains the new lines
void UpdateMultilineStyle(HWND hwnd, const wxString& label);
// flags for ComputeBestSize() and GetFittingSize()
enum
{
Size_AuthNeeded = 1,
Size_ExactFit = 2
};
// NB: All the functions below are implemented in src/msw/button.cpp
// Compute the button size (as if wxBU_EXACTFIT were specified, i.e. without
// adjusting it to be of default size if it's smaller) for the given label size
WXDLLIMPEXP_CORE wxSize
GetFittingSize(wxWindow *win, const wxSize& sizeLabel, int flags = 0);
// Compute the button size (as if wxBU_EXACTFIT were specified) by computing
// its label size and then calling GetFittingSize().
wxSize ComputeBestFittingSize(wxControl *btn, int flags = 0);
// Increase the size passed as parameter to be at least the standard button
// size if the control doesn't have wxBU_EXACTFIT style and also cache it as
// the best size and return its value -- this is used in DoGetBestSize()
// implementation.
wxSize IncreaseToStdSizeAndCache(wxControl *btn, const wxSize& size);
// helper of wxToggleButton::DoGetBestSize()
inline wxSize ComputeBestSize(wxControl *btn, int flags = 0)
{
return IncreaseToStdSizeAndCache(btn, ComputeBestFittingSize(btn, flags));
}
} // namespace wxMSWButton
#endif // _WX_MSW_PRIVATE_BUTTON_H_

View File

@@ -0,0 +1,134 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/msw/private/comptr.h
// Purpose: Smart pointer for COM interfaces.
// Author: PB
// Created: 2012-04-16
// Copyright: (c) 2012 wxWidgets team
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_MSW_PRIVATE_COMPTR_H_
#define _WX_MSW_PRIVATE_COMPTR_H_
// ----------------------------------------------------------------------------
// wxCOMPtr: A minimalistic smart pointer for use with COM interfaces.
// ----------------------------------------------------------------------------
template <class T>
class wxCOMPtr
{
public:
typedef T element_type;
wxCOMPtr()
: m_ptr(nullptr)
{
}
explicit wxCOMPtr(T* ptr)
: m_ptr(ptr)
{
if ( m_ptr )
m_ptr->AddRef();
}
wxCOMPtr(const wxCOMPtr& ptr)
: m_ptr(ptr.get())
{
if ( m_ptr )
m_ptr->AddRef();
}
~wxCOMPtr()
{
if ( m_ptr )
m_ptr->Release();
}
void reset(T* ptr = nullptr)
{
if ( m_ptr != ptr)
{
if ( ptr )
ptr->AddRef();
if ( m_ptr )
m_ptr->Release();
m_ptr = ptr;
}
}
wxCOMPtr& operator=(const wxCOMPtr& ptr)
{
reset(ptr.get());
return *this;
}
wxCOMPtr& operator=(T* ptr)
{
reset(ptr);
return *this;
}
operator T*() const
{
return m_ptr;
}
T& operator*() const
{
return *m_ptr;
}
T* operator->() const
{
return m_ptr;
}
// It would be better to forbid direct access completely but we do need
// for QueryInterface() and similar functions, so provide it but it can
// only be used to initialize the pointer, not to modify an existing one.
T** operator&()
{
wxASSERT_MSG(!m_ptr,
wxS("Can't get direct access to initialized pointer"));
return &m_ptr;
}
T* get() const
{
return m_ptr;
}
T* Get() const
{
return m_ptr;
}
bool operator<(T* ptr) const
{
return get() < ptr;
}
private:
T* m_ptr;
};
// Define a helper for the macro below: we just need a function taking a
// pointer and not returning anything to avoid warnings about unused return
// value of the cast in the macro itself.
namespace wxPrivate { inline void PPV_ARGS_CHECK(void*) { } }
// Takes the interface name and a pointer to a pointer of the interface type
// and expands into the IID of this interface and the same pointer but after a
// type-safety check.
//
// This is similar to the standard IID_PPV_ARGS macro but takes the pointer
// type instead of relying on the non-standard Microsoft __uuidof().
#define wxIID_PPV_ARGS(IType, pType) \
IID_##IType, \
(wxPrivate::PPV_ARGS_CHECK(static_cast<IType*>(*pType)), \
reinterpret_cast<void**>(pType))
#endif // _WX_MSW_PRIVATE_COMPTR_H_

View File

@@ -0,0 +1,203 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/msw/private/comstream.h
// Purpose: COM Stream adapter to wxStreamBase based streams
// Created: 2021-01-15
// Copyright: (c) 2021 wxWidgets team
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef WX_COMSTREAM_H
#define WX_COMSTREAM_H
#include "wx/stream.h"
#include "wx/msw/ole/comimpl.h"
class wxCOMBaseStreamAdapter : public IStream
{
public:
wxCOMBaseStreamAdapter(wxStreamBase* stream):
m_stream(stream)
{ }
virtual ~wxCOMBaseStreamAdapter() = default;
// IUnknown
STDMETHODIMP QueryInterface(REFIID riid, void** ppv) override
{
if (riid == IID_IUnknown ||
riid == IID_ISequentialStream ||
riid == IID_IStream)
{
*ppv = this;
AddRef();
return S_OK;
}
*ppv = nullptr;
return E_NOINTERFACE;
}
STDMETHODIMP_(ULONG) AddRef() override
{
return ++m_cRef;
}
STDMETHODIMP_(ULONG) Release() override
{
if (--m_cRef == wxAutoULong(0))
{
delete this;
return 0;
}
else
return m_cRef;
}
// IStream
virtual HRESULT STDMETHODCALLTYPE Seek(
LARGE_INTEGER WXUNUSED(dlibMove), DWORD WXUNUSED(dwOrigin),
ULARGE_INTEGER *WXUNUSED(plibNewPosition)) override
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE SetSize(ULARGE_INTEGER WXUNUSED(libNewSize)) override
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE CopyTo(IStream *WXUNUSED(pstm),
ULARGE_INTEGER WXUNUSED(cb), ULARGE_INTEGER *WXUNUSED(pcbRead),
ULARGE_INTEGER *WXUNUSED(pcbWritten)) override
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE Commit(DWORD WXUNUSED(grfCommitFlags)) override
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE Revert(void) override
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE LockRegion(ULARGE_INTEGER WXUNUSED(libOffset),
ULARGE_INTEGER WXUNUSED(cb), DWORD WXUNUSED(dwLockType)) override
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE UnlockRegion(ULARGE_INTEGER WXUNUSED(libOffset),
ULARGE_INTEGER WXUNUSED(cb), DWORD WXUNUSED(dwLockType)) override
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE Stat(STATSTG *pstatstg, DWORD WXUNUSED(grfStatFlag)) override
{
pstatstg->type = STGTY_STREAM;
pstatstg->cbSize.QuadPart = m_stream->GetSize();
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE Clone(IStream **WXUNUSED(ppstm)) override
{
return E_NOTIMPL;
}
// ISequentialStream
virtual HRESULT STDMETHODCALLTYPE Read(void *WXUNUSED(pv),
ULONG WXUNUSED(cb), ULONG *WXUNUSED(pcbRead)) override
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE Write(const void *WXUNUSED(pv),
ULONG WXUNUSED(cb), ULONG *WXUNUSED(pcbWritten)) override
{
return E_NOTIMPL;
}
protected:
wxStreamBase* m_stream;
static wxSeekMode OriginToSeekMode(DWORD origin)
{
switch (origin)
{
case STREAM_SEEK_SET:
return wxFromStart;
case STREAM_SEEK_CUR:
return wxFromCurrent;
case STREAM_SEEK_END:
return wxFromEnd;
}
return wxFromStart;
}
private:
wxAutoULong m_cRef;
};
class wxCOMInputStreamAdapter : public wxCOMBaseStreamAdapter
{
public:
wxCOMInputStreamAdapter(wxInputStream* stream):
wxCOMBaseStreamAdapter(stream)
{
}
virtual HRESULT STDMETHODCALLTYPE Seek(
LARGE_INTEGER dlibMove, DWORD dwOrigin,
ULARGE_INTEGER *plibNewPosition) override
{
wxFileOffset newOffset = reinterpret_cast<wxInputStream*>(m_stream)->SeekI(dlibMove.QuadPart, OriginToSeekMode(dwOrigin));
if (plibNewPosition)
plibNewPosition->QuadPart = newOffset;
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE Read(void *pv, ULONG cb, ULONG *pcbRead) override
{
wxInputStream* inputStr = reinterpret_cast<wxInputStream*>(m_stream);
inputStr->Read(pv, cb);
*pcbRead = inputStr->LastRead();
return S_OK;
}
};
class wxCOMOutputStreamAdapter : public wxCOMBaseStreamAdapter
{
public:
wxCOMOutputStreamAdapter(wxOutputStream* stream) :
wxCOMBaseStreamAdapter(stream)
{ }
virtual HRESULT STDMETHODCALLTYPE Seek(
LARGE_INTEGER dlibMove, DWORD dwOrigin,
ULARGE_INTEGER *plibNewPosition) override
{
wxFileOffset newOffset = reinterpret_cast<wxOutputStream*>(m_stream)->SeekO(dlibMove.QuadPart, OriginToSeekMode(dwOrigin));
if (plibNewPosition)
plibNewPosition->QuadPart = newOffset;
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE Write(const void *pv, ULONG cb, ULONG *pcbWritten) override
{
wxOutputStream* outputStr = reinterpret_cast<wxOutputStream*>(m_stream);
outputStr->Write(pv, cb);
*pcbWritten = outputStr->LastWrite();
return S_OK;
}
};
#endif // WX_COMSTREAM_H

View File

@@ -0,0 +1,85 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/msw/private/cotaskmemptr.h
// Purpose: RAII class for pointers to be freed with ::CoTaskMemFree().
// Author: PB
// Created: 2020-06-09
// Copyright: (c) 2020 wxWidgets team
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_MSW_PRIVATE_COTASKMEMPTR_H_
#define _WX_MSW_PRIVATE_COTASKMEMPTR_H_
// needed for ::CoTaskMem{Alloc|Free}()
#include "wx/msw/wrapwin.h"
// ----------------------------------------------------------------------------
// wxCoTaskMemPtr: A barebone RAII class for pointers to be freed with ::CoTaskMemFree().
// ----------------------------------------------------------------------------
template <class T>
class wxCoTaskMemPtr
{
public:
typedef T element_type;
wxCoTaskMemPtr()
: m_ptr(nullptr)
{}
explicit wxCoTaskMemPtr(T* ptr)
: m_ptr(ptr)
{}
// Uses ::CoTaskMemAlloc() to allocate size bytes.
explicit wxCoTaskMemPtr(size_t size)
: m_ptr(static_cast<T*>(::CoTaskMemAlloc(size)))
{}
~wxCoTaskMemPtr()
{
::CoTaskMemFree(m_ptr);
}
void reset(T* ptr = nullptr)
{
if ( m_ptr != ptr )
{
::CoTaskMemFree(m_ptr);
m_ptr = ptr;
}
}
operator T*() const
{
return m_ptr;
}
// It would be better to forbid direct access completely but we do need it,
// so provide it but it can only be used to initialize the pointer,
// not to modify an existing one.
T** operator&()
{
wxASSERT_MSG(!m_ptr,
wxS("Can't get direct access to initialized pointer"));
return &m_ptr;
}
// Gives up the ownership of the pointer,
// making the caller responsible for freeing it.
wxNODISCARD T* release()
{
T* ptr(m_ptr);
m_ptr = nullptr;
return ptr;
}
private:
T* m_ptr;
wxDECLARE_NO_COPY_TEMPLATE_CLASS(wxCoTaskMemPtr, T);
};
#endif // _WX_MSW_PRIVATE_COTASKMEMPTR_H_

View File

@@ -0,0 +1,109 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/msw/private/customdraw.h
// Purpose: Helper for implementing custom drawing support in wxMSW
// Author: Vadim Zeitlin
// Created: 2016-04-16
// Copyright: (c) 2016 Vadim Zeitlin <vadim@wxwidgets.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_MSW_CUSTOMDRAW_H_
#define _WX_MSW_CUSTOMDRAW_H_
#include "wx/itemattr.h"
#include "wx/msw/uxtheme.h"
#include "wx/msw/wrapcctl.h"
namespace wxMSWImpl
{
// ----------------------------------------------------------------------------
// CustomDraw: inherit from this class and forward NM_CUSTOMDRAW to it
// ----------------------------------------------------------------------------
class CustomDraw
{
public:
// Trivial default ctor needed for non-copyable class.
CustomDraw()
{
}
// Virtual dtor for the base class.
virtual ~CustomDraw()
{
}
// Implementation of NM_CUSTOMDRAW handler, returns one of CDRF_XXX
// constants, possibly CDRF_DODEFAULT if custom drawing is not necessary.
LPARAM HandleCustomDraw(LPARAM lParam);
private:
// Return true if we need custom drawing at all.
virtual bool HasCustomDrawnItems() const = 0;
// Return the attribute to use for the given item, can return nullptr if this
// item doesn't need to be custom-drawn.
virtual const wxItemAttr* GetItemAttr(DWORD_PTR dwItemSpec) const = 0;
// Set the colours and font for the specified HDC, return CDRF_NEWFONT if
// the font was changed.
LPARAM HandleItemPrepaint(const wxItemAttr& attr, HDC hdc);
wxDECLARE_NO_COPY_CLASS(CustomDraw);
};
} // namespace wxMSWImpl
// ----------------------------------------------------------------------------
// wxMSWHeaderCtrlCustomDraw: custom draw helper for header control
// ----------------------------------------------------------------------------
class wxMSWHeaderCtrlCustomDraw : public wxMSWImpl::CustomDraw
{
public:
wxMSWHeaderCtrlCustomDraw()
{
}
// Set the colours to the ones used by "Header" theme.
//
// This is required, for unknown reasons, when using dark mode, because
// enabling it for the header control changes the background, but not the
// foreground, making the text completely unreadable.
//
// If this is ever fixed in later Windows versions, this function wouldn't
// need to be called any more.
void UseHeaderThemeColors(HWND hwndHdr)
{
auto theme = wxUxThemeHandle::NewAtStdDPI(hwndHdr, L"Header");
m_attr.SetTextColour(theme.GetColour(HP_HEADERITEM, TMT_TEXTCOLOR));
// Note that TMT_FILLCOLOR doesn't seem to exist in this theme but the
// correct background colour is already used in "ItemsView" theme by
// default anyhow.
}
// Make this field public to let the control update it directly when its
// attributes change.
wxItemAttr m_attr;
private:
virtual bool HasCustomDrawnItems() const override
{
// We only exist if the header does need to be custom drawn.
return true;
}
virtual const wxItemAttr*
GetItemAttr(DWORD_PTR WXUNUSED(dwItemSpec)) const override
{
// We use the same attribute for all items for now.
return &m_attr;
}
};
#endif // _WX_MSW_CUSTOMDRAW_H_

View File

@@ -0,0 +1,82 @@
///////////////////////////////////////////////////////////////////////////////
// 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_

View File

@@ -0,0 +1,70 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/msw/private/darkmode.h
// Purpose: Dark mode support in wxMSW
// Author: Vadim Zeitlin
// Created: 2022-06-25
// Copyright: (c) 2022 Vadim Zeitlin <vadim@wxwidgets.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_MSW_PRIVATE_DARKMODE_H_
#define _WX_MSW_PRIVATE_DARKMODE_H_
#include "wx/settings.h"
namespace wxMSWDarkMode
{
// Return true if the application is using dark mode: note that this will only
// be the case if wxApp::MSWEnableDarkMode() was called.
WXDLLIMPEXP_CORE
bool IsActive();
// Enable dark mode for the given TLW if appropriate.
void EnableForTLW(HWND hwnd);
// Set dark theme for the given (child) window if appropriate.
//
// Optional theme name and ID can be specified if something other than the
// default "Explorer" should be used. If both theme name and theme ID are null,
// no theme is set.
void AllowForWindow(HWND hwnd,
const wchar_t* themeName = L"Explorer",
const wchar_t* themeId = nullptr);
// Return the colour value appropriate for dark mode if it's used or an invalid
// colour if it isn't.
wxColour GetColour(wxSystemColour index);
// Get the pen to use for drawing the border, see wxDarkModeSettings.
wxPen GetBorderPen();
// Return the background brush to be used by default in dark mode.
HBRUSH GetBackgroundBrush();
// Invert the colours of the given bitmap trying to keep it readable.
wxBitmap InvertBitmap(const wxBitmap& bmp);
// If dark mode is active, paint the given window using inverted colours by
// drawing it normally and then applying InvertBitmap() to it.
//
// Otherwise just return false without doing anything.
//
// This 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.
bool PaintIfNecessary(HWND hwnd, WXWNDPROC defWndProc);
// If dark mode is active and if the message is one of those used for menu
// drawing, process it and return true, otherwise just return false without
// doing anything.
bool
HandleMenuMessage(WXLRESULT* result,
wxWindow* w,
WXUINT nMsg,
WXWPARAM wParam,
WXLPARAM lParam);
} // namespace wxMSWDarkMode
#endif // _WX_MSW_PRIVATE_DARKMODE_H_

View File

@@ -0,0 +1,30 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/msw/private/datecontrols.h
// Purpose: implementation helpers for wxDatePickerCtrl and wxCalendarCtrl
// Author: Vadim Zeitlin
// Created: 2008-04-04
// Copyright: (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _MSW_PRIVATE_DATECONTROLS_H_
#define _MSW_PRIVATE_DATECONTROLS_H_
#include "wx/datetime.h"
#include "wx/msw/wrapwin.h"
// namespace for the helper functions related to the date controls
namespace wxMSWDateControls
{
// do the one time only initialization of date classes of comctl32.dll, return
// true if ok or log an error and return false if we failed (this can only
// happen with a very old version of common controls DLL, i.e. before 4.70)
extern bool CheckInitialization();
} // namespace wxMSWDateControls
#endif // _MSW_PRIVATE_DATECONTROLS_H_

View File

@@ -0,0 +1,147 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/msw/private/dc.h
// Purpose: private wxMSW helpers for working with HDCs
// Author: Vadim Zeitlin
// Created: 2009-06-16 (extracted from src/msw/dc.cpp)
// Copyright: (c) 2009 Vadim Zeitlin <vadim@wxwidgets.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _MSW_PRIVATE_DC_H_
#define _MSW_PRIVATE_DC_H_
#include "wx/msw/dc.h"
#include "wx/msw/wrapwin.h"
namespace wxMSWImpl
{
// various classes to change some DC property temporarily
// text background and foreground colours
class wxTextColoursChanger
{
public:
wxTextColoursChanger(HDC hdc, const wxMSWDCImpl& dc)
: m_hdc(hdc)
{
Change(dc.GetTextForeground(), dc.GetTextBackground());
}
wxTextColoursChanger(HDC hdc, const wxColour& colFg, const wxColour& colBg)
: m_hdc(hdc)
{
Change(colFg, colBg);
}
wxTextColoursChanger(HDC hdc, COLORREF colFg, COLORREF colBg)
: m_hdc(hdc)
{
Change(colFg, colBg);
}
~wxTextColoursChanger()
{
if ( m_oldColFg != CLR_INVALID )
::SetTextColor(m_hdc, m_oldColFg);
if ( m_oldColBg != CLR_INVALID )
::SetBkColor(m_hdc, m_oldColBg);
}
protected:
// this ctor doesn't change mode immediately, call Change() later to do it
// only if needed
wxTextColoursChanger(HDC hdc)
: m_hdc(hdc)
{
m_oldColFg =
m_oldColBg = CLR_INVALID;
}
void Change(const wxColour& colFg, const wxColour& colBg)
{
Change(colFg.IsOk() ? colFg.GetPixel() : CLR_INVALID,
colBg.IsOk() ? colBg.GetPixel() : CLR_INVALID);
}
void Change(COLORREF colFg, COLORREF colBg)
{
if ( colFg != CLR_INVALID )
{
m_oldColFg = ::SetTextColor(m_hdc, colFg);
if ( m_oldColFg == CLR_INVALID )
{
wxLogLastError(wxT("SetTextColor"));
}
}
else
{
m_oldColFg = CLR_INVALID;
}
if ( colBg != CLR_INVALID )
{
m_oldColBg = ::SetBkColor(m_hdc, colBg);
if ( m_oldColBg == CLR_INVALID )
{
wxLogLastError(wxT("SetBkColor"));
}
}
else
{
m_oldColBg = CLR_INVALID;
}
}
private:
const HDC m_hdc;
COLORREF m_oldColFg,
m_oldColBg;
wxDECLARE_NO_COPY_CLASS(wxTextColoursChanger);
};
// background mode
class wxBkModeChanger
{
public:
// set background mode to opaque if mode != wxBRUSHSTYLE_TRANSPARENT
wxBkModeChanger(HDC hdc, int mode)
: m_hdc(hdc)
{
Change(mode);
}
~wxBkModeChanger()
{
if ( m_oldMode )
::SetBkMode(m_hdc, m_oldMode);
}
protected:
// this ctor doesn't change mode immediately, call Change() later to do it
// only if needed
wxBkModeChanger(HDC hdc) : m_hdc(hdc) { m_oldMode = 0; }
void Change(int mode)
{
m_oldMode = ::SetBkMode(m_hdc, mode == wxBRUSHSTYLE_TRANSPARENT
? TRANSPARENT
: OPAQUE);
if ( !m_oldMode )
{
wxLogLastError(wxT("SetBkMode"));
}
}
private:
const HDC m_hdc;
int m_oldMode;
wxDECLARE_NO_COPY_CLASS(wxBkModeChanger);
};
} // namespace wxMSWImpl
#endif // _MSW_PRIVATE_DC_H_

View File

@@ -0,0 +1,94 @@
/////////////////////////////////////////////////////////////////////////////
// Name: wx/msw/private/dpiaware.h
// Purpose: AutoSystemDpiAware class
// Author: Maarten Bent
// Created: 2016-10-06
// Copyright: (c) Maarten Bent
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef _WX_MSW_DPI_AWARE_H_
#define _WX_MSW_DPI_AWARE_H_
#ifndef WX_PRECOMP
#include "wx/msw/missing.h"
#endif
#include "wx/dynlib.h"
#include "wx/display.h"
#include "wx/sysopt.h"
namespace wxMSWImpl
{
// ----------------------------------------------------------------------------
// Temporarily change the DPI Awareness context to GDIScaled or System
// ----------------------------------------------------------------------------
class AutoSystemDpiAware
{
#define WXDPI_AWARENESS_CONTEXT_UNAWARE ((WXDPI_AWARENESS_CONTEXT)-1)
#define WXDPI_AWARENESS_CONTEXT_SYSTEM_AWARE ((WXDPI_AWARENESS_CONTEXT)-2)
#define WXDPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED ((WXDPI_AWARENESS_CONTEXT)-5)
typedef WXDPI_AWARENESS_CONTEXT
(WINAPI *SetThreadDpiAwarenessContext_t)(WXDPI_AWARENESS_CONTEXT);
public:
AutoSystemDpiAware()
: m_prevContext(WXDPI_AWARENESS_CONTEXT_UNAWARE)
{
if ( !Needed() )
return;
if ( ms_pfnSetThreadDpiAwarenessContext == (SetThreadDpiAwarenessContext_t)-1)
{
wxLoadedDLL dllUser32("user32.dll");
wxDL_INIT_FUNC(ms_pfn, SetThreadDpiAwarenessContext, dllUser32);
}
if ( ms_pfnSetThreadDpiAwarenessContext )
{
m_prevContext = ms_pfnSetThreadDpiAwarenessContext(
WXDPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED);
if ( !m_prevContext )
{
m_prevContext = ms_pfnSetThreadDpiAwarenessContext(
WXDPI_AWARENESS_CONTEXT_SYSTEM_AWARE);
}
}
}
~AutoSystemDpiAware()
{
if ( ms_pfnSetThreadDpiAwarenessContext &&
ms_pfnSetThreadDpiAwarenessContext != (SetThreadDpiAwarenessContext_t)-1 )
{
ms_pfnSetThreadDpiAwarenessContext(m_prevContext);
}
}
static bool Needed()
{
// use system-dpi-aware context when:
// - the user did not set an option to force per-monitor context
// - there are displays with different DPI
if ( wxSystemOptions::GetOptionInt("msw.native-dialogs-pmdpi") == 1 )
return false;
bool diferentDPI = false;
for ( unsigned i = 1; i < wxDisplay::GetCount() && !diferentDPI; ++i )
diferentDPI = wxDisplay(0u).GetPPI() != wxDisplay(i).GetPPI();
return diferentDPI;
}
private:
WXDPI_AWARENESS_CONTEXT m_prevContext;
// This static member is defined in src/msw/utilswin.cpp.
static SetThreadDpiAwarenessContext_t ms_pfnSetThreadDpiAwarenessContext;
};
} // namespace wxMSWImpl
#endif // _WX_MSW_DPI_AWARE_H_

View File

@@ -0,0 +1,104 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/msw/private/event.h
// Purpose: Simple Windows 'event object' wrapper.
// Author: Troelsk, Vadim Zeitlin
// Created: 2014-05-07
// Copyright: (c) 2014 wxWidgets team
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_MSW_PRIVATE_EVENT_H_
#define _WX_MSW_PRIVATE_EVENT_H_
#include "wx/msw/private.h"
namespace wxWinAPI
{
class Event : public AutoHANDLE<0>
{
public:
enum Kind
{
ManualReset,
AutomaticReset
};
enum InitialState
{
Signaled,
Nonsignaled
};
Event()
{
}
// Wrappers around {Create,Set,Reset}Event() Windows API functions, with
// the same semantics.
bool Create(Kind kind = AutomaticReset,
InitialState initialState = Nonsignaled,
const wxChar* name = nullptr);
bool Set();
bool Reset();
private:
wxDECLARE_NO_COPY_CLASS(Event);
};
} // namespace wxWinAPI
// ----------------------------------------------------------------------------
// Implementations requiring windows.h; these are to moved out-of-line if
// this class is moved to a public header, or if [parts of] msw/private.h is
// changed to not depend on windows.h being included.
// ----------------------------------------------------------------------------
inline bool
wxWinAPI::Event::Create(wxWinAPI::Event::Kind kind,
wxWinAPI::Event::InitialState initialState,
const wxChar* name)
{
wxCHECK_MSG( !IsOk(), false, wxS("Event can't be created twice") );
WXHANDLE handle = ::CreateEvent(nullptr,
kind == ManualReset,
initialState == Signaled,
name);
if ( !handle )
{
wxLogLastError(wxS("CreateEvent"));
return false;
}
m_handle = handle;
return true;
}
inline bool wxWinAPI::Event::Set()
{
wxCHECK_MSG( m_handle, false, wxS("Event must be valid") );
if ( !::SetEvent(m_handle) )
{
wxLogLastError(wxS("SetEvent"));
return false;
}
return true;
}
inline bool wxWinAPI::Event::Reset()
{
wxCHECK_MSG( m_handle, false, wxS("Event must be valid") );
if ( !::ResetEvent(m_handle) )
{
wxLogLastError(wxS("ResetEvent"));
return false;
}
return true;
}
#endif // _WX_MSW_PRIVATE_EVENT_H_

View File

@@ -0,0 +1,91 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/msw/private/filedialog.h
// Purpose: IFileDialog-related functions
// Author: Vadim Zeitlin
// Created: 2022-05-15
// Copyright: (c) 2022 Vadim Zeitlin <vadim@wxwidgets.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_MSW_PRIVATE_FILEDIALOG_H_
#define _WX_MSW_PRIVATE_FILEDIALOG_H_
#include "wx/msw/private.h"
#include "wx/msw/wrapshl.h"
// We want to use IFileDialog if either wxDirDialog or wxFileDialog are used.
//
// Using IFileOpenDialog requires a compiler providing declarations and
// definitions of interfaces available in Windows Vista.
// And it needs OLE support to actually use these interfaces.
#if (wxUSE_DIRDLG || wxUSE_FILEDLG) && wxUSE_OLE && \
defined(__IFileOpenDialog_INTERFACE_DEFINED__)
#define wxUSE_IFILEOPENDIALOG 1
#else
#define wxUSE_IFILEOPENDIALOG 0
#endif
#if wxUSE_IFILEOPENDIALOG
#include "wx/msw/private/comptr.h"
namespace wxMSWImpl
{
// For historical reasons, this class is defined in src/msw/dirdlg.cpp.
class wxIFileDialog
{
public:
// Return true if we can use IFileDialog with an owner: this is
// unfortunately not always the case, as IFileDialog requires using
// apartment threading model in this case.
static bool CanBeUsedWithAnOwner();
// Create the dialog of the specified type.
//
// CLSID must be either CLSID_FileOpenDialog or CLSID_FileSaveDialog.
//
// Use IsOk() to check if the dialog was created successfully.
explicit wxIFileDialog(const CLSID& clsid);
// If this returns false, the dialog can't be used at all.
bool IsOk() const { return m_fileDialog.Get() != nullptr; }
// Set the dialog title.
void SetTitle(const wxString& title);
// Set the initial path to show in the dialog.
void SetInitialPath(const wxString& path);
// Add a shortcut.
void AddPlace(const wxString& path, FDAP fdap);
// Show the file dialog with the given parent window and options.
//
// Returns the selected path, or paths, in the provided output parameters,
// depending on whether FOS_ALLOWMULTISELECT is part of the options.
//
// The return value is wxID_OK if any paths were returned, wxID_CANCEL if the
// dialog was cancelled.
int
Show(HWND owner, int options, wxArrayString* pathsOut, wxString* pathOut);
// Behave as IFileDialog.
IFileDialog* Get() const { return m_fileDialog.Get(); }
IFileDialog* operator->() const { return m_fileDialog.Get(); }
private:
wxCOMPtr<IFileDialog> m_fileDialog;
};
// Initialize an IShellItem object with the given path.
HRESULT InitShellItemFromPath(wxCOMPtr<IShellItem>& item, const wxString& path);
// Extract the filesystem path corresponding to the given shell item.
HRESULT GetFSPathFromShellItem(const wxCOMPtr<IShellItem>& item, wxString& path);
} // namespace wxMSWImpl
#endif // wxUSE_IFILEOPENDIALOG
#endif // _WX_MSW_PRIVATE_FILEDIALOG_H_

View File

@@ -0,0 +1,335 @@
/////////////////////////////////////////////////////////////////////////////
// Name: wx/msw/private/fswatcher.h
// Purpose: File system watcher impl classes
// Author: Bartosz Bekier
// Created: 2009-05-26
// Copyright: (c) 2009 Bartosz Bekier <bartosz.bekier@gmail.com>
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef WX_MSW_PRIVATE_FSWATCHER_H_
#define WX_MSW_PRIVATE_FSWATCHER_H_
#include "wx/filename.h"
#include "wx/vector.h"
#include "wx/msw/private.h"
// ============================================================================
// wxFSWatcherEntry implementation & helper declarations
// ============================================================================
class wxFSWatcherImplMSW;
class wxFSWatchEntryMSW : public wxFSWatchInfo
{
public:
enum
{
BUFFER_SIZE = 4096 // TODO parametrize
};
wxFSWatchEntryMSW(const wxFSWatchInfo& winfo) :
wxFSWatchInfo(winfo)
{
// get handle for this path
m_handle = OpenDir(m_path);
m_overlapped = (OVERLAPPED*)calloc(1, sizeof(OVERLAPPED));
wxZeroMemory(m_buffer);
}
virtual ~wxFSWatchEntryMSW()
{
wxLogTrace(wxTRACE_FSWATCHER, "Deleting entry '%s'", m_path);
if (m_handle != INVALID_HANDLE_VALUE)
{
if (!CloseHandle(m_handle))
{
wxLogSysError(_("Unable to close the handle for '%s'"),
m_path);
}
}
free(m_overlapped);
}
bool IsOk() const
{
return m_handle != INVALID_HANDLE_VALUE;
}
HANDLE GetHandle() const
{
return m_handle;
}
void* GetBuffer()
{
return m_buffer;
}
OVERLAPPED* GetOverlapped() const
{
return m_overlapped;
}
private:
// opens dir with all flags, attributes etc. necessary to be later
// asynchronous watched with ReadDirectoryChangesW
static HANDLE OpenDir(const wxString& path)
{
HANDLE handle = CreateFile(path.t_str(),
FILE_LIST_DIRECTORY,
FILE_SHARE_READ |
FILE_SHARE_WRITE |
FILE_SHARE_DELETE,
nullptr,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS |
FILE_FLAG_OVERLAPPED,
nullptr);
if (handle == INVALID_HANDLE_VALUE)
{
wxLogSysError(_("Failed to open directory \"%s\" for monitoring."),
path);
}
return handle;
}
HANDLE m_handle; // handle to opened directory
char m_buffer[BUFFER_SIZE]; // buffer for fs events
OVERLAPPED* m_overlapped;
wxDECLARE_NO_COPY_CLASS(wxFSWatchEntryMSW);
};
// ============================================================================
// wxFSWatcherImplMSW helper classes implementations
// ============================================================================
class wxIOCPService
{
public:
wxIOCPService() :
m_iocp(INVALID_HANDLE_VALUE)
{
Init();
}
~wxIOCPService()
{
if (m_iocp != INVALID_HANDLE_VALUE)
{
if (!CloseHandle(m_iocp))
{
wxLogSysError(_("Unable to close I/O completion port handle"));
}
}
m_watches.clear();
}
// associates a wxFSWatchEntryMSW with completion port
bool Add(wxSharedPtr<wxFSWatchEntryMSW> watch)
{
wxCHECK_MSG( m_iocp != INVALID_HANDLE_VALUE, false, "IOCP not init" );
wxCHECK_MSG( watch->IsOk(), false, "Invalid watch" );
// associate with IOCP
HANDLE ret = CreateIoCompletionPort(watch->GetHandle(), m_iocp,
(ULONG_PTR)watch.get(), 0);
if (ret == nullptr)
{
wxLogSysError(_("Unable to associate handle with "
"I/O completion port"));
return false;
}
else if (ret != m_iocp)
{
wxFAIL_MSG(_("Unexpectedly new I/O completion port was created"));
return false;
}
// add to watch map
wxFSWatchEntries::value_type val(watch->GetPath(), watch);
return m_watches.insert(val).second;
}
// Removes a watch we're currently using. Notice that this doesn't happen
// immediately, CompleteRemoval() must be called later when it's really
// safe to delete the watch, i.e. after completion of the IO operation
// using it.
bool ScheduleForRemoval(const wxSharedPtr<wxFSWatchEntryMSW>& watch)
{
wxCHECK_MSG( m_iocp != INVALID_HANDLE_VALUE, false, "IOCP not init" );
wxCHECK_MSG( watch->IsOk(), false, "Invalid watch" );
const wxString path = watch->GetPath();
wxFSWatchEntries::iterator it = m_watches.find(path);
wxCHECK_MSG( it != m_watches.end(), false,
"Can't remove a watch we don't use" );
// We can't just delete the watch here as we can have pending events
// for it and if we destroyed it now, we could get a dangling (or,
// worse, reused to point to another object) pointer in ReadEvents() so
// just remember that this one should be removed when CompleteRemoval()
// is called later.
m_removedWatches.push_back(watch);
m_watches.erase(it);
return true;
}
// Really remove the watch previously passed to ScheduleForRemoval().
//
// It's ok to call this for a watch that hadn't been removed before, in
// this case we'll just return false and do nothing.
bool CompleteRemoval(wxFSWatchEntryMSW* watch)
{
for ( Watches::iterator it = m_removedWatches.begin();
it != m_removedWatches.end();
++it )
{
if ( (*it).get() == watch )
{
// Removing the object from here will result in deleting the
// watch itself as it's not referenced from anywhere else now.
m_removedWatches.erase(it);
return true;
}
}
return false;
}
// post completion packet
bool PostEmptyStatus()
{
wxCHECK_MSG( m_iocp != INVALID_HANDLE_VALUE, false, "IOCP not init" );
// The special values of 0 will make GetStatus() return Status_Exit.
const int ret = PostQueuedCompletionStatus(m_iocp, 0, 0, nullptr);
if (!ret)
{
wxLogSysError(_("Unable to post completion status"));
}
return ret != 0;
}
// Possible return values of GetStatus()
enum Status
{
// Status successfully retrieved into the provided arguments.
Status_OK,
// Special status indicating that we should exit retrieved.
Status_Exit,
// An error occurred because the watched directory was deleted.
Status_Deleted,
// Some other error occurred.
Status_Error
};
// Wait for completion status to arrive.
// This function can block forever in it's wait for completion status.
// Use PostEmptyStatus() to wake it up (and end the worker thread)
Status
GetStatus(DWORD* count, wxFSWatchEntryMSW** watch,
OVERLAPPED** overlapped)
{
wxCHECK_MSG( m_iocp != INVALID_HANDLE_VALUE, Status_Error,
"Invalid IOCP object" );
wxCHECK_MSG( count && watch && overlapped, Status_Error,
"Output parameters can't be null" );
const int ret = GetQueuedCompletionStatus(m_iocp, count, (ULONG_PTR *)watch,
overlapped, INFINITE);
if ( ret != 0 )
{
return *count || *watch || *overlapped ? Status_OK : Status_Exit;
}
// An error is returned if the underlying directory has been deleted,
// but this is not really an unexpected failure, so handle it
// specially.
if ( wxSysErrorCode() == ERROR_ACCESS_DENIED &&
*watch && !wxFileName::DirExists((*watch)->GetPath()) )
return Status_Deleted;
// Some other error, at least log it.
wxLogSysError(_("Unable to dequeue completion packet"));
return Status_Error;
}
protected:
bool Init()
{
m_iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, nullptr, 0, 0);
if (m_iocp == nullptr)
{
wxLogSysError(_("Unable to create I/O completion port"));
}
return m_iocp != nullptr;
}
HANDLE m_iocp;
// The hash containing all the wxFSWatchEntryMSW objects currently being
// watched keyed by their paths.
wxFSWatchEntries m_watches;
// Contains the watches which had been removed but are still pending.
typedef wxVector< wxSharedPtr<wxFSWatchEntryMSW> > Watches;
Watches m_removedWatches;
};
class wxIOCPThread : public wxThread
{
public:
wxIOCPThread(wxFSWatcherImplMSW* service, wxIOCPService* iocp);
// finishes this thread
bool Finish();
protected:
// structure to hold information needed to process one native event
// this is just a dummy holder, so it doesn't take ownership of its data
struct wxEventProcessingData
{
wxEventProcessingData(const FILE_NOTIFY_INFORMATION* ne,
const wxFSWatchEntryMSW* watch_) :
nativeEvent(ne), watch(watch_)
{}
const FILE_NOTIFY_INFORMATION* nativeEvent;
const wxFSWatchEntryMSW* watch;
};
virtual ExitCode Entry() override;
// wait for events to occur, read them and send to interested parties
// returns false it empty status was read, which means we would exit
// true otherwise
bool ReadEvents();
void ProcessNativeEvents(wxVector<wxEventProcessingData>& events);
void SendEvent(wxFileSystemWatcherEvent& evt);
static int Native2WatcherFlags(int flags);
static wxString FileNotifyInformationToString(
const FILE_NOTIFY_INFORMATION& e);
static wxFileName GetEventPath(const wxFSWatchEntryMSW& watch,
const FILE_NOTIFY_INFORMATION& e);
wxFSWatcherImplMSW* m_service;
wxIOCPService* m_iocp;
};
#endif /* WX_MSW_PRIVATE_FSWATCHER_H_ */

View File

@@ -0,0 +1,31 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/msw/private/gethwnd.h
// Purpose: Private header for getting HWND from wxWindow
// Author: Vadim Zeitlin
// Created: 2025-03-30
// Copyright: (c) 2025 Vadim Zeitlin <vadim@wxwidgets.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_MSW_PRIVATE_GETHWND_H_
#define _WX_MSW_PRIVATE_GETHWND_H_
#ifdef __WXQT__
// This is needed to call winId()
#include <QtWidgets/QWidget>
#endif // __WXQT__
// Just return the associated HWND if the window is not null.
//
// This is not completely trivial because we want this function to also work
// when compiling MSW-specific code as part of wxQt.
inline HWND wxGetHWND(const wxWindow* parent)
{
#ifdef __WXMSW__
return parent ? (HWND)parent->GetHandle() : nullptr;
#elif defined(__WXQT__)
return parent ? (HWND)parent->GetHandle()->winId() : nullptr;
#endif
}
#endif // _WX_MSW_PRIVATE_GETHWND_H_

View File

@@ -0,0 +1,31 @@
/////////////////////////////////////////////////////////////////////////////
// Name: wx/msw/private/graphicsd2d.h
// Purpose: Allow functions from graphicsd2d.cpp to be used in other files
// Author: New Pagodi
// Created: 2017-10-31
// Copyright: (c) 2017 wxWidgets development team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef WX_MSW_PRIVATE_GRAPHICSD2D_H_
#define WX_MSW_PRIVATE_GRAPHICSD2D_H_
#if wxUSE_GRAPHICS_DIRECT2D
// Ensure no previous defines interfere with the Direct2D API headers
#undef GetHwnd
// include before wincodec.h to prevent winsock/winsock2 redefinition warnings
#include "wx/msw/wrapwin.h"
#include <d2d1.h>
#include <dwrite.h>
#include <wincodec.h>
WXDLLIMPEXP_CORE IWICImagingFactory* wxWICImagingFactory();
WXDLLIMPEXP_CORE ID2D1Factory* wxD2D1Factory();
WXDLLIMPEXP_CORE IDWriteFactory* wxDWriteFactory();
#endif // wxUSE_GRAPHICS_DIRECT2D
#endif // WX_MSW_PRIVATE_GRAPHICSD2D_H_

View File

@@ -0,0 +1,30 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/msw/private/hiddenwin.h
// Purpose: Helper for creating a hidden window used by wxMSW internally.
// Author: Vadim Zeitlin
// Created: 2011-09-16
// Copyright: (c) 2011 Vadim Zeitlin <vadim@wxwidgets.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_MSW_PRIVATE_HIDDENWIN_H_
#define _WX_MSW_PRIVATE_HIDDENWIN_H_
#include "wx/msw/private.h"
/*
Creates a hidden window with supplied window proc registering the class for
it if necessary (i.e. the first time only). Caller is responsible for
destroying the window and unregistering the class (note that this must be
done because wxWidgets may be used as a DLL and so may be loaded/unloaded
multiple times into/from the same process so we can't rely on automatic
Windows class unregistration).
pclassname is a pointer to a caller stored classname, which must initially be
nullptr. classname is the desired wndclass classname. If function successfully
registers the class, pclassname will be set to classname.
*/
extern "C" WXDLLIMPEXP_BASE HWND
wxCreateHiddenWindow(LPCTSTR *pclassname, LPCTSTR classname, WNDPROC wndproc);
#endif // _WX_MSW_PRIVATE_HIDDENWIN_H_

View File

@@ -0,0 +1,41 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/msw/private/keyboard.h
// Purpose: Helper keyboard-related functions.
// Author: Vadim Zeitlin
// Created: 2010-09-09
// Copyright: (c) 2010 Vadim Zeitlin <vadim@wxwidgets.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_MSW_PRIVATE_KEYBOARD_H_
#define _WX_MSW_PRIVATE_KEYBOARD_H_
#include "wx/defs.h"
namespace wxMSWKeyboard
{
// ----------------------------------------------------------------------------
// Functions for translating between MSW virtual keys codes and wx key codes
//
// These functions are currently implemented in src/msw/window.cpp.
// ----------------------------------------------------------------------------
// Translate MSW virtual key code to wx key code. lParam is used to distinguish
// between numpad and extended version of the keys, extended is assumed by
// default if lParam == 0.
//
// Returns WXK_NONE if translation couldn't be done at all (this happens e.g.
// for dead keys and in this case uc will be WXK_NONE too) or if the key
// corresponds to a non-Latin-1 character in which case uc is filled with its
// Unicode value.
WXDLLIMPEXP_CORE int VKToWX(WXWORD vk, WXLPARAM lParam = 0, wchar_t *uc = nullptr);
// Translate wxKeyCode enum element (passed as int for compatibility reasons)
// to MSW virtual key code. isExtended is set to true if the key corresponds to
// a non-numpad version of a key that exists both on numpad and outside it.
WXDLLIMPEXP_CORE WXWORD WXToVK(int id, bool *isExtended = nullptr);
} // namespace wxMSWKeyboard
#endif // _WX_MSW_PRIVATE_KEYBOARD_H_

View File

@@ -0,0 +1,56 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/msw/private/listboxitem.h
// Purpose: Declaration of the wxListBoxItem class.
// Author: Vadim Zeitlin
// Created: 2024-10-27 (extracted from src/msw/listbox.cpp)
// Copyright: (c) 2024 Vadim Zeitlin <vadim@wxwidgets.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_MSW_PRIVATE_LISTBOXITEM_H_
#define _WX_MSW_PRIVATE_LISTBOXITEM_H_
#include "wx/ownerdrw.h"
// ----------------------------------------------------------------------------
// wxListBoxItemBase: base class for wxListBoxItem and wxCheckListBoxItem
// ----------------------------------------------------------------------------
// The template parameter is the control containing these items.
template <typename T>
class wxListBoxItemBase : public wxOwnerDrawn
{
public:
using Control = T;
explicit wxListBoxItemBase(Control *parent)
{ m_parent = parent; }
Control *GetParent() const
{ return m_parent; }
int GetIndex() const
{ return m_parent->GetItemIndex(const_cast<wxListBoxItemBase*>(this)); }
wxString GetName() const override
{ return m_parent->GetString(GetIndex()); }
protected:
void
GetColourToUse(wxODStatus stat,
wxColour& colText,
wxColour& colBack) const override
{
wxOwnerDrawn::GetColourToUse(stat, colText, colBack);
// Default background colour for the owner drawn items is the menu one,
// but it's not appropriate for the listboxes, so override it here.
if ( !(stat & wxODSelected) && !GetBackgroundColour().IsOk() )
colBack = wxSystemSettings::GetColour(wxSYS_COLOUR_LISTBOX);
}
private:
Control *m_parent;
};
#endif // _WX_MSW_PRIVATE_LISTBOXITEM_H_

View File

@@ -0,0 +1,53 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/msw/private/menu.h
// Purpose: Structs used to custom draw and measure menu bar in wxMSW
// Author: Vadim Zeitlin
// Created: 2025-01-24
// Copyright: (c) 2025 wxWidgets development team
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_MSW_PRIVATE_MENU_H_
#define _WX_MSW_PRIVATE_MENU_H_
namespace wxMSWMenuImpl
{
// Definitions for undocumented messages and structs used in this code.
constexpr int WM_MENUBAR_DRAWMENU = 0x91;
constexpr int WM_MENUBAR_DRAWMENUITEM = 0x92;
constexpr int WM_MENUBAR_MEASUREMENUITEM = 0x94;
// This is passed via LPARAM of WM_MENUBAR_DRAWMENU.
struct MenuBarDrawMenu
{
HMENU hmenu;
HDC hdc;
DWORD dwReserved;
};
struct MenuBarMenuItem
{
int iPosition;
// There are more fields in this (undocumented) struct but we don't
// currently need them, so don't bother with declaring them.
};
struct MenuBarDrawMenuItem
{
DRAWITEMSTRUCT dis;
MenuBarDrawMenu mbdm;
MenuBarMenuItem mbmi;
};
struct MenuBarMeasureMenuItem
{
MEASUREITEMSTRUCT mis;
MenuBarDrawMenu mbdm;
MenuBarMenuItem mbmi;
};
} // namespace wxMSWMenuImpl
#endif // _WX_MSW_PRIVATE_MENU_H_

View File

@@ -0,0 +1,43 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/msw/private/metrics.h
// Purpose: various helper functions to retrieve system metrics
// Author: Vadim Zeitlin
// Created: 2008-09-05
// Copyright: (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_MSW_PRIVATE_METRICS_H_
#define _WX_MSW_PRIVATE_METRICS_H_
#include "wx/msw/private.h"
namespace wxMSWImpl
{
// return NONCLIENTMETRICS as retrieved by SystemParametersInfo()
//
// currently this is not cached as the values may change when system settings
// do and we don't react to this to invalidate the cache but it could be done
// in the future
//
// MT-safety: this function is only meant to be called from the main thread
inline const NONCLIENTMETRICS GetNonClientMetrics(const wxWindow* win)
{
WinStruct<NONCLIENTMETRICS> nm;
if ( !wxSystemParametersInfo(SPI_GETNONCLIENTMETRICS,
sizeof(NONCLIENTMETRICS),
&nm,
0,
win) )
{
wxLogLastError(wxT("SystemParametersInfo(SPI_GETNONCLIENTMETRICS)"));
}
return nm;
}
} // namespace wxMSWImpl
#endif // _WX_MSW_PRIVATE_METRICS_H_

View File

@@ -0,0 +1,84 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/msw/private/msgdlg.h
// Purpose: helper functions used with native message dialog
// Author: Rickard Westerlund
// Created: 2010-07-12
// Copyright: (c) 2010 wxWidgets team
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_MSW_PRIVATE_MSGDLG_H_
#define _WX_MSW_PRIVATE_MSGDLG_H_
#include "wx/msw/wrapcctl.h"
#include "wx/scopedarray.h"
// Provides methods for creating a task dialog.
namespace wxMSWMessageDialog
{
class wxMSWTaskDialogConfig
{
public:
enum { MAX_BUTTONS = 4 };
wxMSWTaskDialogConfig()
: buttons(new TASKDIALOG_BUTTON[MAX_BUTTONS]),
parent(nullptr),
iconId(0),
style(0),
useCustomLabels(false)
{ }
// initializes the object from a message dialog.
wxMSWTaskDialogConfig(const wxMessageDialogBase& dlg);
wxScopedArray<TASKDIALOG_BUTTON> buttons;
wxWindow *parent;
wxString caption;
wxString message;
wxString extendedMessage;
long iconId;
long style;
bool useCustomLabels;
wxString btnYesLabel;
wxString btnNoLabel;
wxString btnOKLabel;
wxString btnCancelLabel;
wxString btnHelpLabel;
// Will create a task dialog with its parameters for its creation
// stored in the provided TASKDIALOGCONFIG parameter.
// NOTE: The wxMSWTaskDialogConfig object needs to remain accessible
// during the subsequent call to TaskDialogIndirect().
void MSWCommonTaskDialogInit(TASKDIALOGCONFIG &tdc);
// Used by MSWCommonTaskDialogInit() to add a regular button or a
// button with a custom label if used.
void AddTaskDialogButton(TASKDIALOGCONFIG &tdc,
int btnCustomId,
int btnCommonId,
const wxString& customLabel);
}; // class wxMSWTaskDialogConfig
typedef HRESULT (WINAPI *TaskDialogIndirect_t)(const TASKDIALOGCONFIG *,
int *, int *, BOOL *);
// Return the pointer to TaskDialogIndirect(). It can return a null pointer
// if the task dialog is not available, which may happen even under modern
// OS versions when using comctl32.dll v5, as it happens if the application
// doesn't provide a manifest specifying that it wants to use v6.
TaskDialogIndirect_t GetTaskDialogIndirectFunc();
// Return true if the task dialog is available, but we don't actually need
// to show it yet (if we do, then GetTaskDialogIndirectFunc() should be
// used directly).
bool HasNativeTaskDialog();
// Translates standard MSW button IDs like IDCANCEL into an equivalent
// wx constant such as wxCANCEL.
int MSWTranslateReturnCode(int msAns);
}; // namespace wxMSWMessageDialog
#endif // _WX_MSW_PRIVATE_MSGDLG_H_

View File

@@ -0,0 +1,39 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/msw/private/paint.h
// Purpose: Helpers for handling repainting
// Author: Vadim Zeitlin
// Created: 2020-02-10
// Copyright: (c) 2020 Vadim Zeitlin <vadim@wxwidgets.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_MSW_PRIVATE_PAINT_H_
#define _WX_MSW_PRIVATE_PAINT_H_
#include "wx/stack.h"
namespace wxMSWImpl
{
// Data used by WM_PAINT handler
struct PaintData
{
explicit PaintData(wxWindowMSW* window_)
: window(window_),
createdPaintDC(false)
{
}
// The window being repainted (never null).
wxWindowMSW* const window;
// True if the user-defined paint handler created wxPaintDC.
bool createdPaintDC;
};
// Stack storing data for the possibly nested WM_PAINT handlers.
extern wxStack<PaintData> paintStack;
} // namespace wxMSWImpl
#endif // _WX_MSW_PRIVATE_PAINT_H_

View File

@@ -0,0 +1,50 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/msw/private/pipestream.h
// Purpose: MSW wxPipeInputStream and wxPipeOutputStream declarations
// Author: Vadim Zeitlin
// Created: 2013-06-08 (extracted from src/msw/utilsexc.cpp)
// Copyright: (c) 2013 Vadim Zeitlin <vadim@wxwidgets.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_MSW_PRIVATE_PIPESTREAM_H_
#define _WX_MSW_PRIVATE_PIPESTREAM_H_
class wxPipeInputStream : public wxInputStream
{
public:
explicit wxPipeInputStream(HANDLE hInput);
virtual ~wxPipeInputStream();
// returns true if the pipe is still opened
bool IsOpened() const { return m_hInput != INVALID_HANDLE_VALUE; }
// returns true if there is any data to be read from the pipe
virtual bool CanRead() const override;
protected:
virtual size_t OnSysRead(void *buffer, size_t len) override;
protected:
HANDLE m_hInput;
wxDECLARE_NO_COPY_CLASS(wxPipeInputStream);
};
class wxPipeOutputStream: public wxOutputStream
{
public:
explicit wxPipeOutputStream(HANDLE hOutput);
virtual ~wxPipeOutputStream() { Close(); }
bool Close() override;
protected:
size_t OnSysWrite(const void *buffer, size_t len) override;
protected:
HANDLE m_hOutput;
wxDECLARE_NO_COPY_CLASS(wxPipeOutputStream);
};
#endif // _WX_MSW_PRIVATE_PIPESTREAM_H_

View File

@@ -0,0 +1,40 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/msw/private/gui_resources.h
// Purpose: Functions for getting GUI resources usage on Windows.
// Author: Vadim Zeitlin
// Created: 2024-07-15
// Copyright: (c) 2024 Vadim Zeitlin <vadim@wxwidgets.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_MSW_PRIVATE_GUI_RESOURCES_H_
#define _WX_MSW_PRIVATE_GUI_RESOURCES_H_
// ----------------------------------------------------------------------------
// Get current or peak resources usage
// ----------------------------------------------------------------------------
// Simple struct contains the number of GDI and USER objects.
struct wxGUIObjectUsage
{
unsigned long numGDI = 0;
unsigned long numUSER = 0;
bool operator==(const wxGUIObjectUsage& other) const
{
return numGDI == other.numGDI && numUSER == other.numUSER;
}
bool operator!=(const wxGUIObjectUsage& other) const
{
return !(*this == other);
}
};
// Returns the number of GUI resources currently in use by this process.
WXDLLIMPEXP_CORE wxGUIObjectUsage wxGetCurrentlyUsedResources();
// Returns the highest number of GUI resources ever used by this process.
WXDLLIMPEXP_CORE wxGUIObjectUsage wxGetMaxUsedResources();
#endif // _WX_MSW_PRIVATE_GUI_RESOURCES_H_

View File

@@ -0,0 +1,95 @@
/////////////////////////////////////////////////////////////////////////////
// Name: wx/msw/private/gsockmsw.h
// Purpose: MSW-specific socket implementation
// Authors: Guilhem Lavaux, Guillermo Rodriguez Garcia, Vadim Zeitlin
// Created: April 1997
// Copyright: (C) 1999-1997, Guilhem Lavaux
// (C) 1999-2000, Guillermo Rodriguez Garcia
// (C) 2008 Vadim Zeitlin
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef _WX_MSW_GSOCKMSW_H_
#define _WX_MSW_GSOCKMSW_H_
#include "wx/msw/wrapwin.h"
#if defined(__CYGWIN__)
//CYGWIN gives annoying warning about runtime stuff if we don't do this
# define USE_SYS_TYPES_FD_SET
# include <sys/types.h>
#endif
#if defined(__CYGWIN__)
#include <winsock.h>
#ifdef __LP64__
// We can't use long in this case because it is 64 bits with Cygwin, so
// use their special type used for working around this instead.
#define wxIoctlSocketArg_t __ms_u_long
#endif
#endif
#ifndef wxIoctlSocketArg_t
#define wxIoctlSocketArg_t u_long
#endif
#define wxCloseSocket closesocket
// ----------------------------------------------------------------------------
// MSW-specific socket implementation
// ----------------------------------------------------------------------------
class wxSocketImplMSW : public wxSocketImpl
{
public:
wxSocketImplMSW(wxSocketBase& wxsocket);
virtual ~wxSocketImplMSW();
virtual void ReenableEvents(wxSocketEventFlags WXUNUSED(flags)) override
{
// notifications are never disabled in this implementation, there is no
// need for this as WSAAsyncSelect() only sends notification once when
// the new data becomes available anyhow, so there is no need to do
// anything here
}
virtual void UpdateBlockingState() override
{
if ( GetSocketFlags() & wxSOCKET_BLOCK )
{
// Counter-intuitively, we make the socket non-blocking even in
// this case as it is necessary e.g. for Read() to return
// immediately if there is no data available. However we must not
// install a callback for it as blocking sockets don't use any
// events and generating them would actually be harmful (and not
// just useless) as they would be dispatched by the main thread
// while this blocking socket can be used from a worker one, so it
// would result in data races and other unpleasantness.
wxIoctlSocketArg_t trueArg = 1;
ioctlsocket(m_fd, FIONBIO, &trueArg);
// Uninstall it in case it was installed before.
wxSocketManager::Get()->Uninstall_Callback(this);
}
else
{
// No need to make the socket non-blocking, Install_Callback() will
// do it as a side effect of calling WSAAsyncSelect().
wxSocketManager::Get()->Install_Callback(this);
}
}
private:
virtual wxSocketError GetLastError() const override;
virtual void DoClose() override;
int m_msgnumber;
friend class wxSocketMSWManager;
wxDECLARE_NO_COPY_CLASS(wxSocketImplMSW);
};
#endif /* _WX_MSW_GSOCKMSW_H_ */

View File

@@ -0,0 +1,63 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/msw/private/textmeasure.h
// Purpose: wxMSW-specific declaration of wxTextMeasure class
// Author: Manuel Martin
// Created: 2012-10-05
// Copyright: (c) 1997-2012 wxWidgets team
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_MSW_PRIVATE_TEXTMEASURE_H_
#define _WX_MSW_PRIVATE_TEXTMEASURE_H_
#include "wx/msw/wrapwin.h"
// ----------------------------------------------------------------------------
// wxTextMeasure for MSW.
// ----------------------------------------------------------------------------
class wxTextMeasure : public wxTextMeasureBase
{
public:
explicit wxTextMeasure(const wxDC *dc, const wxFont *font = nullptr)
: wxTextMeasureBase(dc, font)
{
Init();
}
explicit wxTextMeasure(const wxWindow *win, const wxFont *font = nullptr)
: wxTextMeasureBase(win, font)
{
Init();
}
protected:
void Init();
virtual void BeginMeasuring() override;
virtual void EndMeasuring() override;
virtual void DoGetTextExtent(const wxString& string,
wxCoord *width,
wxCoord *height,
wxCoord *descent = nullptr,
wxCoord *externalLeading = nullptr) override;
virtual bool DoGetPartialTextExtents(const wxString& text,
wxArrayInt& widths,
double scaleX) override;
// We use either the HDC of the provided wxDC or an HDC created for our
// window.
HDC m_hdc;
// If we change the font in BeginMeasuring(), we restore it to the old one
// in EndMeasuring().
HFONT m_hfontOld;
wxDECLARE_NO_COPY_CLASS(wxTextMeasure);
};
#endif // _WX_MSW_PRIVATE_TEXTMEASURE_H_

View File

@@ -0,0 +1,36 @@
/////////////////////////////////////////////////////////////////////////////
// Name: wx/msw/private/timer.h
// Purpose: wxTimer class
// Author: Julian Smart
// Created: 01/02/97
// Copyright: (c) Julian Smart
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef _WX_MSW_PRIVATE_TIMER_H_
#define _WX_MSW_PRIVATE_TIMER_H_
#if wxUSE_TIMER
#include "wx/private/timer.h"
#include "wx/msw/wrapwin.h" // for WPARAM
class WXDLLIMPEXP_BASE wxMSWTimerImpl : public wxTimerImpl
{
public:
wxMSWTimerImpl(wxTimer *timer) : wxTimerImpl(timer) { m_id = 0; }
virtual bool Start(int milliseconds = -1, bool oneShot = false) override;
virtual void Stop() override;
virtual bool IsRunning() const override { return m_id != 0; }
protected:
// this must be 64 bit under Win64 as WPARAM (storing timer ids) is 64 bit
// there and so the ids may possibly not fit in 32 bits
WPARAM m_id;
};
#endif // wxUSE_TIMER
#endif // _WX_TIMERH_

View File

@@ -0,0 +1,195 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/msw/private/tlwgeom.h
// Purpose: wxMSW-specific wxTLWGeometry class.
// Author: Vadim Zeitlin
// Created: 2018-04-29
// Copyright: (c) 2018 Vadim Zeitlin <vadim@wxwidgets.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_MSW_PRIVATE_TLWGEOM_H_
#define _WX_MSW_PRIVATE_TLWGEOM_H_
#include "wx/log.h"
#include "wx/msw/private.h"
// names for MSW-specific options
#define wxPERSIST_TLW_MAX_X "xmax"
#define wxPERSIST_TLW_MAX_Y "ymax"
class wxTLWGeometry : public wxTLWGeometryBase
{
public:
wxTLWGeometry()
{
wxZeroMemory(m_placement);
m_placement.length = sizeof(m_placement);
}
virtual bool Save(const Serializer& ser) const override
{
// For compatibility with the existing saved positions/sizes, use the
// same keys as the generic version (which was previously used under
// MSW too).
// Normal position and size.
const RECT& rc = m_placement.rcNormalPosition;
if ( !ser.SaveField(wxPERSIST_TLW_X, rc.left) ||
!ser.SaveField(wxPERSIST_TLW_Y, rc.top) )
return false;
if ( !ser.SaveField(wxPERSIST_TLW_W, rc.right - rc.left) ||
!ser.SaveField(wxPERSIST_TLW_H, rc.bottom - rc.top) )
return false;
// Maximized/minimized state.
UINT show = m_placement.showCmd;
if ( !ser.SaveField(wxPERSIST_TLW_MAXIMIZED, show == SW_SHOWMAXIMIZED) )
return false;
if ( !ser.SaveField(wxPERSIST_TLW_ICONIZED, show == SW_SHOWMINIMIZED) )
return false;
// Maximized window position.
const POINT pt = m_placement.ptMaxPosition;
if ( !ser.SaveField(wxPERSIST_TLW_MAX_X, pt.x) ||
!ser.SaveField(wxPERSIST_TLW_MAX_Y, pt.y) )
return false;
// We don't currently save the minimized window position, it doesn't
// seem useful for anything and is probably just a left over from
// Windows 3.1 days, when icons were positioned on the desktop instead
// of being located in the taskbar.
return true;
}
virtual bool Restore(Serializer& ser) override
{
// Normal position and size.
wxRect r;
if ( !ser.RestoreField(wxPERSIST_TLW_X, &r.x) ||
!ser.RestoreField(wxPERSIST_TLW_Y, &r.y) ||
!ser.RestoreField(wxPERSIST_TLW_W, &r.width) ||
!ser.RestoreField(wxPERSIST_TLW_H, &r.height) )
return false;
wxCopyRectToRECT(r, m_placement.rcNormalPosition);
// Maximized/minimized state.
//
// Note the special case of SW_MINIMIZE: while GetWindowPlacement()
// returns SW_SHOWMINIMIZED when the window is iconized, we restore it
// as SW_MINIMIZE as this is what the code in wxTLW checks to determine
// whether the window is supposed to be iconized or not.
//
// Just to confuse matters further, note that SW_MAXIMIZE is exactly
// the same thing as SW_SHOWMAXIMIZED.
int tmp;
UINT& show = m_placement.showCmd;
if ( ser.RestoreField(wxPERSIST_TLW_MAXIMIZED, &tmp) && tmp )
show = SW_MAXIMIZE;
else if ( ser.RestoreField(wxPERSIST_TLW_ICONIZED, &tmp) && tmp )
show = SW_MINIMIZE;
else
show = SW_SHOWNORMAL;
// Maximized window position.
if ( ser.RestoreField(wxPERSIST_TLW_MAX_X, &r.x) &&
ser.RestoreField(wxPERSIST_TLW_MAX_Y, &r.y) )
{
m_placement.ptMaxPosition.x = r.x;
m_placement.ptMaxPosition.y = r.y;
}
return true;
}
virtual bool GetFrom(const wxTopLevelWindow* tlw) override
{
if ( !::GetWindowPlacement(GetHwndOf(tlw), &m_placement) )
{
wxLogLastError(wxS("GetWindowPlacement"));
return false;
}
if (m_placement.showCmd != SW_SHOWMAXIMIZED && m_placement.showCmd != SW_SHOWMINIMIZED)
{
RECT rcWindow;
::GetWindowRect(tlw->GetHWND(), &rcWindow);
// Height and width should be the same unless the user performed
// an Aero Snap operation.
const RECT rcNormal = m_placement.rcNormalPosition;
if ((rcWindow.bottom - rcWindow.top) != (rcNormal.bottom - rcNormal.top) ||
(rcWindow.right - rcWindow.left) != (rcNormal.right - rcNormal.left))
{
WinStruct<MONITORINFO> mi;
if (!::GetMonitorInfo(::MonitorFromWindow(tlw->GetHWND(),
MONITOR_DEFAULTTONEAREST), &mi))
{
wxLogLastError("GetMonitorInfo");
return false;
}
// If the tray is on the top or the left, then the rectangle needs to
// be adjusted to match what ::SetWindowPlacement expects.
if (mi.rcMonitor.top < mi.rcWork.top ||
mi.rcMonitor.left < mi.rcWork.left)
{
// Negative offset to eliminate the tray width/height.
OffsetRect(&rcWindow, (mi.rcMonitor.left - mi.rcWork.left),
(mi.rcMonitor.top - mi.rcWork.top));
}
::CopyRect(&m_placement.rcNormalPosition, &rcWindow);
}
}
return true;
}
virtual bool ApplyTo(wxTopLevelWindow* tlw) override
{
// There is a subtlety here: if the window is currently hidden,
// restoring its geometry shouldn't show it, so we must use SW_HIDE as
// show command, but showing it later should restore it to the correct
// state, so we need to remember it in wxTLW itself. And even if it's
// currently shown, we still need to update its show command, so that
// it matches the real window state after SetWindowPlacement() call.
tlw->MSWSetShowCommand(m_placement.showCmd);
if ( !tlw->IsShown() )
{
m_placement.showCmd = SW_HIDE;
}
const wxSize oldDPI = tlw->GetDPI();
if ( !::SetWindowPlacement(GetHwndOf(tlw), &m_placement) )
{
wxLogLastError(wxS("SetWindowPlacement"));
return false;
}
// Check if a window DPI hasn't changed, as the result of being placed
// on a monitor with a different DPI from the main one because in this
// case its size is not restored properly.
const wxSize newDPI = tlw->GetDPI();
if ( oldDPI != newDPI )
{
// So try setting the placement again as now it will use the
// correct scaling factor, because the window is already on the
// correct monitor.
if ( !::SetWindowPlacement(GetHwndOf(tlw), &m_placement) )
{
wxLogLastError(wxS("SetWindowPlacement (2nd time)"));
return false;
}
}
return true;
}
private:
WINDOWPLACEMENT m_placement;
};
#endif // _WX_MSW_PRIVATE_TLWGEOM_H_

View File

@@ -0,0 +1,26 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/msw/private/uilocale.h
// Purpose: MSW-specific locale-related helpers
// Author: Vadim Zeitlin
// Created: 2021-08-14
// Copyright: (c) 2021 Vadim Zeitlin <vadim@wxwidgets.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_MSW_PRIVATE_UILOCALE_H_
#define _WX_MSW_PRIVATE_UILOCALE_H_
#include "wx/msw/private.h" // Include <windows.h> to get LCID.
#ifndef LOCALE_SNAME
#define LOCALE_SNAME 0x5c
#endif
#ifndef LOCALE_CUSTOM_UI_DEFAULT
#define LOCALE_CUSTOM_UI_DEFAULT 0x1400
#endif
WXDLLIMPEXP_BASE wxString wxTranslateFromUnicodeFormat(const wxString& fmt);
WXDLLIMPEXP_BASE wxString wxGetMSWDateTimeFormat(wxLocaleInfo index);
#endif // _WX_MSW_PRIVATE_UILOCALE_H_

View File

@@ -0,0 +1,252 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/msw/webrequest_winhttp.h
// Purpose: wxWebRequest WinHTTP implementation
// Author: Tobias Taschner
// Created: 2018-10-17
// Copyright: (c) 2018 wxWidgets development team
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_MSW_WEBREQUEST_WINHTTP_H
#define _WX_MSW_WEBREQUEST_WINHTTP_H
#include "wx/private/webrequest.h"
#include "wx/msw/wrapwin.h"
#include <winhttp.h>
#include "wx/buffer.h"
class wxWebSessionWinHTTP;
class wxWebRequestWinHTTP;
class wxWebResponseWinHTTP : public wxWebResponseImpl
{
public:
wxWebResponseWinHTTP(wxWebRequestWinHTTP& request);
wxFileOffset GetContentLength() const override { return m_contentLength; }
wxString GetURL() const override;
wxString GetHeader(const wxString& name) const override;
std::vector<wxString> GetAllHeaderValues(const wxString& name) const override;
int GetStatus() const override;
wxString GetStatusText() const override;
bool ReadData(DWORD* bytesRead = nullptr);
private:
HINTERNET m_requestHandle;
wxFileOffset m_contentLength;
wxDECLARE_NO_COPY_CLASS(wxWebResponseWinHTTP);
};
class wxWebAuthChallengeWinHTTP : public wxWebAuthChallengeImpl
{
public:
wxWebAuthChallengeWinHTTP(wxWebAuthChallenge::Source source,
wxWebRequestWinHTTP& request);
bool Init();
wxWebRequest::Result DoSetCredentials(const wxWebCredentials& cred);
void SetCredentials(const wxWebCredentials& cred) override;
private:
wxWebRequestWinHTTP& m_request;
DWORD m_target;
DWORD m_selectedScheme;
wxDECLARE_NO_COPY_CLASS(wxWebAuthChallengeWinHTTP);
};
class wxWebRequestWinHTTP : public wxWebRequestImpl
{
public:
// Ctor for asynchronous requests.
wxWebRequestWinHTTP(wxWebSession& session,
wxWebSessionWinHTTP& sessionImpl,
wxEvtHandler* handler,
const wxString& url,
int id);
// Ctor for synchronous requests.
wxWebRequestWinHTTP(wxWebSessionWinHTTP& sessionImpl,
const wxString& url);
~wxWebRequestWinHTTP();
wxWebRequest::Result Execute() override;
void Start() override;
wxWebResponseImplPtr GetResponse() const override
{ return m_response; }
wxWebAuthChallengeImplPtr GetAuthChallenge() const override
{ return m_authChallenge; }
wxFileOffset GetBytesSent() const override { return m_dataWritten; }
wxFileOffset GetBytesExpectedToSend() const override { return m_dataSize; }
void HandleCallback(DWORD dwInternetStatus, LPVOID lpvStatusInformation,
DWORD dwStatusInformationLength);
HINTERNET GetHandle() const { return m_request; }
wxWebRequestHandle GetNativeHandle() const override
{
return (wxWebRequestHandle)GetHandle();
}
private:
void DoCancel() override;
// Initialize m_connect and m_request. This is always synchronous.
wxNODISCARD Result DoPrepareRequest();
// Write next chunk of data to the request.
//
// Precondition: m_dataWritten < m_dataSize.
//
// Fills the output parameter with the number of bytes written in
// synchronous mode. In asynchronous mode, the number of bytes written is
// returned later and this argument must be null.
wxNODISCARD Result DoWriteData(DWORD* bytesWritten = nullptr);
wxWebSessionWinHTTP& m_sessionImpl;
wxString m_url;
HINTERNET m_connect = nullptr;
HINTERNET m_request = nullptr;
wxObjectDataPtr<wxWebResponseWinHTTP> m_response;
wxObjectDataPtr<wxWebAuthChallengeWinHTTP> m_authChallenge;
wxMemoryBuffer m_dataWriteBuffer;
wxFileOffset m_dataWritten = 0;
// Store authentication information from the URL, if any, as well as a flag
// which is reset after the first attempt to use it, so that we don't try
// to do it an infinite loop.
wxWebCredentials m_credentialsFromURL;
bool m_tryCredentialsFromURL = false;
// Proxy credentials (if any) are stored in the session, but we need store
// the same flag for them as for the server credentials here.
bool m_tryProxyCredentials = false;
wxNODISCARD Result SendRequest();
// Write data, if any, and call CreateResponse() if there is nothing left
// to write.
void WriteData();
wxNODISCARD Result CreateResponse();
wxNODISCARD Result InitAuthIfNeeded();
// Return error result with the error message built from the name of the
// operation and WinHTTP error code.
wxNODISCARD Result Fail(const wxString& operation, DWORD errorCode);
// Call Fail() with the error message built from the given operation
// description and the last error code.
wxNODISCARD Result FailWithLastError(const wxString& operation)
{
return Fail(operation, ::GetLastError());
}
// These functions can only be used for asynchronous requests.
void SetFailed(const wxString& operation, DWORD errorCode)
{
return HandleResult(Fail(operation, errorCode));
}
void SetFailedWithLastError(const wxString& operation)
{
return HandleResult(FailWithLastError(operation));
}
friend class wxWebAuthChallengeWinHTTP;
wxDECLARE_NO_COPY_CLASS(wxWebRequestWinHTTP);
};
class wxWebSessionWinHTTP : public wxWebSessionImpl
{
public:
explicit wxWebSessionWinHTTP(Mode mode);
~wxWebSessionWinHTTP();
static bool Initialize();
wxWebRequestImplPtr
CreateRequest(wxWebSession& session,
wxEvtHandler* handler,
const wxString& url,
int id) override;
wxWebRequestImplPtr
CreateRequestSync(wxWebSessionSync& WXUNUSED(session),
const wxString& WXUNUSED(url)) override;
wxVersionInfo GetLibraryVersionInfo() const override;
bool SetProxy(const wxWebProxy& proxy) override;
HINTERNET GetHandle() const { return m_handle; }
wxWebSessionHandle GetNativeHandle() const override
{
return (wxWebSessionHandle)GetHandle();
}
// Used by wxWebRequestWinHTTP to get the proxy credentials.
bool HasProxyCredentials() const
{
return !m_proxyCredentials.GetUser().empty();
}
const wxWebCredentials& GetProxyCredentials() const
{
return m_proxyCredentials;
}
private:
HINTERNET m_handle = nullptr;
bool Open();
wxWebCredentials m_proxyCredentials;
wxString m_proxyURLWithoutCredentials;
wxDECLARE_NO_COPY_CLASS(wxWebSessionWinHTTP);
};
class wxWebSessionFactoryWinHTTP : public wxWebSessionFactory
{
public:
wxWebSessionImpl* Create() override
{
return new wxWebSessionWinHTTP(wxWebSessionImpl::Mode::Async);
}
wxWebSessionImpl* CreateSync() override
{
return new wxWebSessionWinHTTP(wxWebSessionImpl::Mode::Sync);
}
bool Initialize() override
{
return wxWebSessionWinHTTP::Initialize();
}
};
#endif // _WX_MSW_WEBREQUEST_WINHTTP_H

View File

@@ -0,0 +1,149 @@
/////////////////////////////////////////////////////////////////////////////
// Name: include/wx/msw/private/webview_edge.h
// Purpose: wxMSW Edge Chromium wxWebView backend private classes
// Author: Tobias Taschner
// Created: 2020-01-15
// Copyright: (c) 2020 wxWidgets development team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef wxWebViewEdge_PRIVATE_H
#define wxWebViewEdge_PRIVATE_H
#if !wxUSE_WEBVIEW_EDGE_STATIC
#include "wx/dynlib.h"
#endif
#include "wx/msw/private/comptr.h"
#include <unordered_map>
#include <WebView2.h>
#ifndef __ICoreWebView2Settings3_INTERFACE_DEFINED__
#error "WebView2 SDK version 1.0.1722.45 or newer is required"
#endif
#ifndef __VISUALC__
__CRT_UUID_DECL(ICoreWebView2_13, 0xF75F09A8,0x667E,0x4983, 0x88,0xD6,0xC8,0x77,0x3F,0x31,0x5E,0x84);
__CRT_UUID_DECL(ICoreWebView2_2, 0x9E8F0CF8, 0xE670, 0x4B5E, 0xB2, 0xBC, 0x73, 0xE0, 0x61, 0xE3, 0x18, 0x4C);
__CRT_UUID_DECL(ICoreWebView2AddScriptToExecuteOnDocumentCreatedCompletedHandler, 0xb99369f3, 0x9b11, 0x47b5, 0xbc,0x6f, 0x8e,0x78,0x95,0xfc,0xea,0x17);
__CRT_UUID_DECL(ICoreWebView2ClearBrowsingDataCompletedHandler, 0xe9710a06,0x1d1d,0x49b2, 0x82,0x34,0x22,0x6f,0x35,0x84,0x6a,0xe5);
__CRT_UUID_DECL(ICoreWebView2ContainsFullScreenElementChangedEventHandler, 0xe45d98b1, 0xafef, 0x45be, 0x8b,0xaf, 0x6c,0x77,0x28,0x86,0x7f,0x73);
__CRT_UUID_DECL(ICoreWebView2ContentLoadingEventHandler, 0x364471e7, 0xf2be, 0x4910, 0xbd,0xba, 0xd7,0x20,0x77,0xd5,0x1c,0x4b);
__CRT_UUID_DECL(ICoreWebView2ControllerOptions, 0x12aae616,0x8ccb,0x44ec, 0xbc,0xb3,0xeb,0x18,0x31,0x88,0x16,0x35);
__CRT_UUID_DECL(ICoreWebView2CreateCoreWebView2ControllerCompletedHandler, 0x6c4819f3, 0xc9b7, 0x4260, 0x81,0x27, 0xc9,0xf5,0xbd,0xe7,0xf6,0x8c);
__CRT_UUID_DECL(ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler, 0x4e8a3389, 0xc9d8, 0x4bd2, 0xb6,0xb5, 0x12,0x4f,0xee,0x6c,0xc1,0x4d);
__CRT_UUID_DECL(ICoreWebView2DocumentTitleChangedEventHandler, 0xf5f2b923, 0x953e, 0x4042, 0x9f,0x95, 0xf3,0xa1,0x18,0xe1,0xaf,0xd4);
__CRT_UUID_DECL(ICoreWebView2DOMContentLoadedEventHandler, 0x4BAC7E9C, 0x199E, 0x49ED, 0x87, 0xED, 0x24, 0x93, 0x03, 0xAC, 0xF0, 0x19);
__CRT_UUID_DECL(ICoreWebView2Environment, 0xb96d755e, 0x0319, 0x4e92, 0xa2,0x96, 0x23,0x43,0x6f,0x46,0xa1,0xfc);
__CRT_UUID_DECL(ICoreWebView2Environment10, 0xee0eb9df,0x6f12,0x46ce, 0xb5,0x3f,0x3f,0x47,0xb9,0xc9,0x28,0xe0);
__CRT_UUID_DECL(ICoreWebView2EnvironmentOptions, 0x2fde08a8, 0x1e9a, 0x4766, 0x8c,0x05, 0x95,0xa9,0xce,0xb9,0xd1,0xc5);
__CRT_UUID_DECL(ICoreWebView2EnvironmentOptions3, 0x4a5c436e, 0xa9e3, 0x4a2e, 0x89,0xc3, 0x91,0x0d,0x35,0x13,0xf5,0xcc);
__CRT_UUID_DECL(ICoreWebView2ExecuteScriptCompletedHandler, 0x49511172, 0xcc67, 0x4bca, 0x99,0x23, 0x13,0x71,0x12,0xf4,0xc4,0xcc);
__CRT_UUID_DECL(ICoreWebView2NavigationCompletedEventHandler, 0xd33a35bf, 0x1c49, 0x4f98, 0x93,0xab, 0x00,0x6e,0x05,0x33,0xfe,0x1c);
__CRT_UUID_DECL(ICoreWebView2NavigationStartingEventHandler, 0x9adbe429, 0xf36d, 0x432b, 0x9d,0xdc, 0xf8,0x88,0x1f,0xbd,0x76,0xe3);
__CRT_UUID_DECL(ICoreWebView2NewWindowRequestedEventHandler, 0xd4c185fe, 0xc81c, 0x4989, 0x97,0xaf, 0x2d,0x3f,0xa7,0xab,0x56,0x51);
__CRT_UUID_DECL(ICoreWebView2Profile, 0x79110ad3,0xcd5d,0x4373, 0x8b,0xc3,0xc6,0x06,0x58,0xf1,0x7a,0x5f);
__CRT_UUID_DECL(ICoreWebView2Profile2, 0xfa740d4b,0x5eae,0x4344, 0xa8,0xad,0x74,0xbe,0x31,0x92,0x53,0x97);
__CRT_UUID_DECL(ICoreWebView2Settings3, 0xfdb5ab74, 0xaf33, 0x4854, 0x84,0xf0,0x0a,0x63,0x1d,0xeb,0x5e,0xba);
__CRT_UUID_DECL(ICoreWebView2Settings8, 0x9e6b0e8f,0x86ad,0x4e81, 0x81,0x47,0xa9,0xb5,0xed,0xb6,0x86,0x50);
__CRT_UUID_DECL(ICoreWebView2SourceChangedEventHandler, 0x3c067f9f, 0x5388, 0x4772, 0x8b,0x48, 0x79,0xf7,0xef,0x1a,0xb3,0x7c);
__CRT_UUID_DECL(ICoreWebView2WebMessageReceivedEventHandler, 0x57213f19, 0x00e6, 0x49fa, 0x8e,0x07, 0x89,0x8e,0xa0,0x1e,0xcb,0xd2);
__CRT_UUID_DECL(ICoreWebView2WebResourceRequestedEventHandler, 0xab00b74c, 0x15f1, 0x4646, 0x80, 0xe8, 0xe7, 0x63, 0x41, 0xd2, 0x5d, 0x71);
__CRT_UUID_DECL(ICoreWebView2WindowCloseRequestedEventHandler, 0x5c19e9e0,0x092f,0x486b, 0xaf,0xfa,0xca,0x82,0x31,0x91,0x30,0x39);
#endif
using wxStringToWebHandlerMap = std::unordered_map<wxString, wxSharedPtr<wxWebViewHandler>>;
class wxWebViewWindowFeaturesEdge;
class wxWebViewEdgeImpl
{
public:
explicit wxWebViewEdgeImpl(wxWebViewEdge* webview, const wxWebViewConfiguration& config);
explicit wxWebViewEdgeImpl(wxWebViewEdge* webview);
~wxWebViewEdgeImpl();
bool Create();
wxWebViewEdge* m_ctrl;
wxWebViewConfiguration m_config;
wxCOMPtr<ICoreWebView2Environment> m_webViewEnvironment;
wxCOMPtr<ICoreWebView2_2> m_webView;
wxCOMPtr<ICoreWebView2Controller> m_webViewController;
wxCOMPtr<ICoreWebView2NewWindowRequestedEventArgs> m_newWindowArgs;
wxCOMPtr<ICoreWebView2Deferral> m_newWindowDeferral;
bool m_initialized;
bool m_isBusy;
bool m_inEventCallback;
wxString m_pendingURL;
wxString m_pendingPage;
int m_pendingContextMenuEnabled;
int m_pendingAccessToDevToolsEnabled;
int m_pendingEnableBrowserAcceleratorKeys;
wxVector<wxString> m_pendingUserScripts;
wxVector<wxString> m_userScriptIds;
wxString m_scriptMsgHandlerName;
wxString m_pendingUserAgent;
wxStringToWebHandlerMap m_handlers;
// WebView Events tokens
EventRegistrationToken m_navigationStartingToken = { };
EventRegistrationToken m_frameNavigationStartingToken = { };
EventRegistrationToken m_sourceChangedToken = { };
EventRegistrationToken m_navigationCompletedToken = { };
EventRegistrationToken m_newWindowRequestedToken = { };
EventRegistrationToken m_documentTitleChangedToken = { };
EventRegistrationToken m_DOMContentLoadedToken = { };
EventRegistrationToken m_containsFullScreenElementChangedToken = { };
EventRegistrationToken m_webMessageReceivedToken = { };
EventRegistrationToken m_webResourceRequestedToken = { };
EventRegistrationToken m_windowCloseRequestedToken = { };
// WebView Event handlers
HRESULT OnNavigationStarting(ICoreWebView2* sender, ICoreWebView2NavigationStartingEventArgs* args);
HRESULT OnFrameNavigationStarting(ICoreWebView2* sender, ICoreWebView2NavigationStartingEventArgs* args);
HRESULT OnSourceChanged(ICoreWebView2* sender, ICoreWebView2SourceChangedEventArgs* args);
HRESULT OnNavigationCompleted(ICoreWebView2* sender, ICoreWebView2NavigationCompletedEventArgs* args);
HRESULT OnNewWindowRequested(ICoreWebView2* sender, ICoreWebView2NewWindowRequestedEventArgs* args);
HRESULT OnDocumentTitleChanged(ICoreWebView2* sender, IUnknown* args);
HRESULT OnDOMContentLoaded(ICoreWebView2* sender, ICoreWebView2DOMContentLoadedEventArgs* args);
HRESULT OnContainsFullScreenElementChanged(ICoreWebView2* sender, IUnknown* args);
HRESULT OnWebMessageReceived(ICoreWebView2* sender, ICoreWebView2WebMessageReceivedEventArgs* args);
HRESULT OnWebResourceRequested(ICoreWebView2* sender, ICoreWebView2WebResourceRequestedEventArgs* args);
HRESULT OnAddScriptToExecuteOnDocumentedCreatedCompleted(HRESULT errorCode, LPCWSTR id);
HRESULT OnWindowCloseRequested(ICoreWebView2* sender, IUnknown* args);
void EnvironmentAvailable(ICoreWebView2Environment* environment);
HRESULT OnWebViewCreated(HRESULT result, ICoreWebView2Controller* webViewController);
HRESULT HandleNavigationStarting(ICoreWebView2NavigationStartingEventArgs* args, bool mainFrame);
void SendErrorEventForAPI(const wxString& api, HRESULT errorCode);
wxVector<wxSharedPtr<wxWebViewHistoryItem> > m_historyList;
int m_historyPosition;
bool m_historyLoadingFromList;
bool m_historyEnabled;
void UpdateBounds();
ICoreWebView2Settings* GetSettings();
ICoreWebView2Settings3* GetSettings3();
void UpdateWebMessageHandler();
#if !wxUSE_WEBVIEW_EDGE_STATIC
static wxDynamicLibrary ms_loaderDll;
#endif
static bool Initialize();
static void Uninitialize();
friend class wxWebViewEdgeModule;
};
#endif // wxWebViewEdge_PRIVATE_H

View File

@@ -0,0 +1,240 @@
/////////////////////////////////////////////////////////////////////////////
// Name: include/wx/msw/private/webview_ie.h
// Purpose: wxMSW IE wxWebView backend private classes
// Author: Marianne Gagnon
// Copyright: (c) 2010 Marianne Gagnon, 2011 Steven Lamerton
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef wxWebViewIE_PRIVATE_H
#define wxWebViewIE_PRIVATE_H
#include "wx/msw/ole/automtn.h"
#include "wx/msw/private/comptr.h"
#include "wx/msw/private/webview_missing.h"
class ClassFactory;
class wxIEContainer;
class DocHostUIHandler;
class wxFindPointers;
class wxWebViewIEImpl
{
public:
explicit wxWebViewIEImpl(wxWebViewIE* webview);
~wxWebViewIEImpl();
bool Create();
wxWebViewIE* m_webview;
wxIEContainer* m_container;
wxAutomationObject m_ie;
IWebBrowser2* m_webBrowser;
wxCOMPtr<DocHostUIHandler> m_uiHandler;
//We store the current zoom type;
wxWebViewZoomType m_zoomType;
/** The "Busy" property of IWebBrowser2 does not always return busy when
* we'd want it to; this variable may be set to true in cases where the
* Busy property is false but should be true.
*/
bool m_isBusy;
//We manage our own history, the history list contains the history items
//which are added as documentcomplete events arrive, unless we are loading
//an item from the history. The position is stored as an int, and reflects
//where we are in the history list.
wxVector<wxSharedPtr<wxWebViewHistoryItem> > m_historyList;
wxVector<ClassFactory*> m_factories;
int m_historyPosition;
bool m_historyLoadingFromList;
bool m_historyEnabled;
//We store find flag, results and position.
wxVector<wxFindPointers> m_findPointers;
int m_findFlags;
wxString m_findText;
int m_findPosition;
//Generic helper functions
bool CanExecCommand(wxString command) const;
void ExecCommand(wxString command);
wxCOMPtr<IHTMLDocument2> GetDocument() const;
bool IsElementVisible(wxCOMPtr<IHTMLElement> elm);
//Find helper functions.
long Find(const wxString& text, int flags = wxWEBVIEW_FIND_DEFAULT);
void FindInternal(const wxString& text, int flags, int internal_flag);
long FindNext(int direction = 1);
void FindClear();
//Toggles control features see INTERNETFEATURELIST for values.
bool EnableControlFeature(long flag, bool enable = true);
wxDECLARE_NO_COPY_CLASS(wxWebViewIEImpl);
};
class VirtualProtocol : public wxIInternetProtocol, public wxIInternetProtocolInfo
{
protected:
wxIInternetProtocolSink* m_protocolSink;
wxString m_html;
VOID * fileP;
wxFSFile* m_file;
wxSharedPtr<wxWebViewHandler> m_handler;
public:
VirtualProtocol(wxSharedPtr<wxWebViewHandler> handler);
virtual ~VirtualProtocol() = default;
//IUnknown
DECLARE_IUNKNOWN_METHODS;
//IInternetProtocolRoot
HRESULT STDMETHODCALLTYPE Abort(HRESULT WXUNUSED(hrReason),
DWORD WXUNUSED(dwOptions)) override
{ return E_NOTIMPL; }
HRESULT STDMETHODCALLTYPE Continue(wxPROTOCOLDATA *WXUNUSED(pProtocolData)) override
{ return S_OK; }
HRESULT STDMETHODCALLTYPE Resume() override { return S_OK; }
HRESULT STDMETHODCALLTYPE Start(LPCWSTR szUrl,
wxIInternetProtocolSink *pOIProtSink,
wxIInternetBindInfo *pOIBindInfo,
DWORD grfPI,
HANDLE_PTR dwReserved) override;
HRESULT STDMETHODCALLTYPE Suspend() override { return S_OK; }
HRESULT STDMETHODCALLTYPE Terminate(DWORD WXUNUSED(dwOptions)) override { return S_OK; }
//IInternetProtocol
HRESULT STDMETHODCALLTYPE LockRequest(DWORD WXUNUSED(dwOptions)) override
{ return S_OK; }
HRESULT STDMETHODCALLTYPE Read(void *pv, ULONG cb, ULONG *pcbRead) override;
HRESULT STDMETHODCALLTYPE Seek(LARGE_INTEGER WXUNUSED(dlibMove),
DWORD WXUNUSED(dwOrigin),
ULARGE_INTEGER* WXUNUSED(plibNewPosition)) override
{ return E_FAIL; }
HRESULT STDMETHODCALLTYPE UnlockRequest() override { return S_OK; }
//IInternetProtocolInfo
HRESULT STDMETHODCALLTYPE CombineUrl(
LPCWSTR pwzBaseUrl, LPCWSTR pwzRelativeUrl,
DWORD dwCombineFlags, LPWSTR pwzResult,
DWORD cchResult, DWORD *pcchResult,
DWORD dwReserved) override;
HRESULT STDMETHODCALLTYPE ParseUrl(
LPCWSTR pwzUrl, wxPARSEACTION ParseAction,
DWORD dwParseFlags, LPWSTR pwzResult,
DWORD cchResult, DWORD *pcchResult,
DWORD dwReserved) override;
HRESULT STDMETHODCALLTYPE CompareUrl(
LPCWSTR pwzUrl1,
LPCWSTR pwzUrl2,
DWORD dwCompareFlags) override;
HRESULT STDMETHODCALLTYPE QueryInfo(
LPCWSTR pwzUrl, wxQUERYOPTION OueryOption,
DWORD dwQueryFlags, LPVOID pBuffer,
DWORD cbBuffer, DWORD *pcbBuf,
DWORD dwReserved) override;
};
class ClassFactory : public IClassFactory
{
public:
ClassFactory(wxSharedPtr<wxWebViewHandler> handler) : m_handler(handler)
{ AddRef(); }
virtual ~ClassFactory() = default;
wxString GetName() { return m_handler->GetName(); }
//IClassFactory
HRESULT STDMETHODCALLTYPE CreateInstance(IUnknown* pUnkOuter,
REFIID riid, void** ppvObject) override;
HRESULT STDMETHODCALLTYPE LockServer(BOOL fLock) override;
//IUnknown
DECLARE_IUNKNOWN_METHODS;
private:
wxSharedPtr<wxWebViewHandler> m_handler;
};
class wxIEContainer : public wxActiveXContainer
{
public:
wxIEContainer(wxWindow *parent, REFIID iid, IUnknown *pUnk, DocHostUIHandler* uiHandler = nullptr);
virtual ~wxIEContainer();
virtual bool QueryClientSiteInterface(REFIID iid, void **_interface, const char *&desc) override;
private:
DocHostUIHandler* m_uiHandler;
};
class DocHostUIHandler : public wxIDocHostUIHandler
{
public:
DocHostUIHandler(wxWebView* browser) { m_browser = browser; }
virtual ~DocHostUIHandler() = default;
virtual HRESULT wxSTDCALL ShowContextMenu(DWORD dwID, POINT *ppt,
IUnknown *pcmdtReserved,
IDispatch *pdispReserved) override;
virtual HRESULT wxSTDCALL GetHostInfo(DOCHOSTUIINFO *pInfo) override;
virtual HRESULT wxSTDCALL ShowUI(DWORD dwID,
IOleInPlaceActiveObject *pActiveObject,
IOleCommandTarget *pCommandTarget,
IOleInPlaceFrame *pFrame,
IOleInPlaceUIWindow *pDoc) override;
virtual HRESULT wxSTDCALL HideUI(void) override;
virtual HRESULT wxSTDCALL UpdateUI(void) override;
virtual HRESULT wxSTDCALL EnableModeless(BOOL fEnable) override;
virtual HRESULT wxSTDCALL OnDocWindowActivate(BOOL fActivate) override;
virtual HRESULT wxSTDCALL OnFrameWindowActivate(BOOL fActivate) override;
virtual HRESULT wxSTDCALL ResizeBorder(LPCRECT prcBorder,
IOleInPlaceUIWindow *pUIWindow,
BOOL fRameWindow) override;
virtual HRESULT wxSTDCALL TranslateAccelerator(LPMSG lpMsg,
const GUID *pguidCmdGroup,
DWORD nCmdID) override;
virtual HRESULT wxSTDCALL GetOptionKeyPath(LPOLESTR *pchKey,
DWORD dw) override;
virtual HRESULT wxSTDCALL GetDropTarget(IDropTarget *pDropTarget,
IDropTarget **ppDropTarget) override;
virtual HRESULT wxSTDCALL GetExternal(IDispatch **ppDispatch) override;
virtual HRESULT wxSTDCALL TranslateUrl(DWORD dwTranslate,
OLECHAR *pchURLIn,
OLECHAR **ppchURLOut) override;
virtual HRESULT wxSTDCALL FilterDataObject(IDataObject *pDO,
IDataObject **ppDORet) override;
//IUnknown
DECLARE_IUNKNOWN_METHODS;
private:
wxWebView* m_browser;
};
class wxFindPointers
{
public:
wxFindPointers(wxIMarkupPointer *ptrBegin, wxIMarkupPointer *ptrEnd)
{
begin = ptrBegin;
end = ptrEnd;
}
//The two markup pointers.
wxIMarkupPointer *begin, *end;
};
#endif // wxWebViewIE_PRIVATE_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,134 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/msw/private/winstyle.h
// Purpose: Small helper class for updating MSW windows style
// Author: Vadim Zeitlin
// Created: 2017-12-09
// Copyright: (c) 2017 Vadim Zeitlin <vadim@wxwidgets.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_MSW_PRIVATE_WINSTYLE_H_
#define _WX_MSW_PRIVATE_WINSTYLE_H_
// ----------------------------------------------------------------------------
// wxMSWWinLongUpdater
// ----------------------------------------------------------------------------
/*
This class is not used directly, but either as wxMSWWinStyleUpdater or
wxMSWWinExStyleUpdater, both of which inherit from it and can be used like
this:
void SomeFunction()
{
wxMSWWinStyleUpdater updateStyle(GetHwndOf(m_win));
if ( some-condition )
updateStyle.TurnOn(XX_YYY);
// Style update happens here implicitly -- or call Apply().
}
*/
class wxMSWWinLongUpdater
{
public:
// Get the current style.
LONG_PTR Get() const
{
return m_styleCurrent;
}
// Check if the given style bit(s) is (are all) currently turned on.
bool IsOn(LONG_PTR style) const
{
return (m_styleCurrent & style) == style;
}
// Turn on some bit(s) in the style.
wxMSWWinLongUpdater& TurnOn(LONG_PTR on)
{
m_style |= on;
return *this;
}
// Turn off some bit(s) in the style.
wxMSWWinLongUpdater& TurnOff(LONG_PTR off)
{
m_style &= ~off;
return *this;
}
// Turn some bit(s) on or off depending on the condition.
wxMSWWinLongUpdater& TurnOnOrOff(bool cond, LONG_PTR style)
{
return cond ? TurnOn(style) : TurnOff(style);
}
// Perform the style update (only if necessary, i.e. if the style really
// changed).
//
// Notice that if this method is not called, it's still done from the dtor,
// so it's just a convenient way to do it sooner and avoid having to create
// a new scope for ensuring that the dtor runs at the right place, but
// otherwise is equivalent to do this.
bool Apply()
{
if ( m_style == m_styleCurrent )
return false;
::SetWindowLongPtr(m_hwnd, m_gwlSlot, m_style);
m_styleCurrent = m_style;
return true;
}
~wxMSWWinLongUpdater()
{
Apply();
}
protected:
// Create the object for updating the style or extended style of the given
// window.
//
// Ctor is protected, this class can only be used as wxMSWWinStyleUpdater
// or wxMSWWinExStyleUpdater.
wxMSWWinLongUpdater(HWND hwnd, int gwlSlot)
: m_hwnd(hwnd),
m_gwlSlot(gwlSlot),
m_styleCurrent(::GetWindowLongPtr(hwnd, gwlSlot)),
m_style(m_styleCurrent)
{
}
private:
const HWND m_hwnd;
const int m_gwlSlot;
LONG_PTR m_styleCurrent;
LONG_PTR m_style;
wxDECLARE_NO_COPY_CLASS(wxMSWWinLongUpdater);
};
// A variant of wxMSWWinLongUpdater which updates the extended style.
class wxMSWWinStyleUpdater : public wxMSWWinLongUpdater
{
public:
explicit wxMSWWinStyleUpdater(HWND hwnd)
: wxMSWWinLongUpdater(hwnd, GWL_STYLE)
{
}
};
// A variant of wxMSWWinLongUpdater which updates the extended style.
class wxMSWWinExStyleUpdater : public wxMSWWinLongUpdater
{
public:
explicit wxMSWWinExStyleUpdater(HWND hwnd)
: wxMSWWinLongUpdater(hwnd, GWL_EXSTYLE)
{
}
};
#endif // _WX_MSW_PRIVATE_WINSTYLE_H_