This tutorial demonstrates more widgets and useful features.

if (!require ("WindowsSupport"))
error ("Could not load Windows support file");
class MonitorWindow
{
menu_actions;
menu_items;
}
method MonitorWindow.constructor ()
{
local win = new GWindow();
local rect = CreateRect(10, 10, 400, 400);
local b, dt, txt;
win.Create (0, rect, "Monitor", WS_OVERLAPPEDWINDOW, 0);
// This bit of code makes the window translucent.
// win.ModifyStyleEx (0, WS_EX_LAYERED);
// SetLayeredWindowAttributes (win.GetHwnd(), 0, 150, LWA_ALPHA);
win.SetBackground (0, GetSysColor (COLOR_3DFACE), 0);
win.SetChildBackground (0, GetSysColor (COLOR_3DFACE), 0);
win.MessageHandler (WM_DESTROY, `destroy (@self));
txt = win.CreateControl (GStatic, 20, 5, 350, 20,
"Start DataSim to see live data here");
txt.SetForeground (0, 0, 0xff0000);
txt.SetFontEx (20, 8, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "Times");
win.onChange (#$DataSim:DataSim.Sine,
`(@txt).SetWindowText(format ("%a = %.4f", this, value)));
b0 = win.CreateControl (GGroupBox, 20, 30, 350, 40,
"Radio Buttons");
win.AddControlResizeFlags (b0.GetDlgCtrlID(), DLSZ_SIZE_X);
b = b0.CreateControl (GRadioButton, 10, 10, 150, 25,
"UpdateFrequency = 1");
b2 = b0.CreateControl (GRadioButton, 180, 10, 150, 25,
"UpdateFrequency = 10");
b0.AddControlResizeFlags (b2.GetDlgCtrlID(), DLSZ_MOVE_X);
b0.CommandHandler (BN_CLICKED, b.GetDlgCtrlID(),
`((@b0).IsDlgButtonChecked((@b).GetDlgCtrlID()) == 0 ? nil :
$DataSim:DataSim.UpdateFrequency = 1));
b0.CommandHandler (BN_CLICKED, b2.GetDlgCtrlID(),
`((@b0).IsDlgButtonChecked((@b2).GetDlgCtrlID()) == 0 ? nil :
$DataSim:DataSim.UpdateFrequency = 10));
// AddButtonToggle (b0, b, #$DataSim:DataSim.UpdateFrequency, 1, 10,
// "Set update rate = 10",
// "Set update rate = 1");
dt = win.CreateControl (GDateTimePickerCtrl, 20, 80, 150, 25, "Picker");
dt.SetBackground (0, GetSysColor (COLOR_WINDOW), 0);
// Make a field for entering Gamma commands
txt = win.CreateControl (GEdit, 20, 115, 350, 20, "command");
txt.MessageHandler (WM_CHAR, `SubmitEval ((@txt)));
txt.SetBackground (0, GetSysColor (COLOR_WINDOW), 0);
win.AddControlResizeFlags (txt.GetDlgCtrlID(), DLSZ_SIZE_X);
txt.SetWindowText ("Type gamma command here");
// Make a tab control.
tab = win.CreateControl (GTabCtrl, 20, 150, 350, 200, "tabs");
tab.ModifyStyle (TCS_TABS | TCS_RAGGEDRIGHT, TCS_FOCUSONBUTTONDOWN | TCS_FIXEDWIDTH);
tab.SetChildBackground (0, 0xc0ffff, 0);
tab.AddWindow (0, "Waveforms", CreateDialog1 (tab.GetHwnd(), ""));
tab.AddWindow (1, "Parameters", CreateDialog2 (tab.GetHwnd(), ""));
tab.AddWindow (2, "List", CreateDialog3 (tab.GetHwnd(), ""));
win.AddControlResizeFlags (tab.GetDlgCtrlID(), DLSZ_SIZE_X | DLSZ_SIZE_Y);
win.NotifyHandler (TCN_SELCHANGE, tab.GetDlgCtrlID(),
`(@tab).SelChange());
tab.SetCurSel (0);
// if (get_tray_menu() == 0)
// after (2, `(@self).AddMenus());
// else
.AddMenus();
win.ShowWindow (SW_SHOW);
}
method MonitorWindow.destructor ()
{
local id, count, traymenu, i, item;
try
{
with x in .menu_actions do
remove_menu_action (car(x), cdr(x));
}
catch
{
princ ("Error: ", _last_error_, "\n");
print_stack();
}
with x in .menu_items do
{
try
{
id = car(x);
traymenu = get_tray_menu();
count = GetMenuItemCount (traymenu);
item = new MENUITEMINFO;
item.cbSize = 48;
item.fMask = MIIM_ID | MIIM_SUBMENU;
if (cdr(x)) // id is a submenu hmenu
{
for (i=0; i<count; i++)
{
if (GetMenuItemInfo (traymenu, i, 1, item) != 0
&& item.hSubMenu == id)
DeleteMenu (traymenu, i, MF_BYPOSITION);
}
}
else // id is a menu item command id
{
for (i=0; i<count; i++)
{
if (GetMenuItemInfo (traymenu, i, 1, item) != 0
&& item.wID == id)
DeleteMenu (traymenu, i, MF_BYPOSITION);
}
}
}
catch
{
princ ("Error: ", _last_error_, "\n");
print_stack();
}
}
}
function Typing (txt)
{
local str = txt.GetWindowText();
princ (str, "\n");
}
function SubmitEval (txt)
{
if (wParam == VK_RETURN)
{
local str = txt.GetWindowText();
princ (str, "\n");
local x = eval_string (string(str,";"), t);
princ (" ");
pretty_print (x);
terpri();
// show_log();
}
nil;
}
/* =============== Add menu items to the tray menu =========== */
MenuItemID := 10000;
method GFileDialog.OnSelChange ()
{
local buf = make_buffer(256);
.GetFilePath (buf, 256);
princ ("Selection changed: ", buffer_to_string(buf), "\n");
}
method MonitorWindow.SelectTrayMenuItem (id)
{
local win = new GColorDialog();
princ ("HWND: ", win.m_hWnd, " = ", win.GetHwnd(), "\n");
local result = win.DoModal(0);
if (result == 1)
{
princ ("You chose the color: ", hex(win.GetColor()), "\n");
}
}
method MonitorWindow.AddSubMenu (parent, pos, label)
{
local submenu = CreatePopupMenu();
InsertMenu (traymenu, pos, MF_BYPOSITION | MF_POPUP,
submenu, label);
.menu_items = cons (cons (submenu, t), .menu_items);
submenu;
}
method MonitorWindow.AddMenuItem (parent, pos, label, code)
{
local info = new MENUITEMINFO();
info.cbSize = 48;
info.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_ID;
info.fType = MFT_STRING;
info.wID = ++MenuItemID;
info.dwTypeData = label;
InsertMenuItem (parent, pos, 1, info);
local action = add_menu_action (MenuItemID, code);
.menu_actions = cons (action, .menu_actions);
}
method MonitorWindow.AddMenus ()
{
local traymenu = get_tray_menu ();
if (traymenu != 0)
{
local submenu = .AddSubMenu (traymenu, 5, "Monitor Functions");
.AddMenuItem (submenu, -1, "Select Color",
`(@self).SelectTrayMenuItem (@MenuItemID+1));
.AddMenuItem (submenu, -1, "Select File",
`new GFileDialog (1).DoModal(0));
.AddMenuItem (submenu, -1, "Select Folder",
`new GFolderDialog ().DoModal(0));
}
else
{
}
}
/* ==== A dialog within the first tab in the tab control ==== */
class Font
{
m_hFont;
}
method Font.Create(nHeight, // height of font
nWidth, // average character width
nEscapement, // angle of escapement
nOrientation, // base-line orientation angle
fnWeight, // font weight
fdwItalic, // italic attribute option
fdwUnderline, // underline attribute option
fdwStrikeOut, // strikeout attribute option
fdwCharSet, // character set identifier
fdwOutputPrecision, // output precision
fdwClipPrecision, // clipping precision
fdwQuality, // output quality
fdwPitchAndFamily, // pitch and family
lpszFace) // typeface name
{
m_hFont = CreateFontA (nHeight,
nWidth,
nEscapement,
nOrientation,
fnWeight,
fdwItalic,
fdwUnderline,
fdwStrikeOut,
fdwCharSet,
fdwOutputPrecision,
fdwClipPrecision,
fdwQuality,
fdwPitchAndFamily,
lpszFace);
}
method Font.destructor()
{
// if (m_hFont)
// DeleteObject (m_hFont);
}
class Dialog1 GWindow
{
win;
stHeader;
stSine;
stRamp;
stTriangle;
stSquare;
}
function CreateDialog1 (parent, str)
{
local win = new Dialog1();
win.Init (parent, str);
win;
}
method Dialog1.Init (parent, str)
{
local rect = CreateRect(10, 10, 10, 10);
local row = 5, drow = 30, w = 290, h = 20;
.win = self;
// .SetBackground(0, 0x00ff00, 0);
// .SetChildBackground(0, 0x00ff00, 0);
.win.Create (parent, rect, "tab", WS_CHILDWINDOW, 0);
.stSine = .win.CreateControl (GStatic, 5, row, w, h, "Sine");
.win.onChange (#$DataSim:DataSim.Sine, `update (@.stSine, this));
update (.stSine, #$DataSim:DataSim.Sine);
.stRamp = .win.CreateControl (GStatic, 5, row += drow, w, h, "Ramp");
.win.onChange (#$DataSim:DataSim.Ramp, `update (@.stRamp, this));
update (.stRamp, #$DataSim:DataSim.Ramp);
.stTriangle = .win.CreateControl (GStatic, 5, row += drow, w,
h, "Triangle");
.win.onChange (#$DataSim:DataSim.Triangle, `update (@.stTriangle, this));
update (.stTriangle, #$DataSim:DataSim.Triangle);
.stSquare = .win.CreateControl (GStatic, 5, row += drow, w, h, "Square");
.win.onChange (#$DataSim:DataSim.Square, `update (@.stSquare, this));
update (.stSquare, #$DataSim:DataSim.Square);
link = .win.CreateControl (GHyperLink, 5, row += drow, w, h,
"http://www.cogent.ca");
link.SetHyperLink ("http://www.cogent.ca");
link.SetLabel ("Visit Cogent's web page");
link.SetLinkFont (GetStockObject (DEFAULT_GUI_FONT));
link.ShowWindow (SW_SHOW);
.win.onChange (#$DataSim:DataSim.Square,
`progn {
if (value < 0)
{
(@win).SetBackground (0, 0xc0ffff, 0);
(@win).SetChildBackground (0, 0xc0ffff, 0);
}
else
{
(@win).SetBackground (0, 0xffffff, 0);
(@win).SetChildBackground (0, 0xffffff, 0);
}
(@win).Invalidate();
});
win;
}
/* ==== A dialog within the second tab in the tab control ==== */
class Dialog2 GWindow
{
win;
stHeader;
stAmplitude;
stFrequency;
stOffset;
stUpdateFrequency;
}
function CreateDialog2 (parent, str)
{
local win = new Dialog2();
win.Init (parent, str);
win;
}
method Dialog2.Init (parent, str)
{
local rect = CreateRect(10, 10, 10, 10);
local row = 5, drow = 30, w = 290, h = 20;
.win = self;
// .win.SetBackground (0, GetSysColor (COLOR_3DFACE), 0);
//.win.SetChildBackground (0, GetSysColor (COLOR_3DFACE), 0);
.win.Create (parent, rect, "tab", WS_CHILDWINDOW, 0);
.stAmplitude = .win.CreateControl (GStatic, 5, row,
w, h, "Amplitude");
.win.onChange (#$DataSim:DataSim.Amplitude, `update(@.stAmplitude, this));
update (.stAmplitude, #$DataSim:DataSim.Amplitude);
.stFrequency = .win.CreateControl (GStatic, 5, row += drow,
w, h, "Frequency");
.win.onChange (#$DataSim:DataSim.Frequency, `update(@.stFrequency, this));
update (.stFrequency, #$DataSim:DataSim.Frequency);
.stOffset = .win.CreateControl (GStatic, 5, row += drow, w,
h, "Offset");
.win.onChange (#$DataSim:DataSim.Offset, `update(@.stOffset, this));
update (.stOffset, #$DataSim:DataSim.Offset);
.stUpdateFrequency = .win.CreateControl (GStatic, 5, row += drow,
w, h, "UpdateFrequency");
.win.onChange (#$DataSim:DataSim.UpdateFrequency,
`update(@.stUpdateFrequency, this));
update (.stUpdateFrequency, #$DataSim:DataSim.UpdateFrequency);
local tb = .win.CreateControl (GTrackBarCtrl, 5, row += drow,
w, h, "FreqBar");
tb.SetRange (0, 20, 1);
tb.ModifyStyle (0, TBS_AUTOTICKS, 0);
tb.SetTicFreq (2);
.win.MessageHandler (WM_HSCROLL, `(@self).Scrolled(@tb));
.win.onChange (#$DataSim:DataSim.UpdateFrequency,
`(@tb).SetPos (value));
if (!undefined_p($DataSim:DataSim.UpdateFrequency))
tb.SetPos ($DataSim:DataSim.UpdateFrequency);
// b = win.CreateControl (GButton, 20, 50, 150, 25, "Button 1");
// dt = win.CreateControl (GDateTimePickerCtrl, 20, 80, 150, 25, "Picker");
// txt = win.CreateControl (GStatic, 20, 20, 160, 20, "Text");
win;
}
method Dialog2.Scrolled (tb)
{
$DataSim:DataSim.UpdateFrequency = tb.GetPos();
}
/* ==== A dialog containing a List box ==== */
class Dialog3 GWindow
{
win;
lv;
}
function CreateDialog3 (parent, str)
{
local win = new Dialog3();
win.Init (parent, str);
win;
}
method Dialog3.AddPet (name, owner, species)
{
local n = .lv.GetItemCount();
.lv.InsertItem (n, name);
.lv.SetItemText (n, 1, owner);
.lv.SetItemText (n, 2, species);
}
method Dialog3.Init (parent, str)
{
local rect = CreateRect(10, 10, 10, 10);
local w = 10, h = 10;
.win = self;
.win.SetBackground (0, GetSysColor (COLOR_3DFACE), 0);
.win.Create (parent, rect, "tab", WS_CHILDWINDOW, 0);
.lv = .CreateControl (GListViewCtrl, 0, 0, w, h, "lv");
.lv.SetViewType (1);
.lv.SetExtendedListViewStyle (LVS_EX_FULLROWSELECT | LVS_EX_ONECLICKACTIVATE,
LVS_EX_FULLROWSELECT /*| LVS_EX_ONECLICKACTIVATE*/);
.lv.InsertColumn (0, "Pet", 0, 100, 0);
.lv.InsertColumn (1, "Owner", 0, 100, 0);
.lv.InsertColumn (2, "Species", 0, 100, 0);
.lv.SetBackground (0, 0xffffff, 0);
.AddPet ("Fluffy","Harold","cat");
.AddPet ("Claws","Gwen","cat");
.AddPet ("Buffy", "Harold", "dog");
.AddPet ("Fang", "Benny", "dog");
.AddPet ("Bowser", "Diane", "dog");
.AddPet ("Chirpy", "Gwen", "bird");
.AddPet ("Whistler", "Gwen", "bird");
.AddPet ("Slim", "Benny", "snake");
.AddPet ("Blob", "Benny", "slug");
.win.AddControlResizeFlags (.lv.GetDlgCtrlID(), DLSZ_SIZE_X | DLSZ_SIZE_Y);
.win.NotifyHandler (LVN_ITEMACTIVATE, .lv.GetDlgCtrlID(),
`(@self).SelectedItems(@(.lv)));
.win;
}
method Dialog3.SelectedItems (lv)
{
local i, n = lv.GetItemCount(), state, items;
for (i=0; i<n; i++)
{
if ((state = lv.GetItemState (i, LVIS_SELECTED)) != 0)
items = cons (i, items);
}
princ (reverse(items), "\n");
reverse (items);
}
/* ===================== More support functions ================ */
function show_value (win, point)
{
local val, i;
if (!undefined_p (val = eval(point)))
{
point = string (point);
if ((i = strchr (point, ':')) != -1)
point = substr (point, i+1, -1);
win.SetWindowText (format ("%s = %.4f", point, val));
}
}
function update (win, point)
{
show_value (win, point);
}
function AddButtonToggle (win, control, point, val1, val2, txt1, txt2)
{
win.CommandHandler (BN_CLICKED, control.GetDlgCtrlID(),
`toggle (#@point, @control, @val1, @val2,
@txt1, @txt2));
win.onChange (point, `toggle_update (@control, #@point,
@val1, @val2, @txt1, @txt2));
toggle_update (control, point, val1, val2, txt1, txt2);
}
function toggle_update (control, point, val1, val2, txt1, txt2)
{
/* This could run before the data points are created, which
would give us an undefined symbol. */
local curval;
/* the undefined_p function squelches an error that would
otherwise be thrown on an undefined symbol error. */
undefined_p(curval = eval(point));
if (undefined_p(curval) || curval == val1)
control.SetWindowText (txt1);
else
control.SetWindowText (txt2);
}
function toggle (point, control, val1, val2, txt1, txt2)
{
/* This could run before the data points are created, which
would give us an undefined symbol. */
local curval;
undefined_p(curval = eval(point));
if (undefined_p(curval) || curval == val1)
{
set (point, val2);
control.SetWindowText (txt2);
}
else
{
set (point, val1);
control.SetWindowText (txt1);
}
}
/* ============================= Run It ========================== */
new MonitorWindow();
Copyright © 1995-2006 by Cogent Real-Time Systems, Inc. All rights reserved.