Sack Library Documentation
sack::PSI Namespace

PSI is Panther's Slick Interface. 

This is a control library which handles custom controls and regions within a form. This isn't a window manager. 


PSI_CONTROL is the primary structure that this uses. It esists as a pointer to a structure, the content of which should never be accessed by the real world. For purposes of documentation these structures (in controlstruc.h) are presented, but they are inaccessable from outside of SACK itself, and will not be provided in the SDK. 


A PSI_CONTROL can represent a 'Frame' which contains other controls. A Frame owns a PRENDERER which it uses to present its content to the display. A frame can have an outside border, and provides the ability to click on the border and resize the form. The frame can use a custom image, which will be automatically portioned up and used as corner pieces, edge pieces, and may automatically set the default background color for forms. The frame draws directly on the Image from the PRENDERER, and all controls know only their image. Controls are based on sub-images on the frame's displayed image, so when they draw they are drawing directly on the buffer targeted to the display. The image library prohibits any operations that go outside the bounds of a sub-image; though, the user can request the color buffer pointer from an image, and may draw directly anywhere on that surface. 


Controls are implemented as a pair of sub-images on the color buffer of the renderer. The pair is the image containing the border of the control, and a sub-image inside that representing the drawable area of a control. When created, controls are always sized including their frame, this allow positioning controls inside a frame without regard to how much extra space might have been added. The size of the Frame control outside, is handled differently, and is created with the size of the inside of the control. The area of the render surface is expanded outside this. There are BorderOptionTypes that can control whether the border on the frame is handled as an expansion or not. 


Controls are all drawn using an internal table of colors which can be index using ControlColorTypes with SetBaseColor and GetBaseColor


If the fancy border frame image is used for a control, then the color of the center pixel is set into the NORMAL color index. 


What else can I say about controls... 


Any control can contain any other control, but there is a specific container type Frame that is commonly used for dialogs. The top level control can display on a renderer. If a sub-control is told to show, then it is divorced from and opened in a new popup renderer.

Control registration was done original by filling in a CONTROL_REGISTRATION structure, and passing that structure to PSI to register. This method is still available, and is certainly more straight forward method of use, but it's not the easier method or the current method. 

Currently, a registration structure is still used, but only the first few elements are actually filled out, the functions to handle a control's events are declared by fancy macros. 

This relies on the deadstart features of compiler working, but there are fewer places to have to remember to make changes, and controls are much more straight forward to implement, and extend as required, without necessarily requiring everything to be done all at once. Methods registered this way MUST be static, otherwise compiler errors will result; they MUST have the correct return type for the method specified, and they must have the correct parameters. Examples of each method supported will be provided with each method's documentation. These are nasty macros that insert a bit of magic code between the 'static int' and the parameters specified. The names of the parameter values to the callback are up to the user, but the types must match. This is a very exact method, that cannot be circumvented using bad typecasting.

This is a custom control that shows red or green.

struct control_data
    // declare some data that you want to have associated with your control.
    CDATA color;
    _32 last_buttons; // used to track when a click happens
EasyRegisterControl( WIDE( "simple" ), sizeof( struct ball_timer_data ) );
// define the function called when a new 'simple' control is created.
static int OnCreateCommon( WIDE( "simple" ) )( PSI_CONTROL pc )
    MyValidatedControlData( struct control_data*, my_data, pc );
    if( my_data )
        // assign a color to start
        my_data->color = BASE_COLOR_RED;
        return 1;
    return 0;
// define a method to draw the control
static int OnDrawCommon( WIDE( "simple" ) )( PSI_CONTROL pc )
    MyValidatedControlData( struct control_data*, my_data, pc );
    if( my_data )
        Image image = GetControlSufrace( pc );
        BlatColor( image, my_data->color );
        return 1;  // return that the draw happened.
    return 0;  // return no draw - prevents update.
// define a handler when the simple control is clicked.
static int OnMouseCommon( WIDE( "simple" ) )( PSI_CONTROL pc, S_32 x, S_32 y, _32 b )
    MyValidatedControlData( struct control_data*, my_data, pc );
    // this checks to see if any mouse button goes down
    if( MAKE_NEWBUTTON( b, my_data->last_buttons ) )
        if( my_data->color == BASE_COLOR_RED )
            my_data->color = BASE_COLOR_GREEN;
            my_data->color = BASE_COLOR_RED;
        // tell the control to update.
        SmudgeCommon( pc );
    // save this button state as the prior button state for future checks
    my_data->last_buttons = b;
This is for internal organization, events and routines the mouse uses and features it adds to the PSI control... like issuing auto updates on unlock... well... it's internal anyhow 
Buttons. Clickable buttons, Radio buttons and checkboxes. 
A colorwell is a indented control that contains a color. Often, if clicked, the color well will show the palette color selector to allow the color to be changed. The color may be a full alpha representation. When drawn in the well, I think the control itself draws the color with 255 alpha.

Color well controls are "Color Well"
Shade well controls are "Shade Well"
Palette Shader grid is "Color Matrix" 
Edit Control. This is a control that allows for text input. It also works as a drop file acceptor, and the name of the file or folder being dropped on it is entered as text
Font Control - Really this is all about a font picker. The data used to create the font to show can be retreived to be saved for later recreation. 
This namespace is not completely implemented (if at all). At the start it looked good, and a lot of it was a copy-insert-modify of the existing functions, it wasn't that much work to lay out. But then looking at the content of the interface, and realizing that each individual registered component needed to have custom methods associated with it, it will be a different sort of project to support dynamic remote controls... so we look at how WPF did it, and that is a solution, I suppose. 
ListBox Control 
This is namespace sack::PSI::old_constants. 
methods to edit frames at runtime. 
This is a scrollbar type control. It's got an up/down or left/right arrow, and a thumb that can be clicked on. Used by the listbox control. 
Misc Controls (and widgets
Slider Control - this is a generic control that has a minimum value, and a maximum value, and a clickable knob that can select a value inbetween.
the maximum value may be less than the minimum value, the current selected value will be between these.
A horizontal slider, the value for minimum is on the left. A vertical slider, the value for minimum is on the bottom. 
Static Text - this control just shows simple text on a dialog. Non selectable. 
This is actually a load/save namespace. These functions are used to save and load frames and their layouts to and from XML. 
The following table lists functions in this documentation. 
The following table lists structs, records, enums in this documentation. 
The following table lists types in this documentation. 
The following table lists variables in this documentation. 
The following table lists macros in this documentation. 
This is function sack::PSI::_SQLPromptINIValue. 
This is function sack::PSI::AddCommonAcceptDroppedFiles. 
This is function sack::PSI::AddCommonButtons. 
This is function sack::PSI::AddCommonDraw. 
This is function sack::PSI::AddCommonKey. 
This is function sack::PSI::AddCommonMouse. 
This is function sack::PSI::AdoptCommon. 
This is function sack::PSI::AdoptCommonEx. 
This is function sack::PSI::AlignBaseToWindows. 
Attach a frame to a renderer. Not sure which is sized to which if they are not the same size... probably the control is sized to the display. 
This is function sack::PSI::CaptionHeight. 
perhaps give a callback for within the loop? 
perhaps give a callback for within the loop? 
a frame in edit mode, once edit mode done, continue 
This is function sack::PSI::ControlExtraData. 
This is function sack::PSI::ControlType. 
result with an image pointer, will sue the image passed as prior_image to copy into (resizing if nessecary), if prior_image is NULL then a new Image will be returned. If the surface has not been marked as parent_cleaned, then NULL results, as no Original image is available. The image passed as a destination for the surface copy is not released, it is resized, and copied into. THe result may still be NULL the image will still be the last valid copy of the surface. 
This is function sack::PSI::CopyOriginalSurfaceEx. 
This is function sack::PSI::CreateFrame. 
internal routine now exposed... results in a frame from a given renderer - a more stable solution than MKPFRAME which would require MUCH work to implement all checks everywhere... 
This is function sack::PSI::DestroyCommonEx. 
This is function sack::PSI::DestroyControlEx. 
This is function sack::PSI::DetachFrameFromRenderer. 
This is function sack::PSI::DisplayFrame. 
This is function sack::PSI::DisplayFrameOn. 
This is function sack::PSI::DisplayFrameOver. 
This is function sack::PSI::DisplayFrameOverOn. 
stacks the physical display behind this other frame... 
please fill out the required forms, submit them once and only once. see form definition above, be sure to sign them. in the future (after now), expansion can be handled by observing the size of the registration entry. at sizeof(registration) - 4 is always the type ID result of this registration... 
each control has itself a draw border method. void CPROC DrawBorder( PTRSZVAL psv, PSI_CONTROL pc ); check box uses these... ??? 
This is function sack::PSI::DrawThinFrameImage. 
This is function sack::PSI::DrawThinFrameInverted. 
This is function sack::PSI::DrawThinFrameInvertedImage. 
This is function sack::PSI::DrawThinnerFrame. 
Draw a 2 pixel frame around a control. 
This is function sack::PSI::DrawThinnerFrameInverted. 
This is function sack::PSI::DrawThinnerFrameInvertedImage. 
This is function sack::PSI::DumpFrameContents. 
This is function sack::PSI::EnableCommonUpdates. 
This is function sack::PSI::EnableControl. 
1) causes all updates to be done in video thread, otherwise selecting opengl context fails. 2) ... 
This is function sack::PSI::FixFrameFocus. 
results in the total width (left and right) of the frame 
results in left offset of the surface within the frame... 
results in the total height (top and bottom) of frame (and caption) 
results in top offset of the surface within the frame... 
This is function sack::PSI::GetBaseColor. 
This is function sack::PSI::GetCommonFontEx. 
Generic control functions 
This is function sack::PSI::GetCommonTextEx. 
This is function sack::PSI::GetControl. 
This is function sack::PSI::GetControlColor. 
This is function sack::PSI::GetControlID. 
depricated PSI_PROC( PSI_CONTROL, CreateControl)( PSI_CONTROL pFrame , int nID , int x, int y , int w, int h , int BorderType , int extra ); 
This is function sack::PSI::GetControlTypeName. 
This is function sack::PSI::GetCurrentDisplaySurface. 
This is function sack::PSI::GetFrame. 
This is function sack::PSI::GetFrameFromRenderer. 
This is function sack::PSI::GetFramePosition. 
any control on a frame may be passed, and the top level 
This is function sack::PSI::GetFrameSize. 
This is function sack::PSI::GetMyInterface. 
This is function sack::PSI::GetNearControl. 
This is function sack::PSI::GetPhysicalCoordinate. 
This is function sack::PSI::HideCommon. 
This is function sack::PSI::HideFrame. 
This is function sack::PSI::InitCommonButton. 
This is function sack::PSI::IntelligentFrameUpdateAllDirtyControls. 
This is function sack::PSI::IsControlEnabled. 
This is function sack::PSI::IsControlFocused. 
This is function sack::PSI::IsControlHidden. 
This is function sack::PSI::LoadFrame. 
This is function sack::PSI::LoadFrameFromFile. 
This is function sack::PSI::LoadFrameFromMemory. 
This is function sack::PSI::MakeCaptionedControl. 
This is function sack::PSI::MakeControl. 
init is called with an extra parameter on the stack works as long as we guarantee C stack call basis... the register_control structure allows this override. 
This is function sack::PSI::MakeNamedCaptionedControl. 
This is function sack::PSI::MakeNamedControl. 
MakePrivateControl passes BORDER_NO_EXTRA_INIT... 
MakePrivateControl passes BORDER_NO_EXTRA_INIT... 
This is function sack::PSI::MoveCommon. 
This is function sack::PSI::MoveCommonRel. 
This is function sack::PSI::MoveSizeCommon. 
This is function sack::PSI::MoveSizeCommonRel. 
This is function sack::PSI::OpenPhysicalDevice. 
This is function sack::PSI::OrphanCommon. 
This is function sack::PSI::OrphanCommonEx. 
bOwn sets the ownership of mouse events to a control, where it remains until released. Some other control has no way to steal it. 
This is function sack::PSI::ProcessControlMessages. 
This is function sack::PSI::PSI_OpenFile. 
This is function sack::PSI::RegisterResource. 
restore background restores the prior background of the control so that semi-opaque controls can draw over the correct surface. 
This is function sack::PSI::RevealCommonEx. 
This is function sack::PSI::SaveFrame. 
use scale_x and scale_y to scale a, b, results are done in a, b 
This is function sack::PSI::SetBaseColor. 
This is function sack::PSI::SetCommonAcceptDroppedFiles. 
Update the border type of a control. See BorderOptionTypes 
This is function sack::PSI::SetCommonButtons. 
This is function sack::PSI::SetCommonDraw. 
set focus to this control, it's container which needs to be updated is discoverable from the control itself. 
This is function sack::PSI::SetCommonFont. 
This is function sack::PSI::SetCommonKey. 
This is function sack::PSI::SetCommonLoad. 
This is function sack::PSI::SetCommonMouse. 
This is function sack::PSI::SetCommonSave. 
setting scale of this control immediately scales all contained controls, but the control itself remains at it's current size. 
This is function sack::PSI::SetCommonText. 
this allows the application to toggle the transparency characteristic of a control. If a control is transparent, then it behaves automatically as one should using CopyOriginalSurface and restoring that surface before doing the draw. The application does not need to concern itself with restoring the prior image, but it must also assume that the entire surface has been destroyed, and partial updates are not possible. 
This is function sack::PSI::SetCommonUserData. 
This is function sack::PSI::SetControlColor. 
This is function sack::PSI::SetControlID. 
This is function sack::PSI::SetControlImageInterface. 
Initialize colors to current windows colors 
This is function sack::PSI::SetControlText. 
update to current border type drawing. 
This is function sack::PSI::SetFrameInit. 
This is function sack::PSI::SetFrameText. 
This is function sack::PSI::SetNoFocus. 
This is function sack::PSI::SetUpdateRegionEx. 
Misc Controls (and widgets
result is the address of a user buffer to read into, reslen is the size of that buffer. question is put above the question... pAbove is the window which this one should be placed above (lock-stacked) 
This is function sack::PSI::SizeCommon. 
This is function sack::PSI::SizeCommonRel. 
This is function sack::PSI::SmudgeCommonAreaEx. 
This is function sack::PSI::SmudgeCommonEx. 
This is function sack::PSI::SmudgeSomeControls. 
This is function sack::PSI::TryLoadingFrameImage. 
PSI_PROC void SetControlKey( PSI_CONTROL pc, void (*KeyMethod)( PSI_CONTROL pc, int key ) ); 
else define UpdateCommon(pc) UpdateCommonEx(pc,TRUE DBG_SRC) endif define UpdateControlEx(pc,draw) UpdateCommonEx( (PSI_CONTROL)pc, draw ) define UpdateFrameEx(pc,draw) UpdateCommonEx( (PSI_CONTROL)pc, draw ) 
do the draw to the display... 
output to the physical surface the rectangle of the control's surface specified. 
This is function sack::PSI::VMakeCaptionedControl. 
This is function sack::PSI::VMakeControl. 
This is macro sack::PSI::AdoptControl. 
This is macro sack::PSI::AdoptControlEx. 
This is macro sack::PSI::AdoptFrame. 
This is macro sack::PSI::ARG. 
, PTRSZVAL nID, ... ); 
This is macro sack::PSI::COMMON_BUTTON_HEIGHT. 
This is macro sack::PSI::COMMON_BUTTON_PAD. 
This is macro sack::PSI::COMMON_BUTTON_WIDTH. 
This is macro sack::PSI::CONTROL_INIT. 
This is macro sack::PSI::CONTROL_INIT_EX. 
, PTRSZVAL nID, ... ); 
default_width, default_height, 
This is macro sack::PSI::CONTROL_PROC_DEF_EX. 
This is macro sack::PSI::CONTROL_PROPERTIES. 
This is macro sack::PSI::CONTROL_PROPERTIES_DONE. 
PSI_PROC( int, DoRegisterSubcontrol )( PSUBCONTROL_REGISTRATION pcr ); 
This is macro sack::PSI::CopyOriginalSurface. 
This is macro sack::PSI::DeclMethod. 
This is macro sack::PSI::DeclSingleMethod. 
This is macro sack::PSI::DestroyCommon. 
This is macro sack::PSI::DestroyControl. 
PSI_PROC( void, DestroyFrameEx)( PSI_CONTROL pf DBG_PASS ); 
This is macro sack::PSI::DoRegisterControl. 
This is macro sack::PSI::EasyRegisterControl. 
This is macro sack::PSI::EasyRegisterControlEx. 
This is macro sack::PSI::EasyRegisterControlWithBorder. 
This is macro sack::PSI::EasyRegisterControlWithBorderEx. 
This is macro sack::PSI::EasyRegisterResource. 
This is macro sack::PSI::EasyRegisterResourceRange. 
This is macro sack::PSI::EnableControlUpdates. 
This is macro sack::PSI::EnableFrameUpdates. 
This is macro sack::PSI::FFF_BACKWARD. 
This is macro sack::PSI::FFF_FORWARD. 
dir 0 here only... in case we removed ourself from focusable dir -1 go backwards dir 1 go forwards 
This is macro sack::PSI::FP_ARG. 
This is macro sack::PSI::GetCommonFont. 
This is macro sack::PSI::GetControlText. 
This is macro sack::PSI::GetControlTextEx. 
This is macro sack::PSI::GetFrame. 
This is macro sack::PSI::GetFrameFont. 
This is macro sack::PSI::GetFrameSurface. 
This is macro sack::PSI::GetFrameText. 
This is macro sack::PSI::GetFrameUserData. 
This is macro sack::PSI::IDCANCEL. 
This is macro sack::PSI::IDOK. 
right now - all these methods evolved from a void function, therefore, this needs to invoke all key/draw methods not just until 'processed' 
This is macro sack::PSI::InvokeMethod. 
This is macro sack::PSI::InvokeResultingMethod. 
This is macro sack::PSI::InvokeSingleMethod. 
This is macro sack::PSI::LinePaste. 
This is macro sack::PSI::LinePaste2. 
this was never implemented. 
PSI_PROC( int, RegisterControlProcName )( CTEXTSTR name, POINTER MakeProc, POINTER LoadProc ); 
This is macro sack::PSI::MoveControl. 
This is macro sack::PSI::MoveControlRel. 
This is macro sack::PSI::MoveFrame. 
This is macro sack::PSI::MoveFrameRel. 
This is macro sack::PSI::MoveSizeControl. 
This is macro sack::PSI::MoveSizeControlRel. 
This is macro sack::PSI::MoveSizeFrame. 
This is macro sack::PSI::MoveSizeFrameRel. 
This is macro sack::PSI::MyControlID. 
This is macro sack::PSI::MyControlIDEx. 
This is macro sack::PSI::MyValidatedControlData. 
This is macro sack::PSI::MyValidatedControlDataEx. 
bFocused will be true if control gains focus if !bFocused, control is losing focus.
Return type is actually void now. The below notes were for before.

  1. with current focus is told it will lose focus (!bFocus).
    1. control may allow focus loss (return !FALSE) (goto 3)
    2. control may reject focus loss, which will force it to remain (return FALSE)
  2. current focus reference of the container is cleared
  3. newly focused control is told it now has focus.
    1. it may accept the focus (return TRUE/!FALSE)
    2. it may reject the focus - and the focus will be left... more 
This is the first event a control will receive. When it is created with MakeNamedControl, et al. this event will be called. It allows the control to initialize its personal data to something. It can be considered a constructor of the control. 
Event when a control is being destroyed. Allows a control to destroy any internal resources it may have associated with the control. 
Event given to a control when it needs to draw. 
The frame edit mode has begun, and controls are given an opportunity to make life good for themselves and those around them - such as sheet controls displaying sheets separately. 
When a frame's edit phase ends, controls are notified with this event. 
This event is called when a control is hidden. A control that is now hidden might do something like stop update timers, stop reading input information, or whatever else the control is doing that affects its display. 
Controls may register a keyboard event procedure. This will receive notifications about what key is hit. Using mouse keys are impractical, because you would have to test every key for a new up/down status and figure out which key it was that went up and down and whether you should so something. A Simple test for like 'is this the space bar' might work as a mouse event processing MK_OBUTTON events. 
move_starting is TRUE when the position starts changing and is false when the change is done... this allows a critical section to be entered and left around the resize. 
User event callback called when a mouse event happens over a control, unless the control has claimed the mouse, in which case the mouse may not be over the control. X and Y are signed coordinates, if OwnMouse is called, then mouse events outside of the control may be trapped. buttons is a combination of ButtonFlags. If there is no keyboard event, keys will also be given to mouse event as button MK_OBUTTON. 
This event callback is called when a control's position changes. Usually only happens on the outer parent frame. 
return a frame page to the caller for display. 
on cancel return void ( your_control, the sheet your resulted to get_property_page 
some controls may change their appearance and drawing characteristics based on having their properties edited. This is done after either read or abort is done, also after the container dialog is destroyed, thereby indicating that any reference to the frame you created is now gone, unless you did magic. 
on okay - read your information for ( your control, from the frame ) 
Event given to the control when it is shown. Some controls assign new content to themselves if they are now able to be shown. 
User event that is triggered when the size of a control changes. 
This is macro sack::PSI::OrphanControl. 
This is macro sack::PSI::OrphanControlEx. 
This is macro sack::PSI::OrphanFrame. 
typedef POINTER PSI_CONTROL; any remaining code should reference PSI_CONTROL 
This is macro sack::PSI::PCONTROL. 
This is macro sack::PSI::PROP_HEIGHT. 
This is macro sack::PSI::PROP_PAD. 
size of the property dialog page... 
This is macro sack::PSI::PSI_PROC. 
This is macro sack::PSI::PSI_ROOT_REGISTRY. 
this was never implemented. 
This is macro sack::PSI::RegisterControl. 
This is macro sack::PSI::RegisterFrame. 
this was never implemented. 
This is macro sack::PSI::RevealCommon. 
Scroll Control 
This is macro sack::PSI::SCROLL_VERITCAL. 
This is macro sack::PSI::SetCommonBorder. 
This is macro sack::PSI::SetControlData. 
This is macro sack::PSI::SetControlLoad. 
This is macro sack::PSI::SetControlSave. 
This is macro sack::PSI::SetFrameFont. 
This is macro sack::PSI::SetFrameLoad. 
This is macro sack::PSI::SetFrameSave. 
This is macro sack::PSI::SetFrameUserData. 
This is macro sack::PSI::SetUpdateRegion. 
This is macro sack::PSI::SimpleRegisterAppResource. 
assuming one uses a 
This is macro sack::PSI::SizeControl. 
This is macro sack::PSI::SizeControlRel. 
This is macro sack::PSI::SizeFrame. 
This is macro sack::PSI::SizeFrameRel. 
This is macro sack::PSI::SmudgeCommon. 
This is macro sack::PSI::SmudgeCommonArea. 
This is macro sack::PSI::SYMVAL. 
these IDs are used to designate default control IDs for buttons... 
ifdef SOURCE_PSI2 
This is macro sack::PSI::UpdateControl. 
This is macro sack::PSI::UpdateFrame. 
This is macro sack::PSI::ValidatedControlData. 
This enumeration defines flags that can be used to specify the border of controls. 
This is record sack::PSI::common_button_data. 
these are the indexes for base color 
Control Registration structure. Obsolete method of registering a control and the methods of a control. Internally these methods are just registered as they would with the procedure registration methods 
This is record sack::PSI::edit_state_tag. 
define ControlType(pc) ((pc)->nType) 
This is record sack::PSI::physical_device_interface. 
This is type sack::PSI::COMMON_BUTTON_DATA. 
This is type sack::PSI::PCOMMON_BUTTON_DATA. 
Internal event callback definition. This is called when the control needs to draw itself. This happens when SmudgeCommon is called on the control or on a parent of the control. 
Internal event callback definition. A key has been pressed. 
Internal event callback definition. A mouse event is happening over the control. 
Internal event callback definition. A file has been dropped on the control. 
Internal event callback definition.
A control has been added to this control. 
Internal event callback definition. Triggered when edit on a frame is started. 
Internal event callback definition. The caption of a control is changing (Edit control uses this). 
Internal event callback definition. The focus of a control is changing. 
Internal event callback definition. Destruction of the control is in progress. Allow control to free internal resources. 
Internal event callback definition. Draw border, this usually pointing to an internal function, but may be used for a control to draw a custom border. 
Internal event callback definition. Ending control editing. 
Internal event callback definition. Called when the control's position (x,y) is changing. 
Internal event callback definition. Called when a control is being resized. Width or height changing. 
Internal defintion of the callback to invoke when a property sheet is requested to be applied when editing the control. 
This is type sack::PSI::CONTROL_REGISTRATION. 
Control Init Proc is called each time a control is created a control may be created either with a 'make' routine or by loading a dialog resource. 
Tells a control that the edit process is done with the property sheet requested.
Internal event callback definition. 
This is type sack::PSI::EDIT_STATE. 
Internal event callback definition. After creation, an initializer is available to call on controls to pass arguments to. This is more useful for loading from an XML file where the control may have specified extra data. 
Internal event callback definition. Request an additional page to add to the control property edit dialog. 
This is type sack::PSI::PEDIT_STATE. 
This is type sack::PSI::PHYSICAL_DEVICE. 
This is type sack::PSI::PPHYSICAL_DEVICE. 
A handle to a PSI control or frame. The User's data is stored as the first member of this structure, so de-referencing the pointer twice gets the user data. All PSI functions work against PSI_CONTROL. Once upon a time this was just PSI_CONTROL, and so the methods for registering to handle events on the control still reference 'Common'. 
This is variable sack::PSI::DefaultColors. 
Created with a commercial version of Doc-O-Matic. In order to make this message disappear you need to register this software. If you have problems registering this software please contact us at
Copyright (c) 2000+. All rights reserved.
What do you think about this topic? Send feedback!