#ifndef MRUI_H
#define MRUI_H
#include <Windows.h>
/**
* Allocate a block of heap memory.
*
* @param dwBytes Number of bytes to allocate.
* @return Pointer to the allocated memory, or NULL on failure.
*/
EXTERN_C LPVOID mruiMemAlloc(SIZE_T dwBytes);
/**
* Free a previously allocated memory block.
*
* @param hMem Handle to the memory block.
* @return TRUE on success, FALSE on failure.
*/
EXTERN_C BOOL mruiMemRelease(HANDLE hMem);
/**
* Verify whether a memory handle points to a valid block.
*
* @param hMem Handle to the memory block.
* @return TRUE if valid, FALSE otherwise.
*/
EXTERN_C BOOL mruiMemIsValid(HANDLE hMem);
/**
* Instantiate a new child control.
*
* @param hParent Handle of the parent container.
* @return Handle to the new control, or NULL on failure.
*/
EXTERN_C HANDLE mruiChildCreate(HANDLE hParent);
/**
* Instantiate a top-level window.
*
* @param dwExStyle Extended window style.
* @param dwStyle Window style.
* @param lpClassName Registered window class name.
* @param lpWindowName Window title.
* @return Handle to the new window control, or NULL on failure.
*/
EXTERN_C HANDLE mruiWndCreate(DWORD dwExStyle, DWORD dwStyle, LPCWSTR lpClassName, LPCWSTR lpWindowName);
/**
* Destroy a control and release its memory.
*
* @param hControl Handle to the control.
* @return TRUE on success, FALSE on failure.
*/
EXTERN_C BOOL mruiDestroy(HANDLE hControl);
/**
* Enter the application message loop.
*
* @param hControl Optional handle to a window or control.
* @return Exit code on success, 0 on failure.
*/
EXTERN_C LRESULT mruiRunLoop(HANDLE hControl);
/**
* Reparent a control to a new parent.
*
* @param hControl Handle to the control.
* @param hParent Handle to the new parent.
* @return TRUE on success, FALSE on failure.
*/
EXTERN_C BOOL mruiReparent(HANDLE hControl, HANDLE hParent);
/**
* Retrieve the parent of a control.
*
* @param hControl Handle to the control.
* @return Handle to the parent, or NULL if none.
*/
EXTERN_C HANDLE mruiQueryParent(HANDLE hControl);
/**
* Detach a control from its parent without destroying it.
*
* @param hControl Handle to the control.
* @return TRUE on success, FALSE on failure.
*/
EXTERN_C BOOL mruiDetach(HANDLE hControl);
/**
* Install an event filter callback.
*
* @param hControl Handle to the control.
* @param filter Function pointer with signature BOOL(*)(LPVOID object, UINT message, LPVOID arg1, LPVOID arg2, LPVOID arg3).
* @return TRUE on success, FALSE on failure.
*/
EXTERN_C BOOL mruiInstallFilter(HANDLE hControl, LPVOID filter);
/**
* Get the current event filter callback.
*
* @param hControl Handle to the control.
* @return Filter function pointer, or NULL.
*/
EXTERN_C LPVOID mruiQueryFilter(HANDLE hControl);
/**
* Manually invoke the event filter for a control.
*
* @param hControl Handle to the control.
* @param message Event identifier.
* @param arg1 First argument.
* @param arg2 Second argument.
* @param arg3 Third argument.
* @return Return value of the filter, or FALSE on failure.
*/
EXTERN_C LRESULT mruiDispatchFilter(HANDLE hControl, UINT message, LPVOID arg1, LPVOID arg2, LPVOID arg3);
/**
* Associate a custom class pointer with a control.
*
* @param hControl Handle to the control.
* @param handle User-defined pointer.
* @return TRUE on success, FALSE on failure.
*/
EXTERN_C BOOL mruiSetUserPtr(HANDLE hControl, LPVOID handle);
/**
* Retrieve the custom class pointer associated with a control.
*
* @param hControl Handle to the control.
* @return User-defined pointer, or NULL.
*/
EXTERN_C LPVOID mruiQueryUserPtr(HANDLE hControl);
/**
* Assign an application-defined ID to a control.
*
* @param hControl Handle to the control.
* @param id Identifier.
* @return TRUE on success, FALSE on failure.
*/
EXTERN_C BOOL mruiSetId(HANDLE hControl, LPVOID id);
/**
* Get the application-defined ID of a control.
*
* @param hControl Handle to the control.
* @return ID pointer, or NULL.
*/
EXTERN_C LPVOID mruiQueryId(HANDLE hControl);
/**
* Check whether a handle refers to a valid control.
*
* @param hControl Handle to inspect.
* @return TRUE if valid, FALSE otherwise.
*/
EXTERN_C BOOL mruiIsValidHandle(HANDLE hControl);
/**
* Check whether a handle refers to a window control.
*
* @param hControl Handle to inspect.
* @return TRUE if window, FALSE otherwise.
*/
EXTERN_C BOOL mruiIsWnd(HANDLE hControl);
/**
* Check whether a handle refers to a child control.
*
* @param hControl Handle to inspect.
* @return TRUE if child control, FALSE otherwise.
*/
EXTERN_C BOOL mruiIsChild(HANDLE hControl);
/**
* Invalidate a rectangular area of a control for repainting.
*
* @param hControl Handle to the control.
* @param lpRect Rectangle to invalidate; NULL means the entire control.
* @return TRUE on success, FALSE on failure.
*/
EXTERN_C BOOL mruiInvalidateRect(HANDLE hControl, LPRECT lpRect);
/**
* Obtain the control's rectangle relative to the screen.
*
* @param hControl Handle to the control.
* @param lpRect Output RECT.
* @return TRUE on success, FALSE on failure.
*/
EXTERN_C BOOL mruiScreenRect(HANDLE hControl, LPRECT lpRect);
/**
* Obtain the client area rectangle of the control.
*
* @param hControl Handle to the control.
* @param lpRect Output RECT.
* @return TRUE on success, FALSE on failure.
*/
EXTERN_C BOOL mruiClientRect(HANDLE hControl, LPRECT lpRect);
/**
* Obtain the control's local bounding rectangle.
*
* @param hControl Handle to the control.
* @param lpRect Output RECT.
* @return TRUE on success, FALSE on failure.
*/
EXTERN_C BOOL mruiLocalRect(HANDLE hControl, LPRECT lpRect);
/**
* Retrieve the dirty rectangle during a paint event.
*
* @param hControl Handle to the control.
* @param lpRect Output RECT.
* @return TRUE on success, FALSE on failure.
*/
EXTERN_C BOOL mruiDirtyRect(HANDLE hControl, LPRECT lpRect);
/**
* Set the geometry (position and size) of a control.
*
* @param hControl Handle to the control.
* @param x Left coordinate.
* @param y Top coordinate.
* @param width Width.
* @param height Height.
* @return TRUE on success, FALSE on failure.
*/
EXTERN_C BOOL mruiSetRect(HANDLE hControl, LONG x, LONG y, LONG width, LONG height);
/**
* Determine whether the control belongs to a layered window.
*
* @param hControl Handle to the control.
* @return TRUE if layered, FALSE otherwise.
*/
EXTERN_C BOOL mruiIsLayWin(HANDLE hControl);
/**
* Determine whether the mouse cursor is currently over the control.
*
* @param hControl Handle to the control.
* @return TRUE if mouse is inside the control's rectangle, FALSE otherwise.
*/
EXTERN_C BOOL mruiHitTest(HANDLE hControl);
/**
* Get the owning window handle for a control.
*
* @param hControl Handle to the control.
* @return Window handle, or NULL.
*/
EXTERN_C HANDLE mruiOwningWindow(HANDLE hControl);
/**
* Request keyboard focus for a control.
*
* @param hControl Handle to the control.
* @return TRUE on success, FALSE on failure.
*/
EXTERN_C BOOL mruiGrabFocus(HANDLE hControl);
/**
* Return the control that currently owns the focus.
*
* @param hControl Handle to any control in the hierarchy.
* @return Handle to the focused control, or NULL.
*/
EXTERN_C HANDLE mruiFocusedCtrl(HANDLE hControl);
/**
* Check if a control has keyboard focus.
*
* @param hControl Handle to the control.
* @return TRUE if focused, FALSE otherwise.
*/
EXTERN_C BOOL mruiHasFocus(HANDLE hControl);
/**
* Revoke keyboard focus from the currently focused control.
*
* @param hControl Handle to the control whose hierarchy is affected.
* @return TRUE on success, FALSE on failure.
*/
EXTERN_C BOOL mruiYieldFocus(HANDLE hControl);
/**
* Capture mouse events.
*
* @param hControl Handle to the control.
* @return TRUE on success, FALSE on failure.
*/
EXTERN_C BOOL mruiMouseCapture(HANDLE hControl);
/**
* Retrieve the control that currently has mouse capture.
*
* @param hControl Handle to any control in the hierarchy.
* @return Handle to the capturing control, or NULL.
*/
EXTERN_C HANDLE mruiCaptorCtrl(HANDLE hControl);
/**
* Release mouse capture.
*
* @param hControl Handle to the control.
* @return TRUE on success, FALSE on failure.
*/
EXTERN_C BOOL mruiMouseRelease(HANDLE hControl);
/**
* Get the current mouse position relative to the control.
*
* @param hControl Handle to the control.
* @param lpPoint Output POINT.
* @return TRUE on success, FALSE on failure.
*/
EXTERN_C BOOL mruiCursorPos(HANDLE hControl, LPPOINT lpPoint);
/**
* Obtain the device context for painting the control.
*
* @param hControl Handle to the control.
* @return HDC, or NULL.
*/
EXTERN_C HDC mruiPaintDC(HANDLE hControl);
/**
* Access the first child control.
*
* @param hControl Handle to the parent control.
* @return Handle to the first child, or NULL.
*/
EXTERN_C HANDLE mruiFirstChild(HANDLE hControl);
/**
* Access the last child control.
*
* @param hControl Handle to the parent control.
* @return Handle to the last child, or NULL.
*/
EXTERN_C HANDLE mruiLastChild(HANDLE hControl);
/**
* Access the control currently under the mouse pointer.
*
* @param hControl Handle to any control in the hierarchy.
* @return Handle to the hovered control, or NULL.
*/
EXTERN_C HANDLE mruiHoveredCtrl(HANDLE hControl);
/**
* Access the previous sibling control.
*
* @param hControl Handle to the control.
* @return Handle to the previous sibling, or NULL.
*/
EXTERN_C HANDLE mruiPrevSibling(HANDLE hControl);
/**
* Access the next sibling control.
*
* @param hControl Handle to the control.
* @return Handle to the next sibling, or NULL.
*/
EXTERN_C HANDLE mruiNextSibling(HANDLE hControl);
/**
* Raise the control to the top of its parent's Z-order.
*
* @param hControl Handle to the control.
* @return TRUE on success, FALSE on failure.
*/
EXTERN_C BOOL mruiBringFront(HANDLE hControl);
/**
* Retrieve the native HWND associated with a window control.
*
* @param hControl Handle to the control.
* @return HWND, or NULL.
*/
EXTERN_C HWND mruiNativeWnd(HANDLE hControl);
/**
* Map a native HWND back to a control handle.
*
* @param hWnd Window handle.
* @return Control handle, or NULL.
*/
EXTERN_C HANDLE mruiFromHwnd(HWND hWnd);
/**
* Show or hide a control.
*
* @param hControl Handle to the control.
* @param visible TRUE to show, FALSE to hide.
* @return TRUE on success, FALSE on failure.
*/
EXTERN_C BOOL mruiSetVisible(HANDLE hControl, BOOL visible);
/**
* Query the visible state of a control.
*
* @param hControl Handle to the control.
* @return TRUE if visible, FALSE otherwise.
*/
EXTERN_C BOOL mruiIsVisible(HANDLE hControl);
/**
* Enable or disable a control.
*
* @param hControl Handle to the control.
* @param disabled TRUE to disable, FALSE to enable.
* @return TRUE on success, FALSE on failure.
*/
EXTERN_C BOOL mruiSetDisabled(HANDLE hControl, BOOL disabled);
/**
* Query the disabled state of a control.
*
* @param hControl Handle to the control.
* @return TRUE if disabled, FALSE otherwise.
*/
EXTERN_C BOOL mruiIsDisabled(HANDLE hControl);
/**
* Toggle mouse-passthrough mode for a control.
*
* @param hControl Handle to the control.
* @param penetr TRUE to pass mouse events through, FALSE otherwise.
* @return TRUE on success, FALSE on failure.
*/
EXTERN_C BOOL mruiSetMouseProxy(HANDLE hControl, BOOL penetr);
/**
* Query the mouse-passthrough mode.
*
* @param hControl Handle to the control.
* @return TRUE if passthrough is active, FALSE otherwise.
*/
EXTERN_C BOOL mruiIsMouseProxy(HANDLE hControl);
/**
* Set a boolean attribute on a control.
*
* @param hControl Handle to the control.
* @param attribute Attribute identifier.
* @param state TRUE or FALSE.
* @return TRUE on success, FALSE on failure.
*/
EXTERN_C BOOL mruiSetAttr(HANDLE hControl, DWORD attribute, BOOL state);
/**
* Retrieve a boolean attribute value.
*
* @param hControl Handle to the control.
* @param attribute Attribute identifier.
* @return Attribute value, or FALSE on failure.
*/
EXTERN_C BOOL mruiGetAttr(HANDLE hControl, DWORD attribute);
/**
* Set the opacity level of a control.
*
* @param hControl Handle to the control.
* @param opacity Opacity value (0.0 = transparent, 1.0 = opaque).
* @return TRUE on success, FALSE on failure.
*/
EXTERN_C BOOL mruiSetOpacity(HANDLE hControl, FLOAT opacity);
/**
* Query the current opacity level.
*
* @param hControl Handle to the control.
* @return Opacity value, or 0.0 on failure.
*/
EXTERN_C FLOAT mruiGetOpacity(HANDLE hControl);
// Event type identifiers
enum mruiEvent {
Event_None,
Event_Close,
Event_Timer,
Event_KeyDown,
Event_KeyUp,
Event_KeyChar,
Event_FocusIn,
Event_FocusOut,
Event_Render,
Event_Move,
Event_Resize,
Event_Show,
Event_Hide,
Event_MouseDown,
Event_MouseUp,
Event_MouseDbl,
Event_MouseMove,
Event_MouseEnter,
Event_MouseExit,
Event_MouseWheel,
Event_CaptureLost,
Event_WinMsg,
Event_User
};
// Mouse button identifiers
enum MouseBtn {
Btn_None,
Btn_Left,
Btn_Right,
Btn_Middle
};
// Attribute flags
enum CtrlAttr {
Attr_None,
Attr_AlphaChannel,
Attr_UserFlag
};
#endif
#ifndef CCONTROL_H
#define CCONTROL_H
#include <Windows.h>
#include <mrui.h>
#include <CClass.h>
#include <CEvent.h>
#include <CPoint.h>
#include <CSize.h>
#include <CRect.h>
class CControl {
public:
CControl(CControl * parent);
~CControl();
public:
template<class T>
BOOL connect(LONG event, T * t, const BOOL(T::*f)(CControl&, CEvent&));
public:
virtual BOOL filterEvent(CEvent & event);
virtual BOOL closeEvent(CEvent & event);
virtual BOOL timerEvent(CEvent & event);
virtual BOOL keyDownEvent(CEvent & event);
virtual BOOL keyUpEvent(CEvent & event);
virtual BOOL keyCharEvent(CEvent & event);
virtual BOOL focusInEvent(CEvent & event);
virtual BOOL focusOutEvent(CEvent & event);
virtual BOOL renderEvent(CEvent & event);
virtual BOOL moveEvent(CEvent & event);
virtual BOOL resizeEvent(CEvent & event);
virtual BOOL showEvent(CEvent & event);
virtual BOOL hideEvent(CEvent & event);
virtual BOOL mouseDownEvent(CEvent & event);
virtual BOOL mouseUpEvent(CEvent & event);
virtual BOOL mouseDblEvent(CEvent & event);
virtual BOOL mouseMoveEvent(CEvent & event);
virtual BOOL mouseEnterEvent(CEvent & event);
virtual BOOL mouseExitEvent(CEvent & event);
virtual BOOL mouseWheelEvent(CEvent & event);
virtual BOOL captureLostEvent(CEvent & event);
virtual BOOL winMsgEvent(CEvent & event);
public:
const BOOL close();
const BOOL remove();
const BOOL setGeometry(CRect & rect);
const BOOL setGeometry(CPoint & pt);
const BOOL setGeometry(CSize & size);
const BOOL setGeometry(CPoint & pt, CSize & size);
const BOOL setGeometry(LONG x, LONG y, LONG width, LONG height);
const BOOL move(CPoint & pt);
const BOOL move(LONG x, LONG y);
const BOOL resize(CSize & size);
const BOOL resize(LONG width, LONG height);
const CRect dirtyRect();
const CRect screenRect();
const CRect clientRect();
const CRect localRect();
const LONG x();
const LONG y();
const LONG width();
const LONG height();
const CPoint cursorPos();
const BOOL setEnabled(BOOL enabled);
const BOOL isEnabled();
const BOOL setVisible(BOOL visible);
const BOOL isVisible();
const BOOL show();
const BOOL hide();
const BOOL setFocus();
const BOOL clearFocus();
const CControl * focused();
const BOOL isFocused();
const BOOL setParent(CControl * parent);
const CControl * parent();
const BOOL invalidate();
const BOOL underMouse();
const HDC hdc();
const HWND nativeWnd();
const CControl * window();
const CControl * firstChild();
const CControl * lastChild();
const CControl * hovered();
const CControl * prevSibling();
const CControl * nextSibling();
const BOOL isWindow();
const BOOL isChildControl();
const BOOL isLayWin();
const BOOL raise();
const BOOL captureMouse();
const BOOL hasCapture();
const BOOL releaseCapture();
const BOOL setId(LPVOID id);
const LPVOID id();
const LRESULT run();
const BOOL setAttr(INT attribute, BOOL state);
const BOOL attr(INT attribute);
const BOOL setOpacity(FLOAT opacity);
const FLOAT opacity();
};
#endif
#ifndef CBUTTON_H
#define CBUTTON_H
#include <Windows.h>
#include <CClass.h>
#include <CControl.h>
enum ButtonState {
STATE_NORMAL,
STATE_HOVERED,
STATE_PRESSED,
STATE_DISABLED,
STATE_POSTPROCESS
};
class CButton : public CControl {
public:
CButton(CControl * parent = nullptr);
virtual BOOL renderEvent(CEvent & event) override;
virtual BOOL mouseDownEvent(CEvent & event) override;
virtual BOOL mouseUpEvent(CEvent & event) override;
virtual BOOL mouseEnterEvent(CEvent & event) override;
virtual BOOL mouseExitEvent(CEvent & event) override;
virtual BOOL captureLostEvent(CEvent & event) override;
private:
void drawBackground(HDC dc, const RECT & rc, COLORREF bg, COLORREF border, const wchar_t* label);
ButtonState m_state;
};
#endif // CBUTTON_H
#include <CButton.h>
CButton::CButton(CControl * parent) : CControl(parent) {
m_state = STATE_NORMAL;
}
void CButton::drawBackground(HDC dc, const RECT & rc, COLORREF bg, COLORREF border, const wchar_t* label) {
HBRUSH brushBg = CreateSolidBrush(bg);
HBRUSH brushBorder = CreateSolidBrush(border);
FillRect(dc, &rc, brushBg);
FrameRect(dc, &rc, brushBorder);
DeleteObject(brushBg);
DeleteObject(brushBorder);
DrawTextW(dc, label, (INT)wcslen(label), (LPRECT)&rc, DT_VCENTER | DT_SINGLELINE | DT_CENTER | DT_END_ELLIPSIS);
}
BOOL CButton::renderEvent(CEvent & event) {
CRect dirty = dirtyRect();
RECT rc = { dirty.left(), dirty.top(), dirty.right(), dirty.bottom() };
switch (m_state) {
case STATE_NORMAL:
drawBackground(hdc(), rc, RGB(255, 255, 255), RGB(200, 200, 200), L"button");
break;
case STATE_HOVERED:
drawBackground(hdc(), rc, RGB(230, 230, 230), RGB(111, 111, 255), L"button");
break;
case STATE_PRESSED:
drawBackground(hdc(), rc, RGB(200, 200, 200), RGB(111, 119, 255), L"button");
break;
default:
break;
}
return TRUE;
}
BOOL CButton::mouseDownEvent(CEvent & event) {
captureMouse();
m_state = STATE_PRESSED;
invalidate();
return TRUE;
}
BOOL CButton::mouseUpEvent(CEvent & event) {
releaseCapture();
m_state = underMouse() ? STATE_HOVERED : STATE_NORMAL;
invalidate();
return TRUE;
}
BOOL CButton::mouseEnterEvent(CEvent & event) {
m_state = STATE_HOVERED;
invalidate();
return TRUE;
}
BOOL CButton::mouseExitEvent(CEvent & event) {
m_state = STATE_NORMAL;
invalidate();
return TRUE;
}
BOOL CButton::captureLostEvent(CEvent & event) {
m_state = underMouse() ? STATE_HOVERED : STATE_NORMAL;
invalidate();
return TRUE;
}
#include <Windows.h>
#include <tchar.h>
#include "CControl\CControl.h"
#include "CControl\CButton.h"
class MainWindow : public CControl {
public:
MainWindow(CControl * parent = nullptr) : CControl(parent) {
CButton * btn = new CButton(this);
btn->setGeometry(100, 100, 100, 50);
btn->setOpacity(0.5f);
btn->connect(Event_MouseUp, this, &MainWindow::OnClick);
}
const BOOL OnClick(CControl & object, CEvent & event) {
::MessageBoxA(nativeWnd(), "Button clicked", "Info", MB_OK);
return FALSE;
}
virtual BOOL closeEvent(CEvent & event) override {
PostQuitMessage(0);
CControl::closeEvent(event);
return TRUE;
}
};
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE, LPTSTR, int) {
MainWindow wnd(nullptr);
wnd.show();
wnd.run();
return 0;
}