Implementation helpers

These classes and functions can be used to make implementing panels easier.

Container window

struct container_window_v3_config

Window and window class styles, names and other parameters for a container_window_v3.

Public Functions

inline container_window_v3_config(const wchar_t *class_name, bool use_transparent_background = true, unsigned class_styles = 0)

Public Members

const wchar_t *class_name = {}
bool use_transparent_background = {true}

Whether to use the parent window’s background for this window.

If true, on_message() will not be called when the WM_ERASEBKGND message is received. The window (but not its children) will also be invalidated on resize or move.

You can also set this to false and use uie::win32::paint_background_using_parent() in your on_message() implementation for more flexibility.

If set to false, you should ensure a background is painted for this window.

bool invalidate_children_on_move_or_resize = {}
bool forward_wm_settingchange = {true}

Whether to forward WM_SETTINGCHANGE messages to direct child windows.

This should be set to false if a toolbar control is a direct child window, as they can misbehave when handling WM_SETTINGCHANGE.

unsigned window_styles = {WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS}
unsigned extended_window_styles = {WS_EX_CONTROLPARENT}
unsigned class_styles = {}
LPWSTR class_cursor = {IDC_ARROW}
HBRUSH class_background = {}
const wchar_t * window_title   = {L""}
int class_extra_wnd_bytes = {}
class container_window_v3

Implements a window that serves either as an empty container for other windows, or as window for a custom control.

Public Functions

inline container_window_v3(container_window_v3_config config, std::function<LRESULT(HWND wnd, UINT msg, WPARAM wp, LPARAM lp)> on_message = nullptr)
container_window_v3(const container_window_v3 &p_source) = delete
container_window_v3 &operator=(const container_window_v3 &p_source) = delete
HWND create(HWND wnd_parent, int x, int y, int cx, int cy)
HWND create(HWND wnd_parent)
void destroy() const

Destroy the window.

If this is the last instance of this window class, the window class will also be deregistered.

inline HWND get_wnd() const
void deregister_class() const

Deregister the window class.

If not using destroy() to destryoy the window, call this to deregister the window class when all windows belonging to the class have ben destroyed.

template<class Base = window>
class container_uie_window_v3_t : public uie::window

A base implementation of uie::window using uie::container_window_v3

Public Functions

virtual container_window_v3_config get_window_config() = 0

Get window and window class styles, names and other parameters.

virtual LRESULT on_message(HWND wnd, UINT msg, WPARAM wp, LPARAM lp) = 0
inline virtual bool is_available(const window_host_ptr &p) const override

Get whether the window is available to be inserted in a particular host.

For multi-instance windows, you can always return true.

For single-instance windows, if an existing host has been assigned to the window, return false if its GUID is equal to the GUID of p_host. Otherwise, return `true.

Returns:

whether this instance can be created in or moved to the given host

inline const window_host_ptr &get_host() const
inline virtual HWND get_wnd() const final

Get the extension window handle.

Pre:

May only be called on hosted extensions.

Returns:

Window handle of the extension window (or nullptr if the window has not been created)

inline virtual HWND create_or_transfer_window(HWND parent, const window_host_ptr &host, const ui_helpers::window_position_t &position) final

Create the panel or toolbar window or transfer the window to a new host.

A canonical implementation of this method is similar to:

if (m_wnd) {
    ShowWindow(m_wnd, SW_HIDE);
    SetParent(m_wnd, parent);
    m_host->relinquish_ownership(get_wnd());
    m_host = host;
    SetWindowPos(get_wnd(), nullptr, position.x, position.y, position.cx, position.cy, SWP_NOZORDER);
} else {
    m_host = host;
    m_wnd = CreateWindowEx(ex_styles, class_name, window_name, styles,
        position.x, position.y, position.cx, position.cy, parent,
        reinterpret_cast<HMENU>(0), core_api::get_my_instance(), nullptr);
}

return m_wnd;

Note that the case where this method is called to transfer an already-created window to a new host is only relevant for single-instance windows. For multi-instance windows, you can instead call uBugCheck() or do something similar if that happens.

Remark

  • The window must have the WS_CHILD window style. It must not have the WS_POPUP, WS_CAPTION or WS_VISIBLE styles.

  • Do not make the window visible – the host will do this when ready.

  • Use the WS_EX_CONTROLPARENT extended style if the window has child windows that receive keyboard input, and you want them to be included in tab operations in the host window.

  • Do not directly create a common control as your window. You must create an intermediate window to contain any common controls (or other child windows) that communicate to the parent window via WM_COMMAND and WM_NOTIFY window messages.

  • If this window is not itself hosting another panel or toolbar, it can be dialog managed (i.e. using modeless_dialog_manager) if required.

  • The window must have a dialog item ID of 0.

Parameters:
  • wnd_parent[in] Handle to the window to use as the parent for your window

  • p_host[in] Pointer to the host that creates the extension. This parameter may not be NULL.

  • p_position[in] Initial position of the window

Pre:

May only be called if is_available() returned true.

Returns:

Window handle of the panel or toolbar window, or nullptr on failure

inline virtual void destroy_window() final

Destroy the window.

Typically, you would call DestroyWindow() in this method, and clean up any resources that are no longer required.

In normal circumstances, the window will always be destroyed using this method.

using uie::container_uie_window_v3 = container_uie_window_v3_t<>

Functions

LRESULT uie::win32::paint_background_using_parent(HWND wnd, HDC dc, bool use_wm_printclient)