INTRODUCTION

SGL

version 1.3.5
April 08, 2020

Henri Serindat

What is SGL?

SGL (Small GUI Library) is a graphical user interface library that will help you to build Win32® applications on x86 or x64 system. It handle most of the burden of the Windows® environment and lets you concentrate on creative tasks.

It allows you to easily draw or paint you own objects without having to restart from scratch. It does not introduces new concepts and uses the ones of Windows®.

Usually, when a program grows in complexity, it ends up with a huge DialogProc stuffed with code, and therefore very painful to maintain. SGL promotes the use of function callbacks for each object and a unified approach, whatever they are windows, dialog boxes or controls.

Drawing and painting is pretty easy with the Win32® API. It may even be pleasant, and it is the only way to do some specific widgets. The problem is with the remaining stuff, dealing with the message loop, device contexts, bitmaps, pixel coordinates, etc. That where SGL has an added value.

If you have notions about Win32® programming, you are in the right place. If you don't, look at the sample programs and read some introduction to the Win32® API.

While allowing professional layouts, SGL is simple: the basic Hello program is only 12 lines

Windows® and Win32® are registered trademarks of Microsoft Corp. in the U.S. and other countries.


Features

INTRODUCTION ››

Designing a user interface requires a lot of parameters to set all the details of the graphic objects. SGL makes a lot to help the developers:

  • The position and size of the SGL objects are mostly automated via a grid layout.
  • Application windows can be easily sized and dynamically scaled.
  • Child objects inherit characteristics of their parents.
  • Objects can be duplicated.
  • Context is provided for custom drawing and intercepting events.
  • No constraint on the application data.
  • Homogeneous set of functions.
  • Event are handled by callback functions.
  • Versions for x86 (32-bit) and x64 (64-bit) computers starting with WindowsXP.

You can start by a quick look at basic examples:

  • A minimum Hello program: cf. Startup and exit .
  • A grid of colored buttons: cf. SGL objects .
  • Simple user interaction with editable buttons: cf. Callback function and data .

More features are illustrated in the EXAMPLE PROGRAMS .


Version history

INTRODUCTION ››

Version 1.0

This is the first release.

Version 1.1

Some improvements in resizing and default values:

  • Panel sizing is now possible (cf. PANEL OBJECTS ).
  • Graph object: the default size is null.
  • SGL fonts are now strictly linked to the desktop menu font. More details in Startup and exit and Font settings .
  • New function SGL_RefSizeGet (cf. Metrics and default padding ).
  • The separator object is now spanned to its parent border.

New features:

  • New macros for testing the mouse buttons: SGL_LBUTTON, SGL_MBUTTON, SGL_RBUTTON.
  • New tool for Automatic resizing .
  • New object OPENGL object.

Version 1.2

Removed feature:

  • The background color of the Edit popup is white (cannot be changed).

New features:

  • For standard and push buttons, the style sets the alignment of the text in the button.
  • Date time popup with support functions.

Version 1.3

New features:

  • Temporary Font loading
  • Table object:
    • The SGL_TableUpdate function can update the header (row = -1), and all columns (col = -1) (cf. Table update ).
    • Table filling callback : explicit notifications for start and end of paint.
    • The default cell background color is now the table background color.
    • SGL_TableHeightAdjust: new function.
  • Debug tools: the SGL_Log(FATAL, ..) does not require the console any more.
  • New tools for reading and writing in a configuration file:
    • Basic tools (cf. Configuration file ).
    • Size and position (cf. Other functions ).
    • Colors (cf. Setting colors ).
  • New sample code: Message box

Changes:

  • SGL_Init is now a void function (errors are processed internally).
  • The default font for symbols is now WingDings for better compatibility with previous versions of the operating system. (cf. Font settings ).
  • Function renaming: SGL_ColorInterpolate, SGL_GraphBGcolorSet[Get].
  • Table control: the default cell background color is now the table background color.
  • Panel control: SGL_PanelNoExitSet[Get] removed and replaced by a see simpler method for Popup panels .

Bug fixes:

  • Graph control: the WM_MOUSEWHEEL default processing prevents event mess.
  • Edit popup - callback function: the first parameter virtKey (changed to integer) can now be VK_RETURN as stated.

Documentation:

  • More details on the size of button controls and the padding of separators.
  • Resize callback : example has been corrected.
  • Minor corrections.

Version 1.3.1

This version restores the WindowsXP compatibility which was loosed in the 1.3 version.

Version 1.3.2

The default font is now the system message font (cf. Font settings ).

Documentation: minor update:

  • SGL_Layout (cf. Other functions ),
  • SGL_ColorsConfigure (cf. Setting colors ).

Version 1.3.3

Bug fix in SGL_ProfileIntGet (cf. Configuration file ):handling of ill formatted fields and default values.

Version 1.3.4

Bug fix in the callback of the Edit popup . The virtKey parameter could have a wrong value (VK_ESCAPE versus VK_RETURN) when closing the popup.

Version 1.3.5

Bug fix in SGL_Error . The eResult parameter is now correctly handled when less than -6.

Improvements in this help file:

  • New subject: Terms of use
  • More details ( SGL objects , SGL_Error )
  • Table sample : missing picture added.


Installation

INTRODUCTION ››

The downnloadable kit contains the files required to buiild applications:

  • sgl.h and sgl_*.h.
  • sgl32.lib and sgl64.lib.
  • sgh.chm.

The EXAMPLE PROGRAMS with projects and exe files are also included.

SGL has been developped with Pelles C for Windows (Copyright © Pelle Orinius).

The compiler options are:

  • for sgl32: -std:C99 -Tx86-coff -MT -Ob1 -fp:precise -W2 -Gd -Ze
  • for sgl64: -std:C99 -Tx64-coff -MT -Ob1 -fp:precise -W2 -Gr -Ze


Terms of use

INTRODUCTION ››

This software is provided 'as-is', without any express or implied warranty. In no event will the author be held liable for any damages arising from the use of this software.

SGL is free software. You can use this software free of charge for as long as you wish, for any purpose including modifications and commercial applications.

This apply to all files: sources, project, binary and help files.

You can redistribute it freely, provided that you do not misrepresent the origin of this software and that you do not claim that you wrote the original software.

Feddback

Please send any bug report to the author: hserindat@gmail.com

Any feedback is welcome.

Credits

SGL is developped with PellesC version 9.00 ( http://www.smorgasbordet.com/pellesc/ ).


BASIC CONCEPTS

This section deals with common concepts, definitions, and how to use the library.

Typing conventions:

  • variable.
  • SGL keyword.
  • Win32® keyword.


SGL objects

BASIC CONCEPTS ››

SGL objects are Win32® windows; they are identified by a HWND handle. As a result, Win32® functions can be used with any SGL object with some restrictions:

  • Do not alter the GWLP_USERDATA with the SetWindowLongPtr().
  • Use SGL functions only to modify COMMON ATTRIBUTES .

SGL objects are panels and controls.

Only panel objects can contain other objects. The container is called the parent, the contained is called the child. The position of a child is defined by its coordinates in the parent's grid (cf. Layout and padding ).

A control must have a parent. A panel without parent is a top window. A top window can be set to be a popup window.

Popups controls have a special behavior and are described separately.

Example

This example displays a grid of buttons with the system colors.

#include "sgl.h"

#include <stdio.h>

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,

PSTR szCmdLine, int iCmdShow)

{

SGL_Init(hInstance, NULL) ;

HWND mainPanel = SGL_New(0, SGL_PANEL, 0, "SYSCOLORS", 90, 30) ;

const int cnt = 32 ; // number of syscolors

char s[cnt][24] ;

for (int i = 0 ; i < cnt ; i++)

{

sprintf(s[i], "%d", i) ;

HWND b = SGL_New(mainPanel, SGL_CTRL_BUTTON, 0, s[i],

i % 4, i / 4) ; // 4 items by row

COLORREF color = GetSysColor(i) ;

SGL_BGcolorSet(b, color) ;

if (GetBValue(color) < 0x80) // adjust text color

SGL_FGcolorSet(b, 0xffffff) ;

}

SGL_Layout(mainPanel) ;

SGL_VisibleSet(mainPanel, 1) ;

SGL_Run() ;

SGL_Exit() ;

return 0 ;

}


Layout and padding

BASIC CONCEPTS ››

The layout of objects uses 3 concepts.

Grid

In a panel, an SGL object is always located in a cell on a 60 x 60 grid (coordinates: 0 .. 60 - 1).

Row(column) numbering does not need to be continuous: unused rows(columns) are ignored.

Padding

Some additional space is added:

  • Padding: margin around any object (excepted top windows).
  • Internal padding: margin between a panel and its grid.

A Default padding is applied to all objects unless stated in the object description.

Alignment

The height(width) of a grid row(column) is the one of its bigger object. As a result, an object can be smalled than the cell it is located in, and it can be:

  • Centered.
  • Aligned along some side.
  • Spanned to occupy all the available width(height).


Metrics

BASIC CONCEPTS ››

Dimensions can be defined as default values (if null), as pixel counts (positive values), or as relative values (if negative).

Unless specified for some objects, relative values are defined in twips; a twip is 1/100th of the normal font height - not exactly the usual definition (cf. Metrics and default padding ).

The normal font is the system font, unless modified (cf. Font setting ).

The origin (0,0) of the coordinate system is (top, left).


Colors

BASIC CONCEPTS ››

Colors are defined according to the Win32® API, ie:

COLORREF yellow = RGB(255,255,0);

System colors depends on the desktop settings; they are defined by the argument of the GetSysColor() plus SGL_SYSCOLOR (0x80000000).

Example:

COLORREF ActiveCaptionColor = SGL_SYSCOLOR + COLOR_ACTIVECAPTION;

Predefined colors are:

SGL definition | GetSysColor() equivalent | Usage
SGL_BLACK |  | default foreground color
SGL_WHITE |  |
SGL_LTGRAY | COLOR_BTNFACE | default background color
SGL_GRAY | COLOR_BTNSHADOW |


Events

BASIC CONCEPTS ››

The application responds to user interface events such as mouse clicks or keyboard inputs through callback functions. Events correspond to Windows® messages.

Win32® window procedure are defined per class, and are not uniform between Win32® dialog boxes and controls; SGL callbacks are object based and have an uniform behavior, whatever for SGL panels or controls. SGL callback functions are similar to Win32® window procedures.

Several SGL objects can share a common callback function. An application data structure can also be linked to an object and retrieved by the callback function.

cf. Callback function and data

Specific messages (WM_USER,...) may be used by SGL controls: check the appropriate sections.

Processing events inside SGL follows this sequence:

  1. Mouse wheel events are propagated to the window under the cursor (one can scroll background windows!).
  2. Send back notifications to children. This concerns WM_COMMAND (excepted menu), WM_CTLCOLORSTATIC and WM_CTLCOLOREDIT.
  3. In case of window move, save the new position.
  4. Change the focus to the clicked object.
  5. When a window is closed, free the object hierarchy and, for top windows calls PostQuitMessage() (see also Popup panels ).
  6. Process user callback. If the function result is not null, event processing stops here.
    If the callback function does not exists or if returned 0, keyboard events are recursively dispatched to the parent objects.
  7. Process SGL object specific callback.
  8. If needed, do the default processing.


How to create an application

BASIC CONCEPTS ››

We recommend Pelles C © to create applications. Here is the procedure:

  • Open the menu File → New → Project and select Win32 program (EXE) or Win64 program (EXE).
  • Set the project options:
    • Compiler C99 or C11 with Microsoft extensions (compiler tab).
    • Machine X86 for Win32, X64 for Win64 program (compiler, assembler and linker tabs).
    • Debug options (compiler, assembler and linker tabs).
    • Linked libraries (linker tab): kernel32.lib, user32.lib and sgl32.lib or sgl64.lib.
      (Other libraries are automatically included by #pragma comment(lib, "xxx.lib" directives.)
  • Create a source code and insert it to you project.
  • Either copy the SGL files (cf. Installation ) to your project directory or tell Pelles C where to find them (menu Project → Options, or menu Tools → Options).

Your project should compile, build and run.

You can start with a simple Hello program (cf. Startup and exit ) or with the EXAMPLE PROGRAMS whose source and project files are included in the downloadable kit.

Tip

The warning level should be set to 2 (highest). To ignore the less significant warnings, these lines can be inserted in your code:

#pragma warn(disable: 2118 2216) /* disable some warnings */

/* 2118: Parameter {parameter_name} is not referenced. */

/* 2216: The return value from {function_name} is never used. */

See also

Debug


Error codes

BASIC CONCEPTS ››

SGL functions which return an object handle will return NULL if the object could not be created.

For other functions, the return value is:

 | ≥ 0 | Success.
SGL_ERR_INT | - 1 | Internal error.
SGL_ERR_ALLOC | - 2 | Allocation error.
SGL_ERR_TYPE | - 3 | Wrong type (the required operation is not compatible with the object's type).
SGL_ERR_PARM | - 4 | Wrong 1st parameter.
SGL_ERR_PARM - i | - 3 - i | Wrong ith parameter.


OBJECT HANDLING

Functions described here are:

  • Startup and exit.
  • Object creation.
  • Object destruction.
  • Object display.


Startup and exit

OBJECT HANDLING ››

Syntax

void SGL_Init(HINSTANCE hInstance, char *iconRsc);

void SGL_Run(void);

void SGL_Exit(void);

Parameters

hInstance | Handle to application instance.
iconRsc | Handle of an icon resource. Example: "#8001"

Description

Before using SGL objects, some initialization must be performed, that is why SGL_Init must be called first (see also Debugging functions for startup messages). This function selects the default font face and size according to the desktop settings (cf. Font settings ); it can be called later for the same purpose.

The SGL_Run function runs the SGL user interface until the top window is closed (see also Popup panels ).

At exit, allocated resource should be released as well with SGL_Exit.

Example

The code below is a minimum application with something visible.

#include "sgl.h"

int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPInst, PSTR cmdLine, int cmdShow)

{

SGL_Init(hInst, NULL) ;

HWND panel = SGL_New(0, SGL_PANEL, 0, "SGL", -1, -1) ;

HWND btn = SGL_New(panel, SGL_CTRL_BUTTON, 0, "Hello!", 0, 0) ;

SGL_Layout(panel) ;

SGL_VisibleSet(panel, 1) ;

SGL_Run() ;

SGL_Exit() ;

return 0 ;

}


Object creation

OBJECT HANDLING ››

First time creation of SGL objects is done by the SGL_New funtion.

Next similar objects can be created with SGL_Duplicate .


SGL_New

OBJECT HANDLING ›› Object creation ››

Syntax

HWND SGL_New(HWND parent, int type, DWORD style, char *title, int left, int top);

Parameters

parent | Handle of an SGL panel in which the object is to be created. This parameter is null only for top windows (see PANEL OBJECTS ).
type | Object's type.
style | Style option, depends on the object's type.
title | Object's title, statically allocated. (cf. Title ).
left, top | Grid coordinates of the new object in its parent (cf. Size and position ). Values: 0 .. 60 - 1; unused rows or columns are ignored. For top windows (parent = NULL): screen coordinates (centered window for negative values).

Description

The SGL_New function creates a new object in the parent panel.

If parent is null, the created object is a top window (see PANEL OBJECTS ). Its position (left, top) is defined as screen pixel coordinates; negative values center the top window on the screen.

If parent is not null, the object's position (left, top) is indicated as coordinates in the parent's grid.

The type corresponds to the available objects (cf. PANEL OBJECTS , CONTROL OBJECTS ).

Depending on the object's type, the title may appear or not.

The SGL_New function returns the window handle of the created object, or NULL if it failed.

Example

This call installs a main panel horizontally centered at the top of the screen:

mainPanel = SGL_New(0, SGL_PANEL, 0, "Main panel", -1, 0);


SGL_Duplicate

OBJECT HANDLING ›› Object creation ››

Syntax

HWND SGL_Duplicate(HWND parentDest, HWND childSource, char *title, int left, int top);

Parameters

parentDest | Handle of an existing SGL panel in which the object is to be created.
childSource | Handle of the SGL object to duplicate.
title | Object's title, statically allocated. (cf. Title ).
left, top | Grid coordinates (idem SGL_New ). Values: 0 .. 60 - 1; unused rows or columns are ignored.

Description

The SGL_Duplicate function creates a new object in the parentDest panel.

The new object inherits the attributes of childSource that exist at the time of duplication.

This function can also be used for panel objects (children objects are not duplicated).

The SGL_Duplicate function returns the window handle of the created object, or NULL if it failed.


Other functions

OBJECT HANDLING ››

Syntax

int SGL_Layout(HWND hwnd);

int SGL_Redraw(HWND hwnd);

void SGL_Destroy(HWND hwnd);

int SGL_LayoutConfigure(HWND hwnd, char *section, int op);

Parameters

hwnd | Panel object.
section | Section in which the position and size are saved..
op | A combination of SGL_SAVE_POSITION and SGL_SAVE_SIZE.

Description

The SGL_Layout function is mandatory after the creation of objects or when objects have been resized, moved or dimmed. The object hierarchy inherits attributes from its parents ; it is not redrawn.

The SGL_Redraw redraws an object hierarchy.

The SGL_Destroy function destroys an object and its children, even if created in another thread.

The SGL_LayoutConfigure function defines if the size and the position of an object are saved in a configuration file. This function must be called before SGL_Layout; the previous saved configuration is then applied. (cf. Configuration file ).


COMMON ATTRIBUTES

Set functions define the attribute of an SGL object; they look like:

int e = SGL_AttributeSet(HWND hwnd, .., attribute_value);

The get functions have two variants:

  • If the attribute value is always ≥ 0:

int attribute_value = SGL_AttributeGet(HWND hwnd, ..);

  • If the attribute value can be < 0:

int e = SGL_AttributeGet(HWND hwnd, .., int* attribute_value);

In all cases, the return value is negative in case of error (cf. Error codes ). The SGL_ERR_TYPE error means that the attribute is not available for the object.

This applies also to object specific attributes.


Callback function and data

COMMON ATTRIBUTES ››

Syntax

int SGL_CallbackFunctionSet(HWND hwnd, SGL_CB func);
int SGL_CallbackFunctionGet(HWND hwnd, SGL_CB *func);

int SGL_CallbackDataSet(HWND hwnd, void *dataPtr);
int SGL_CallbackDataGet(HWND hwnd, void ** dataPtr);

Parameters

hwnd | SGL object.
func | Callback function
dataPtr | Pointer to an object specific data structure.

Description

To respond to mouse clicks or keyboard inputs, each object must use a callback function.

When executing, it may need access to object's data. Rather than declaring them as global, it is a good practice to pack them in a private structure, and to link this structure to the object as callback data.

Several SGL objects can share a common callback function.

These functions return 0, or value a negative value in case of error (cf. Error codes ).

Example

Here is an example with 6 buttons with an editable label.

#include "sgl.h"

#include <stdio.h>

#define BTN_NB 6

#define TEXT_LEN 10

int buttonCB(HWND hwnd, UINT event, WPARAM wParm, LPARAM lParm)

{

if (event == WM_LBUTTONUP)

{

RECT rect ; // rectangle for the edit box

GetClientRect(hwnd, &rect) ;

MapWindowPoints(hwnd, NULL, (POINT*) &rect, 2) ;

char* text ; // edited text

SGL_CallbackDataGet(hwnd, (void*) &text) ;

SGL_PopupEdit(hwnd, &rect, ES_CENTER, text, TEXT_LEN, NULL, NULL) ;

return 1 ;

}

return 0 ;

}

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,

PSTR szCmdLine, int iCmdShow)

{

static char btnText[BTN_NB][TEXT_LEN] ; // buttons' text

SGL_Init(hInstance, NULL) ;

HWND topPanel = SGL_New(0, SGL_PANEL, 0, "BUTTONS", 90, 30) ;

for (int i = 0 ; i < BTN_NB ; i++) // create each button

{

sprintf(btnText[i], "Button #%d", i + 1) ;

HWND btn = SGL_New(topPanel, SGL_CTRL_BUTTON, 0, btnText[i], 0, i) ;

SGL_CallbackFunctionSet(btn, buttonCB) ;

SGL_CallbackDataSet(btn, (void*) &btnText[i]) ;

}

SGL_Layout(topPanel) ;

SGL_VisibleSet(topPanel, 1) ;

SGL_Run() ;

SGL_Exit() ;

return 0 ;

}


Callback function

COMMON ATTRIBUTES ›› Callback function and data ››

Syntax

int CBfunction(HWND hwnd, UINT event, WPARAM wParam, LPARAM lParam);

Parameters

The object callback function has the same parameters as a Win32® window procedure.

hwnd | SGL object.
event | Identifier of the Win32® message that has been received.
wParam | First message parameter.
lParam | Second message parameter.

Description

This function is called when the SGL object receive a Win32® message.

It must return a non null value when the event processing is terminated.

If the function result is null, processing continues with the default event processing including SGL and Win32® processing.


Visibility

COMMON ATTRIBUTES ››

Syntax

int SGL_VisibleSet(HWND hwnd, int visible);
int SGL_VisibleGet(HWND hwnd);

int SGL_DimmedSet(HWND hwnd, int dimmed);
int SGL_DimmedGet(HWND hwnd);

Parameters

hwnd | SGL object.
visible | Visible status: 0 or 1
dimmed | Dimmed status: 0 or 1

Description

Freshly created objects are visible, excepted top windows.

Dimming propagates to children when SGL_Layout is called. Any object which is dimmed or whose any ancestor is dimmed will appear dimmed. A dimmed object has dimmed colors and does not respond to mouse or keyboard entry; it can still be redrawn (cf. SGL_Redraw ).

The normal return value is 0 for the set functions, and the visible or dimmed status for the set functions (0 or 1).

The return value is negative in case of error (cf. Error codes ).


Title

COMMON ATTRIBUTES ››

Syntax

int SGL_TitleSet(HWND hwnd, char* title);
int SGL_TitleGet(HWND hwnd, char** title);

Parameters

hwnd | SGL object.
title | Object's title, statically allocated.

Description

Depending on the object's type, the title may appear or not.

These functions return 0, or a negative value in case of error (cf. Error codes ).

See also

SGL_New


Fonts

COMMON ATTRIBUTES ››

SGL provides 4 font sizes and 6 font styles.

Unless special effects are needed, these predefined should be enough.

When icons are needed, it is recommended to use an ad'hoc font. Size and color are much more easily set than with any image or graphic format.

Predefined Font settings can be changed.


Font size

COMMON ATTRIBUTES ›› Fonts ››

Syntax

int SGL_FontSizeIxSet(HWND hwnd, int sizeIx);
int SGL_FontSizeIxGet(HWND hwnd);

int SGL_FontSizeGet(HWND hwnd);
int SGL_FontHeightGet(HWND hwnd);

Parameters

hwnd | SGL object.
sizeIx | Index of a predefined size: SGL_FONT_SMALL SGL_FONT_NORMAL (default) SGL_FONT_LARGE SGL_FONT_BIG

Description

The SGL_FontSizeIxSet function sets the size index of an SGL object. It returns 0, or a negative value in case of error (cf. Error codes ).

The SGL_FontSizeIxGet function returns the font size index of an SGL object.

The SGL_FontSizeGet function returns the pixel font size of an SGL object.

The SGL_FontHeightGet function returns the pixel font height of an SGL object (line height without any spacing, may depend on the font style).

These functions return a negative value in case of error (cf. Error codes ).

See also

The section Font setting indicates the default values and how to change these settings.


Font style

COMMON ATTRIBUTES ›› Fonts ››

Syntax

int SGL_FontStyleSet(HWND hwnd, int style);
int SGL_FontStyleGet(HWND hwnd);

Parameters

hwnd | SGL object.
style | Index of a a predefined style: SGL_FONT_NORMAL (default) SGL_FONT_FIXED SGL_FONT_BOLD SGL_FONT_ITALIC SGL_FONT_SYMBOL SGL_FONT_EXTRA (not predefined)

Description

The SGL_FontStyleSet function sets the font style of an object; it returns 0 or a negative value in case of error (cf. Error codes ).

The SGL_FontStyleGet function returns the font style of an object, or a negative value in case of error (cf. Error codes ).

See also

The section Font setting indicates the default values and how to change these settings.


Font loading

COMMON ATTRIBUTES ›› Fonts ››

Syntax

int SGL_FontLoad(char* fName);

Parameters

fName

File name or resource locator.

Resource locator: ":resource_type:resource_name" (see example below).

Description

The SGL_FontLoad function allows an application to use a particular font without installing it.

The return value is the number of fonts installed (0 in case of error).

When the application goes away, the system will unload the font.

Example

If the resource file contains:

8006 MY_FONT "sanremo.ttf"

Loading this font is performed by calling:

SGL_FontLoad(imageHwnd, ":MY_FONT:#8006");

(Do not use predefined resource types!)


Font handle

COMMON ATTRIBUTES ›› Fonts ››

Syntax

HFONT SGL_FontHandleGet(HWND hwnd, int sizeIx, int style);

Parameters

hwnd | SGL object (ignored if sizeIx and style are <0)
sizeIx | Index of a predefined size (cf. Font size ). If <0, the size index is the one of the hwnd object.
style | Font style (cf. Font style ). If <0, the style is the one of the hwnd object.

Description

The SGL_FontHandleGet function retrieves the font for a given size, style or object; it returns NULL in case of error.

Examples

The following example shows how to use temporary a small font:

HFONT hFont = SGL_FontHandleGet(hwnd, SGL_FONT_SMALL, -1);

hFont = SelectObject(hdc, hFont);

DrawText(hdc, text, -1, rect, style);

SelectObject(hdc, hFont); // restore the previous font

The following function returns the size of a text when written in an object:

static void textSizeGet(HWND hwnd, char* text, int *w, int *h)

{

SGL_Layout(hwnd); /* required to retrieve the font handle */

HFONT hfont = SGL_FontHandleGet(hwnd, -1, -1);

HDC hdc = GetDC(hwnd) ;

SelectObject(hdc, hfont);

RECT rect = { 0 } ;

DrawText(hdc, text, -1, &rect, DT_CALCRECT) ;

*w = rect.right + SGL_FontSizeGet(hwnd) ; /* add some extra width */

*h = rect.bottom ;

ReleaseDC(0, hdc) ;

}


Colors

COMMON ATTRIBUTES ››

Syntax

int SGL_FGcolorSet(HWND hwnd, COLORREF color);
int SGL_FGcolorGet(HWND hwnd);

int SGL_BGcolorSet(HWND hwnd, COLORREF color);
int SGL_BGcolorGet(HWND hwnd);

Parameters

hwnd | SGL object.
color | Color.

Description

The SGL_FGcolorSet function sets the foregroung color of an object. This color is mainly used for text drawing. The SGL_BGcolorSet functon sets the backgroung color.

The given color includes system colors (cf. Colors ) and the special value -1 is used to indicate that the object will inherit the color of its parent.

These functions return 0 in case of success, or a negative value in case of error (cf. Error codes ).

The SGL_FGcolorGet and SGL_BGcolorGet functions retrieve the actual colors, or a negative value in case of error (cf. Error codes ).

Example

The following example sets the background color of a panel:

SGL_BGcolorSet(panel, SGL_SYSCOLOR | COLOR_MENUHILIGHT);


Borders

COMMON ATTRIBUTES ››

Borders are attributes of PANELS and BUTTONS ; they are defined by a style, a thickness and a color.

SGL_BORDER_ | NONE | FLAT RFLAT | BEVEL_DOWN BEVEL_UP | ETCHED_DOWN ETCHED_UP
aspect | n.a. |  |  |
thickness | n.a. | ≥ 1 | ≥ 1 | ≥ 2
color | n.a. | default: not visible above example: 0xee6666 | default (-1): object background color

The color setting applies to the mid tones.

Example with color = xee6666:

See also

Border drawing


Border style

COMMON ATTRIBUTES ›› Borders ››

Syntax

int SGL_BorderStyleSet(HWND hwnd, int style);
int SGL_BorderStyleGet(HWND hwnd)

Parameters

hwnd | SGL object.
style | Border's style, one of: SGL_BORDER_NONE, SGL_BORDER_FLAT, SGL_BORDER_RFLAT, SGL_BORDER_BEVEL_UP, SGL_BORDER_BEVEL_DOWN, SGL_BORDER_ETCHED_UP, SGL_BORDER_ETCHED_DOWN.

Description

The style of a border can be set or retrieved with these functions.

The SGL_BorderStyleSet function returns a negative value in case of error (cf. Error codes ).

The SGL_BorderStyleGet function returns the style of the border, or a negative value in case of error (cf. Error codes ).


Border width and color

COMMON ATTRIBUTES ›› Borders ››

Syntax

int SGL_BorderThicknessSet(HWND hwnd, int e);
int SGL_BorderThicknessGet(HWND hwnd, int *e);

int SGL_BorderColorSet(HWND hwnd, COLORREF color);
int SGL_BorderColorGet(HWND hwnd, COLORREF *color);

Parameters

hwnd | SGL object.
e | Border's thickness (see Metrics ).
color | Border's color (see Colors , Borders ). Default value: - 1; it is used to indicate that the border inherit the color of the object it belongs to: the foreground color for SGL_ROUNDEDFRAME panels, the background color in the other cases.

Description

These functions set or retrieve the thickness and the color of an object's border. They return 0 in case of success, or a negative value in case of error (cf. Error codes ).


Size and position

COMMON ATTRIBUTES ››

Syntax

int SGL_SizeSet(HWND hwnd, int sizeID, int size);
int SGL_SizeGet(HWND hwnd, int sizeID, int *size);

int SGL_PositionSet(HWND hwnd, int left, int top);
int SGL_PositionGet(HWND hwnd, int *left, int *top);

Parameters

hwnd | SGL object.
sizeID | SGL_WIDTH or SGL_HEIGHT.
size | Size value (cf. Metrics ).
left, top | Grid coordinates (0 .. 60 - 1) or screen coordinates for top windows.

Description

These functions set or retrieve the size or the position of an SGL object. They return 0 in case of success, or a negative value in case of error (cf. Error codes ).

Setting the size:

  • A null value correspond to a default size,
  • A positive value is a pixel count,
  • A negative value, unless stated for some SGL objects, is a twip count (cf. Metrics ).

Setting the position uses the same parameters as SGL_New .

The retrieved size and position values are the ones defined by the set function. To retrieve the actual values, one can use GetWindowRect() or GetClientRect().


Alignment and padding

COMMON ATTRIBUTES ››

These functions apply to child objects only.

Syntax

int SGL_AlignmentSet(HWND hwnd, int align);
int SGL_AlignmentGet(HWND hwnd);

int SGL_PaddingSet(HWND hwnd, RECT *padding);
int SGL_PaddingGet(HWND hwnd, RECT *padding);

Parameters

hwnd | SGL object.
align | SGL_CENTER (default value), SGL_LEFT, SGL_RIGHT, SGL_TOP or SGL_BOTTOM
padding | Added space around the object in the 4 directions (cf. Metrics , Default padding ). If padding is null, the padding is set to 0 in all directions.

Description

These functions concern the way SGL objects are drawn in the grid cells where they are located (cf. Layout and padding ).

The SGL_AlignmentSet (SGL_AlignmentGet) function sets (returns) the alignment of an SGL object. The alignment parameter defines the position of an object in a cell: this applies when an object is smaller than the available area. If two opposite directions are given, the object is spanned to occupy all the available space.

The padding is the space provided between an object and its grid cell (cf. Layout and padding , Default padding ).The SGL_PaddingSet (SGL_PaddingGet) function sets (retrieves) the padding of an SGL object.

These functions return a negative value in case of error (cf. Error codes ).

Examples

This call has 2 effects, top alignment and horizontal span:

SGL_AlignmentSet(obj, SGL_LEFT | SGL_RIGHT | SGL_TOP);

This sequence produces a 100 twips at the bottom of an object:

RECT pad;

SGL_PaddingGet(obj, &pad);

pad.bottom = -100;

SGL_PaddingSet(obg, &pad);


PANEL OBJECTS

A panel is a grid container: it can be the parent of other objects. Child objects are located on that grid; their position is defined by the grid coordinates.

There are 4 panel's types:

  • SGL_PANEL (top window)
  • SGL_PANEL (child panel)
  • SGL_ROUNDEDFRAME
  • SGL_HIDDENFRAME

SGL_ | PANEL | PANEL | ROUNDEDFRAME | HIDDENFRAME
parent | NULL | != NULL (parent must exist)
usage | top window | child panel | child panel with a light border and caption | child panel for grouping objects only
size | default (0): automatically adjusted to the content of the panel
position | screen coordinates; if <0 the panel is centered | grid coordinates
colors | background and foreground colors |  |  | none
border | Windows® application | border | rounded frame and title | none
aspect options | window's style (cf. CreateWindow) | border style, thickness and color | border: thickness and color title: alignment | none (the panel is not drawn)
alignment | n.a. | panel spanned to the all the available space
padding | internal padding only | internal and external padding

Once created, a top window is not built nor visible.

To build it, call SGL_Layout(panel).

To make it visible, call SGL_VisibleSet(panel, 1).

Style (cf. SGL_New)

A top window (panel without parent) accepts some window styles (cf. CreateWindow). The most useful are WS_SIZEBOX and WS_MINIMIZEBOX.

A SGL_ROUNDEDFRANE panel accept the title alignment: DT_LEFT (default), DT_CENTER or DT_RIGHT.

No other style is supported.

Common attributes

Trying to set or get attributes other than those allowed in the above table may produce an error (WRONG TYPE).

Font attributes have no direct effect but are used as default by the children of the panel.

A SGL_HIDDENFRAME panel has no default padding.

Example

In this example, the top window is horizontally centered on the screen.

#include "sgl.h"

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPInst, PSTR cmdLine, int cmdShow)

{

SGL_Init(hInst, NULL) ;

HWND topPanel = SGL_New(0, SGL_PANEL, 0, "Main Panel", -1, 50) ;

HWND panel = SGL_New(topPanel, SGL_PANEL, 0, "SGL_PANEL", 0, 1) ;

HWND textBox = SGL_New(panel, SGL_CTRL_EDIT, ES_MULTILINE | ES_READONLY

| ES_AUTOVSCROLL | ES_CENTER, "Edit box", 0, 0) ;

SGL_SizeSet(textBox, SGL_WIDTH, -20) ;

SGL_SizeSet(textBox, SGL_HEIGHT, -3) ;

SGL_AlignmentSet(textBox, SGL_LEFT | SGL_RIGHT) ;

SGL_EditTextSet(textBox, "Default SGL_PANEL panel containing") ;

SGL_EditTextAppend(textBox, "\r\n4 SGL_ROUNDEDFRAME panel variants.") ;

HWND frame ; /* frame variants */

frame = SGL_New(panel, SGL_ROUNDEDFRAME, DT_LEFT,

"Style: DT_LEFT (default)", 0, 1) ;

frame = SGL_New(panel, SGL_ROUNDEDFRAME, DT_CENTER,

"Style: DT_CENTER", 0, 2) ;

frame = SGL_New(panel, SGL_ROUNDEDFRAME, DT_RIGHT,

"Style: DT_RIGHT", 0, 3) ;

frame = SGL_New(panel, SGL_ROUNDEDFRAME, 0,

"With a specific border", 0, 4) ;

SGL_BorderThicknessSet(frame, -50) ;

SGL_BorderColorSet(frame, 0xccfcff) ;

SGL_Layout(topPanel) ;

SGL_VisibleSet(topPanel, 1) ;

SGL_Run() ;

SGL_Exit() ;

return 0 ;

}


Internal padding

PANEL OBJECTS ››

Syntax

int SGL_PanelIpaddingSet(HWND hwnd, RECT *ipad);
int SGL_PanelIpaddingGet(HWND hwnd, RECT *ipad);

Parameters

hwnd | Panel object.
ipad | Rectangle whose member values are the margins in the four directions. Positive value: pixels; negative value: twips. Default margins: Default padding or 0 for SGL_HIDDENFRAME panels.

Description

Use these functions to set or get the space between the panel's border and its grid.

If these functions succeed, the return value is 0. If they fails, the return value is negative (cf. Error codes ).


Popup panels

PANEL OBJECTS ››

Description

When a top window is closed, the SGL_Run function returns. This default behavior should not apply to popup panels.

One suggests to create the secondary top panels at start, and to show or hide them according to the user actions.

Example

This example demonstrates 2 top windows:

  • a main window;
  • a tool window.

Closing the tool window does not close the application.

#include "sgl.h"

HWND tool ;

static int show(HWND hwnd, UINT event, WPARAM wParam, LPARAM lParam)

{

if (event == WM_USER)

SGL_VisibleSet(tool, 1) ;

return 0 ;

}

static int hide(HWND hwnd, UINT event, WPARAM wParam, LPARAM lParam)

{

if (event == WM_SYSCOMMAND && wParam == SC_CLOSE)

{

SGL_VisibleSet(tool, 0) ;

return 1 ;

}

return 0 ;

}

int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPInst, PSTR cmdLine, int cmdShow)

{

SGL_Init(hInst, NULL) ;

HWND panel1 = SGL_New(0, SGL_PANEL, 0, "Main", 200, 100) ; // main window

HWND btn1 = SGL_New(panel1, SGL_CTRL_PUSHBUTTON, DT_CENTER, "Show slave", 0, 0) ;

SGL_CallbackFunctionSet(btn1, show) ;

SGL_Layout(panel1) ;

SGL_VisibleSet(panel1, 1) ;

tool = SGL_New(0, SGL_PANEL, 0, "Slave", 200, 200) ; // tool window

SGL_New(tool, SGL_CTRL_BUTTON, DT_CENTER, " ", 0, 0) ;

SGL_CallbackFunctionSet(tool, hide) ;

SGL_Layout(tool) ;

SGL_Run() ;

SGL_Exit() ;

return 0 ;

}


CONTROL OBJECTS

SGL provides the following control types:

  • BUTTON
  • SEPARATOR
  • EDIT BOX
  • TABLE
  • GRAPH
  • IMAGE


BUTTON

CONTROL OBJECTS ››

There are 4 button types:

  • SGL_CTRL_BUTTON
  • SGL_CTRL_PUSHBUTTON
  • SGL_CTRL_CHECKBUTTON
  • SGL_CTRL_RADIOBUTTON

SGL_CTRL_ | BUTTON | PUSHBUTTON | CHECKBUTTON | RADIOBUTTON
Use | Indicator or button | Button | Binary choice | Select one option
Aspect |  |  |  |
Aspect when pushed or set | No change | If bevel or etched: up ↔ down | Selected ↔ Not selected
Aspect options | Border: style, thickness and color cf. Borders |  | Style: text alignment (DT_LEFT [default] or DT_RIGHT)
WM_USER event | . | When the left button of the mouse is released | When the left button of the mouse is pressed.

Style (cf. SGL_New)

For standard and push-buttons, the style defines the text alignment in the button: SGL_LEFT, SGL_CENTER (default) or SGL_RIGHT.

For check or radio buttons, the style defines the relative position of the text and the button:

DT_LEFT (default): the button is at left and the text is left aligned.

DT_RIGHT: the button is at right and the text is right aligned.

No other style is allowed.

Common attributes

All common attributes are allowed.

The size of a button can be set as a pixel count if positive or a character height count if negative. The default width (0) corresponds to 7 character heights. The default height (0) corresponds to the character height and some padding.

Events

The event WM_USER (generated by SGL) notifies that the button has been operated (cf. above table). The wParam and lParam parameters are not used and set to zero (cf. Callback function ).

Example

This sample code displays check and radio buttons.

#include "sgl.h"

int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPInst, PSTR cmdLine, int cmdShow)

{

HWND panel, frame, btn ;

SGL_Init(hInst, NULL) ;

panel = SGL_New(0, SGL_PANEL, 0, "Style for Check & Radio Buttons", 90, 40) ;

for (int i = 0 ; i < 2 ; i++)

{

int style = i ? DT_RIGHT : DT_LEFT ;

char *caption = i ? "DT_RIGHT" : "DT_LEFT" ;

frame = SGL_New(panel, SGL_ROUNDEDFRAME, DT_CENTER, caption, 2*i, 0) ;

btn = SGL_New(frame, SGL_CTRL_RADIOBUTTON, style, "Channel 24", i, 0) ;

btn = SGL_New(frame, SGL_CTRL_RADIOBUTTON, style, "Channel 25", i, 1) ;

btn = SGL_New(frame, SGL_CTRL_CHECKBUTTON, style, "Video", i, 2) ;

btn = SGL_New(frame, SGL_CTRL_CHECKBUTTON, style, "Audio", i, 3) ;

}

SGL_Layout(panel) ;

SGL_VisibleSet(panel, 1) ;

SGL_Run() ;

SGL_Exit() ;

return 0 ;

}


Button value

CONTROL OBJECTS ›› BUTTON ››

Syntax

int SGL_ButtonValueSet(HWND hwnd, int value);
int SGL_ButtonValueGet(HWND hwnd);

Parameters

hwnd | Graph object.
value | Object value.

Description

A button has a value which can be 0 (button reset) or 1 (button set).

For check or a radio button, this value is automatically set (to 1) or reset (to 0) when the used clicks on it.

The SGL_ButtonValueSet function returns a negative value in case of error (cf. Error codes ). When setting a button's value, its aspect is updated.

The SGL_ButtonValueGet function returns the value of the button, or a negative value in case of error (cf. Error codes ).


SEPARATOR

CONTROL OBJECTS ››

SGL provides 2 separator objects, that is a thick border which can be moved to change the layout of a window.

SGL_CTRL_HSEP horizontal separator.

SGL_CTRL_VSEP vertical separator.

Style (cf. SGL_New)

None.

Common attributes

A horizontal(vertical) separator is spanned horizontally(vertically) to its parent panel (internal padding is ignored). As a result:

  • Its horizontal(vertical) position is ignored.
  • Its width(height) cannot be set nor retrieved.
  • Its height(width) can be set (default is 40 twips) or retrieved.

A separator does not support any border.

The font attributes have no effect.

The default padding is set to 0 and can be modified. The left/right(top/bottom) padding values of a horizontal(vertical) separator is ignored.

The separator is a rectangle with a color varying from the foreground color (top or left) to, but not including, the background color (bottom or right). Default values are respectively white and black. Setting both to the background color of the parent window will hide the separator. Its effect is still visible when the cursor passes over the separator: a sizing cursor appears.

Events

The event WM_USER (generated by SGL) notifies that the separator has been moved. The move distance is the value of the wParam and lParam parameters (cf. Callback function ).

Example

This sample code illustrates a horizontal separator.

#include "sgl.h"

HWND mainPanel ;

int sepCB(HWND hwnd, int event, WPARAM wParam, LPARAM lParam)

{

if (event == WM_USER) // the separator has moved {wParam} pixels

{

// change the size of some objects

SGL_Layout(mainPanel);

}

return 0 ;

}

int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrInst, PSTR cmdLine, int cmdShow)

{

SGL_Init(hInst, NULL);

mainPanel = SGL_New(0, SGL_PANEL, 0, "Main panel", 30, 30);

RECT pad ; // get main panel padding

SGL_PanelIpaddingGet(mainPanel, &pad) ;

HWND topPanel = SGL_New(mainPanel, SGL_HIDDENFRAME, 0, "mainPanel", 0, 0);

... // install objects in the top panel

HWND sep = SGL_New(mainPanel, SGL_CTRL_HSEP, 0, "sep1", 0, 1);

SGL_PaddingSet(sep, &pad) ; // apply padding to the separator

SGL_CallbackFunctionSet(sep, sepCB);

HWND bottomPanel = SGL_Duplicate(mainPanel, topPanel, "mainPanel", 0, 2);

... // install objects in the bottom panel

SGL_Layout(mainPanel);

SGL_VisibleSet(mainPanel, 1);

SGL_Run();

SGL_Exit();

return 0;

}


EDIT BOX

CONTROL OBJECTS ››

The edit object is a standard Win32® edit control. It's type is SGL_CTRL_EDIT.

Style (cf. SGL_New)

The default style is an edit box without border.

WS_CAPTION, WS_SIZEBOX and WS_BORDER can be used for borders and title bar.

Main control styles

WS_HSCROLL Creates an edit box that has a horizontal scroll bar.

WS_VSCROLL Creates an edit box that has a vertical scroll bar.

ES_MULTILINE Designates a multiple-line edit control. (The default is single line.) Multiple-line edit controls can have scroll bars.

ES_NOHIDESEL Normally, an edit control hides the selection when the control loses the input focus and inverts the selection when the control receives the input focus. Specifying ES_NOHIDESEL deletes this default action.

Display and alignment styles

ES_PASSWORD Displays all characters as an asterisk (*) as they are typed into the edit control.

ES_AUTOHSCROLL Automatically scrolls text to the right by 10 characters when the user types a character at the end of the line. When the user presses [Enter], the control scrolls all text back to position 0.

ES_AUTOVSCROLL Automatically scrolls text up one page when the user presses [Enter] on the last line.

ES_LEFT, ES_CENTER, ES_RIGHT: Aligns text in a single-line or multiline edit control.

Text styles

ES_READONLY Prevents the user from entering or editing text in the edit control.

ES_NUMBER Allows only digits to be entered into the edit control.

ES_LOWERCASE Converts all characters to lowercase as they are typed into the edit control.

ES_UPPERCASE Converts all characters to uppercase as they are typed into the edit control.

ES_OEMCONVERT Text entered in the edit control is converted from the ANSI character set to the OEM character set and then back to ANSI. This style is most useful for edit controls that contain filenames.

Common attributes

The size of an edit box is defined in pixels if positive, or in character heights for negative values. Default size:

  • Width: 25 character heights.
  • Height: 8 character heights.

The edit box does not support any border. If required, include it in a panel with the requested border, or try a Win32® style.


Text setting

CONTROL OBJECTS ›› EDIT BOX ››

Syntax

int SGL_EditTextSet(HWND hwnd, char *text);

int SGL_EditTextAppend(HWND hwnd, char *text);

Parameters

hwnd | Graph object.
text | Character array.

Description

The SGL_EditTextSet function replaces the current content with the new text.

The SGL_EditTextAppend function appends the new text to the current content of the edit control.

The new text is copied in the control; any further change of its content are ignored.

These functions return 0 in case of success, or a negative value in case of error (cf. Error codes ).

Example

This example demonstrates a panel duplicate. Each panel contains an edit box; the upper one only is set to receive dropped files.

#include "sgl.h"

#pragma comment(lib, "shell32.lib")

HWND fileList ; /* Edit box with list of the dropped files */

/* Callback function for the panel that will receive the dropped files */

static int fileAdd(HWND hwnd, UINT event, WPARAM wParam, LPARAM lParam)

{

if (event == WM_DROPFILES)

{

HDROP hDrop = (HDROP) wParam ;

int numFiles = DragQueryFile(hDrop, -1, NULL, 0) ;

for (int i = 0 ; i < numFiles ; i++)

{

char buff[MAX_PATH] ;

DragQueryFile(hDrop, i, buff, sizeof(buff)) ;

SGL_EditTextAppend(fileList, "\r\n->") ;

SGL_EditTextAppend(fileList, buff) ;

}

DragFinish(hDrop) ;

}

return 0 ;

}

int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPInst, PSTR cmdLine, int cmdShow)

{

SGL_Init(hInst, NULL) ;

HWND mainPanel = SGL_New(0, SGL_PANEL, 0, "Main Panel", 300, 100) ;

HWND panel = SGL_New(mainPanel, SGL_PANEL, 0, "Panel", 0, 0) ;

DragAcceptFiles(panel, 1) ;

SGL_CallbackFunctionSet(panel, fileAdd) ;

fileList = SGL_New(panel, SGL_CTRL_EDIT, WS_VSCROLL | ES_READONLY |

ES_AUTOVSCROLL | ES_MULTILINE,

"Edit Box", 0, 0) ;

SGL_SizeSet(fileList, SGL_WIDTH, -40) ;

SGL_SizeSet(fileList, SGL_HEIGHT, -6) ;

SGL_AlignmentSet(fileList, SGL_LEFT | SGL_RIGHT) ;

SGL_EditTextSet(fileList, "Drop files here:") ;

HWND dum = SGL_Duplicate(mainPanel, panel, "Bottom Panel", 0, 1) ;

HWND dum2 = SGL_Duplicate(dum, fileList, "Dummy Edit Box", 0, 0) ;

SGL_EditTextSet(dum2, "Not here!") ;

SGL_Layout(mainPanel) ;

SGL_VisibleSet(mainPanel, 1) ;

SGL_Run() ;

SGL_Exit() ;

return 0 ;

}


Text retrieval

CONTROL OBJECTS ›› EDIT BOX ››

Syntax

int SGL_EditTextLengthGet(HWND hwnd);

int SGL_EditTextGet(HWND hwnd, char *text, int maxLen);

Parameters

hwnd | Graph object.
text | Character buffer for text.
maxLen | Maximum number of characters to copy to the buffer. If the text exceeds this limit, it is truncated.

Description

If the function SGL_EditTextLengthGet succeeds, the return value is the length, in characters, of the text (not including the terminating null character), or a negative value in case of error (cf. Error codes ).

If the function SGL_EditTextGet succeeds, the return value is the length, in characters, of the copied string (not including the terminating null character). The return value is negative in case of error (cf. Error codes ).

(These functions are close to GetWindowTextLength() and GetWindowText().)


TABLE

CONTROL OBJECTS ››

The table object (or data grid) is versatile tool for representing data organized by lines and columns. It's type is SGL_CTRL_TABLE.

The number of columns is limited by the size of the screen; the number of rows is not limited. Data is not duplicated in the control.

Row and column numbering start at 0; the row number -1 corresponds to the table header.

Column headers and data cell contents are drawn by the Table filling callback . Data storage is the responsibility of the developer.

Basic Selection services are also provided.

Style (cf. SGL_New)

The default style is a table without border.

WS_CAPTION, WS_SIZEBOX and WS_BORDER can be used for borders and title bar.

The WS_VSCROLL option which adds a vertical scroll bar.

Common attributes

The default width of a table is set to show all columns. If set, a positive value is a pixel count, a negative value is a character height count.

The default height will display a table with 8 rows. If set, a positive value represents a pixel count, a negative value is the number of displayed rows.

The background color is used outside cells, ie. in the header and in free space if any, below and at right of the table. The background color of the cells is defined by column (cf. Columns setting ).

The table does not support any border. If required, include it in a panel with the requested border, or try a Win32® style.


Columns setting

CONTROL OBJECTS ›› TABLE ››

Syntax

typedef struct {

int width; | Column width: - positive value: pixel count; - negative value: character height; - zero: end of the column array.
int headerMerge; | If set, merge with the next column. The right border is not displayed; the label will be the one of the next column. This option should not be set for the last column.
int cellNoRightSep; | If set, supress the right border of each cell. To set the thickness of the border see Data cells appearance .
COLORREF cellBGcolor; | Background color.

} SGL_TABLE_COLUMN_T;

int SGL_TableColumnsSet(HWND hwnd, SGL_TABLE_COLUMN_T* columns);
int SGL_TableColumnsGet(HWND hwnd, SGL_TABLE_COLUMN_T** columns);

Parameters

hwnd | Table object.
columns | Static array of column descriptors.

Description

The SGL_TableColumnsSet function defines the horizontal layout of the table. The SGL_TableColumnsGet function retrieves this layout.

The normal return value is zero, or a negative value in case of error (cf. Error codes ).


Headers setting

CONTROL OBJECTS ›› TABLE ››

Syntax

int SGL_TableHeaderHeightSet(HWND hwnd, int linePercent);
int SGL_TableHeaderHeightGet(HWND hwnd);

int SGL_TableHeaderBorderThicknessSet(HWND hwnd, int e);
int SGL_TableHeaderBorderThicknessGet(HWND hwnd, int *e);

Parameters

hwnd | Table object.
linePercent | Header height in lines x 100. The default value is 100 (1 line).
e | Border's thickness for the headers. Positive value: pixels; negative value: twips. Default value: -23.

Description

The SGL_TableHeaderHeightSet function defines the height of the table headers. The normal return value is zero, or a negative value in case of error (cf. Error codes ).

The SGL_TableHeaderHeightGet function returns this height, or a negative value in case of error (cf. Error codes ).

The SGL_TableHeaderBorderThicknessSet function sets the border's thickness of the headers; the SGL_TableHeaderBorderThicknessGet function retrieves it. These functions should return zero, or a negative value in case of error (cf. Error codes ).


Rows setting

CONTROL OBJECTS ›› TABLE ››

Syntax

int SGL_TableRowNbSet(HWND hwnd, int rowNB);
int SGL_TableRowNbGet(HWND hwnd);

int SGL_TableRowShow(HWND hwnd, int row);

int SGL_TableCellHeightGet(HWND hwnd);

int SGL_TableHeightAdjust(HWND hwnd, int rowMin);

Parameters

hwnd | Table object.
rowNB | Number of rows.
row | Index of the row which must be visible (0 .. rowNb - 1).
rowMin | Minimum number of displayed lines.

Description

The SGL_TableRowNbSet function sets the number of rows. The normal return value is zero, or a negative value in case of error (cf. Error codes ).

The SGL_TableRowNbGet function returns the number of rows, or a negative value in case of error (cf. Error codes ).

The SGL_TableRowShow makes a row visible by scrolling the table if necessary. The normal return value is zero, or a negative value in case of error (cf. Error codes ).

The SGL_TableCellHeightGet function returns the height of data cells (pixel count), or a negative value in case of error (cf. Error codes ).

The SGL_TableHeightAdjust function forces a table to display an integer number of lines with a minimum value. It returns the pixel height of the table corresponding to rowMin lines, or a negative value in case of error.


Table update

CONTROL OBJECTS ›› TABLE ››

Syntax

int SGL_TableUpdate(HWND hwnd, int row1, int rowNB, int col);

Parameters

hwnd | Table object.
row1 | First row to update (-1 for the header).
rowNB | Number of rows to update (ignored for the header).
col | Column to update (-1 for all columns).

Description

The function SGL_TableUpdate requests a redraw for the cells of column col and rowNB rows starting at row1.

The return value is 0 or a negative value in case of error (cf. Error codes ).

This function does not work if the table is dimmed. One can use instead SGL_Redraw .

When updating the header (row = -1), in case of merged cells (cf. Columns setting ), one must indicate the last merged column.


Table filling

CONTROL OBJECTS ›› TABLE ››

Syntax

int SGL_TableFillFunctionSet(HWND hwnd, SGL_TABLE_FILLCB fillCB);

Parameters

hwnd | Table object.
fillCB | Table filling callback

Description

This function installs the callback function which draws the content of headers and cells. Several SGL objects can share a common filling function.

This function is called by the SGL kernel when the table is displayed or updated.

The return value is 0, or negative value in case of error (cf. Error codes ).


Table filling callback

CONTROL OBJECTS ›› TABLE ›› Table filling ››

Syntax

void fillCB(HWND hwnd, HDC hdc, int row, int col, RECT *rect)

Parameters

hwnd

Table object.

hdc

Device context.

row, col

If col ≥ 0: coordinates of the header (row = -1) or of the cell to fill (row ≥ 0).

If col < 0: notification

 | col = -1 | col = -2
row = -1 | start of paint | end of paint
row ≥ 0 | start of row | end of row

rect

Rectangle in which to draw.

Description

This function is supposed to draw in rect something representing the content of the cell {row, col}.

When called with col < 0 it is a notification, nothing has to be drawn. Notifications is useful for handling data files, remote data access or complex data structures.

The filling sequence corresponds to this pseudocode:

fillCB(hwnd, -1, -1, rect) // start of paint

for all columns

fillCB(hwnd, -1, column, rect) // paint header

for all visible rows

fillCB(hwnd, row, -1, rect) // start of row

for all columns

fillCB(hwnd, row, column, rect) // paint row

fillCB(hwnd, row, -2) // end of row

fillCB(hwnd, -1, -2, rect) // end of paint

UNICODE characters may be drawn with DrawTextW().

Additional data for drawing can be obtained from the Drawing context .

Example

The following example fills a table with the content of a float array.

static void fillCB(HWND hwnd, HDC hdc, int row, int col, RECT *rect)

{

UINT style = DT_SINGLELINE | DT_VCENTER | DT_CENTER ; // text style

if (col < 0) return ; // ignore notification

if (row < 0) // draw header

{

char *headers[] = { "col_0", "col_1", "col_2" } ;

DrawText(hdc, headers[col], -1, rect, style) ;

}

else // draw cell

{

char l[32] ;

sprintf(l, "%.2f", FloatArray[col][row]) ;

DrawText(hdc, l, -1, rect, style) ;

}

}


User interaction

CONTROL OBJECTS ›› TABLE ››

Syntax

int SGL_TableCellCoordinatesGet(HWND hwnd, int *row, int *col);

int SGL_TableCellRectangleGet(HWND hwnd, int row, int col, RECT *rect);

Parameters

hwnd | Table object.
row, col | Cell coordinates (row = -1 for the table header).
rect | Rectangle corresponding to the cell (screen coordinates).

Description

User interaction is defined in the object callback function (cf. Callback function and data ). The SGL_TableCellCoordinatesGet function can then retrieve the cell coordinates of the last mouse click event. The SGL_TableCellRectangleGet function retrieves the rectangle corresponding to the cell {row, col}.

The return value is 0 or a negative value in case of error (cf. Error codes ).

Example

Here is a example of a table callback function. A user click in column 2 to change a boolean value, or in column 3 to select an option in a popup menu.

The SGL_TableCellCoordinatesGet function is used to identify the clicked cell. The SGL_TableCellRectangleGet function is used to put the popup menu at the right positon.

See also Table sample code .

static int tableCB(HWND hwnd, UINT event, WPARAM wParam, LPARAM lParam)

{

if (event == WM_LBUTTONUP) // mouse click

{

int r, c ; // clicked cell

if (SGL_TableCellCoordinatesGet(hwnd, &r, &c)) return 0 ;

if (r >= 0 && c == 2) // change the checked value

{

tableCheck[r] = tableCheck[r] ? 0 : 1 ; // update data

SGL_TableUpdate(hwnd, r, 1, c) ; // update display

}

if (r >= 0 && c == 3) // open popup

{

RECT rect ; // cell rectangle for popup position

SGL_TableCellRectangleGet(hwnd, r, c, &rect) ;

int e = SGLpopupMenu(hwnd, options, &rect, SGL_CENTER) ;

if (e >= 0)

tableOption[r] = e ; // update data

SGL_TableUpdate(hwnd, r, 1, c) ; // update display

}

}

return 0 ;

}


Selection

CONTROL OBJECTS ›› TABLE ››

Syntax

int SGL_TableSelectionModeSet(HWND hwnd, int selMode);
int SGL_TableSelectionModeGet(HWND hwnd);

int SGL_TableSelectionSet(HWND hwnd, int row, int col);
int SGL_TableSelectionGet(HWND hwnd, int *row, int *col);

Parameters

hwnd | Table object.
selMode | Selection mode: 0: no selection; 1: single cell selection; 2: single line selection; 3: selection of a compact set of lines.
row, col | Selected cells, depends on selMode (see below).

Description

When a selection mode is active (selMode > 0), the selected cells appears with the same colors as Win32® selected items. A mouse click on a cell changes the selection, as well as the [Up], [Down], [PageUp], [PageDown], [Home] and [End] keys when the table has the focus.

A compact set of lines is selected as above for the first line, and with the [Shift] key for the last line.

The SGL_TableSelectionModeSet function defines the selection mode. It returns zero, or a negative value in case of error (cf. Error codes ).

The SGL_TableSelectionModeGet function returns the selection mode, or a negative value in case of error (cf. Error codes ).

The SGL_TableSelectionSet sets the selection:

  • if row or col is < 0, the previous value is kept;
  • if selMode = 2: col is ignored;
  • if selMode = 3: col is the number of lines.

SGL_TableSelectionGet retrieves the selected cells. If selMode = 3, col will get the number of lines.

These functions return zero, or a negative value in case of error (cf. Error codes ).


Data cells appearance

CONTROL OBJECTS ›› TABLE ››

Syntax

int SGL_TableHGridSet(HWND hwnd, int rowGrid);
int SGL_TableHGridGet(HWND hwnd);

int SGL_TableGridThicknessSet(HWND hwnd, int e);
int SGL_TableGridThicknessGet(HWND hwnd, int *e);

int SGL_TableGridColorSet(HWND hwnd, COLORREF color);
int SGL_TableGridColorGet(HWND hwnd, COLORREF *color);

int SGL_TableAltRowSet(HWND hwnd, int dim);
int SGL_TableAltRowGet(HWND hwnd, int *dim);

hwnd | Table object.
rowGrid | If null, the horizontal border of cells is not displayed. Default value: 1.
e | Thickness of the grid (cf. Metrics ). Positive value: pixels; negative value: twips. Default value: -13.
color | Color of the cells' border. Default value: COLOR_BTNSHADOW.
dim | Color shadowing of odd rows. Typical values: -3 to +3. Default value: 0.

Description

The 6 first functions concern the cells' borders.

The SGL_TableHGridSet function defines wether the horizontal borders are visible (rowGrid = 1) or not (rowGrid = 0). It returns zero, or a negative value in case of error (cf. Error codes ). The SGL_TableHGridGet function returns the visibility of the horizontal borders, or a negative value in case of error (cf. Error codes ). The visibility of the vertical borders is defined for each column - see Columns setting .

The SGL_TableGridThicknessSet function defines the thickness of the grid; the SGL_TableGridThicknessGet function retrieves it.

The SGL_TableGridColorSet function defines the color of the grid. The SGL_TableGridColorGet function retrieves it.

The SGL_TableAltRowSet function changes the color of odd rows in order to improve the readability. The SGL_TableAltRowGet function retrieves the shadowing of odd rows.

These functions return zero, or a negative value in case of error (cf. Error codes ).

Tip

The bottom border of a table may become a separator when a table is filled line by line, even if rowGrid has been set to 0.

To prevent this effect, update the table globally or do not use any border (set thickness to 0).


GRAPH

CONTROL OBJECTS ››

A graph is a powerfull object used for real time data display. SGL provides a layer management and a coordinate system.

It's type is SGL_CTRL_GRAPH.

Style (cf. SGL_New)

The default style is a graph without border.

WS_CAPTION, WS_SIZEBOX and WS_BORDER can be used for borders and title bar.

Common attributes

The size must be defined (the default value is 0).

The object background color applies outside the plotting area (within the margins).

The graph does not support any border. If required, include the object in a panel with the requested border, or try a Win32® style.

Where to draw

Drawing is made in layers; SGL support 25 layers.

  • The layer 0 is the background.
    The plot area contains axes and grids (cf. Scales ); it has a background color (cf. Background aspect ).
    Outside the plot area are margins with tick marks and labels; the background color is the object's background color.
  • Layers 1 to (25 - 1) are free for the application. Only the plot area is visible.

As consequence, graph updating needs 2 operations:

  • Call SGL_GraphPlotRequest for each layer to be redrawn.
  • Call SGL_Redraw to stacks the layers and update the screen.

When to draw

Drawing requests may be sent by any thread. The plot function is called by the main thread, either following a user request, or following an SGL request when the graph window is installed or resized.

How to draw

Drawing is done by the Plot callback with simple Win32® drawing functions and SGL Coordinate conversion functions.

Events

The GRAPH object should process the mouse wheel event. If nothing has to be done, the callback function should just include:

switch (event)

{

...

case WM_MOUSEWHEEL :

return 1 ;

...

}

return 0 ;

SGL uses internally the WM_USER event for processing requests. The program must not use this event within graph processing.


Background appearance

CONTROL OBJECTS ›› GRAPH ››

Syntax

int SGL_GraphMarginSet(HWND hwnd, RECT *margin);

int SGL_GraphMarginGet(HWND hwnd, RECT *margin);

int SGL_GraphBGcolorSet(HWND hwnd, int layer, COLORREF bgColor);

int SGL_GraphBGcolorGet(HWND hwnd, int layer, COLORREF *bgColor);

int SGL_GraphTickLengthSet(HWND hwnd, int tickLen);

int SGL_GraphTickLengthGet(HWND hwnd, int *tickLen);

int SGL_GraphPlotRectGet(HWND hwnd, RECT *plotRect);

Parameters

hwnd | Graph object.
margin | Rectangle whose member values are the margin in the four directions. Positive values: pixels; negative values: twips. Color: the background color of the GRAPH object. Defaulf margins: none.
plotRect | Rectangle corresponding to the plot area.
layer | Layer index (0 .. 25 - 1).
bgColor | Background color of a layer. For the background layer (layer = 0), it is the background color of the plot area. For other layers (layer > 0), it is the color used for transparency. Default color: black.
tickLen | Length of tick marks. Default value: 40 twips.

Description

Use these function to set some aspects of the graph:

SGL_GraphMarginSet defines the margins in which tick marks and labels are displayed; setting is not necessary if these elements are not required.

SGL_GraphBGColorSet is required if the background (layer = 0) in not black, or if application layers (layer > 0) must display black objects.

SGL_GraphTickLengthSet for changing the of the tick marks along axis.

The SGLGraphXxxGet functions retrieve the corresponding aspects.

The SGL_GraphPlotRectGet function retrieves the plot rectangle.

These functions return 0 in case of success, or a negative value in case of error (cf. Error codes ).

Example

The following code is a graph callback function that changes the cursor when inside the plot area.

static int graphCB(HWND hwnd, UINT event, WPARAM wParam, LPARAM lParam)

{

if (event == WM_SETCURSOR)

{

POINT cursorPos; SGL_CursorPositionGet(hwnd, 0, &cursorPos);

RECT plotRect; SGL_GraphPlotRectGet(hwnd, &plotRect);

if (PtInRect(&plotRect, cursorPos))

{

SetCursor(myCursor);

return 1;

}

}

return 0;

}


Scales

CONTROL OBJECTS ›› GRAPH ››

Syntax

typedef struct {

double lowValue; | Value at the left or bottom of the axis.
double highValue; | Value at the right or top of the axis.
double interval; | Interval between major ticks; set this value to 0 for a logarithmic scale. The sign of interval is ignored.
int ntick; | Linear scale: number of minor ticks between each major tick. Log scale: 0 to 3 for less or more ticks marks.
SGL_GRAPH _LABELCB labelCB; | Label drawing callback .
int grid; | Grid display option: 0: none, 1: at each major tick, 2: at major and minor tick marks.
COLORREF color; | Color of the axis.

} SGL_GRAPH_AXIS_T;

int SGL_GraphAxisSet(HWND hwnd, int axisID, SGL_GRAPH_AXIS_T* uAxis) ;

int SGL_GraphAxisGet(HWND hwnd, int axisID, SGL_GRAPH_AXIS_T* uAxis) ;

Parameters

hwnd | Graph object.
axisID | Position of the axis: SGL_LEFT, SGL_BOTTOM, SGL_RIGHT or SGL_TOP.
uAxis | Structure containing the axis parameters. If null, the axis is no more used.

Description

Setting an axis makes it visible (provided sufficient margins have been set - see SGL_GraphMarginSet) and allows user to pixel conversions.

Setting an axis fails in the following cases:

  • if highValue = lowValue;
  • and for logarithmic scales:
    • if lowValue ≤ 0;
    • if highValue < lowValue.

The normal return value is zero, or a negative value in case of error (cf. Error codes ).

Example

The following code sets a left vertical axis from 1 (bottom) to 2 (top) (note that grid, tick marks and labels will not be visible).

SGL_GRAPH_AXIS_T yaxis = {

.lowValue = 1.0 ,

.highValue = 2.0 ,

.interval = 3.0 ,

.ntick = 0 ,

.labelCB = NULL ,

.grid = 0 ,

.color = 0xffffff } ;

SGL_GraphAxisSet(graph, SGL_LEFT, &yaxis);


Label drawing callback

CONTROL OBJECTS ›› GRAPH ›› Scales ››

Syntax

void labelCB(HWND hwnd, HDC hdc, double value, RECT *rect, int axisID);

Parameters

hwnd | Graph object.
hdc | Device context.
value | User value for the label.
rect | Rectangle in which to draw.
axisID | Position of the axis: SGL_LEFT, SGL_BOTTOM, SGL_RIGHT or SGL_TOP.

Description

This function is supposed to draw in rect something corresponding to value. If labelCB is null in the SGL_GRAPH_AXIS_T structure, no label will be displayed.

Usually a simple %g format and the DrawText() function does the job (cf. example below). It is even possible to draw anything anywhere in the background layer: the GetClientRect() function can retrieve the rectangle of the backgroung layer.

Example

void labelCB(HWND hwnd, HDC hdc, double z, RECT *rect, int iaxis)

{

char l[32] ; // label text

sprintf(l, "%g", z) ;

UINT dtFormat = DT_SINGLELINE ;

switch (iaxis) // position of the text in the rectangle

{

case SGL_LEFT : dtFormat |= DT_RIGHT ; break ;

case SGL_RIGHT : dtFormat |= DT_LEFTT ; break ;

case SGL_TOP :

case SGL_BOTTOM : dtFormat |= DT_CENTER ; break ;

}

DrawText(hdc, l, -1, rect, dtFormat) ;

}

Do not mistake SGL_LEFT and DT_LEFT: the former is the alignment of an SGL object, the latter is the alignment of text used by Win32®.


Drawing

CONTROL OBJECTS ›› GRAPH ››

One cannot draw directly, but only send requests that will be queued. The plot callback function will then be called with the right device context and layer index to draw in. SGL provides Coordinate conversion functions.

Use the SGL_Redraw function to refresh the graph.

Syntax

int SGL_GraphPlotFunctionSet(HWND hwnd, SGL_GRAPH_PLOTCB plotCB);

int SGL_GraphPlotFunctionGet(HWND hwnd, SGL_GRAPH_PLOTCB *plotCB);

Parameters

hwnd | Graph object.
plotFunc | Plot callback .

Description

The SGL_GraphPlotFunctionSet function installs a plot callback. This is mandatory, otherwise a black panel will be displayed.

The normal return value is zero, or a negative value in case of error (cf. Error codes ).


Plot callback

CONTROL OBJECTS ›› GRAPH ›› Drawing ››

Syntax

void plotCB(HWND hwnd, HDC hdc, int layer, int item);

Parameters

hwnd | Graph object.
hdc | Device context for drawing.
layer | Layer index (0 .. 25 - 1). If this parameter is < 0, all layers must be drawn and hdc is NULL.
item | This parameter indicates which part must be painted. For the background layer (layer = 0): 0: backgroung color only, 1: full background. For other layers (layer > 0): parameter set by SGL_GraphPlotRequest .

Description

This function is called following Requests sent by SGL or by the user.

If drawing some color does not appear, check if it is not a transparency color (cf. Background appearance ).

Example

Simple example plotting an a 1-dimension array in a single layer:

void plotCB(HWND hwnd, HDC hdc, int layer, int item)

{

if (layer < 0) // system request: [re]draw all

{

SGL_GraphPlotRequest(graph, 0, 1) ; // full background

SGL_GraphPlotRequest(graph, 1, 1) ; // my single layer

}

else if (layer == 1) // plot array[i:0..N]

{

SGL_GraphClear(hwnd, layer) ; // clear previous drawings

SetDCBrushColor(hdc, myColor) ;

for (int i = 0 ; i < N ; i++) // for each value

{

int xp = SGL_GraphUserToPixel(hwnd, SGL_BOTTOM , (double) i) ;

int yp = SGL_GraphUserToPixel(hwnd, SGL_LEFT, array[i]) ;

RECT rect ; // 3-pixel square

SetRect(&rect, xp - 1, yp - 1, xp + 2, yp + 2) ;

FillRect(hdc, &rect, GetStockObject(DC_BRUSH)) ;

}

SGL_Redraw(hwnd) ; // send to screen

}

return ;

}


Coordinate conversion

CONTROL OBJECTS ›› GRAPH ›› Drawing ››

Syntax

int SGL_GraphUserToPixel(HWND hwnd, int axisID, double x);

int SGL_GraphPixelToUser(HWND hwnd, int axisID, int xp, double *x);

Parameters

hwnd | Graph object.
axisID | Position of the axis: SGL_LEFT, SGL_BOTTOM, SGL_RIGHT or SGL_TOP.
x | User coordinate.
xp | Pixel coordinate.

Description

The conversion uses the scale data used by the SGL_GraphAxisSet function for the corresponding axis.

The SGL_GraphUserToPixel function returns a pixel coordinate or a negative value in it failed (cf. Error codes ).

The SGL_GraphPixelToUser function should return zero, or a negative value in it failed (cf. Error codes ).


Requests

CONTROL OBJECTS ›› GRAPH ››

Syntax

int SGL_GraphPlotRequest(HWND hwnd, int layer, int item);

int SGL_GraphClear(HWND hwnd, int layer);

Parameters

hwnd | Graph object.
layer | Layer index (0 .. 25 - 1), or -1 for plotting all layers.
item | This parameter indicates which part must be painted For the background layer (layer = 0): 0: background color only, 1: full background. For the other layers (layer > 0): parameter sent to the plot callback function.

Description

The SGL_GraphPlotRequest function posts a request that is queued in the Windows® event system; it returns immediately and can be called from any thread. This request produces a call to an SGL function for painting the background (layer = 0), or to the Plot callback for the other layers (layer > 0).

The SGL_GraphClear function returns when the layer has been cleared. It is normally called at the beginning of a Plot callback .

The normal return value is zero, or a negative value in case of error (cf. Error codes ).

Example

The next two calls clear the background:

SGL_GraphPlotRequest(hwnd, 0, 0); // returns immediatly

SGL_GraphClear(hwnd, 0); // returns when the layer is cleared


OPENGL

CONTROL OBJECTS ››

OpenGL is the major standard for displaying 3D animated graphics.

It's type is SGL_CTRL_OPENGL.

OpenGL programming requires initialization, drawing, lighting and viewing.

SGL supports entirely the first task: pixel format, graphic context, viewport and even reshaping when the window is resized.

The other tasks are defined by the application program (see below).

Event processing remains handled by Win32® and the Callback function .

SGL support of OpenGL is limited to the features of Windows®, and typically to one OpenGL window.

Style (cf. SGL_New)

The default style is an OpenGL object without border.

WS_CAPTION, WS_SIZEBOX and WS_BORDER can be used for borders and title bar.

Common attributes

The size must be defined (the default size is 160 x 120 pixels).

The OpenGL object does not use colors or fonts.

It does not support any border. If required, include the control in a panel with the requested border, or try a Win32® style.

How to draw

Drawing must be done in the callback function of the object; it should start with glClear() and end with SwapBuffers():

int oglCB(HWND hwnd, UINT event, WPARAM wParam, LPARAM lParam)

{

int animate = 0 ;

switch (event)

{

case {some events} :

animate = ..

case WM_PAINT :

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) ;

if (animate) // move & rotate

{

glTranslatef(...);

glRotatef(...);

...

}

glBegin(...); // OpenGL draw

glVertex3f(...);

...

glEnd();

SwapBuffers(GetDC(hwnd)); // display the result

break ;

}

return 0 ;

}

Lighting

Lighting is defined with the standard OpenGL functions.

Viewing

Two functions are provided by SGL for the Camera setting .

Typical viewing setting:

// camera setting (SGL)
SGL_OglZoomSet(..); // set the focal distance

SGL_OglDepthOfFieldSet(..); // set the depth of field

// other standard OpenGL settings

gluLookAt(..); // position & orientation of the camera

glEnable(GL_DEPTH_TEST); // process hidden parts


Camera setting

CONTROL OBJECTS ›› OPENGL ››

Syntax

int SGL_OglZoomSet(HWND hwnd, double nFoc);
int SGL_OglZoomGet(HWND hwnd, double *nFoc);

int SGL_OglDepthOfFieldSet(HWND hwnd, double zNear, double zFar);
int SGL_OglDepthOfFieldGet(HWND hwnd, double *zNear, double *zFar);

Parameters

hwnd | OpenGL object.
nFoc | Focal distance, must be positive. 1.0 (default) for normal; <1 for wide angle; >1 for telephoto.
zNear, zFar | The distances to the near- and far-depth clipping planes. Both distances must be positive.

Description

These functions allow setting and retrieving respectively the relative focal distance and the field of view.

The normal return value is 0, or a negative value in case of error (cf. Error codes ).

For still photography, the normal focal distance corresponds to the diagonal size of the film or sensor (ie. 43 mm for a 135 film; diagonal angle of view about 53°).

The depth of field defines an interval. Only the scene within this interval is displayed; outside elements are ignored.


IMAGE

CONTROL OBJECTS ››

The image object is a display tool using the GDI+ API. It's type is SGL_CTRL_IMAGE.

The image formats supported are: JPEG, TIFF, BMP, PNG, GIF, WMF, EMF, ICON.

Images can be loaded directly from file or from a resource.

Multiframe TIFF files and GIF animation are supported with limitations on WindowsXP.

Style (cf. SGL_New)

The default style is an image without border.

WS_CAPTION, WS_SIZEBOX and WS_BORDER can be used for borders and title bar.

Common attributes

The image does not support any border. If required, include the object in a panel with the requested border, or try a Win32® style.

The foreground and font attributes have no effect.


Loading and unloading

CONTROL OBJECTS ›› IMAGE ››

Syntax

int SGL_ImageLoad(HWND hwnd, char* fileName) ;

int SGL_ImageUnload(HWND hwnd) ;

Parameters

hwnd | SGL object.
fileName | File name or resource locator. Resource locator: ":resource_type:resource_name" (see example below).

Description

The SGL_ImageLoaD function loads an image. This string can be a file name or a resource locator.

When no more used, the image content must be unloaded with the function SGL_ImageUnload.

These functions return 0, or a negative value in case of error (cf. Error codes ).

Example

If the resource file contains:

8007 MY_IMAGE "sanremo.jpg"

Loading this image is performed by calling:

SGL_ImageLoad(imageHwnd, ":MY_IMAGE:#8007");

(Do not use predefined resource types!)


Size fitting

CONTROL OBJECTS ›› IMAGE ››

Syntax

int SGL_ImageFittingSet(HWND hwnd, int fit);
int SGL_ImageFittingGet(HWND hwnd);

Parameters

hwnd | SGL object.
fit | Size fitting mode: 0: no size fitting; 1: image are reduced as needed to fit the display area; 2: image are reduced or magnified to fit the display area.

Description

The SGL_ImageFittingSet function sets the image zoom depending on the image size and the size of the display area. The aspect ratio is preserved in all cases. The normal return value is 0, or a negative value in case of error (cf. Error codes ).

The SGL_ImageFittingGet function returns the fitting mode, or a negative value in case of error (cf. Error codes ).


Multiframe images

CONTROL OBJECTS ›› IMAGE ››

Syntax

int SGL_ImageFrameCountGet(HWND hwnd);

int SGL_ImageFrameIndexSet(HWND hwnd, int frameIndex);
int SGL_ImageFrameIndexGet(HWND hwnd);

int SGL_ImagePlay(HWND hwnd, int speed100);

Parameters

hwnd | Graph object.
frameIndex | Frame index (0 .. number of frames).
speed100 | Speed (x100) of the animation. The default value is 100 which corresponds to: - the normal frame rate for GIF files, - 1 frame per second for TIFF frames.

Description

GIF files and TIFF files may contain several frames

The SGL_ImageFrameCountGet function returns the number of frames, or a negative value in case of error (cf. Error codes ).

The SGL_ImageFrameIndexSet function sets the current frame index. Its normal return value is 0, or a negative value in case of error (cf. Error codes ). The function SGL_ImageFrameIndexGet returns the current frame index, or a negative value in case of error (cf. Error codes ).

The SGL_ImagePlay function plays a multiframe file. A GIF file will be played at speed100 / 100 times its normal speed. A TIFF file will be played at speed100 / 100 frames per second. This function should return 0, or a negative value in case of error (cf. Error codes ).

Under WindowsXP, some features may not be available :

  • Mutiframe TIFF.
  • Animation when dimmed.


POPUP CONTROLS

Popup controls are stand alone objets; they are not concerned by the common attributes.


Menu popup

POPUP CONTROLS ››

Syntax

typedef struct {

int state; | 0 (default), MF_CHECKED, MF_DISABLED or MF_SEPARATOR.
char *text; | Option text: ignored if separator, NULL at end.

} SGL_POPUPMENU_OPTIONS_T;

int SGL_PopupMenu(HWND hwnd, SGL_POPUPMENU_OPTIONS_T* options, RECT *rect, int align);

Parameters

hwnd | Parent object.
options | Array of menu options.
rect | Rectangle to which the menu is anchored (screen coordinates).
align | Alignment of the menu with the above rectangle (SGL_LEFT, SGL_CENTER or SGL_RIGHT).

Description

The menu options are defined by an array of SGL_POPUPMENU_OPTIONS_T.

The position of the menu is defined by the rect and align parameters.

The function returns when the user has selected an option or cancelled the choice (click outside or [ESC] key).

The return value is the index of the selected option, or a negative value in case of error (cf. Error codes ; SGL_ERR_INT: the menu could not be operated or has been canceled).

Example

The example installs a popup menu on the right of the blue button.

SGL_POPUPMENU_OPTIONS_T ppm[] =

{

{MF_DISABLED, "my header"},

{MF_SEPARATOR , "separator"},

{0, "your option"},

{MF_CHECKED, "his check"},

{0, NULL}

} ;

int e = SGL_PopupMenu(ctrl, ppm, rect, SGL_RIGHT) ;

_cprintf("popup returns %d\?n", e) ;


Edit popup

POPUP CONTROLS ››

Syntax

HWND SGL_PopupEdit(HWND hwnd, RECT *rect, DWORD style, char *text, int textLen, SGL_EDITCB editCB, void* CBdataPtr);

Parameters

hwnd | Parent object.
rect | Position of the popup.
style | Extra style options (OR'ed): ES_LEFT, ES_CENTER, ES_RIGHT, ES_LOWERCASE, ES_UPPERCASE, ES_NUMBER, ES_PASSWORD.
text | Text buffer.
textLen | Size of the text buffer (including the terminal '\0')
editCB | Pointer to an optionnal callback function (can be NULL).
CBdataPtr | Pointer to an optionnal callback data (NULL).

Description

The SGL_PopupEdit function installs a temporary edit popup window for user entry (single line, small text, number,...).

The aspect of the popup is inherited from the parent object, excepted for the background color which is an argument of SGL_PopupEdit.

The popup is closed when the user hits the [Esc] or [Ret] key, if the edit popup looses the focus, or if the callback function returns -1.

The function returns the handle of the edit control, or NULL if it fails.


Callback function

POPUP CONTROLS ›› Edit popup ››

Syntax

int editCB(int virtKey, char* text, int textLen, int caret, void* CBdataPtr)

Parameters

virtKey

Virtual key corresponding to the user event:

  • 0: the user entry has been changed but is not yet displayed.
  • VK_ESCAPE: the user has hit the [Esc] key; the edit control has lost the focus.
  • VK_RETURN: the user has hit the [Ret] key.
  • VK_UP, VK_DOWN: the user has hit the [Up] or [Down] key, or rotated the mouse wheel.

text

Text buffer.

textLen

Size of the text buffer (including the terminal '\0')

caret

Position of the text cursor.

CBdataPtr

Pointer to an optionnal callback data (NULL).

Description

This application-defined callback function responds to user events defined by virtKey.

The allowed return values are:

  • 0: do nothing (the callback continues to process the user entries),
  • 1: the user entry has been modified by the callback function and must be displayed (USE ONLY IF THE DISPLAYED TEXT MUST BE CHANGED)
  • -1: the popup must be closed.


Date time popup

POPUP CONTROLS ››

Syntax

HWND SGL_PopupDatetime(HWND hwnd, RECT *rect, int style, char *format, SYSTEMTIME *datetime, SGL_DTIMECB dtimeCB, void* CBdataPtr);

Parameters

hwnd | Parent object.
rect | Position of the popup
style | Date & time style, one of: SGL_DATE, SGL_TIME. Optional style for all: SGL_DT_NONE Optional styles for date: SGL_DT_LONG, SGL_DT_CALENDAR, SGL_DT_WEEKNB, SGL_DT_TODAY.
format | Custom format string , must be null if not used.
datetime | Win32® structure containing the date & time values.
dtimeCB | Callback function
CBdataPtr | Data pointer.

Description

This function installs a Win32® date time picker popup.

If SGL_DT_NONE is specified and then user hits the [Delete] key, the value is erased (set to null).

For date entry, a calendar can be displayed (SGL_DT_CALENDAR) with the current date (SGL_DT_TODAY) and with the week number (SGL_DT_WEEKNB).

If format is NULL and SGL_DT_LONG is set, the date will be displayed with a long format.

The function returns the handle of the date time control, or NULL if it fails.

Example

This example shows an entry for departing and returning.

#include "sgl.h"

#include <stdio.h>

/* the application window has 2 rows */

char *label[] = { "Andata", "Ritorno" } ; /* left column: labels */

struct

{ /* next two columns: data */

HWND hwnd[2] ; /* object handle */

char pszDate[2][32] ; /* text */

SYSTEMTIME datetime ; /* date-time */

} dt[2] ;

/* aspect for the two data columns */

char *format[2] = { "dd MMM yyyy", "HH:mm" }; /* specific format */

int width[2] = { -7, -4 }; /* column width */

int style[2] = {

SGL_DATE | SGL_DT_CALENDAR | SGL_DT_NONE, /* left: date style */

SGL_TIME | SGL_DT_NONE }; /* time style */

void dtimeCB(int event, SYSTEMTIME *u, void* CBdataPtr) /* update */

{

if (event == SGL_DT_RELEASE) /* when a date or time popup is closed: */

{

int r = (int) CBdataPtr / 2 ; /* row index */

int c = (int) CBdataPtr % 2 ; /* index of the data column */

SGL_Redraw(dt[r].hwnd[1-c]) ; /* refresh the other one */

}

}

/* callback function for the date & time buttons */

int buttonCB(HWND hwnd, UINT event, WPARAM wParm, LPARAM lParm)

{

void* ptr ; SGL_CallbackDataGet(hwnd, &ptr) ;

int r = (int) ptr / 2 ;

int c = (int) ptr % 2 ;

switch (event)

{

case WM_PAINT : /* set the data to be displayed */

SGL_DateTimeStringGet(&(dt[r].datetime), style[c],

format[c], dt[r].pszDate[c], 32) ;

SGL_TitleSet(dt[r].hwnd[c], dt[r].pszDate[c]) ;

return 0 ; /* continue with default processing */

case WM_LBUTTONUP : /* user clicked in a date or time button */

{

RECT rect ; /* rectangle for the date time edit box */

GetClientRect(hwnd, &rect) ;

MapWindowPoints(hwnd, NULL, (POINT*) &rect, 2) ;

if (SGL_DATETIME_NONE_IS(dt[r].datetime)) /* default is now */

dt[r].datetime = SGL_DateTimeNow() ;

SGL_PopupDatetime(hwnd, &rect, style[c], format[c],

&dt[r].datetime, dtimeCB, ptr) ;

return 1 ; /* done */

}

}

return 0 ;

}

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,

PSTR szCmdLine, int iCmdShow)

{

SGL_Init(hInstance, NULL) ;

HWND topPanel = SGL_New(0, SGL_PANEL, 0, "BIGLIETTO", 200, 100);

SGL_FontSizeSet(1, -120) ; /* global font scale factor */

SGL_FontStyleSet(topPanel, SGL_FONT_BOLD); /* inherited style */

for (int r = 0 ; r < 2 ; r++)

{

HWND h ; /* temporary control */

h = SGL_New(topPanel, SGL_CTRL_BUTTON, SGL_RIGHT, label[r], 0, r) ;

SGL_BorderThicknessSet(h, 0) ;

SGL_SizeSet(h, SGL_WIDTH, -4) ;

for (int c = 0 ; c < 2 ; c++)

{

h = SGL_New(topPanel, SGL_CTRL_BUTTON, SGL_LEFT, "", c + 1, r) ;

SGL_SizeSet(h, SGL_WIDTH, width[c]) ;

SGL_CallbackFunctionSet(h, buttonCB) ;

SGL_CallbackDataSet(h, (void*) (2 * r + c)) ;

dt[r].hwnd[c] = h ;

}

}

SGL_VisibleSet(topPanel, 1) ;

SGL_Layout(topPanel) ;

SGL_Run() ;

SGL_Exit() ;

return 0 ;

}

The date and time values are displayed on buttons. The button callback is used to refresh the displayed text (on WM_PAINT message) and to install the popup (on user click).

If the user hits the [Delete] key, it erases the value (style option SGL_DT_NONE). The popup callback is then used to synchronize the displayed values. It the date (or time) is displayed (erased), the time (or date) will also be displayed (erased).


Custom format string

POPUP CONTROLS ›› Date time popup ››

You specify a format string that tells the control how to format the time or date output.The following format strings are supported:

String | Description
d | The one- or two-digit day.
dd | The two-digit day. Single digit day values are preceded by a zero.
ddd | The three-character day-of-week abbreviation.
dddd | The full day-of-week name.
h | The one- or two-digit hour in 12-hour format.
hh | The two-digit hour in 12-hour format. Single digit values are preceded by a zero.
H | The one- or two-digit hour in 24-hour format.
HH | The two-digit hour in 24-hour format. Single digit values are preceded by a zero.
m | The one- or two-digit minute.
mm | The two-digit minute. Single digit values are preceded by a zero.
M | The one- or two-digit month number.
MM | The two-digit month number. Single digit values are preceded by a zero.
MMM | The three-character month abbreviation.
MMMM | The full month name.
s | The one- or two- digit seconds.
ss | The two-digit seconds. Single digit values are proceeded by a zero.
t | The one-letter AM/PM abbreviation (that is, "AM" is displayed as "A").
tt | The two-letter AM/PM abbreviation (that is, "AM" is displayed as "AM").
y | The one-digit year (that is, 1996 would be displayed as "6").
yy | The last two digits of the year (that is, 1996 would be displayed as "96").
yyy | The full year (that is, 1996 would be displayed as "1996").

To display string literals that contain date and time separators or to format strings, you must use escape characters in the substring. For example, to display the date as "June 15 at 12:00 PM", set the CustomFormat property to "MMMM dd 'at' t:mm tt". If the "at" substring is not enclosed by escape characters, the result is "June 15 aP 12:00PM" because the "t" character is read as the one-letter A.M./P.M. format string (see the format string table below).

See GetDateFormat() and GetTimeFormat() documentation.


Callback function

POPUP CONTROLS ›› Date time popup ››

Syntax

void dtimeCB(int event, SYSTEMTIME *datetime, void* CBdataPtr);

Parameters

event

Event causing the function to be called:

  • SGL_DT_INSTALL: the user entry has been changed but is not yet displayed.
  • SGL_DT_DELETE: the SGL_DT_NONE style was set and the user has hit the [Delete] key.
  • SGL_DT_CHANGED: the date time value has been changed..
  • SGL_DT_RELEASE: the popup has been released.

datetime

Win32® structure containing the date & time value.

CBdataPtr

Pointer to an optional callback data (NULL).

Description

This application-defined callback function responds to user events defined by event.


Tools

POPUP CONTROLS ›› Date time popup ››

Syntax

SGL_DATETIME_NONE_SET(datetime)
SGL_DATETIME_NONE_IS(datetime)

int SGL_DateTimeStringGet(SYSTEMTIME *datetime, int style, char *format, char* dst, int max) ;

SYSTEMTIME SGL_DateTimeNow(void) ;

Parameters

datetime | Win32® structure containing the date & time values.
style | Date & time style, one of: SGL_DATE, SGL_TIME. Optional style for date: SGL_DT_LONG. If format is NULL and SGL_DT_LONG is set, the date will be displayed with a long format.
format | Custom format string , must be null if not used.
dst | Pointer to a buffer that receives the formatted date or time string.
max | Specifies the size of the dst buffer. If max is zero, the function returns the number of characters required to hold the formatted string, and dst is not used.

Description

The SGL_DateTimeStringGet function produces a text representation of datetime. If datetime is null (see hereunder), the output is an empty string. This function returns the number of characters produced, including the final '\0', or 0 in case of error.

Two macro are provided:

  • SGL_DATETIME_NONE_SET set its parameter to a null value (the wYear member is set to 0).
  • SGL_DATETIME_NONE_IS returns 0 if its parameter is a null value (the wYear member is null).

The SGL_DateTimeNow function returns the current date & time.


Example

POPUP CONTROLS ›› Date time popup ››

This example shows an entry for departing and returning.

#include "sgl.h"

#include <stdio.h>

#define TEXT_LEN 20

/* the application window has 2 rows */

char *label[] = { "Andata", "Ritorno" } ; /* left column: labels */

struct

{ /* next two columns: data */

HWND hwnd[2] ; /* object handle */

char pszDate[2][32] ; /* text */

SYSTEMTIME datetime ; /* date-time */

} dt[2] ;

/* aspect for the two data columns */

char *format[2] = { "dd MMM yyyy", "HH:mm" }; /* specific format */

int width[2] = { -7, -4 }; /* column width */

int style[2] = {

SGL_DATE | SGL_DT_CALENDAR | SGL_DT_NONE, /* left: date style */

SGL_TIME | SGL_DT_NONE }; /* time style */

void dtimeCB(int event, SYSTEMTIME *u, void* CBdataPtr) /* update */

{

if (event == SGL_DT_RELEASE) /* when a date or time popup is closed: */

{

int r = (int) CBdataPtr / 2 ; /* row index */

int c = (int) CBdataPtr % 2 ; /* index of the data column */

SGL_Redraw(dt[r].hwnd[1-c]) ; /* refresh the other one */

}

}

/* callback function for the date & time buttons */

int buttonCB(HWND hwnd, UINT event, WPARAM wParm, LPARAM lParm)

{

void* ptr ; SGL_CallbackDataGet(hwnd, &ptr) ;

int r = (int) ptr / 2 ;

int c = (int) ptr % 2 ;

switch (event)

{

case WM_PAINT : /* set the data to be displayed */

SGL_DateTimeStringGet(&(dt[r].datetime), style[c],

format[c], dt[r].pszDate[c], 32) ;

SGL_TitleSet(dt[r].hwnd[c], dt[r].pszDate[c]) ;

return 0 ; /* continue with default processing */

case WM_LBUTTONUP : /* user clicked in a date or time button */

{

RECT rect ; /* rectangle for the date time edit box */

GetClientRect(hwnd, &rect) ;

MapWindowPoints(hwnd, NULL, (POINT*) &rect, 2) ;

if (SGL_DateTimeNullGet(&dt[r].datetime)) /* default is now */

dt[r].datetime = SGL_DateTimeNow() ;

SGL_PopupDatetime(hwnd, &rect, style[c], format[c],

&dt[r].datetime, dtimeCB, ptr) ;

return 1 ; /* done */

}

}

return 0 ;

}

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,

PSTR szCmdLine, int iCmdShow)

{

SGL_Init(hInstance, NULL) ;

HWND topPanel = SGL_New(0, SGL_PANEL, 0, "BIGLIETTO", 200, 100);

SGL_FontSizeSet(1, -120) ; /* global font scale factor */

SGL_FontStyleSet(topPanel, SGL_FONT_BOLD); /* inherited style */

for (int r = 0 ; r < 2 ; r++)

{

HWND h ; /* temporary control */

h = SGL_New(topPanel, SGL_CTRL_BUTTON, SGL_RIGHT, label[r], 0, r) ;

SGL_BorderThicknessSet(h, 0) ;

SGL_SizeSet(h, SGL_WIDTH, -4) ;

for (int c = 0 ; c < 2 ; c++)

{

h = SGL_New(topPanel, SGL_CTRL_BUTTON, SGL_LEFT, "", c + 1, r) ;

SGL_SizeSet(h, SGL_WIDTH, width[c]) ;

SGL_CallbackFunctionSet(h, buttonCB) ;

SGL_CallbackDataSet(h, (void*) (2 * r + c)) ;

dt[r].hwnd[c] = h ;

}

}

SGL_VisibleSet(topPanel, 1) ;

SGL_Layout(topPanel) ;

SGL_Run() ;

SGL_Exit() ;

return 0 ;

}

The date and time values are displayed on buttons. The button callback is used to refresh the displayed text (on WM_PAINT message) and to install the popup (on user click).

If the user hits the [Delete] key, it erases the value (style option SGL_DT_NONE). The popup callback is then used to synchronize the displayed values. It the date (or time) is displayed (erased), the time (or date) will also be displayed (erased).


TOOLS

SGL provides tools for various purposes:

  • Set the appearance: Metrics and default padding , Font setting .
  • Drawing in controls: Color dimming , Color interpolation , Border drawing , Drawing context .
  • Automatic resizing .
  • Interact with the user: Cursor position .
  • Debug tools .
  • Other tools .


Metrics and default padding

TOOLS ››

Syntax

int SGL_DefPaddingSet(int l);
int SGL_DefPaddingGet(void);

int SGL_RefSizeGet(void);

Parameters

l

Default padding (cf. Metrics ).

Description

A default space is provided between an object and its grid cell. The same default space if provided for panels, between its internal border and its grid.

The function SGL_DefPaddingSet. allow a global setting of this space; a positive value is a pixel size, a negative value is a twip count. The normal return value is 0, or a negative value in case of error (cf. Error codes ).

The function SGL_DefPaddingGet returns the pixel value of the default padding.

The function SGL_RefSizeGet is useful when a twip to/from pixel conversion is needed. It returns a pixel count which corresponds to 100 twips (that is the size of the normal font). The result may change after Font settings .

See also

Metrics , Font settings

Alignment and padding , Internal padding


Font settings

TOOLS ››

Syntax

int SGL_FontSizeSet(int sizeIx, int size);

int SGL_FontFaceSet(int style, char *name);
int SGL_FontFaceGet(int style, char *name);

Parameters

sizeIx | Index of a predefined size.
size | Font size: >0: pixel size, <0: percent of the normal font size.
style | Index of a a predefined style.
name | Typeface name of the font (cf. lpszFace parameter of the CreateFont()). With SGL_FontFaceSet, name must not exceed 32 characters, including the null terminator. With SGL_FontFaceGet, name must be declared as LF_FACESIZE character buffer.

Default values

Size index | Size
SGL_FONT_SMALL | 85 %
SGL_FONT_NORMAL | 100 %
SGL_FONT_LARGE | 135 %
SGL_FONT_BIG | 185 %

Font style | Default typeface name
SGL_FONT_NORMAL | desktop message font
SGL_FONT_FIXED | Lucida console
SGL_FONT_BOLD | desktop menu font
SGL_FONT_ITALIC | desktop menu font
SGL_FONT_SYMBOL | WingDings
SGL_FONT_EXTRA | (undefined)

Unless modified by the user, the desktop message font is Segoe or Tahoma.

Description

The SGL_FontSizeSet function sets the size globally, ie. of all objects having a given size index. The default size for SGL_FONT_NORMAL follows the Windows® appearance settings; changing its value has a global effect. Windows® menus and popup menus ignore this setting.

The SGL_FontFaceSet and SGL_FontFaceGet functions are used to set or retrieve the font style of an SGL object.

These function returns 0 in case of success, or a negative value in case of error (cf. Error codes ).

See also

For own drawn objects, it is possible to retrieve a Font handle .

Examples

This example sets everything 50% bigger:

SGL_FontSizeSet(SGL_FONT_NORMAL, 150); // make everything 50% bigger

SGL_Layout(hwnd); // apply

This example installs an icon font for SGL_FONT_EXTRA style:

AddFontResourceEx("data\\IcoMoonFont\\IcoMoon-Free.ttf", FR_PRIVATE, NULL);

SGL_FontFaceSet(SGL_FONT_EXTRA, "IcoMoon-Free");

This example is a callback function of a top windows for updating the predefined fonts when the user changes the desktop settings:

int topWindowCB(HWND hwnd, UINT event, WPARAM wParam, LPARAM lParam)

{

if (event == WM_SYSCOLORCHANGE)

{

SGL_Init(NULL, NULL) ;

SGL_Layout(hwnd) ;

}

return 0 ;

}


Colors

TOOLS ››

This section contains 2 simples tools to manipulate colors:

  • Color dimming
  • Color interpolation

A popup tool is also provided for Setting colors . It is designed for configuring the colors of an application; its immediate effect makes its use particularly pleasant.


Color dimming

TOOLS ›› Colors ››

Syntax

COLORREF SGL_ColorDim(COLORREF color, int dimmed);

Parameters

color | Color
dimmed | Dim status.

Description

This function returns color if dimmed is 0. If dimmed is not nul, it returns the dimmed color.

The appearance of an SGL object depends on its dim status (cf. Visibility ). This function is useful when drawing in objects that can be dimmed.

Example

The following creates a red pen, possibly dimmed:

hpen = CreatePen(PS_SOLID, 1, SGL_ColorDim(RGB(0xff, 0, 0), dimmed));

See also

The SGL_ContextGet gives access to the dim status of an object.


Color interpolation

TOOLS ›› Colors ››

Syntax

COLORREF SGL_ColorInterpolate(COLORREF color0, COLORREF color1, double k);

Parameters

color0 | Start color.
color1 | End color.
k | Interpolation factor.

Description

This function returns a color between color0 if k = 0 and color1 if k = 1.

System colors are accepted


Setting colors

TOOLS ›› Colors ››

For aesthetic reasons, compliance with the desktop theme or color code, a user may want to configure the colors of a SGL application.

The provided service allows setting colors with a HSL color picker. Each one is loaded at start, and saved when changed in the Configuration file When adjusting colors, the result is immediately applied and saved.

Syntax

int SGL_ColorsConfigure(char **colorKey, char *section, COLORS_CB func) ;

void SGL_ColorsSet(void) ;

Parameters

colorKey | Array of color keys used to save the RGB values in the ini file. The end of the array is identified by a null key.
section | Section of the .ini file.
func | Callback function for setting colors in the calling program.

Description

The SGL_ColorsConfigure function create a hidden color picker, reads the colors in the .ini file and apply them to individual objects through the callback function. It returns 0, or value a negative value in case of error (cf. Error codes ).

The SGL_ColorsSet function makes the color picker visible:

The top button display a popup list with the color keys.

Three slider provide a color adjustment (hue, saturation, lightness).

The bottom area is the color sample with its RGB value. This value can be edited.


Color setting callback

TOOLS ›› Colors ›› Setting colors ››

Syntax

void colorCB(int ix, COLORREF color);

Parameters

ix | Color index (index in the array of color keys).
color | Color to apply (-1: default value).

Description

This function is supposed to apply the color corresponding to the key colorKey[ix].

Example

This example displays a button in a window. The button makes the color picker visible.

This picker allows setting 3 colors and saving them in a COLORS section.

#include "sgl.h"

HWND mainPanel, btn;

void colorChange(int ix, COLORREF color)

{

switch (ix)

{

case 0 : SGL_BGcolorSet(mainPanel, color); break;

case 1 : SGL_BGcolorSet(btn, color); break;

case 2 : SGL_FGcolorSet(btn, color); break;

}

SGL_Redraw(mainPanel);

}

static int btnCB(HWND hwnd, UINT event, WPARAM wParm, LPARAM lParm)

{

if (event == WM_USER)

SGL_ColorsSet(); // turn on picker

return 0; // default event processing

}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

PSTR szCmdLine, int iCmdShow)

{

SGL_Init(hInstance, NULL);

mainPanel = SGL_New(0, SGL_PANEL, 0, "Main_panel", 111, 111);

btn = SGL_New(mainPanel, SGL_CTRL_PUSHBUTTON, 0, "Button", 0, 0);

SGL_CallbackFunctionSet(btn, btnCB);

SGL_Layout(mainPanel);

SGL_VisibleSet(mainPanel, 1);

char *colorDef[] = { "Panel BG", "Button BG", "Button FG", NULL };

SGL_ColorsConfigure(colorDef, "COLORS", colorChange);

SGL_Run();

SGL_Exit();

return 0;

}


Border drawing

TOOLS ››

Syntax

int SGL_BorderDraw(HDC hdc, RECT *rect, int e, int style, int color, int dim);

Parameters

hdc | Graph object.
rect | End color.
e | Border's thickness (cf. Borders ).
style | Border's style (cf. Borders ).
color | Border's color (cf. Borders ).
dim | Dimmed aspect (cf. Visibility ).

Description

This function draws a border in the rect rectangle.


Drawing context

TOOLS ››

Syntax

typedef struct {

int selected; | For buttons: 1 when the button is being pushed. For tables: 1 when the cell is selected. 0 in all other cases.
int dimmed; | Actual dimming state (see also Visibility ).
COLORREF bgdColor, fgdColor; | Actual background and foreground colors (see also Colors ).
int fontSizeIx, fontStyle; | Font size index and style (cf. Fonts ).

} SGL_CONTEXT_T;

int SGL_ContextGet(HWND hwnd, SGL_CONTEXT_T *context);

Parameters

hwnd | Table object.
context | Structure filled with the drawing context.

Description

This function is typically used in object callback for drawing text and graphic.


Automatic resizing

TOOLS ››

Syntax

int SGL_ResizeInstall(HWND hwnd, int widthMin, int heightMin, SGL_RESIZECB resizeCB);

Parameters

hwnd | SGL object to resize when a top window is resized.
widthMin | Minimum width (cf. Metrics ). If null, the width cannot be changed.
heightMin | Minimum height (cf. Metrics ). If null, the height cannot be changed.
resizeCB | Resize callback (can be null). Never called if both widthMin and heightMin are null.

Description

The purpose of this function is to allow the user to drag borders and corners of a top window with the mouse pointer.

The size change will be applied to hwnd with minimum values defined by the second and third parameters.

For more sophisticated sizing, a callback may be defined. The values of widthMin and heightMin are only tested for null values.

This function also sets the border' style of the top window.

Tip

Considering a layout with 2 objects on the same row, h1 and h2:

panel = SGL_New(0, SGL_PANEL, 0, "", -1, -1);

h1 = SGL_New(panel, SGL_..., 0, "", 0, 0);

h2 = SGL_New(panel, SGL_..., 0, "", 1, 0);

SGL_ResizeInstall(h1, 0, 100, NULL);

Resizing the window will change the height of h1 to not less than 100 pixels.

If h2 is higher than h1, h1 will be vertically centered in its cell (cf. Layout and padding ).

If h1 is vertically spanned:

SGL_AlignmentSet(h1, SGL_TOP | SGL_BOTTOM);

Its minimum size is now the height of h2 if more than 100 pixels.

This principle is used in Table sample .

Such a feature can be hidden by using used for h2 a SGL_HIDDENFRAME.

Example

This call resizes an object and prevents its size from being less than 220 x 180 pixels.

SGL_ResizeInstall(hwnd, 220, 180, NULL) ;


Resize callback

TOOLS ›› Automatic resizing ››

Syntax

int resizeCB(HWND hwnd, int wOffset, int hOffset);

Parameters

hwnd | Object to be resized.
wOffset | Width change.
hOffset | Height change.

Description

This function is called when the user ends dragging the sides of the top window.

The second and third parameters contains the drag distances of these sides:

wOffset = {right side drag distance} or - {left side drag distance}

hOffset = {bottom side drag distance} or - {top side drag distance}

The function is not called if both values are null.

The return value must be null if the hwnd object has been resized (SGL_Layout is then called for the top window).

Example

Main program setting to resize hwnd with a callback function:

...

SGL_ResizeInstall(hwnd, 1, 1, resizeCB);

...

Callback function:

int resizeCB(HWND hwnd, int wOffset, int hOffset)

{

RECT rectResize; // get the previous size

GetClientRect(hwnd, &rectResize);

// new size required by the user

int widthNew = rectResize.right - rectResize.left + wOffset;

int heightNew = rectResize.bottom - rectResize.top + hOffset;

// set size with minimum values

SGL_SizeSet(hwnd, SGL_WIDTH, max(220, widthNew));

SGL_SizeSet(hwnd, SGL_HEIGHT, max(180, heightNew));

return 0 ;

}

The above code has the same effect as:

SGL_ResizeInstall(hwnd, 220, 180, NULL);


Configuration file

TOOLS ››

A default configuration is defined with the same name as the program but an .ini extension.

Functions are provided to get and change this file name, read and write strings and integer values.

Syntax

char *SGL_ProfileInit(char *fileName) ;

void SGL_ProfileStringGet(char *section, char *key, char *l, int size);

void SGL_ProfileStringSet(char *section, char *key, char *l);

int SGL_ProfileIntGet(char *section, char *key, int defValue);

int SGL_ProfileIntSet(char *section, char *key, int value, int hex);

Parameters

fileName | Full path of the configuration file. The configuration file is unchanged if fileName is a null pointer. The configuration file is set to its default value if fileName is an empty string ("").
section, key | Section and key names
l | String value
size | Size of the l buffer.
defValue | Default numeric value.
hex | Numeric format - 0: decimal, else: hexadecimal.

Description

The SGL_ProfileInit returns a pointer on the name of the configuration file. This file can be changed or reset to the default file name (name of the program with an ini extension).

The SGL_ProfileStringGet function gets a string value from the configuration file. Trailing spaces and comment (starting with ';') are removed.

The SGL_ProfileStringSet function stores a string value in the configuration file. If key is null, the section is deleted.

The SGL_ProfileIntGet function gets an integer value from the configuration file. If the key is not provided or in case of error, the default value is returned. Hexadecimal values are recognized (starting with 0X or 0x, without sign).

The SGL_ProfileIntSet function stores an integer value in the configuration file. If hex is set, data is written in hexadecimal format.

See also:

Setting colors


Cursor position

TOOLS ››

Syntax

int SGL_CursorPositionSet(HWND hwnd, POINT *pt);
int SGL_CursorPositionGet(HWND hwnd, int current, POINT *pt);

Parameters

hwnd | SGL object.
current | If not null: pt is the current cursor position. If null: pt is the position at time of the last Windows® message.
pt | Cursor position.

Description

The function SGL_CursorPositionSet sets the position of the cursor. If hwnd is a valid SGL object, pt is the cursor coordinates in the client area of this object.If hwnd is null or not a valid SGL object, pt is the screen coordinates.

The function SGL_CursorPositionGet retrieves the position of the cursor when the function is called if current is not null. If current is null, the retrieved position is the point occupied by the cursor when the last Windows® message was processed (cf. function GetMessagePos()).

These functions return 0 in case of success, or a negative value in case of error (cf. Error codes ).


Debugging tools

TOOLS ››

Debug services provide message logging on the console.

To install a console, call AllocConsole() at the start of the main (WinMain) function.


Message functions

TOOLS ›› Debugging tools ››

Syntax

void SGL_Log(int mask, char *fmt,...) ;

void SGL_Error(char *file, int line, int eresult) ;

void SGL_Fatal(char *file, int line, char *diag) ;

Parameters

mask | NONE (0), STD (1), ERR (2), FATAL (3) or QUIT (4)
fmt | Format specification followed by optional arguments (idem printf).
file | If line > 0, file is a file name (the path is not displayed) If line ≤ 0, file is handled as a simple test message.
line | Line number (ignored if ≤ 0).
eresult | Function return value (error if <0, cf. Error codes ).
diag | Diagnostic message.

Description

The main function is SGL_Log. It send a message to the console according to the mask:

NONE: no message.

STD: the message is built according to fmt.

ERR: same as STD, but the message is headed by "** ERROR **, and signaled by a beep.

QUIT: same as STD and the program asks for exit.

A CR/LF is automatically generated at the end of each message.

The console must be installed at start of the program (use AllocConsole).

If the mask is FATAL:, the console is not required, a special message box is used (cf. FatalAppExit).

The SGL_Error and SGL_Fatal functions are used by the Debug macros .

They works respectively like SGL_Log(ERR,..) and SGL_Log(FATAL, ..).


Debugging functions

TOOLS ›› Debugging tools ››

Syntax

void SGL_DebugSet(HWND hwnd, int debugLevel);
int SGL_DebugGet(HWND hwnd);

Parameters

hwnd | SGL object (can be null for global debug setting).
debugLevel | Debugging level. If null, no debug messages are generated.

Description

The debugging level is set by the SGL_DebugSet function or returned by the SGL_DebugGet function.

When set, messages are issued by SGL for the specified object if hwnd is not null. Global debug (hwnd = NULL) can be set before calling SGL_Init.

Examples

 | Log messages
SGL_DebugSet(0, 1) | Font installation, default values, object creation. Font installation messages include for each style, the name, the normal size and the heights for each size option.
SGL_DebugSet(0, 2) | Same as above plus layout operations (object size and position).
SGL_DebugSet(0, -1) | Same as above plus all Windows® messages.
SGL_DebugSet(hwnd, 1) | Windows® messages for this object.


Check macros

TOOLS ›› Debugging tools ››

Syntax

PCHECK(p) ;
CHKERR(m) ;

Parameters

p | Pointer or expression equivalent to a pointer or a handle.
m | SGL set or get function result (cf. Error codes ).

Description

In case of error (p is null, or m is <0), an error message is logged with the file name and the line number.

Message logging requires the console to be enabled.

Caution: p or m must not contain test or loop instructions.

Example

AllocConsole();

...

PCHECK(p = calloc(..));

PCHECK(h = SGL_New(..));

CHKERR(SGL_XxxSet(..));

CHKERR(e = SGL_XxxGet(..));


Performance check

TOOLS ›› Debugging tools ››

Syntax

GCLK(m) ;

Parameters

m

Code to monitor.

Description

This macro execute the code m and issues a message with its execution time.

Caution: compilation may fail if m is too big.


Other tools

TOOLS ››

Functions

double SGL_Timer(void);

Returns the elapsed time in seconds since the first call.
(This function uses the RDTSC machine instruction.)

Macros

SGL_KEY_SHIFT | Returns 1 if the [Shift] key is pressed, 0 if not.
SGL_KEY_CTRL | Returns 1 if the [Ctrl] key is pressed, 0 if not.
SGL_LBUTTON | Returns 1 if the left mouse button is pressed, 0 if not.
SGL_MBUTTON | Returns 1 if the middle mouse button (three-button mouse) is pressed, 0 if not.
SGL_RBUTTON | Returns 1 if the right mouse button is pressed, 0 if not.
NELEMS(array) | Returns the number of elements of array.

Example

A callback function can use this sequence to increments val when [Up] or [Down] keys are pressed:

switch (virtKey)

{

case VK_UP :

case VK_DOWN :

{

int inc = SGL_KEY_SHIFT ? 10 : 1 ;

val += (virtKey == VK_UP) ? inc : - inc ;

break ;

}

}


EXAMPLE PROGRAMS

Example programs illustrate the features of SGL. They are provided for x86 (32-bit) and x64 (64-bit) OSs.


Button sample

EXAMPLE PROGRAMS ››

The button sample code demonstrates how to use buttons as simple bargraph indicators.

Each bargraph consists in a button with custom drawing, and a caption (edit control at left).

A simple animation is implemented.

Files: sample_bargraph*.*

Source size: 132 lines.

See also the Slider sample which includes a scale and user input.


Message box

EXAMPLE PROGRAMS ››

The message box sample code demonstrates the following features:

  • Window size and position setting and saving for panels and buttons.
  • Setting and saving of custom colors (cf. Setting colors ).
  • Custom popup.
  • Automatic size adjustments.
  • Version info (right click on the .exe file: properties / details).

Files: sample_messagebox*.*
Source size: 183 lines.

Resizable panel

Message box


Text sample

EXAMPLE PROGRAMS ››

The text sample code demonstrates the following features:

  • Edit box operation.
  • Top window resizing with function keys.
  • Text size and style.

Files: sample_text*.*

Source size: 160 lines.


Table sample

EXAMPLE PROGRAMS ››

The table sample code demonstrates the following features:

  • Table operations:
    • header merge;
    • no right separator;
    • vertical scrolling;
    • editing (string, option selection, numeric and date - see below);
    • selection (green code).
  • Data handling independently of SGL.
  • Top window resizing (drag the bottom border).
  • Dimming.
  • Radio buttons.
  • Font loading.

String editing is straight forward: an edit popup is installed on top of the cell. The edit background color is white.

Option selection for binary choice is set or reset with a mouse click. The displayed character is got from a unicode symbol font.

Option selection for multiple choice is done by installing a popup menu below the cell. The cell background color is temporary changed to white during editing.

Date editing uses the date time popup with options:

  • calendar: click on the down arrow;
  • none option: pressing [Delete] blanks the edited cell.. The mouse wheel can be used to changed fields

The mouse wheel can be used to changed fields

Files: sample_table*.*

Source size: 368 lines.


Image sample

EXAMPLE PROGRAMS ››

The table sample code demonstrates all the features of image handling.

The image object is displayed with a caption.

A GIF file is played at its nominal speed; a multiframe TIFF file is played at 1 image per second (not available under WindowXP).

Files: sample_image*.*

Source size: 119 lines.


Slider sample

EXAMPLE PROGRAMS ››

This sample demonstrates the use of the graph object to build a slider control.

The slider can be operated:

  • Using the mouse on the slider.
  • Editing the numerical indicator:
    • Editing the value directly.
    • Using the [UP] / [Down] keys.
    • Using the [Shift][Up] / [Shift][Down] keys.

When operated, the slider 0 calls a notification function:

void notif(SLIDER_T* slider, int event);

The value of event is 0:

  • When the graphic part is clicked or during the mouse drag.
  • When the numeric value is modified.

The value is 1 when the slider is released (mouse button released or edit box closed).

The demonstrated features are:

  • The graph control with one axis.
  • Edit popup on a button.
  • Mouse dragging.
  • Creation of a new control object (sliderNew(), sliderSet(), sliderGet(), sliderCBset()).

Files: sample_slider*.*

Source size: 287 lines.


Graph sample

EXAMPLE PROGRAMS ››

The graph sample code demonstrates the following features:

  • Use of a standard Win32® menu.
  • Use of the configuration file to load and save the position of the window.
  • Table operation.
  • Graph operation with a logarithmic scale.
  • Separator operation:
    • Fixed separator between the menu and the table.
    • Moving separator between the table and the graph.
  • How to create interaction between the table and the graph.

Files: graph_table*.*

Source size: 644 lines.


OpenGL sample

EXAMPLE PROGRAMS ››

The OpenGL sample code demonstrates OpenGL with animation and resizing.

Files: sample_opengl*.*

Source size: 105 lines.