Design Pattern Examples
Overview of object-oriented design patterns
HandlerChain_MessageWindow_Class.cs
Go to the documentation of this file.
1
6
7using System;
8using System.Collections.Generic;
9
11{
18 public class WindowRectangle
19 {
20 const int MINIMUM_WIDTH = 4;
21 const int MINIMUM_HEIGHT = 4;
22
23 public int Left;
24 public int Top;
25 public int Right;
26 public int Bottom;
27
35 public WindowRectangle(int x, int y, int width, int height)
36 {
37 if (width < MINIMUM_WIDTH)
38 {
39 width = MINIMUM_WIDTH;
40 }
41 if (height < MINIMUM_HEIGHT)
42 {
43 height = MINIMUM_HEIGHT;
44 }
45 Left = x;
46 Top = y;
47 Right = x + width;
48 Bottom = y + height;
49 }
50
56 public bool PointInside(MessagePosition point)
57 {
58 bool isInside = false;
59
60 if (point.X >= Left && point.X < Right &&
61 point.Y >= Top && point.Y < Bottom)
62 {
63 isInside = true;
64 }
65
66 return isInside;
67 }
68
73 public override string ToString()
74 {
75 return String.Format("x1={0,2}, y1={1,2}, x2={2,2}, y2={3,2}", Left, Top, Right, Bottom);
76 }
77 }
78
79
80
81 //========================================================================
82 //========================================================================
83 //========================================================================
84
85
86
98 {
99 // Size of QUIT region in the upper right corner of the region.
100 const int CLOSE_WIDTH = 2;
101 const int CLOSE_HEIGHT = 2;
102
103 delegate bool MessageHandler(Message message);
104
108 private Dictionary<MessageType, MessageHandler> _messageHandlers = new Dictionary<MessageType, MessageHandler>();
109
113 private int _windowId;
114
118 private string _title;
119
124
131
136 private bool _selected;
137
142
143
147 static int _nextWindowId = 1;
148
165 public static MessageWindow CreateWindow(string title, int x, int y, int width, int height, HandlerChain handlerChain)
166 {
167 MessageWindow window = new MessageWindow(_nextWindowId, title, x, y, width, height, handlerChain);
169
170 handlerChain.AddHandler(window);
171 return window;
172 }
173
174
180 private bool _PointInWindow(MessagePosition position)
181 {
182 return _windowBox.PointInside(position);
183 }
184
185
193 private bool _PointInCloseBox(MessagePosition position)
194 {
195 return _closeBox.PointInside(position);
196 }
197
198
211 private MessageWindow(int windowId, string title, int x, int y, int width, int height, HandlerChain handlerChain)
212 {
213 _windowId = windowId;
214 _title = title;
215 _windowBox = new WindowRectangle(x, y, width, height); // Guaranteed to be at least 4x4
217 _selected = false;
218 _handlerChain = handlerChain;
219
220 // Construct our lookup table for message handlers.
224 }
225
226
227 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
228 // The message handlers.
229 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
230 // To add a new message handler:
231 // - Add a new message type to the MessageTypes enumeration.
232 // - Add a new handler method here for the new message type.
233 // - Update MessageWindow constructor to add a mapping from the
234 // new message type to the new handler method.
235
242 private bool _HandleButtonDownMessage(Message message)
243 {
244 // Note: we are not saying we handled the message here since
245 // we want other windows to get the button down message as
246 // well so they can select or deselect themselves.
247 bool messageProcessed = false;
248
249 if (_PointInWindow(message.Position))
250 {
251 if (!_selected)
252 {
253 _selected = true;
254 Console.WriteLine(" --> Button Down in \"{0}\", window selected", _title);
255 }
256 }
257 else
258 {
259 if (_selected)
260 {
261 _selected = false;
262 Console.WriteLine(" --> Button Down not in \"{0}\", window deselected", _title);
263 }
264 }
265 return messageProcessed;
266 }
267
268
275 private bool _HandleButtonUpMessage(Message message)
276 {
277 bool messageProcessed = false;
278 if (_selected)
279 {
280 if (_PointInWindow(message.Position))
281 {
282 // The Button Up is in the same window as Button Down so
283 // we will handle this message and let no other window see
284 // it.
285 messageProcessed = true;
286 if (_PointInCloseBox(message.Position))
287 {
288 Console.WriteLine(" --> Button Up in \"{0}\" close box, sending Close message", _title);
290 }
291 else
292 {
293 Console.WriteLine(" --> Button Up in \"{0}\", no further action taken", _title);
294 }
295 }
296 }
297 return messageProcessed;
298 }
299
300
307 private bool _HandleCloseMessage(Message message)
308 {
309 bool messageProcessed = false;
310 if (_selected)
311 {
312 Console.WriteLine(" --> Close in \"{0}\", removing window from handler chain", _title);
313 // This window is being closed. We are handling the message
314 // so no other window needs to see it.
315 messageProcessed = true;
317 _selected = false;
318 }
319 else
320 {
321 Console.WriteLine(" --> Close seen in \"{0}\" but this window is not selected, ignoring", _title);
322 }
323 return messageProcessed;
324 }
325
326
327 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
328 // Implementation of the IMessageHandler interface.
329 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
330
334 public int ID
335 {
336 get
337 {
338 return _windowId;
339 }
340 }
341
342
354 public bool ProcessMessage(Message message)
355 {
356 bool messageProcessed = false;
357 MessageHandler? handler;
358
359 if (_messageHandlers.TryGetValue(message.MessageType, out handler))
360 {
361 messageProcessed = handler(message);
362 }
363
364 return messageProcessed;
365 }
366
367
372 public override string ToString()
373 {
374 return String.Format("[id={0,2}] \"{1}\" ({2}), selected={3}", ID, _title, _windowBox, _selected);
375 }
376 }
377
378}
Represents a list of handlers that all implement the IMessageHandler interface. This list can be dyna...
void AddHandler(IMessageHandler window)
Add an instance of the IMessageHandler interface to end of the list of handlers, protected by a multi...
void RemoveHandler(IMessageHandler window)
Remove an instance of the IMessageHandler interface from the list, protected by a multi-threading loc...
void SendMessage(Message message)
Send a message to each of the handlers in the list, protected by a multi-threading lock.
Represents a rectangular region that can handle messages directed to that region.
WindowRectangle _closeBox
Position of the close window within the window box, although the coordinates are also global coordina...
static int _nextWindowId
Used for assigning a unique ID to each created window.
bool _HandleButtonUpMessage(Message message)
Helper method to handle the ButtonUp message.
bool _PointInWindow(MessagePosition position)
Determine if the specified point is in this MessageWindow's region.
bool _HandleButtonDownMessage(Message message)
Helper method to handle the ButtonDown message.
MessageWindow(int windowId, string title, int x, int y, int width, int height, HandlerChain handlerChain)
Constructor.
delegate bool MessageHandler(Message message)
bool ProcessMessage(Message message)
Processes a message.
static MessageWindow CreateWindow(string title, int x, int y, int width, int height, HandlerChain handlerChain)
Creates an instance of the MessageWindow class with the specified attributes and adds the new instanc...
bool _selected
Whether this window has been selected (a button click occurred within the window).
HandlerChain _handlerChain
The HandlerChain to which this window belongs (as an IMessageHandler object).
override string ToString()
Convert this handler to a string.
WindowRectangle _windowBox
Position of this window in global coordinates.
bool _HandleCloseMessage(Message message)
Helper method to handle the Close message.
bool _PointInCloseBox(MessagePosition position)
Determine if the specified point is in this MessageWindow's "close" region.
Dictionary< MessageType, MessageHandler > _messageHandlers
Maps a message type to a handler method of type MessageHandler.
int ID
Returns the ID of the message handler.
Represents a rectangular region, with upper left and lower right coordinates.
WindowRectangle(int x, int y, int width, int height)
Constructor.
override string ToString()
Convert this rectangle to a string.
bool PointInside(MessagePosition point)
Determine if the given point is in the rectangle.
Represents a handler in a chain of handlers. All objects that participate in the HandlerChain class m...
The namespace containing all Design Pattern Examples implemented in C#.
MessageType
Type of message handled by MessageWindow.
Represents a message sent to the windows. A message contains a type and a position.
MessagePosition Position
Position of message when the message was sent. In a real system, this would generally represent the p...
MessageType MessageType
Value from the MessageType enumeration indicating the type of this message.
Position of the message in global coordinates (same scope of coordinates as windows)....