2015-05-14 08:43:25 -05:00
// 7 april 2015
/*
This file assumes that you have included < windows . h > and " ui.h " beforehand . It provides API - specific functions for interfacing with foreign controls in Windows .
*/
2015-08-28 20:42:21 -05:00
# ifndef __LIBUI_UI_WINDOWS_H__
# define __LIBUI_UI_WINDOWS_H__
2015-08-29 19:38:12 -05:00
typedef struct uiWindowsSizing uiWindowsSizing ;
2015-08-28 20:42:21 -05:00
typedef struct uiWindowsControl uiWindowsControl ;
struct uiWindowsControl {
uiControl c ;
void ( * CommitSetParent ) ( uiWindowsControl * , HWND ) ;
2015-08-29 19:38:12 -05:00
void ( * MinimumSize ) ( uiWindowsControl * , uiWindowsSizing * , intmax_t * , intmax_t * ) ;
2015-08-30 17:24:57 -05:00
void ( * Relayout ) ( uiWindowsControl * , intmax_t , intmax_t , intmax_t , intmax_t ) ;
2015-08-28 20:42:21 -05:00
} ;
_UI_EXTERN uintmax_t uiWindowsControlType ( void ) ;
# define uiWindowsControl(this) ((uiWindowsControl *) uiIsA((this), uiWindowsControlType(), 1))
// TODO document
2015-08-30 17:24:57 -05:00
_UI_EXTERN void uiWindowsControlQueueRelayout ( uiWindowsControl * ) ;
2015-08-28 20:42:21 -05:00
// TODO document
# define uiWindowsDefineControlWithOnDestroy(type, typefn, onDestroy) \
static uintmax_t _ # # type # # Type = 0 ; \
uintmax_t typefn ( void ) \
{ \
if ( _ # # type # # Type = = 0 ) \
_ # # type # # Type = uiRegisterType ( # type , uiWindowsControlType ( ) , sizeof ( type ) ) ; \
return _ # # type # # Type ; \
} \
static void _ # # type # # CommitDestroy ( uiControl * c ) \
{ \
type * this = type ( c ) ; \
onDestroy ; \
uiWindowsEnsureDestroyWindow ( this - > hwnd ) ; \
} \
static uintptr_t _ # # type # # Handle ( uiControl * c ) \
{ \
return ( uintptr_t ) ( type ( c ) - > hwnd ) ; \
} \
static void _ # # type # # ContainerUpdateState ( uiControl * c ) \
{ \
/* do nothing */ \
} \
static void _ # # type # # CommitSetParent ( uiWindowsControl * c , HWND parent ) \
{ \
uiWindowsEnsureSetParent ( type ( c ) - > hwnd , parent ) ; \
} \
2015-08-30 17:24:57 -05:00
static void _ # # type # # Relayout ( uiWindowsControl * c , intmax_t x , intmax_t y , intmax_t width , intmax_t height ) \
2015-08-28 20:42:21 -05:00
{ \
2015-08-30 17:24:57 -05:00
uiWindowsEnsureMoveWindow ( type ( c ) - > hwnd , x , y , width , height ) ; \
2015-08-29 19:38:12 -05:00
} \
static void minimumSize ( uiWindowsControl * c , uiWindowsSizing * d , intmax_t * width , intmax_t * height ) ;
2015-08-28 20:42:21 -05:00
# define uiWindowsDefineControl(type, typefn) \
uiWindowsDefineControlWithOnDestroy ( type , typefn , ( void ) this ; )
# define uiWindowsFinishNewControl(variable, type) \
uiControl ( variable ) - > CommitDestroy = _ # # type # # CommitDestroy ; \
uiControl ( variable ) - > Handle = _ # # type # # Handle ; \
uiControl ( variable ) - > ContainerUpdateState = _ # # type # # ContainerUpdateState ; \
uiWindowsControl ( variable ) - > CommitSetParent = _ # # type # # CommitSetParent ; \
2015-08-29 19:38:12 -05:00
uiWindowsControl ( variable ) - > MinimumSize = minimumSize ; \
2015-08-28 20:42:21 -05:00
uiWindowsControl ( variable ) - > Relayout = _ # # type # # Relayout ; \
uiWindowsFinishControl ( uiControl ( variable ) ) ;
// This is a function used to set up a control.
// Don't call it directly; use uiWindowsFinishNewControl() instead.
_UI_EXTERN void uiWindowsFinishControl ( uiControl * c ) ;
2015-05-14 08:43:25 -05:00
2015-06-05 15:56:43 -05:00
// This creates a HWND compatible with libui.
2015-08-28 20:42:21 -05:00
// It has no failure state; libui handles errors for you.
_UI_EXTERN HWND uiWindowsEnsureCreateControlHWND ( DWORD dwExStyle , LPCWSTR lpClassName , LPCWSTR lpWindowName , DWORD dwStyle , HINSTANCE hInstance , LPVOID lpParam , BOOL useStandardControlFont ) ;
// This is a wrapper for certain Windows API functions; use them to have libui handle errors for you.
_UI_EXTERN void uiWindowsEnsureDestroyWindow ( HWND hwnd ) ;
_UI_EXTERN void uiWindowsEnsureSetParent ( HWND hwnd , HWND parent ) ;
2015-08-30 17:24:57 -05:00
// Use this in your Relayout() implementation to move and resize HWNDs. libui handles errors for you.
_UI_EXTERN void uiWindowsEnsureMoveWindow ( HWND hwnd , intmax_t x , intmax_t y , intmax_t width , intmax_t height ) ;
2015-08-28 20:42:21 -05:00
////////////////////////////////////////////
/////////////////// TODO ///////////////////
////////////////////////////////////////////
2015-06-05 15:56:43 -05:00
// These provide single-HWND implementations of uiControl methods you can use in yours.
2015-05-29 13:56:11 -05:00
_UI_EXTERN void uiWindowsUtilDestroy ( HWND hwnd ) ;
_UI_EXTERN void uiWindowsUtilSetParent ( HWND hwnd , uiControl * parent ) ;
2015-06-01 12:02:43 -05:00
_UI_EXTERN void uiWindowsUtilShow ( HWND hwnd ) ;
2015-05-29 13:56:11 -05:00
_UI_EXTERN void uiWindowsUtilHide ( HWND hwnd ) ;
2015-06-01 12:02:43 -05:00
_UI_EXTERN void uiWindowsUtilEnable ( HWND hwnd ) ;
2015-05-29 13:56:11 -05:00
_UI_EXTERN void uiWindowsUtilDisable ( HWND hwnd ) ;
2015-05-30 16:17:20 -05:00
_UI_EXTERN uintptr_t uiWindowsUtilStartZOrder ( HWND hwnd ) ;
_UI_EXTERN uintptr_t uiWindowsUtilSetZOrder ( HWND hwnd , uintptr_t insertAfter ) ;
_UI_EXTERN int uiWindowsUtilHasTabStops ( HWND hwnd ) ;
2015-06-05 15:56:43 -05:00
2015-05-14 08:43:25 -05:00
// This contains the Windows-specific parts of the uiSizing structure.
// BaseX and BaseY are the dialog base units.
// InternalLeading is the standard control font's internal leading; labels in uiForms use this for correct Y positioning.
2015-05-18 11:04:52 -05:00
// CoordFrom and CoordTo are the window handles to convert coordinates passed to uiControlResize() from and to (viaa MapWindowRect()) before passing to one of the Windows API resizing functions.
2015-08-29 19:38:12 -05:00
struct uiWindowsSizing {
2015-08-31 16:50:23 -05:00
intmax_t XPadding ;
intmax_t YPadding ;
2015-05-14 08:43:25 -05:00
int BaseX ;
int BaseY ;
LONG InternalLeading ;
2015-05-18 11:04:52 -05:00
HWND CoordFrom ;
HWND CoordTo ;
2015-05-14 08:43:25 -05:00
} ;
// Use these in your preferredSize() implementation with baseX and baseY.
# define uiWindowsDlgUnitsToX(dlg, baseX) MulDiv((dlg), baseX, 4)
# define uiWindowsDlgUnitsToY(dlg, baseY) MulDiv((dlg), baseY, 8)
// and use this if you need the text of the window width
_UI_EXTERN intmax_t uiWindowsWindowTextWidth ( HWND hwnd ) ;
2015-06-03 14:49:44 -05:00
// these functions get and set the window text for a single HWND
2015-05-14 08:43:25 -05:00
// the value returned should be freed with uiFreeText()
2015-06-03 13:54:25 -05:00
_UI_EXTERN char * uiWindowsUtilText ( HWND ) ;
_UI_EXTERN void uiWindowsUtilSetText ( HWND , const char * ) ;
2015-05-14 08:43:25 -05:00
2015-06-05 15:56:43 -05:00
// These provide event handling.
// For WM_COMMAND, the WORD parameter is the notification code.
// For WM_HSCROLL, the WORD parameter is the scroll operation.
2015-08-29 19:38:12 -05:00
_UI_EXTERN void uiWindowsRegisterWM_COMMANDHandler ( HWND , BOOL ( * ) ( uiControl * , HWND , WORD , LRESULT * ) , uiControl * ) ;
_UI_EXTERN void uiWindowsRegisterWM_NOTIFYHandler ( HWND , BOOL ( * ) ( uiControl * , HWND , NMHDR * , LRESULT * ) , uiControl * ) ;
_UI_EXTERN void uiWindowsRegisterWM_HSCROLLHandler ( HWND , BOOL ( * ) ( uiControl * , HWND , WORD , LRESULT * ) , uiControl * ) ;
_UI_EXTERN void uiWindowsUnregisterWM_COMMANDHandler ( HWND ) ;
_UI_EXTERN void uiWindowsUnregisterWM_NOTIFYHandler ( HWND ) ;
_UI_EXTERN void uiWindowsUnregisterWM_HSCROLLHandler ( HWND ) ;
_UI_EXTERN void uiWindowsRegisterReceiveWM_WININICHANGE ( HWND ) ;
_UI_EXTERN void uiWindowsUnregisterReceiveWM_WININICHANGE ( HWND ) ;
2015-06-05 15:56:43 -05:00
2015-05-14 08:43:25 -05:00
# endif