TOPIC: Getting Rid of the server window
#324
Getting Rid of the server window 4 Years ago
Getting Rid of the server window
Category: Coding
Author: Santiago Ottonello ( This e-mail address is being protected from spam bots, you need JavaScript enabled to view it )


Ingredients

The Windows API FindWindow
The Windows API ShowWindow
TaskbarIconControl

Problem

When you start Suneido as server window remain on
the desktop and someone closes it leaving the clients without service

Recipe

create a library called "svrctl" to hold the code

We need to hide the server Window. To do that we need a handler to this window.
In order to find the desired handler we can use FindWindow, this functions receives
a string with the window title and returns a handler to the first window with that title.

NOTE. If you use suneido.exe -s="My Own Title" you will have to fix ServerControl accordingly
because it searchs for "Suneido" as the title.

As FindWindow is not defined in stdlib we define it in our own lib svrctl, as follows

dll long User32:FindWindow([in] string c, [in] string n)

With the handler in hand we can call API ShowWindow (Already defined in stdlib) to instruct
the window to hide:

ShowWindow(FindWindow(NULL, "Suneido"), SW.HIDE)

Now the annoying window is gone, but we need some way to end the server politely.
If you use task manager you will see the process suneido.exe running. Using finalize on
it will stop the server harshly, and in next start you will have a rebuild.

TaskbarIconControl comes to the rescue.
You will need a Window as well as a class to control the icon.
We can therefore use the window to show some server statistics as memory usage
and users connected.
TaskbarIcon pattern goes this way:

a) The tray icon is visible and its associated window is not ...or
b) It's associated window is visible and the tray icon is not.

Class ServerControl gobernates the visibility of the components and
also manages a contextual menu for the icon

Class ServerControWindow draws the associated window server state
To use it you have to pass a call to server control at command line, as follows


start suneido -s Use('utllib');Use('cm_mysu_admin');Use('svrctl');ServerControl()

Note Use('svrctl');ServerControl() this lines do the trick.

You can use a go file as well

Code:


ServerControl

class
{
New()
{
if not Server?()
return
ShowWindow(FindWindow(NULL, "Suneido"), SW.HIDE)
.taskIcons = new TaskbarIconControl(this)
.setWindowVisibility(false)
}

setWindowVisibility(show, add = false)
{
if (show)
{
if (.taskIcons.NumIcons() > 0)
.taskIcons.RemoveIcon(0)
status = Dialog(0, Object("ServerWindow" manager:this ))
if (status is 1)  // 1 indicates miminize...
.setWindowVisibility(false)
else // 0 indicates exist scheduler
.Destroy()
}
else
.taskIcons.AddIcon(Object(szTip:""))
}

On_TaskIconContext(index)
{
GetCursorPos(cursorPosPt = Object())
menu = ContextMenu(Object(
"Server &Status",
"",
"Server Shutdown"
))
.taskIcons.ShowMenu(menu, this, cursorPosPt.x, cursorPosPt.y)
}

On_TaskIconLDown(index)
{ .mouseDown = true }

On_TaskIconLUp(index)
{
if (.mouseDown)
{
.mouseDown = false
.On_TaskIconContext(index)
}
}

On_TaskIconRDown(index)
{ .On_TaskIconLDown(index) }

On_TaskIconRUp(index)
{ .On_TaskIconLUp(index) }

On_TaskIconDblClk(index)
{ .setWindowVisibility(true) }

SetWindowControl(windowControl)
{ .windowControl = windowControl }

On_Context_Server_Status()
{.setWindowVisibility(true) }

On_Context_Server_Shutdown()
{
ok=1
usersOnline=Database.Connections().Size()
if usersOnline > 0
ok=Alert('There are:'$usersOnline$ ' user/s onlinen Disconnect anyway?', 'Warning', flags: MB.ICONQUESTION|MB.OKCANCEL  )

if ok is 1{
Shutdown(true)
}

}

}


Code:


ServerWindowControl

Controller {
Title:'Server Status'
Controls: (Border (Vert
(Pair (Static 'System') (Static "Windows XP 999 Mb" name: 'system') name: 'system')
(Pair (Static 'Heap Size') (Static "999 mb" name: 'arena') name: 'arena')
(Pair (Static 'Database Size') (Static "9999 mb" name: 'dbsize') name: 'dbsize')
(Pair (Static Transactions) (Static "9999" name: 'transactions') name: 'transactions')
(Pair (Static TempDest) (Static "9999" name: 'tempdest') name: 'tempdest')
(Pair (Static Callbacks) (Static "999" name: 'callbacks') name: 'callbacks')
(List columns:#("User") xstretch: 0, ystretch: 0 name: 'users')
(Button name:"Server Shutdown")
) xstretch: , ystretch: 0)

New(manager)
{
.manager=manager
.system=.Border.Vert.system.system
.timer = SetTimer(.WndProc.Hwnd, 100, 1000, .OnTimer)
.arena = .Border.Vert.arena.arena
.users = .Border.Vert.users
.users.SetReadOnly(true, false)
.dbsize = .Border.Vert.dbsize.dbsize
.tempdest = .Border.Vert.tempdest.tempdest
.transactions = .Border.Vert.transactions.transactions
.callbacks = .Border.Vert.callbacks.callbacks
}

OnTimer(@unused_arguments)
{
.arena.Set((MemoryArena() / (1024 * 1024)).Format("### mb"))
.dbsize.Set((Database.CurrentSize() / (1024 * 1024)).Format("#### mb"))
.tempdest.Set(Database.TempDest())
.transactions.Set(Database.Transactions().Size())
callbacks = Callbacks()
.callbacks.Set(callbacks.Size())
callbacks.Delete(all:)

connections=Database.Connections()
dataobject=Object()
foreach(value connection in connections)
dataobject.Add(Object(User: connection))
.users.Set(dataobject)


GlobalMemoryStatus(gms = Object())
.system.Set((OperatingSystem() $ " "$(gms.dwTotalPhys / (1024 * 1024)).Int()) $ " Mb")
return 0
}
On_Server_Shutdown()
{
 .manager.On_Context_Server_Shutdown()
 .Window.Result(1)
}
Destroy()
{
KillTimer(.WndProc.Hwnd, .timer)
ClearCallback(.OnTimer)
.manager.SetWindowControl(false); // inform manager that it no longer has a Window
.Window.Result(1)
}
}

File Attachment:
File Name: svrctl.zip
File Size: 4183


Post edited by: sanotto, at: 2006/08/18 19:03
 
 
#325
Re:Getting Rid of the server window 4 Years ago
Very nice, thanks!
 
 
andrew
 
#326
Re:Getting Rid of the server window 4 Years ago
Hi andrew, glad you like it.
But...There is a problem with svrctl.
When tray icon dialog is displayed the server stops
leaving clients on wait until dialog is closed.
The cause was using Dialog to show the controller,
Dialogs runs in the same thread that its parent, blocking it.
Changing the container to Window fixed the problem.
I've also added a context menu option to start a client
from the tray icon.
I've defined a few extra API to call CreateProcedure,
because system opens a command window.
File Attachment:
File Name: svrctl-f5cfb9bb21525a955b63cc88c04216a5.zip
File Size: 2598


Post edited by: sanotto, at: 2006/08/18 19:13
 
 
#327
Re:Getting Rid of the server window 4 Years ago
Thanks, I'll add the API calls to stdlib.

You can also use Spawn.
 
 
andrew