Dear Group,
My name is Ruben Van Havermaet. I am trying to finish a project in C#
involving pda's and a desktop server. I am using Microsoft Visual .NET 2003
and a pda with Windows Mobile 2003 Second Edition Version 4.21.1088 (Build
14260.2.0.5)
Here comes the problem:
Given Class ClientCommunicator (which sends notifications to listeners on
events of connected, data sent, data received, etc)
In my case there is one listening class RunningWaiter, which catches
these notifications. When the "data is received"-notification is
caught, the data sent with it is parsed and new notifications are sent
upward to other listeners. (these notifications are in fact the
different commands that a server can send and that the pda can respond
to.)
For these notifications there are two listeners: the class MainForm
(which owns the GUI) and a class MenuKaart.
So we have something like:
ClientCommunicator <-> RunningWaiter <-> {MainForm | MenuKaart}
My problem is, while dealing with these last notifications, when the
user touches the main GUI, the program hangs.
Thanks in advance,
Ruben.
PS Here is the Code:
// CLASS CLIENTCOMMUNICATOR
namespace PocketWaiter.Communication
{
public enum NotifyCommand
{
Connected,
Disconnected,
SentData,
ReceivedData,
Error
}
public delegate void NetNotifEventHandler(object o, NetNotifEventArgs a);
public class NetNotifEventArgs : EventArgs
{
public string _data;
public NotifyCommand _cmd;
public NetNotifEventArgs(NotifyCommand c, string d)
{
_data = d;
_cmd = c;
}
}
/// <summary>
/// Summary description for ClientCommunicator.
/// </summary>
public class ClientCommunicator
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// * MEMBER VARIABLES
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// Notification Event
public event NetNotifEventHandler NetNotif;
// Socket that exchanges information with the server
Socket _socket;
bool _disconnecting = false;
// Received data in buffer
private ServerCommandBuffer _buffer;
public string Buffer
{
get
{
return _buffer.nextCommand();
}
}
// Represents a packet that is sent to the server
public class SocketPacket
{
public System.Net.Sockets.Socket thisSocket;
public byte[] dataBuffer = new byte[Global.Const.MaxBufferLength];
// Get the data in string format. The size parameter determines the
// number of relevant bytes.
public string StringData(int size)
{
return ASCIIEncoding.ASCII.GetString(dataBuffer,0,size);
}
}
// async callbacks
AsyncCallback _connectCallback;
AsyncCallback _sendCallback;
AsyncCallback _receiveCallback;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// * PROPERTIES
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
/// <summary>
/// Returns true if the socket is connected to the server. The property
/// Socket.Connected does not always indicate if the socket is currently
/// connected. This polls the socket to determine the latest connection
state.
/// </summary>
public bool Connected
{
get
{
// return right away if no socket was created
if (_socket == null)
return false;
// the socket is not connected if the Connected property is false
if (!_socket.Connected)
return false;
// there is no guarantee that the socket is connected even if the
// Connected property is true
try
{
// poll for error to see if socket is connected
return !_socket.Poll(1,SelectMode.SelectError);
}
catch
{
return false;
}
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// * CONSTRUCTORS
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
public ClientCommunicator()
{
// hookup async callback methods
_connectCallback = new AsyncCallback(connectCallback);
_sendCallback = new AsyncCallback(sendCallback);
_receiveCallback = new AsyncCallback(receiveCallback);
_buffer = new ServerCommandBuffer();
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// * PUBLIC MEMBER FUNCTIONS
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
/// <summary>
/// Connect to the specified address and port number.
/// </summary>
public void connect(string address, int port)
{
try
{
// make sure the existing connection is closed
disconnect();
// Connect to the server
IPAddress ipAddress = IPAddress.Parse(address);
IPEndPoint endPoint = new IPEndPoint(ipAddress, port);
_socket = new Socket( AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
_socket.BeginConnect(endPoint, _connectCallback, null);
}
catch (Exception ex)
{
OnNetNotif(new NetNotifEventArgs(NotifyCommand.Error,"CONNECT: " +
ex.Message));
}
}
/// <summary>
/// Disconnect from the server.
/// </summary>
public void disconnect()
{
// return right away if no socket was created
if (_socket == null)
return;
// set this flag so we don't raise any error notification
// event when disconnecting
_disconnecting = true;
try // shutdown the socket
{
_socket.Shutdown(SocketShutdown.Both);
}
catch {}
try // close socket; terminates any pending async operations
{
_socket.Close();
}
catch {}
_socket = null;
_disconnecting = false;
OnNetNotif(new NetNotifEventArgs(NotifyCommand.Disconnected, null));
}
/// <summary>
/// Send data to the server.
/// </summary>
public void send(string data)
{
try
{
SocketPacket s = new SocketPacket();
s.thisSocket = _socket;
// Convert the message to a byte array
s.dataBuffer = System.Text.Encoding.ASCII.GetBytes(data);
// Send the data asychronously
s.thisSocket.BeginSend(s.dataBuffer, 0, data.Length,
SocketFlags.None, _sendCallback, s);
}
catch (SocketException se)
{
OnNetNotif(new NetNotifEventArgs(NotifyCommand.Error,
"SEND: " + se.Message + "(" + se.ErrorCode + ")"));
}
catch (Exception ex)
{
OnNetNotif(new NetNotifEventArgs(NotifyCommand.Error,
"SEND: " + ex.Message));
}
}
/// <summary>
/// This function sends the data synchronously
/// </summary>
public void sendNow(string data)
{
try
{
NetworkStream networkStream = new NetworkStream(_socket);
System.IO.StreamWriter streamWriter = new
System.IO.StreamWriter(networkStream);
streamWriter.WriteLine(data);
streamWriter.Flush();
}
catch (SocketException se)
{
OnNetNotif(new NetNotifEventArgs(NotifyCommand.Error,
"SENDNOW: " + se.Message + "(" + se.ErrorCode + ")"));
}
catch (Exception ex)
{
OnNetNotif(new NetNotifEventArgs(NotifyCommand.Error,
"SENDNOW: " + ex.Message));
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// * PRIVATE MEMBER FUNCTIONS
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
/// <summary>
/// Read data from server.
/// </summary>
public void waitReceive()
{
if (_socket.Connected)
{
try
{
SocketPacket sPacket = new SocketPacket();
sPacket.thisSocket = _socket;
_asyncStatus = _socket.BeginReceive (sPacket.dataBuffer,
0, sPacket.dataBuffer.Length,
SocketFlags.None,
_receiveCallback,
sPacket);
}
catch(SocketException se)
{
OnNetNotif(new NetNotifEventArgs(NotifyCommand.Error,"WAITRECEIVE: " +
se.Message));
}
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// * NOTIFY EVENTS - which are send a level up
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
/// <summary>
/// Raise Notification event
/// </summary>
protected virtual void OnNetNotif(NetNotifEventArgs args)
{
// if there was an error: disconnect the socket
if (args._cmd == NotifyCommand.Error)
{
disconnect();
}
// don't raise notificaton events when disconnecting
if ((this.NetNotif != null) && !_disconnecting)
NetNotif(this, args);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// * CALLBACKS - which you get back from a level down
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
private void connectCallback(IAsyncResult ar)
{
try
{
_socket.EndConnect(ar);
// Send hostname
string hostname = Dns.GetHostName();
byte[] hostBuffer = System.Text.Encoding.ASCII.GetBytes(hostname);
_socket.Send(hostBuffer,0,hostBuffer.Length,SocketFlags.None);
// Pass remote ip address with notification event.
string ip = ((IPEndPoint)this._socket.RemoteEndPoint).Address.ToString();
OnNetNotif(new NetNotifEventArgs(NotifyCommand.Connected, ip));
// Start listening for server's messages asynchronously
waitReceive();
}
catch (Exception ex)
{
OnNetNotif(new NetNotifEventArgs(NotifyCommand.Error,"CLB_CONNECT: " +
ex.Message));
}
}
private void sendCallback(IAsyncResult ar)
{
SocketPacket s = null;
try
{
s = (SocketPacket)ar.AsyncState;
// End the asynchronous send
int size = _socket.EndSend(ar);
// Raise a sent event
OnNetNotif(new
NetNotifEventArgs(NotifyCommand.SentData,s.StringData(size)));
}
catch (SocketException se)
{
OnNetNotif(
new NetNotifEventArgs(NotifyCommand.Error,
"CLB_SENT_DATA: " + se.Message + "(" + se.ErrorCode + ")"));
}
catch(Exception se)
{
OnNetNotif(
new NetNotifEventArgs(NotifyCommand.Error,
"CLB_SENT_DATA: " + se.Message));
}
}
private void receiveCallback(IAsyncResult ar)
{
SocketPacket s = (SocketPacket)ar.AsyncState;
if (s.thisSocket.Connected)
{
try
{
// Mark received and get the size of the packet
int size = s.thisSocket.EndReceive(ar);
// The serversocket is disconnected
if (size < 1)
{
disconnect();
return;
}
// Save the byte array into a string
string data = s.StringData(size);
// Add data to the receivedBuffer
_buffer.addCommand(data);
// Notify any listeners that some data was received
OnNetNotif(new NetNotifEventArgs(NotifyCommand.ReceivedData, data));
// Wait for new data
waitReceive();
}
catch (SocketException se)
{
OnNetNotif(new NetNotifEventArgs(NotifyCommand.Error,
"CLB_RECEIVE: " + se.Message + "(" + se.ErrorCode + ")"));
}
catch (Exception ex)
{
OnNetNotif(new NetNotifEventArgs(NotifyCommand.Error,
"CLB_RECEIVE: " + ex.Message));
}
}
}
} // End Class ClientCommunicator
} // Close Namespace Communication
// CLASS MENUKAART
namespace PocketWaiter.Menu
{
/// <summary>
/// Summary description for MenuKaart.
/// </summary>
public class MenuKaart
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// * MEMBER VARIABLES
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// The Running Waiter to listen to
RunningWaiter _runningWaiter;
// The list of groups inside this MenuKaart
Groups _groups;
// The list of articles inside this MenuKaart
// Articles _articles
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// * CONSTRUCTOR
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
public MenuKaart(RunningWaiter runningWaiter)
{
_runningWaiter = runningWaiter;
_runningWaiter.ServerCommandNotif += new
ServerCommandNotifEventHandler(onServerCommandNotif);
_groups = new Groups(Global.Const.AutoWriteMenu);
//_articles = new Articles(Global.Const.AutoWriteMenu);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// * PUBLIC MEMBER FUNCTIONS
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// TODO: as above we should consider what functionality this MenuKaart
// class should implement.
public Group getGroupByID(short id)
{
return _groups.getGroup(id);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// * CALLBACK-RELATED - which you get back from a level down
// * (RunningWaiter in this case)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
private void onServerCommandNotif(
object sender, ServerCommandNotifEventArgs args)
{
try
{
lock (this)
{
switch (args._cmd.ID)
{
case ServerCommandID.CreateGroup:
processCreateGroup(
((CreateGroupServerCommand)args._cmd).Group);
break;
case ServerCommandID.DeleteGroup:
processDeleteGroup(
((DeleteGroupServerCommand)args._cmd).GroupID);
break;
case ServerCommandID.DeleteAllGroups:
processDeleteAllGroups();
break;
}
}
}
catch {}
}
// This function specifies the course of action when the RunningWaiter
// notifies that a group needs to be created or updated.
private void processCreateGroup(Group grp)
{
bool added = _groups.addGroup(grp);
if (added)
Logger.log(this, "Added Group " + grp.ID + ".");
else
Logger.log(this, "Updated Group (NYI) " + grp.ID + ".");
}
// This function specifies the course of action when the RunningWaiter
// signals a DeleteGroup command
private void processDeleteGroup(short id)
{
bool removed = _groups.removeGroup(id);
if (removed)
Logger.log(this, "Removed Group " + id + ".");
else
Logger.log(this, "NotFound Group " + id + ".");
}
// This function defines the actions to be taken when the RunningWaiter
// signals a DeleteAllGroups command
private void processDeleteAllGroups()
{
_groups.clearGroups();
Logger.log(this, "Removed all Groups.");
}
}
}
// CLASS MAINFORM
namespace PocketWaiter
{
/// <summary>
/// TODO: Summary description for MainForm.
/// </summary>
public class MainForm : System.Windows.Forms.Form, ILogArea
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// * MEMBER VARIABLES
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// The communication object
ClientCommunicator _client = new ClientCommunicator();
// The Running Waiter, responsible for processing requests made
// by the server and the client program.
RunningWaiter _runningWaiter;
// The Menu
MenuKaart _menu;
// Handle commands from the server
EventHandler _processServerCommandNotif;
// Hold RunningWaiter command arguments
ServerCommand _serverCommand;
// Windows Components
private System.Windows.Forms.TextBox _mainTxtOutput;
private System.Windows.Forms.MainMenu _mainMenu;
private System.Windows.Forms.MenuItem _menuItemSetup;
private ConnectButton _btnConnect;
private System.Windows.Forms.Button _btnFollowTable;
private System.Windows.Forms.Button _btnOrder;
private System.Windows.Forms.Button _btnShowTable;
private System.Windows.Forms.Button _btnLeeg1;
private System.Windows.Forms.Button _btnMessage;
private System.Windows.Forms.Button _btnMoveTable;
private System.Windows.Forms.MenuItem _menuItemExit;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// * CONSTRUCTOR, MAIN, WINDOWS FORM DESIGNER GENERATED *
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
public MainForm()
{
_runningWaiter = new RunningWaiter(_client);
_menu = new MenuKaart(_runningWaiter);
this._btnConnect = new ConnectButton(_client);
this._btnConnect.Location = new System.Drawing.Point(192, 184);
this._btnConnect.Size = new System.Drawing.Size(40, 80);
this.Controls.Add(this._btnConnect);
// Install callback for servercommands
_runningWaiter.ServerCommandNotif +=
new ServerCommandNotifEventHandler(onServerCommandNotif);
_processServerCommandNotif = new EventHandler(processServerCommandNotif);
InitializeComponent();
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this._menuItemSetup = new System.Windows.Forms.MenuItem();
this._menuItemExit = new System.Windows.Forms.MenuItem();
this._mainMenu = new System.Windows.Forms.MainMenu();
this._mainTxtOutput = new System.Windows.Forms.TextBox();
this._btnFollowTable = new System.Windows.Forms.Button();
this._btnOrder = new System.Windows.Forms.Button();
this._btnShowTable = new System.Windows.Forms.Button();
this._btnLeeg1 = new System.Windows.Forms.Button();
this._btnMessage = new System.Windows.Forms.Button();
this._btnMoveTable = new System.Windows.Forms.Button();
//
// _menuItemSetup
//
this._menuItemSetup.Text = "Setup";
this._menuItemSetup.Click += new
System.EventHandler(this.menuItemSetup_Click);
//
// _menuItemExit
//
this._menuItemExit.Text = "Exit";
this._menuItemExit.Click += new
System.EventHandler(this.menuItemExit_Click);
//
// _mainMenu
//
this._mainMenu.MenuItems.Add(this._menuItemSetup);
this._mainMenu.MenuItems.Add(this._menuItemExit);
//
// _mainTxtOutput
//
this._mainTxtOutput.AcceptsReturn = true;
this._mainTxtOutput.AcceptsTab = true;
this._mainTxtOutput.Font = new System.Drawing.Font("Microsoft Sans
Serif", 9F, System.Drawing.FontStyle.Regular);
this._mainTxtOutput.Location = new System.Drawing.Point(8, 88);
this._mainTxtOutput.Multiline = true;
this._mainTxtOutput.ReadOnly = true;
this._mainTxtOutput.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this._mainTxtOutput.Size = new System.Drawing.Size(176, 176);
this._mainTxtOutput.Text = "PocketWaiter v0.1\r\n";
//
// _btnFollowTable
//
this._btnFollowTable.Font = new System.Drawing.Font("Microsoft Sans
Serif", 14.25F, System.Drawing.FontStyle.Regular);
this._btnFollowTable.Location = new System.Drawing.Point(128, 32);
this._btnFollowTable.Size = new System.Drawing.Size(104, 24);
this._btnFollowTable.Text = "Tafel Mag\r\nVolgen";
this._btnFollowTable.Click += new
System.EventHandler(this._btnFollowTable_Click);
//
// _btnOrder
//
this._btnOrder.Font = new System.Drawing.Font("Microsoft Sans Serif",
14.25F, System.Drawing.FontStyle.Regular);
this._btnOrder.Location = new System.Drawing.Point(8, 8);
this._btnOrder.Size = new System.Drawing.Size(104, 24);
this._btnOrder.Text = "Begin\r\nBestelling";
this._btnOrder.Click += new System.EventHandler(this._btnOrder_Click);
//
// _btnShowTable
//
this._btnShowTable.Font = new System.Drawing.Font("Microsoft Sans Serif",
14.25F, System.Drawing.FontStyle.Regular);
this._btnShowTable.Location = new System.Drawing.Point(8, 56);
this._btnShowTable.Size = new System.Drawing.Size(104, 24);
this._btnShowTable.Text = "Save";
this._btnShowTable.Click += new
System.EventHandler(this._btnShowTable_Click);
//
// _btnLeeg1
//
this._btnLeeg1.Font = new System.Drawing.Font("Microsoft Sans Serif",
14.25F, System.Drawing.FontStyle.Regular);
this._btnLeeg1.Location = new System.Drawing.Point(128, 56);
this._btnLeeg1.Size = new System.Drawing.Size(104, 24);
this._btnLeeg1.Text = "Groups";
this._btnLeeg1.Click += new System.EventHandler(this._btnLeeg1_Click);
//
// _btnMessage
//
this._btnMessage.Font = new System.Drawing.Font("Microsoft Sans Serif",
14.25F, System.Drawing.FontStyle.Regular);
this._btnMessage.Location = new System.Drawing.Point(128, 8);
this._btnMessage.Size = new System.Drawing.Size(104, 24);
this._btnMessage.Text = "Stuur\r\nBericht";
this._btnMessage.Click += new System.EventHandler(this._btnMessage_Click);
//
// _btnMoveTable
//
this._btnMoveTable.Font = new System.Drawing.Font("Microsoft Sans Serif",
14.25F, System.Drawing.FontStyle.Regular);
this._btnMoveTable.Location = new System.Drawing.Point(8, 32);
this._btnMoveTable.Size = new System.Drawing.Size(104, 24);
this._btnMoveTable.Text = "Verplaats\r\nTafel";
this._btnMoveTable.Click += new
System.EventHandler(this._btnMoveTable_Click);
//
// MainForm
//
this.Controls.Add(this._btnMoveTable);
this.Controls.Add(this._btnMessage);
this.Controls.Add(this._btnLeeg1);
this.Controls.Add(this._btnShowTable);
this.Controls.Add(this._btnOrder);
this.Controls.Add(this._btnFollowTable);
this.Controls.Add(this._mainTxtOutput);
this.Menu = this._mainMenu;
this.Text = "PocketWaiter";
this.Closing += new
System.ComponentModel.CancelEventHandler(this.MainForm_Closing);
this.Load += new System.EventHandler(this.MainForm_Load);
this.MouseDown += new MouseEventHandler(MainForm_MouseDown);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
Application.Run(new MainForm());
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// * EVENTS *
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
private void MainForm_Load(object sender, System.EventArgs e)
{
// Register MainForm as a logArea
Logger.register(this);
}
private void MainForm_Closing(object sender,
System.ComponentModel.CancelEventArgs e)
{
this.quit();
}
// * BUTTONS * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
private void _btnOrder_Click(object sender, System.EventArgs e)
{
}
private void _btnMoveTable_Click(object sender, System.EventArgs e)
{
MoveTableForm form = new MoveTableForm();
form.ShowDialog();
_runningWaiter.moveTable(form.FromTable, form.ToTable);
}
private void _btnShowTable_Click(object sender, System.EventArgs e)
{
}
private void _btnMessage_Click(object sender, System.EventArgs e)
{
NumericInputForm form =
new NumericInputForm(false, "Enter GroupID:", false);
form.ShowDialog();
if (form.InputGiven)
{
Group grp = _menu.getGroupByID((short)form.NumberInput);
if (grp != null)
_runningWaiter.sendString(grp.ToString());
else
_runningWaiter.sendString("GROUPID does not exist");
}
}
private void _btnFollowTable_Click(object sender, System.EventArgs e)
{
}
private void _btnLeeg1_Click(object sender, System.EventArgs e)
{
_menu.showGroups();
}
// * MENU ITEMS * * * * * * * * * * * * * * * * * * * * * * * * * * *
private void menuItemSetup_Click(
object sender, System.EventArgs e)
{
showSetupForm();
}
private void menuItemExit_Click(object sender, System.EventArgs e)
{
this.quit();
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// * PRIVATE MEMBER FUNCTIONS
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// This function makes MainForm implement the ILogArea interface
public void log(Object o, string msg)
{
if ((_mainTxtOutput.Text.Length + msg.Length)
> _mainTxtOutput.MaxLength)
_mainTxtOutput.Text = "";
_mainTxtOutput.Text = Thread.CurrentThread.GetHashCode()+ ">" + msg +
"\r\n" + _mainTxtOutput.Text;
}
// QUIT the program
private void quit()
{
disconnectFromServer();
Application.Exit();
}
// Disconnect from server
private void disconnectFromServer()
{
if (_client.Connected)
{
Logger.log(this,"Disconnecting");
_client.disconnect();
}
}
// Show Test form
private void showSetupForm()
{
//SetupForm form = new SetupForm();
//form.ShowDialog();
}
// This function shows a numerical input form, requesting the user
// to enter the waiterNumber.
private void showWaiterNumberForm()
{
NumericInputForm form = new
NumericInputForm(false, "Waiter Number?", false);
form.ShowDialog();
Logger.log(this, "WAITER NUMBER = " + form.NumberInput.ToString());
_runningWaiter.sendWaiterNumber(form.NumberInput);
}
// This function shows a numerical input form, requesting the user
// to enter the waiter password.
private void showWaiterPassForm()
{
NumericInputForm form =
new NumericInputForm(true, "Waiter Password?", false);
form.ShowDialog();
Logger.log(this, "WAITER PASS = " + form.NumberInput.ToString());
_runningWaiter.sendWaiterPassword(form.NumberInput);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// * CALLBACK-RELATED - which you get back from a level down
// * and how to respond!
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
private void onServerCommandNotif(object sender,
ServerCommandNotifEventArgs args)
{
try
{
// The .NET Compact Framework does not support Control.Invoke
// with which you can pass arguments to the delegate. So save
// arguments to class fields and then invoke the delegate.
lock (this)
{
_serverCommand = args._cmd;
Invoke(_processServerCommandNotif);
}
}
catch (Exception ex)
{
Logger.log(this, "MAINFORM ERROR: " + ex.Message);
}
}
private void processServerCommandNotif(Object sender, EventArgs args)
{
switch(_serverCommand.ID)
{
case ServerCommandID.GetWaiterNumber:
showWaiterNumberForm();
break;
case ServerCommandID.GetWaiterPassword:
showWaiterPassForm();
break;
case ServerCommandID.SetWaiterName:
break;
}
}
private void MainForm_MouseDown(object sender, MouseEventArgs e)
{
Logger.log(this, "TESTING MOUSEDOWN");
}
}
}