(svn r8683) [cpp_gui] -Codechange: first steps towards OO GUI (together with Bjarni) without changes in the logic cpp_gui
authorKUDr
Sun, 11 Feb 2007 22:57:24 +0000
branchcpp_gui
changeset 6235 5077e6ed3788
parent 6234 42bf2d268a86
child 6236 ec056d324811
(svn r8683) [cpp_gui] -Codechange: first steps towards OO GUI (together with Bjarni) without changes in the logic
-Windows are now constructed/destroyed when needed instead of reusing them from _windows[25]. This array is now replaced by std::list<> of smart pointers (eliminates the need of _z_windows)
-some Window related functions turned into Window (or WindowList) methods
-note that although the number of windows is now unlimited, the maximum number of viewports is still hardcoded. This causes game crash when too many industry windows are opened.
-tested only on VC8/WinXP
src/aircraft_gui.cpp
src/airport_gui.cpp
src/autoreplace_gui.cpp
src/bridge_gui.cpp
src/build_vehicle_gui.cpp
src/console.cpp
src/depot_gui.cpp
src/dock_gui.cpp
src/engine_gui.cpp
src/genworld.cpp
src/genworld_gui.cpp
src/graph_gui.cpp
src/industry_gui.cpp
src/main_gui.cpp
src/misc/countedptr.hpp
src/misc_cmd.cpp
src/misc_gui.cpp
src/music_gui.cpp
src/network/network_gui.cpp
src/newgrf_gui.cpp
src/news_gui.cpp
src/openttd.cpp
src/order_gui.cpp
src/player_gui.cpp
src/rail_gui.cpp
src/road_gui.cpp
src/roadveh_gui.cpp
src/settings_gui.cpp
src/ship_gui.cpp
src/smallmap_gui.cpp
src/sound.cpp
src/station_gui.cpp
src/terraform_gui.cpp
src/town_gui.cpp
src/train_gui.cpp
src/vehicle_gui.cpp
src/viewport.cpp
src/widget.cpp
src/window.cpp
src/window.h
--- a/src/aircraft_gui.cpp	Sun Feb 11 21:20:30 2007 +0000
+++ b/src/aircraft_gui.cpp	Sun Feb 11 22:57:24 2007 +0000
@@ -349,7 +349,7 @@
 		if (plane_stopped != IsWindowWidgetHidden(w, 7) || plane_stopped == IsWindowWidgetHidden(w, 11)) {
 			SetWindowWidgetHiddenState(w,  7, plane_stopped);  // send to hangar
 			SetWindowWidgetHiddenState(w, 11, !plane_stopped); // clone
-			SetWindowDirty(w);
+			w->SetDirty();
 		}
 	} break;
 	}
--- a/src/airport_gui.cpp	Sun Feb 11 21:20:30 2007 +0000
+++ b/src/airport_gui.cpp	Sun Feb 11 22:57:24 2007 +0000
@@ -99,9 +99,9 @@
 		break;
 
 	case WE_ABORT_PLACE_OBJ:
-		RaiseWindowButtons(w);
+		w->RaiseButtons();
 
-		w = FindWindowById(WC_BUILD_STATION, 0);
+		w = Window::FindById(WC_BUILD_STATION, 0);
 		if (w != 0)
 			WP(w,def_d).close = true;
 		break;
@@ -206,21 +206,21 @@
 			_selected_airport_type = e->we.click.widget - 7;
 			LowerWindowWidget(w, _selected_airport_type + 7);
 			SndPlayFx(SND_15_BEEP);
-			SetWindowDirty(w);
+			w->SetDirty();
 			break;
 		case 16: case 17:
 			_station_show_coverage = (e->we.click.widget != 16);
 			SetWindowWidgetLoweredState(w, 16, !_station_show_coverage);
 			SetWindowWidgetLoweredState(w, 17, _station_show_coverage);
 			SndPlayFx(SND_15_BEEP);
-			SetWindowDirty(w);
+			w->SetDirty();
 			break;
 		}
 	} break;
 
 	case WE_MOUSELOOP: {
 		if (WP(w,def_d).close) {
-			DeleteWindow(w);
+			w->Close();
 			return;
 		}
 
--- a/src/autoreplace_gui.cpp	Sun Feb 11 21:20:30 2007 +0000
+++ b/src/autoreplace_gui.cpp	Sun Feb 11 22:57:24 2007 +0000
@@ -311,7 +311,7 @@
 					WP(w, replaceveh_d).wagon_btnstate = !(WP(w, replaceveh_d).wagon_btnstate);
 					WP(w, replaceveh_d).update_left = true;
 					WP(w, replaceveh_d).init_lists  = true;
-					SetWindowDirty(w);
+					w->SetDirty();
 					break;
 
 				case 14:
@@ -351,7 +351,7 @@
 							WP(w, replaceveh_d).update_right = true;
 							WP(w, replaceveh_d).init_lists   = true;
 						}
-						SetWindowDirty(w);
+						w->SetDirty();
 						}
 					break;
 					}
@@ -370,7 +370,7 @@
 			WP(w, replaceveh_d).update_left  = true;
 			WP(w, replaceveh_d).update_right = true;
 			WP(w, replaceveh_d).init_lists   = true;
-			SetWindowDirty(w);
+			w->SetDirty();
 		} break;
 
 		case WE_RESIZE:
@@ -384,7 +384,7 @@
 		case WE_INVALIDATE_DATA:
 			if (_rebuild_left_list) WP(w, replaceveh_d).update_left = true;
 			if (_rebuild_right_list) WP(w, replaceveh_d).update_right = true;
-			SetWindowDirty(w);
+			w->SetDirty();
 			break;
 
 		case WE_DESTROY:
--- a/src/bridge_gui.cpp	Sun Feb 11 21:20:30 2007 +0000
+++ b/src/bridge_gui.cpp	Sun Feb 11 22:57:24 2007 +0000
@@ -32,7 +32,7 @@
 
 static void BuildBridge(Window *w, int i)
 {
-	DeleteWindow(w);
+	w->Close();
 	DoCommandP(_bridgedata.end_tile, _bridgedata.start_tile,
 		_bridgedata.indexes[i] | (_bridgedata.type << 8), CcBuildBridge,
 		CMD_BUILD_BRIDGE | CMD_AUTO | CMD_MSG(STR_5015_CAN_T_BUILD_BRIDGE_HERE));
--- a/src/build_vehicle_gui.cpp	Sun Feb 11 21:20:30 2007 +0000
+++ b/src/build_vehicle_gui.cpp	Sun Feb 11 22:57:24 2007 +0000
@@ -812,14 +812,14 @@
 			bv->descending_sort_order ^= true;
 			_last_sort_order[bv->vehicle_type] = bv->descending_sort_order;
 			bv->regenerate_list = true;
-			SetWindowDirty(w);
+			w->SetDirty();
 			break;
 
 		case BUILD_VEHICLE_WIDGET_LIST: {
 			uint i = (e->we.click.pt.y - 26) / GetVehicleListHeight(bv->vehicle_type) + w->vscroll.pos;
 			uint num_items = EngList_Count(&bv->eng_list);
 			bv->sel_engine = (i < num_items) ? bv->eng_list[i] : INVALID_ENGINE;
-			SetWindowDirty(w);
+			w->SetDirty();
 			break;
 		}
 
@@ -875,7 +875,7 @@
 	switch (e->event) {
 		case WE_INVALIDATE_DATA:
 			bv->regenerate_list = true;
-			SetWindowDirty(w);
+			w->SetDirty();
 			break;
 
 		case WE_DESTROY:
@@ -915,7 +915,7 @@
 				_last_sort_criteria[bv->vehicle_type] = bv->sort_criteria;
 				bv->regenerate_list = true;
 			}
-			SetWindowDirty(w);
+			w->SetDirty();
 			break;
 
 		case WE_RESIZE:
--- a/src/console.cpp	Sun Feb 11 21:20:30 2007 +0000
+++ b/src/console.cpp	Sun Feb 11 22:57:24 2007 +0000
@@ -51,7 +51,7 @@
 	_iconsole_cmdline.width = 0;
 	_iconsole_cmdline.caretpos = 0;
 	_iconsole_cmdline.caretxoffs = 0;
-	SetWindowDirty(FindWindowById(WC_CONSOLE, 0));
+	Window::SetDirtyById(WC_CONSOLE, 0);
 }
 
 static inline void IConsoleResetHistoryPos(void) {_iconsole_historypos = ICON_HISTORY_SIZE - 1;}
@@ -91,7 +91,7 @@
 		}
 		case WE_MOUSELOOP:
 			if (HandleCaret(&_iconsole_cmdline))
-				SetWindowDirty(w);
+				w->SetDirty();
 			break;
 		case WE_DESTROY:
 			_iconsole_mode = ICONSOLE_CLOSED;
@@ -101,11 +101,11 @@
 			switch (e->we.keypress.keycode) {
 				case WKC_UP:
 					IConsoleHistoryNavigate(+1);
-					SetWindowDirty(w);
+					w->SetDirty();
 					break;
 				case WKC_DOWN:
 					IConsoleHistoryNavigate(-1);
-					SetWindowDirty(w);
+					w->SetDirty();
 					break;
 				case WKC_SHIFT | WKC_PAGEUP:
 					if (iconsole_scroll - (w->height / ICON_LINE_HEIGHT) - 1 < 0) {
@@ -113,7 +113,7 @@
 					} else {
 						iconsole_scroll -= (w->height / ICON_LINE_HEIGHT) - 1;
 					}
-					SetWindowDirty(w);
+					w->SetDirty();
 					break;
 				case WKC_SHIFT | WKC_PAGEDOWN:
 					if (iconsole_scroll + (w->height / ICON_LINE_HEIGHT) - 1 > ICON_BUFFER) {
@@ -121,7 +121,7 @@
 					} else {
 						iconsole_scroll += (w->height / ICON_LINE_HEIGHT) - 1;
 					}
-					SetWindowDirty(w);
+					w->SetDirty();
 					break;
 				case WKC_SHIFT | WKC_UP:
 					if (iconsole_scroll <= 0) {
@@ -129,7 +129,7 @@
 					} else {
 						--iconsole_scroll;
 					}
-					SetWindowDirty(w);
+					w->SetDirty();
 					break;
 				case WKC_SHIFT | WKC_DOWN:
 					if (iconsole_scroll >= ICON_BUFFER) {
@@ -137,7 +137,7 @@
 					} else {
 						++iconsole_scroll;
 					}
-					SetWindowDirty(w);
+					w->SetDirty();
 					break;
 				case WKC_BACKQUOTE:
 					IConsoleSwitch();
@@ -157,7 +157,7 @@
 				case (WKC_CTRL | 'V'):
 					if (InsertTextBufferClipboard(&_iconsole_cmdline)) {
 						IConsoleResetHistoryPos();
-						SetWindowDirty(w);
+						w->SetDirty();
 					}
 					break;
 				case (WKC_CTRL | 'L'):
@@ -165,18 +165,18 @@
 					break;
 				case (WKC_CTRL | 'U'):
 					DeleteTextBufferAll(&_iconsole_cmdline);
-					SetWindowDirty(w);
+					w->SetDirty();
 					break;
 				case WKC_BACKSPACE: case WKC_DELETE:
 					if (DeleteTextBufferChar(&_iconsole_cmdline, e->we.keypress.keycode)) {
 						IConsoleResetHistoryPos();
-						SetWindowDirty(w);
+						w->SetDirty();
 					}
 					break;
 				case WKC_LEFT: case WKC_RIGHT: case WKC_END: case WKC_HOME:
 					if (MoveTextBufferPos(&_iconsole_cmdline, e->we.keypress.keycode)) {
 						IConsoleResetHistoryPos();
-						SetWindowDirty(w);
+						w->SetDirty();
 					}
 					break;
 				default:
@@ -184,7 +184,7 @@
 						iconsole_scroll = ICON_BUFFER;
 						InsertTextBufferChar(&_iconsole_cmdline, e->we.keypress.key);
 						IConsoleResetHistoryPos();
-						SetWindowDirty(w);
+						w->SetDirty();
 					} else {
 						e->we.keypress.cont = true;
 					}
@@ -403,7 +403,7 @@
 
 	IConsoleWriteToLogFile(_iconsole_buffer[ICON_BUFFER]);
 
-	SetWindowDirty(FindWindowById(WC_CONSOLE, 0));
+	Window::SetDirtyById(WC_CONSOLE, 0);
 }
 
 /**
--- a/src/depot_gui.cpp	Sun Feb 11 21:20:30 2007 +0000
+++ b/src/depot_gui.cpp	Sun Feb 11 22:57:24 2007 +0000
@@ -218,7 +218,7 @@
 	uint16 boxes_in_each_row = w->widget[DEPOT_WIDGET_MATRIX].data & 0xFF;
 
 	/* setup disabled buttons */
-	SetWindowWidgetsDisabledState(w, !IsTileOwner(tile, _local_player),
+	w->SetWidgetsDisabledState(!IsTileOwner(tile, _local_player),
 		DEPOT_WIDGET_STOP_ALL,
 		DEPOT_WIDGET_START_ALL,
 		DEPOT_WIDGET_SELL,
@@ -445,7 +445,7 @@
 				}
 
 				WP(w, depot_d).sel = v->index;
-				SetWindowDirty(w);
+				w->SetDirty();
 				SetObjectToPlaceWnd(image, GetVehiclePalette(v), 4, w);
 			}
 			}
@@ -733,7 +733,7 @@
 		+ (type == VEH_Train ? 1 : w->hscroll.cap); // number of boxes in each row. Trains always have just one
 
 
-	SetWindowWidgetsHiddenState(w, type != VEH_Train,
+	w->SetWidgetsHiddenState(type != VEH_Train,
 		DEPOT_WIDGET_H_SCROLL,
 		DEPOT_WIDGET_SELL_CHAIN,
 		WIDGET_LIST_END);
@@ -892,7 +892,7 @@
 					VehicleID sel = WP(w, depot_d).sel;
 
 					WP(w, depot_d).sel = INVALID_VEHICLE;
-					SetWindowDirty(w);
+					w->SetDirty();
 
 					if (WP(w, depot_d).type == VEH_Train) {
 						GetDepotVehiclePtData gdvp;
@@ -925,11 +925,11 @@
 						if (IsWindowWidgetDisabled(w, e->we.click.widget)) return;
 						if (WP(w, depot_d).sel == INVALID_VEHICLE) return;
 
-						HandleButtonClick(w, e->we.click.widget);
+						w->HandleButtonClick(e->we.click.widget);
 
 						v = GetVehicle(WP(w, depot_d).sel);
 						WP(w, depot_d).sel = INVALID_VEHICLE;
-						SetWindowDirty(w);
+						w->SetDirty();
 
 						sell_cmd = (v->type == VEH_Train && (e->we.click.widget == DEPOT_WIDGET_SELL_CHAIN || _ctrl_pressed)) ? 1 : 0;
 
@@ -953,7 +953,7 @@
 					break;
 				default:
 					WP(w, depot_d).sel = INVALID_VEHICLE;
-					SetWindowDirty(w);
+					w->SetDirty();
 			}
 			break;
 
@@ -1003,7 +1003,7 @@
 	 * If that is the case, we can skip looping though the windows and save time                                */
 	if (_special_mouse_mode != WSM_DRAGDROP) return;
 
-	w = FindWindowById(WC_VEHICLE_DEPOT, v->tile);
+	w = Window::FindById(WC_VEHICLE_DEPOT, v->tile);
 	if (w != NULL) {
 		WP(w, depot_d).sel = INVALID_VEHICLE;
 		ResetObjectToPlace();
--- a/src/dock_gui.cpp	Sun Feb 11 21:20:30 2007 +0000
+++ b/src/dock_gui.cpp	Sun Feb 11 22:57:24 2007 +0000
@@ -160,12 +160,12 @@
 		break;
 
 	case WE_ABORT_PLACE_OBJ:
-		RaiseWindowButtons(w);
+		w->RaiseButtons();
 
-		w = FindWindowById(WC_BUILD_STATION, 0);
+		w = Window::FindById(WC_BUILD_STATION, 0);
 		if (w != NULL) WP(w,def_d).close = true;
 
-		w = FindWindowById(WC_BUILD_DEPOT, 0);
+		w = Window::FindById(WC_BUILD_DEPOT, 0);
 		if (w != NULL) WP(w,def_d).close = true;
 		break;
 
@@ -250,14 +250,14 @@
 				_station_show_coverage = (e->we.click.widget != 3);
 				LowerWindowWidget(w, _station_show_coverage + 3);
 				SndPlayFx(SND_15_BEEP);
-				SetWindowDirty(w);
+				w->SetDirty();
 				break;
 		}
 		break;
 
 	case WE_MOUSELOOP:
 		if (WP(w,def_d).close) {
-			DeleteWindow(w);
+			w->Close();
 			return;
 		}
 
@@ -325,13 +325,13 @@
 			LowerWindowWidget(w, _ship_depot_direction + 3);
 			SndPlayFx(SND_15_BEEP);
 			UpdateDocksDirection();
-			SetWindowDirty(w);
+			w->SetDirty();
 			break;
 		}
 	} break;
 
 	case WE_MOUSELOOP:
-		if (WP(w,def_d).close) DeleteWindow(w);
+		if (WP(w,def_d).close) w->Close();
 		break;
 
 	case WE_DESTROY:
--- a/src/engine_gui.cpp	Sun Feb 11 21:20:30 2007 +0000
+++ b/src/engine_gui.cpp	Sun Feb 11 22:57:24 2007 +0000
@@ -98,7 +98,7 @@
 				DoCommandP(0, w->window_number, 0, NULL, CMD_WANT_ENGINE_PREVIEW);
 				/* Fallthrough */
 			case 3:
-				DeleteWindow(w);
+				w->Close();
 				break;
 		}
 		break;
--- a/src/genworld.cpp	Sun Feb 11 21:20:30 2007 +0000
+++ b/src/genworld.cpp	Sun Feb 11 22:57:24 2007 +0000
@@ -286,7 +286,7 @@
 	ShowGenerateWorldProgress();
 
 	/* Centre the view on the map */
-	if (FindWindowById(WC_MAIN_WINDOW, 0) != NULL) {
+	if (Window::FindById(WC_MAIN_WINDOW, 0) != NULL) {
 		ScrollMainWindowToTile(TileXY(MapSizeX() / 2, MapSizeY() / 2));
 	}
 }
--- a/src/genworld_gui.cpp	Sun Feb 11 21:20:30 2007 +0000
+++ b/src/genworld_gui.cpp	Sun Feb 11 22:57:24 2007 +0000
@@ -328,7 +328,7 @@
 		break;
 	case WE_CLICK:
 		switch (e->we.click.widget) {
-		case 0: DeleteWindow(w); break;
+		case 0: w->Close(); break;
 		case GLAND_TEMPERATE: case GLAND_ARCTIC: case GLAND_TROPICAL: case GLAND_TOYLAND:
 			RaiseWindowWidget(w, _opt_newgame.landscape + GLAND_TEMPERATE);
 			SetNewLandscapeType(e->we.click.widget - GLAND_TEMPERATE);
@@ -349,7 +349,7 @@
 			_patches_newgame.generation_seed = InteractiveRandom();
 			snprintf(_genseed_buffer, lengthof(_genseed_buffer), "%u", _patches_newgame.generation_seed);
 			UpdateTextBufferSize(&_genseed_query.text);
-			SetWindowDirty(w);
+			w->SetDirty();
 			break;
 		case GLAND_GENERATE_BUTTON: // Generate
 			if (mode == GLWP_HEIGHTMAP && (
@@ -367,8 +367,8 @@
 		case GLAND_START_DATE_DOWN: case GLAND_START_DATE_UP: // Year buttons
 			/* Don't allow too fast scrolling */
 			if ((w->flags4 & WF_TIMEOUT_MASK) <= 2 << WF_TIMEOUT_SHL) {
-				HandleButtonClick(w, e->we.click.widget);
-				SetWindowDirty(w);
+				w->HandleButtonClick(e->we.click.widget);
+				w->SetDirty();
 
 				_patches_newgame.starting_year = clamp(_patches_newgame.starting_year + e->we.click.widget - GLAND_START_DATE_TEXT, MIN_YEAR, MAX_YEAR);
 			}
@@ -382,8 +382,8 @@
 		case GLAND_SNOW_LEVEL_DOWN: case GLAND_SNOW_LEVEL_UP: // Snow line buttons
 			/* Don't allow too fast scrolling */
 			if ((w->flags4 & WF_TIMEOUT_MASK) <= 2 << WF_TIMEOUT_SHL) {
-				HandleButtonClick(w, e->we.click.widget);
-				SetWindowDirty(w);
+				w->HandleButtonClick(e->we.click.widget);
+				w->SetDirty();
 
 				_patches_newgame.snow_line_height = clamp(_patches_newgame.snow_line_height + e->we.click.widget - GLAND_SNOW_LEVEL_TEXT, 2, 13);
 			}
@@ -467,7 +467,7 @@
 				DoCommandP(0, 13, _opt_newgame.diff.quantity_sea_lakes, NULL, CMD_CHANGE_DIFFICULTY_LEVEL);
 				break;
 		}
-		SetWindowDirty(w);
+		w->SetDirty();
 		break;
 
 	case WE_ON_EDIT_TEXT: {
@@ -485,7 +485,7 @@
 				break;
 			}
 
-			SetWindowDirty(w);
+			w->SetDirty();
 		}
 		break;
 	}
@@ -628,8 +628,8 @@
 		case CSCEN_START_DATE_DOWN: case CSCEN_START_DATE_UP: // Year buttons
 			/* Don't allow too fast scrolling */
 			if ((w->flags4 & WF_TIMEOUT_MASK) <= 2 << WF_TIMEOUT_SHL) {
-				HandleButtonClick(w, e->we.click.widget);
-				SetWindowDirty(w);
+				w->HandleButtonClick(e->we.click.widget);
+				w->SetDirty();
 
 				_patches_newgame.starting_year = clamp(_patches_newgame.starting_year + e->we.click.widget - CSCEN_START_DATE_TEXT, MIN_YEAR, MAX_YEAR);
 			}
@@ -643,8 +643,8 @@
 		case CSCEN_FLAT_LAND_HEIGHT_DOWN: case CSCEN_FLAT_LAND_HEIGHT_UP: // Height level buttons
 			/* Don't allow too fast scrolling */
 			if ((w->flags4 & WF_TIMEOUT_MASK) <= 2 << WF_TIMEOUT_SHL) {
-				HandleButtonClick(w, e->we.click.widget);
-				SetWindowDirty(w);
+				w->HandleButtonClick(e->we.click.widget);
+				w->SetDirty();
 
 				_patches_newgame.se_flat_world_height = clamp(_patches_newgame.se_flat_world_height + e->we.click.widget - CSCEN_FLAT_LAND_HEIGHT_TEXT, 0, 15);
 			}
@@ -663,7 +663,7 @@
 			case CSCEN_MAPSIZE_X_PULLDOWN: _patches_newgame.map_x = e->we.dropdown.index + 6; break;
 			case CSCEN_MAPSIZE_Y_PULLDOWN: _patches_newgame.map_y = e->we.dropdown.index + 6; break;
 		}
-		SetWindowDirty(w);
+		w->SetDirty();
 		break;
 
 	case WE_ON_EDIT_TEXT: {
@@ -681,7 +681,7 @@
 				break;
 			}
 
-			SetWindowDirty(w);
+			w->SetDirty();
 		}
 		break;
 	}
@@ -791,7 +791,7 @@
 		SetDParam(1, _tp.total);
 		DrawStringCentered(90, 58, STR_GENERATION_PROGRESS, 0);
 
-		SetWindowDirty(w);
+		w->SetDirty();
 		break;
 	}
 }
--- a/src/graph_gui.cpp	Sun Feb 11 21:20:30 2007 +0000
+++ b/src/graph_gui.cpp	Sun Feb 11 22:57:24 2007 +0000
@@ -281,7 +281,7 @@
 		if (IS_INT_INSIDE(e->we.click.widget, 3, 11)) {
 			TOGGLEBIT(_legend_excluded_players, e->we.click.widget - 3);
 			ToggleWidgetLoweredState(w, e->we.click.widget);
-			SetWindowDirty(w);
+			w->SetDirty();
 			InvalidateWindow(WC_INCOME_GRAPH, 0);
 			InvalidateWindow(WC_OPERATING_PROFIT, 0);
 			InvalidateWindow(WC_DELIVERED_CARGO, 0);
@@ -774,7 +774,7 @@
 		case 11: case 12: case 13: case 14:
 			TOGGLEBIT(_legend_excluded_cargo, e->we.click.widget - 3);
 			ToggleWidgetLoweredState(w, e->we.click.widget);
-			SetWindowDirty(w);
+			w->SetDirty();
 			break;
 		}
 	} break;
@@ -929,7 +929,7 @@
 					/* Raise and disable the widget for the previous selection. */
 					RaiseWindowWidget(w, _performance_rating_detail_player + 13);
 					DisableWindowWidget(w, _performance_rating_detail_player + 13);
-					SetWindowDirty(w);
+					w->SetDirty();
 
 					_performance_rating_detail_player = INVALID_PLAYER;
 				}
@@ -938,7 +938,7 @@
 					if (GetPlayer(i)->is_active) {
 						/* Lower the widget corresponding to this player. */
 						LowerWindowWidget(w, i + 13);
-						SetWindowDirty(w);
+						w->SetDirty();
 
 						_performance_rating_detail_player = i;
 						break;
@@ -958,7 +958,7 @@
 						DisableWindowWidget(w, i + 13);
 
 						// We need a repaint
-						SetWindowDirty(w);
+						w->SetDirty();
 					}
 					continue;
 				}
@@ -968,7 +968,7 @@
 					// New player! Yippie :p
 					EnableWindowWidget(w, i + 13);
 					// We need a repaint
-					SetWindowDirty(w);
+					w->SetDirty();
 				}
 
 				x = (i == _performance_rating_detail_player) ? 1 : 0;
@@ -1057,7 +1057,7 @@
 					RaiseWindowWidget(w, _performance_rating_detail_player + 13);
 					_performance_rating_detail_player = (PlayerID)(e->we.click.widget - 13);
 					LowerWindowWidget(w, _performance_rating_detail_player + 13);
-					SetWindowDirty(w);
+					w->SetDirty();
 				}
 			}
 			break;
@@ -1080,7 +1080,7 @@
 			w->custom[1] = 5;
 
 			if (_performance_rating_detail_player != INVALID_PLAYER) LowerWindowWidget(w, _performance_rating_detail_player + 13);
-			SetWindowDirty(w);
+			w->SetDirty();
 
 			break;
 		}
@@ -1097,7 +1097,7 @@
 						// Skip if player is not active
 						if (p2->is_active) UpdateCompanyRatingAndValue(p2, false);
 					}
-					SetWindowDirty(w);
+					w->SetDirty();
 				}
 			}
 
--- a/src/industry_gui.cpp	Sun Feb 11 21:20:30 2007 +0000
+++ b/src/industry_gui.cpp	Sun Feb 11 22:57:24 2007 +0000
@@ -54,7 +54,7 @@
 		break;
 
 	case WE_ABORT_PLACE_OBJ:
-		RaiseWindowButtons(w);
+		w->RaiseButtons();
 		break;
 	}
 }
@@ -373,7 +373,7 @@
 					}
 
 					UpdateIndustryProduction(i);
-					SetWindowDirty(w);
+					w->SetDirty();
 					w->flags4 |= 5 << WF_TIMEOUT_SHL;
 					WP(w,vp2_d).data_2 = line+1;
 					WP(w,vp2_d).data_3 = (x < 15 ? 1 : 2);
@@ -395,7 +395,7 @@
 	case WE_TIMEOUT:
 		WP(w,vp2_d).data_2 = 0;
 		WP(w,vp2_d).data_3 = 0;
-		SetWindowDirty(w);
+		w->SetDirty();
 		break;
 
 	case WE_ON_EDIT_TEXT:
@@ -405,7 +405,7 @@
 
 			i->production_rate[line] = clampu(atoi(e->we.edittext.str), 0, 255);
 			UpdateIndustryProduction(i);
-			SetWindowDirty(w);
+			w->SetDirty();
 		}
 	}
 }
@@ -626,25 +626,25 @@
 		case 3: {
 			_industry_sort_order = _industry_sort_order==0 ? 1 : 0;
 			_industry_sort_dirty = true;
-			SetWindowDirty(w);
+			w->SetDirty();
 		} break;
 
 		case 4: {
 			_industry_sort_order = _industry_sort_order==2 ? 3 : 2;
 			_industry_sort_dirty = true;
-			SetWindowDirty(w);
+			w->SetDirty();
 		} break;
 
 		case 5: {
 			_industry_sort_order = _industry_sort_order==4 ? 5 : 4;
 			_industry_sort_dirty = true;
-			SetWindowDirty(w);
+			w->SetDirty();
 		} break;
 
 		case 6: {
 			_industry_sort_order = _industry_sort_order==6 ? 7 : 6;
 			_industry_sort_dirty = true;
-			SetWindowDirty(w);
+			w->SetDirty();
 		} break;
 
 		case 8: {
@@ -661,7 +661,7 @@
 		break;
 
 	case WE_4:
-		SetWindowDirty(w);
+		w->SetDirty();
 		break;
 
 	case WE_RESIZE:
@@ -689,6 +689,6 @@
 		w->vscroll.cap = 16;
 		w->resize.height = w->height - 6 * 10; // minimum 10 items
 		w->resize.step_height = 10;
-		SetWindowDirty(w);
+		w->SetDirty();
 	}
 }
--- a/src/main_gui.cpp	Sun Feb 11 21:20:30 2007 +0000
+++ b/src/main_gui.cpp	Sun Feb 11 22:57:24 2007 +0000
@@ -111,7 +111,7 @@
 	if (IsWindowWidgetDisabled(w, widget)) return false;
 
 	SndPlayFx(SND_15_BEEP);
-	SetWindowDirty(w);
+	w->SetDirty();
 
 	if (IsWindowWidgetLowered(w, widget)) {
 		ResetObjectToPlace();
@@ -456,9 +456,9 @@
 	} break;
 
 	case WE_DESTROY: {
-			Window *v = FindWindowById(WC_MAIN_TOOLBAR, 0);
+			Window *v = Window::FindById(WC_MAIN_TOOLBAR, 0);
 			RaiseWindowWidget(v, WP(w,menu_d).main_button);
-			SetWindowDirty(v);
+			v->SetDirty();
 			return;
 		}
 
@@ -468,13 +468,13 @@
 
 
 		if (index < 0) {
-			Window *w2 = FindWindowById(WC_MAIN_TOOLBAR,0);
+			Window *w2 = Window::FindById(WC_MAIN_TOOLBAR,0);
 			if (GetWidgetFromPos(w2, e->we.popupmenu.pt.x - w2->left, e->we.popupmenu.pt.y - w2->top) == WP(w,menu_d).main_button)
 				index = WP(w,menu_d).sel_index;
 		}
 
 		action_id = WP(w,menu_d).action_id;
-		DeleteWindow(w);
+		w->Close();
 
 		if (index >= 0) {
 			assert((uint)index <= lengthof(_menu_clicked_procs));
@@ -490,7 +490,7 @@
 		if (index == -1 || index == WP(w,menu_d).sel_index) return;
 
 		WP(w,menu_d).sel_index = index;
-		SetWindowDirty(w);
+		w->SetDirty();
 		return;
 		}
 	}
@@ -531,11 +531,11 @@
 
 	if (WP(w,menu_d).item_count != num) {
 		WP(w,menu_d).item_count = num;
-		SetWindowDirty(w);
+		w->SetDirty();
 		num = num * 10 + 2;
 		w->height = num;
 		w->widget[0].bottom = w->widget[0].top + num - 1;
-		SetWindowDirty(w);
+		w->SetDirty();
 	}
 }
 
@@ -591,9 +591,9 @@
 		}
 
 	case WE_DESTROY: {
-		Window *v = FindWindowById(WC_MAIN_TOOLBAR, 0);
+		Window *v = Window::FindById(WC_MAIN_TOOLBAR, 0);
 		RaiseWindowWidget(v, WP(w,menu_d).main_button);
-		SetWindowDirty(v);
+		v->SetDirty();
 		return;
 		}
 
@@ -610,12 +610,12 @@
 		}
 
 		if (index < 0) {
-			Window *w2 = FindWindowById(WC_MAIN_TOOLBAR,0);
+			Window *w2 = Window::FindById(WC_MAIN_TOOLBAR,0);
 			if (GetWidgetFromPos(w2, e->we.popupmenu.pt.x - w2->left, e->we.popupmenu.pt.y - w2->top) == WP(w,menu_d).main_button)
 				index = WP(w,menu_d).sel_index;
 		}
 
-		DeleteWindow(w);
+		w->Close();
 
 		if (index >= 0) {
 			assert(index >= 0 && index < 30);
@@ -639,7 +639,7 @@
 		if (index == -1 || index == WP(w,menu_d).sel_index) return;
 
 		WP(w,menu_d).sel_index = index;
-		SetWindowDirty(w);
+		w->SetDirty();
 		return;
 		}
 	}
@@ -707,7 +707,7 @@
 	width = max(GetStringListMaxWidth(base_string, item_count) + 6, 140);
 	x = w->left + clamp(x, 0, w->width - width); // or alternatively '_screen.width - width'
 
-	w = AllocateWindow(x, 22, width, item_count * 10 + 2, MenuWndProc, WC_TOOLBAR_MENU, _menu_widgets);
+	w = Window::Allocate(x, 22, width, item_count * 10 + 2, MenuWndProc, WC_TOOLBAR_MENU, _menu_widgets);
 	w->widget[0].bottom = item_count * 10 + 1;
 	w->flags4 &= ~WF_WHITE_BORDER_MASK;
 
@@ -733,7 +733,7 @@
 	InvalidateWidget(w, main_button);
 
 	DeleteWindowById(WC_TOOLBAR_MENU, 0);
-	w = AllocateWindow(x, 0x16, 0xF1, 0x52, PlayerMenuWndProc, WC_TOOLBAR_MENU, _player_menu_widgets);
+	w = Window::Allocate(x, 0x16, 0xF1, 0x52, PlayerMenuWndProc, WC_TOOLBAR_MENU, _player_menu_widgets);
 	w->flags4 &= ~WF_WHITE_BORDER_MASK;
 	WP(w,menu_d).item_count = 0;
 	WP(w,menu_d).sel_index = (_local_player != PLAYER_SPECTATOR) ? _local_player : GetPlayerIndexFromMenu(0);
@@ -883,7 +883,7 @@
 		vp->virtual_left = WP(w, vp_d).scrollpos_x;
 		vp->virtual_top = WP(w, vp_d).scrollpos_y;
 	}
-	SetWindowDirty(w);
+	w->SetDirty();
 	/* Update the windows that have zoom-buttons to perhaps disable their buttons */
 	SendWindowMessageClass(w->window_class, how, w->window_number, 0);
 	return true;
@@ -891,16 +891,16 @@
 
 static void ToolbarZoomInClick(Window *w)
 {
-	if (DoZoomInOutWindow(ZOOM_IN, FindWindowById(WC_MAIN_WINDOW, 0))) {
-		HandleButtonClick(w, 17);
+	if (DoZoomInOutWindow(ZOOM_IN, Window::FindById(WC_MAIN_WINDOW, 0))) {
+		w->HandleButtonClick(17);
 		SndPlayFx(SND_15_BEEP);
 	}
 }
 
 static void ToolbarZoomOutClick(Window *w)
 {
-	if (DoZoomInOutWindow(ZOOM_OUT,FindWindowById(WC_MAIN_WINDOW, 0))) {
-		HandleButtonClick(w, 18);
+	if (DoZoomInOutWindow(ZOOM_OUT,Window::FindById(WC_MAIN_WINDOW, 0))) {
+		w->HandleButtonClick(18);
 		SndPlayFx(SND_15_BEEP);
 	}
 }
@@ -975,8 +975,8 @@
 {
 	// don't allow too fast scrolling
 	if ((w->flags4 & WF_TIMEOUT_MASK) <= 2 << WF_TIMEOUT_SHL) {
-		HandleButtonClick(w, 6);
-		SetWindowDirty(w);
+		w->HandleButtonClick(6);
+		w->SetDirty();
 
 		_patches_newgame.starting_year = clamp(_patches_newgame.starting_year - 1, MIN_YEAR, MAX_YEAR);
 		SetDate(ConvertYMDToDate(_patches_newgame.starting_year, 0, 1));
@@ -988,8 +988,8 @@
 {
 	// don't allow too fast scrolling
 	if ((w->flags4 & WF_TIMEOUT_MASK) <= 2 << WF_TIMEOUT_SHL) {
-		HandleButtonClick(w, 7);
-		SetWindowDirty(w);
+		w->HandleButtonClick(7);
+		w->SetDirty();
 
 		_patches_newgame.starting_year = clamp(_patches_newgame.starting_year + 1, MIN_YEAR, MAX_YEAR);
 		SetDate(ConvertYMDToDate(_patches_newgame.starting_year, 0, 1));
@@ -1005,16 +1005,16 @@
 
 static void ToolbarScenZoomIn(Window *w)
 {
-	if (DoZoomInOutWindow(ZOOM_IN, FindWindowById(WC_MAIN_WINDOW, 0))) {
-		HandleButtonClick(w, 9);
+	if (DoZoomInOutWindow(ZOOM_IN, Window::FindById(WC_MAIN_WINDOW, 0))) {
+		w->HandleButtonClick(9);
 		SndPlayFx(SND_15_BEEP);
 	}
 }
 
 static void ToolbarScenZoomOut(Window *w)
 {
-	if (DoZoomInOutWindow(ZOOM_OUT, FindWindowById(WC_MAIN_WINDOW, 0))) {
-		HandleButtonClick(w, 10);
+	if (DoZoomInOutWindow(ZOOM_OUT, Window::FindById(WC_MAIN_WINDOW, 0))) {
+		w->HandleButtonClick(10);
 		SndPlayFx(SND_15_BEEP);
 	}
 }
@@ -1313,17 +1313,17 @@
 			break;
 		case 12: case 13: { /* Increase/Decrease terraform size */
 			int size = (e->we.click.widget == 12) ? 1 : -1;
-			HandleButtonClick(w, e->we.click.widget);
+			w->HandleButtonClick(e->we.click.widget);
 			size += _terraform_size;
 
 			if (!IS_INT_INSIDE(size, 1, 8 + 1)) return;
 			_terraform_size = size;
 
 			SndPlayFx(SND_15_BEEP);
-			SetWindowDirty(w);
+			w->SetDirty();
 		} break;
 		case 14: /* gen random land */
-			HandleButtonClick(w, 14);
+			w->HandleButtonClick(14);
 			ShowCreateScenario();
 			break;
 		case 15: /* Reset landscape */
@@ -1362,8 +1362,8 @@
 		break;
 
 	case WE_ABORT_PLACE_OBJ:
-		RaiseWindowButtons(w);
-		SetWindowDirty(w);
+		w->RaiseButtons();
+		w->SetDirty();
 		break;
 	}
 }
@@ -1383,7 +1383,7 @@
 
 static void ToolbarScenGenLand(Window *w)
 {
-	HandleButtonClick(w, 11);
+	w->HandleButtonClick(11);
 	SndPlayFx(SND_15_BEEP);
 
 	ShowEditorTerraformToolBar();
@@ -1437,7 +1437,7 @@
 		case 5: {/* random town */
 			Town *t;
 
-			HandleButtonClick(w, 5);
+			w->HandleButtonClick(5);
 			_generating_world = true;
 			t = CreateRandomTown(20, _scengen_town_size);
 			_generating_world = false;
@@ -1451,7 +1451,7 @@
 			break;
 		}
 		case 6: {/* many random towns */
-			HandleButtonClick(w, 6);
+			w->HandleButtonClick(6);
 
 			_generating_world = true;
 			if (!GenerateTowns()) ShowErrorMessage(STR_NO_SPACE_FOR_TOWN, STR_CANNOT_GENERATE_TOWN, 0, 0);
@@ -1463,7 +1463,7 @@
 			RaiseWindowWidget(w, (_scengen_town_size - 1) + 7);
 			_scengen_town_size = (e->we.click.widget - 7) + 1;
 			LowerWindowWidget(w, (_scengen_town_size - 1) + 7);
-			SetWindowDirty(w);
+			w->SetDirty();
 			break;
 		}
 		break;
@@ -1471,15 +1471,15 @@
 	case WE_TIMEOUT:
 		RaiseWindowWidget(w, 5);
 		RaiseWindowWidget(w, 6);
-		SetWindowDirty(w);
+		w->SetDirty();
 		break;
 	case WE_PLACE_OBJ:
 		_place_proc(e->we.place.tile);
 		break;
 	case WE_ABORT_PLACE_OBJ:
-		RaiseWindowButtons(w);
+		w->RaiseButtons();
 		LowerWindowWidget(w, (_scengen_town_size - 1) + 7);
-		SetWindowDirty(w);
+		w->SetDirty();
 		break;
 	}
 }
@@ -1494,7 +1494,7 @@
 
 static void ToolbarScenGenTown(Window *w)
 {
-	HandleButtonClick(w, 12);
+	w->HandleButtonClick(12);
 	SndPlayFx(SND_15_BEEP);
 
 	AllocateWindowDescFront(&_scen_edit_town_gen_desc, 0);
@@ -1645,7 +1645,7 @@
 
 	case WE_CLICK:
 		if (e->we.click.widget == 3) {
-			HandleButtonClick(w, 3);
+			w->HandleButtonClick(3);
 
 			if (!AnyTownExists()) {
 				ShowErrorMessage(STR_0286_MUST_BUILD_TOWN_FIRST, STR_CAN_T_GENERATE_INDUSTRIES, 0, 0);
@@ -1685,8 +1685,8 @@
 		break;
 	}
 	case WE_ABORT_PLACE_OBJ:
-		RaiseWindowButtons(w);
-		SetWindowDirty(w);
+		w->RaiseButtons();
+		w->SetDirty();
 		break;
 	case WE_TIMEOUT:
 		RaiseWindowWidget(w, 3);
@@ -1737,28 +1737,28 @@
 
 static void ToolbarScenGenIndustry(Window *w)
 {
-	HandleButtonClick(w, 13);
+	w->HandleButtonClick(13);
 	SndPlayFx(SND_15_BEEP);
 	AllocateWindowDescFront(_scenedit_industry_descs[_opt.landscape],0);
 }
 
 static void ToolbarScenBuildRoad(Window *w)
 {
-	HandleButtonClick(w, 14);
+	w->HandleButtonClick(14);
 	SndPlayFx(SND_15_BEEP);
 	ShowBuildRoadScenToolbar();
 }
 
 static void ToolbarScenPlantTrees(Window *w)
 {
-	HandleButtonClick(w, 15);
+	w->HandleButtonClick(15);
 	SndPlayFx(SND_15_BEEP);
 	ShowBuildTreesScenToolbar();
 }
 
 static void ToolbarScenPlaceSign(Window *w)
 {
-	HandleButtonClick(w, 16);
+	w->HandleButtonClick(16);
 	SndPlayFx(SND_15_BEEP);
 	SelectSignTool();
 }
@@ -1811,9 +1811,9 @@
 		/* If spectator, disable all construction buttons
 		 * ie : Build road, rail, ships, airports and landscaping
 		 * Since enabled state is the default, just disable when needed */
-		SetWindowWidgetsDisabledState(w, _current_player == PLAYER_SPECTATOR, 19, 20, 21, 22, 23, WIDGET_LIST_END);
+		w->SetWidgetsDisabledState(_current_player == PLAYER_SPECTATOR, 19, 20, 21, 22, 23, WIDGET_LIST_END);
 		/* disable company list drop downs, if there are no companies */
-		SetWindowWidgetsDisabledState(w, ActivePlayerCount() == 0, 7, 8, 13, 14, 15, 16, WIDGET_LIST_END);
+		w->SetWidgetsDisabledState(ActivePlayerCount() == 0, 7, 8, 13, 14, 15, 16, WIDGET_LIST_END);
 
 		DrawWindowWidgets(w);
 		break;
@@ -1865,7 +1865,7 @@
 
 	case WE_ABORT_PLACE_OBJ: {
 		RaiseWindowWidget(w, 25);
-		SetWindowDirty(w);
+		w->SetDirty();
 	} break;
 
 	case WE_MOUSELOOP:
@@ -1892,7 +1892,7 @@
 	}
 
 		case WE_MESSAGE:
-			HandleZoomMessage(w, FindWindowById(WC_MAIN_WINDOW, 0)->viewport, 17, 18);
+			HandleZoomMessage(w, Window::FindById(WC_MAIN_WINDOW, 0)->viewport, 17, 18);
 			break;
 	}
 }
@@ -2064,23 +2064,23 @@
 
 	case WE_ABORT_PLACE_OBJ: {
 		RaiseWindowWidget(w, 25);
-		SetWindowDirty(w);
+		w->SetDirty();
 	} break;
 
 	case WE_MOUSELOOP:
 		if (IsWindowWidgetLowered(w, 0) != !!_pause) {
 			ToggleWidgetLoweredState(w, 0);
-			SetWindowDirty(w);
+			w->SetDirty();
 		}
 
 		if (IsWindowWidgetLowered(w, 1) != !!_fast_forward) {
 			ToggleWidgetLoweredState(w, 1);
-			SetWindowDirty(w);
+			w->SetDirty();
 		}
 		break;
 
 		case WE_MESSAGE:
-			HandleZoomMessage(w, FindWindowById(WC_MAIN_WINDOW, 0)->viewport, 9, 10);
+			HandleZoomMessage(w, Window::FindById(WC_MAIN_WINDOW, 0)->viewport, 9, 10);
 			break;
 	}
 }
@@ -2167,7 +2167,7 @@
 			DrawStringCentered(320, 1, STR_032F_AUTOSAVE, 0);
 		} else if (_pause) {
 			DrawStringCentered(320, 1, STR_0319_PAUSED, 0);
-		} else if (WP(w,def_d).data_1 > -1280 && FindWindowById(WC_NEWS_WINDOW,0) == NULL && _statusbar_news_item.string_id != 0) {
+		} else if (WP(w,def_d).data_1 > -1280 && Window::FindById(WC_NEWS_WINDOW,0) == NULL && _statusbar_news_item.string_id != 0) {
 			// Draw the scrolling news text
 			if (!DrawScrollingStatusText(&_statusbar_news_item, WP(w,def_d).data_1))
 				WP(w,def_d).data_1 = -1280;
@@ -2185,7 +2185,7 @@
 
 	case WE_MESSAGE:
 		w->message.msg = e->we.message.msg;
-		SetWindowDirty(w);
+		w->SetDirty();
 		break;
 
 	case WE_CLICK:
@@ -2415,7 +2415,7 @@
 	width = _screen.width;
 	height = _screen.height;
 
-	w = AllocateWindow(0, 0, width, height, MainWindowWndProc, WC_MAIN_WINDOW, NULL);
+	w = Window::Allocate(0, 0, width, height, MainWindowWndProc, WC_MAIN_WINDOW, NULL);
 	AssignWindowViewport(w, 0, 0, width, height, TileXY(32, 32), 0);
 
 	// XXX: these are not done
@@ -2474,3 +2474,4 @@
 
 
 
+
--- a/src/misc/countedptr.hpp	Sun Feb 11 21:20:30 2007 +0000
+++ b/src/misc/countedptr.hpp	Sun Feb 11 22:57:24 2007 +0000
@@ -3,7 +3,7 @@
 #ifndef COUNTEDPTR_HPP
 #define COUNTEDPTR_HPP
 
-#if 0 // reenable when needed
+#if 1 // reenable when needed
 /** @file CCountedPtr - smart pointer implementation */
 
 /** CCountedPtr - simple reference counting smart pointer.
@@ -54,7 +54,7 @@
 	FORCEINLINE operator const Tcls*() const {assert(m_pT == NULL); return m_pT;}
 
 	/** raw pointer casting operator - non-const way */
-	FORCEINLINE operator Tcls*() {assert(m_pT == NULL); return m_pT;}
+	FORCEINLINE operator Tcls*() {return m_pT;}
 
 	/** operator & to support output arguments */
 	FORCEINLINE Tcls** operator &() {assert(m_pT == NULL); return &m_pT;}
@@ -72,10 +72,10 @@
 	FORCEINLINE bool IsNull() const {return m_pT == NULL;}
 
 	/** another way how to test for NULL value */
-	FORCEINLINE bool operator == (const CCountedPtr& sp) const {return m_pT == sp.m_pT;}
+	//FORCEINLINE bool operator == (const CCountedPtr& sp) const {return m_pT == sp.m_pT;}
 
 	/** yet another way how to test for NULL value */
-	FORCEINLINE bool operator != (const CCountedPtr& sp) const {return m_pT != sp.m_pT;}
+	//FORCEINLINE bool operator != (const CCountedPtr& sp) const {return m_pT != sp.m_pT;}
 
 	/** assign pointer w/o incrementing ref count */
 	FORCEINLINE void Attach(Tcls* pT) {Release(); m_pT = pT;}
--- a/src/misc_cmd.cpp	Sun Feb 11 21:20:30 2007 +0000
+++ b/src/misc_cmd.cpp	Sun Feb 11 22:57:24 2007 +0000
@@ -329,7 +329,7 @@
 		/* If we are a network-client, update the difficult setting (if it is open).
 		 * Use this instead of just dirtying the window because we need to load in
 		 * the new difficulty settings */
-		if (_networking && !_network_server && FindWindowById(WC_GAME_OPTIONS, 0) != NULL)
+		if (_networking && !_network_server && Window::FindById(WC_GAME_OPTIONS, 0) != NULL)
 			ShowGameDifficulty();
 	}
 	return 0;
--- a/src/misc_gui.cpp	Sun Feb 11 21:20:30 2007 +0000
+++ b/src/misc_gui.cpp	Sun Feb 11 22:57:24 2007 +0000
@@ -277,7 +277,7 @@
 	case WE_MOUSELOOP: /* Timer to scroll the text and adjust the new top */
 		if (WP(w, scroller_d).counter++ % 3 == 0) {
 			WP(w, scroller_d).height--;
-			SetWindowDirty(w);
+			w->SetDirty();
 		}
 		break;
 	}
@@ -398,7 +398,7 @@
 		break;
 
 	case WE_ABORT_PLACE_OBJ:
-		RaiseWindowButtons(w);
+		w->RaiseButtons();
 		break;
 	}
 }
@@ -529,11 +529,11 @@
 		break;
 
 	case WE_MOUSELOOP:
-		if (_right_button_down) DeleteWindow(w);
+		if (_right_button_down) w->Close();
 		break;
 
 	case WE_4:
-		if (--_errmsg_duration == 0) DeleteWindow(w);
+		if (--_errmsg_duration == 0) w->Close();
 		break;
 
 	case WE_DESTROY:
@@ -545,7 +545,7 @@
 		if (e->we.keypress.keycode == WKC_SPACE) {
 			// Don't continue.
 			e->we.keypress.cont = false;
-			DeleteWindow(w);
+			w->Close();
 		}
 		break;
 	}
@@ -572,7 +572,7 @@
 
 		if ( (x|y) != 0) {
 			pt = RemapCoords2(x, y);
-			vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport;
+			vp = Window::FindById(WC_MAIN_WINDOW, 0)->viewport;
 
 			// move x pos to opposite corner
 			pt.x = ((pt.x - vp->virtual_left) >> vp->zoom) + vp->left;
@@ -586,18 +586,18 @@
 			pt.x = (_screen.width - 240) >> 1;
 			pt.y = (_screen.height - 46) >> 1;
 		}
-		w = AllocateWindow(pt.x, pt.y, 240, 46, ErrmsgWndProc, WC_ERRMSG, _errmsg_widgets);
+		w = Window::Allocate(pt.x, pt.y, 240, 46, ErrmsgWndProc, WC_ERRMSG, _errmsg_widgets);
 	} else {
 		if ( (x|y) != 0) {
 			pt = RemapCoords2(x, y);
-			vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport;
+			vp = Window::FindById(WC_MAIN_WINDOW, 0)->viewport;
 			pt.x = clamp(((pt.x - vp->virtual_left) >> vp->zoom) + vp->left - (334/2), 0, _screen.width - 334);
 			pt.y = clamp(((pt.y - vp->virtual_top) >> vp->zoom) + vp->top - (137/2), 22, _screen.height - 137);
 		} else {
 			pt.x = (_screen.width - 334) >> 1;
 			pt.y = (_screen.height - 137) >> 1;
 		}
-		w = AllocateWindow(pt.x, pt.y, 334, 137, ErrmsgWndProc, WC_ERRMSG, _errmsg_face_widgets);
+		w = Window::Allocate(pt.x, pt.y, 334, 137, ErrmsgWndProc, WC_ERRMSG, _errmsg_face_widgets);
 	}
 
 	w->desc_flags = WDF_STD_BTN | WDF_DEF_WIDGET;
@@ -663,9 +663,9 @@
 			/* We can show tooltips while dragging tools. These are shown as long as
 			 * we are dragging the tool. Normal tooltips work with rmb */
 			if (WP(w, tooltips_d).paramcount == 0 ) {
-				if (!_right_button_down) DeleteWindow(w);
+				if (!_right_button_down) w->Close();
 			} else {
-				if (!_left_button_down) DeleteWindow(w);
+				if (!_left_button_down) w->Close();
 			}
 
 			break;
@@ -708,7 +708,7 @@
 	if (y + br.height > _screen.height - 12) y = _cursor.pos.y + _cursor.offs.y - br.height - 5;
 	x = clamp(_cursor.pos.x - (br.width >> 1), 0, _screen.width - br.width);
 
-	w = AllocateWindow(x, y, br.width, br.height, TooltipsWndProc, WC_TOOLTIPS, _tooltips_widgets);
+	w = Window::Allocate(x, y, br.width, br.height, TooltipsWndProc, WC_TOOLTIPS, _tooltips_widgets);
 
 	WP(w, tooltips_d).string_id = str;
 	assert(sizeof(WP(w, tooltips_d).params[0]) == sizeof(params[0]));
@@ -764,7 +764,7 @@
 {
 	if (_thd.dirty & 1) {
 		_thd.dirty &= ~1;
-		SetWindowDirty(w);
+		w->SetDirty();
 	}
 }
 
@@ -1092,7 +1092,7 @@
 					}
 					/* Fallthrough */
 				case QUERY_STR_WIDGET_CANCEL:
-					DeleteWindow(w);
+					w->Close();
 					break;
 			}
 			break;
@@ -1104,7 +1104,7 @@
 		case WE_KEYPRESS:
 			switch (HandleEditBoxKey(w, qs, QUERY_STR_WIDGET_TEXT, e)) {
 				case 1: goto press_ok; /* Enter pressed, confirms change */
-				case 2: DeleteWindow(w); break; /* ESC pressed, closes window, abandons changes */
+				case 2: w->Close(); break; /* ESC pressed, closes window, abandons changes */
 			}
 			break;
 
@@ -1218,7 +1218,7 @@
 					if (q->proc != NULL) q->proc(w->parent, true);
 					/* Fallthrough */
 				case QUERY_WIDGET_NO:
-					DeleteWindow(w);
+					w->Close();
 					break;
 				}
 			break;
@@ -1232,7 +1232,7 @@
 					/* Fallthrough */
 				case WKC_ESC:
 					e->we.keypress.cont = false;
-					DeleteWindow(w);
+					w->Close();
 					break;
 			}
 			break;
@@ -1278,7 +1278,7 @@
 	Window *w = AllocateWindowDesc(&_query_desc);
 	if (w == NULL) return;
 
-	if (parent == NULL) parent = FindWindowById(WC_MAIN_WINDOW, 0);
+	if (parent == NULL) parent = Window::FindById(WC_MAIN_WINDOW, 0);
 	w->parent = parent;
 	w->left = parent->left + (parent->width / 2) - (w->width / 2);
 	w->top = parent->top + (parent->height / 2) - (w->height / 2);
@@ -1468,19 +1468,19 @@
 			_savegame_sort_order = (_savegame_sort_order == SORT_BY_NAME) ?
 				SORT_BY_NAME | SORT_DESCENDING : SORT_BY_NAME;
 			_savegame_sort_dirty = true;
-			SetWindowDirty(w);
+			w->SetDirty();
 			break;
 
 		case 3: /* Sort save names by date */
 			_savegame_sort_order = (_savegame_sort_order == SORT_BY_DATE) ?
 				SORT_BY_DATE | SORT_DESCENDING : SORT_BY_DATE;
 			_savegame_sort_dirty = true;
-			SetWindowDirty(w);
+			w->SetDirty();
 			break;
 
 		case 6: /* OpenTTD 'button', jumps to OpenTTD directory */
 			FiosBrowseTo(&o_dir);
-			SetWindowDirty(w);
+			w->SetDirty();
 			BuildFileList();
 			break;
 
@@ -1502,13 +1502,13 @@
 					ttd_strlcpy(_file_to_saveload.name, name, sizeof(_file_to_saveload.name));
 					ttd_strlcpy(_file_to_saveload.title, file->title, sizeof(_file_to_saveload.title));
 
-					DeleteWindow(w);
+					w->Close();
 				} else if (_saveload_mode == SLD_LOAD_HEIGHTMAP) {
 					SetFiosType(file->type);
 					ttd_strlcpy(_file_to_saveload.name, name, sizeof(_file_to_saveload.name));
 					ttd_strlcpy(_file_to_saveload.title, file->title, sizeof(_file_to_saveload.title));
 
-					DeleteWindow(w);
+					w->Close();
 					ShowHeightmapLoad();
 				} else {
 					// SLD_SAVE_GAME, SLD_SAVE_SCENARIO copy clicked name to editbox
@@ -1518,7 +1518,7 @@
 				}
 			} else {
 				// Changed directory, need repaint.
-				SetWindowDirty(w);
+				w->SetDirty();
 				BuildFileList();
 			}
 			break;
@@ -1535,13 +1535,13 @@
 		break;
 	case WE_KEYPRESS:
 		if (e->we.keypress.keycode == WKC_ESC) {
-			DeleteWindow(w);
+			w->Close();
 			return;
 		}
 
 		if (_saveload_mode == SLD_SAVE_GAME || _saveload_mode == SLD_SAVE_SCENARIO) {
 			if (HandleEditBoxKey(w, &WP(w, querystr_d), 10, e) == 1) /* Press Enter */
-					HandleButtonClick(w, 12);
+					w->HandleButtonClick(12);
 		}
 		break;
 	case WE_TIMEOUT:
@@ -1559,7 +1559,7 @@
 			}
 
 			UpdateTextBufferSize(&WP(w, querystr_d).text);
-			SetWindowDirty(w);
+			w->SetDirty();
 		} else if (IsWindowWidgetLowered(w, 12)) { /* Save button clicked */
 			_switch_mode = SM_SAVE;
 			FiosMakeSavegameName(_file_to_saveload.name, WP(w,querystr_d).text.buf, sizeof(_file_to_saveload.name));
@@ -1663,7 +1663,7 @@
 
 void RedrawAutosave(void)
 {
-	SetWindowDirty(FindWindowById(WC_STATUS_BAR, 0));
+	Window::SetDirtyById(WC_STATUS_BAR, 0);
 }
 
 void SetFiosType(const byte fiostype)
@@ -1739,7 +1739,7 @@
 
 	SetDate(ConvertYMDToDate(_cur_year + p2, ymd.month, ymd.day));
 	EnginesMonthlyLoop();
-	SetWindowDirty(FindWindowById(WC_STATUS_BAR, 0));
+	Window::SetDirtyById(WC_STATUS_BAR, 0);
 	return _cur_year;
 }
 
@@ -1896,17 +1896,17 @@
 
 			if (value != oldvalue) {
 				WriteValue(ce->variable, ce->type, (int64)value);
-				SetWindowDirty(w);
+				w->SetDirty();
 			}
 
 			w->flags4 |= 5 << WF_TIMEOUT_SHL;
 
-			SetWindowDirty(w);
+			w->SetDirty();
 		}
 		break;
 	case WE_TIMEOUT:
 		WP(w,def_d).data_1 = 0;
-		SetWindowDirty(w);
+		w->SetDirty();
 		break;
 	}
 }
--- a/src/music_gui.cpp	Sun Feb 11 21:20:30 2007 +0000
+++ b/src/music_gui.cpp	Sun Feb 11 22:57:24 2007 +0000
@@ -255,7 +255,7 @@
 				if (p[i] == 0) {
 					p[i] = y + 1;
 					p[i + 1] = 0;
-					SetWindowDirty(w);
+					w->SetDirty();
 					SelectSongToPlay();
 					break;
 				}
@@ -275,13 +275,13 @@
 				p[i] = p[i + 1];
 				}
 
-			SetWindowDirty(w);
+			w->SetDirty();
 			SelectSongToPlay();
 		} break;
 
 		case 11: // clear
 			_playlists[msf.playlist][0] = 0;
-			SetWindowDirty(w);
+			w->SetDirty();
 			StopMusic();
 			SelectSongToPlay();
 			break;
@@ -294,7 +294,7 @@
 
 		case 5: case 6: case 7: case 8: case 9: case 10: /* set playlist */
 			msf.playlist = e->we.click.widget - 5;
-			SetWindowDirty(w);
+			w->SetDirty();
 			InvalidateWindow(WC_MUSIC_WINDOW, 0);
 			StopMusic();
 			SelectSongToPlay();
@@ -440,7 +440,7 @@
 				*vol = new_vol;
 				if (vol == &msf.music_vol)
 					MusicVolumeChanged(new_vol);
-				SetWindowDirty(w);
+				w->SetDirty();
 			}
 
 			_left_button_clicked = false;
@@ -455,7 +455,7 @@
 			break;
 		case 12: case 13: case 14: case 15: case 16: case 17: // playlist
 			msf.playlist = e->we.click.widget - 12;
-			SetWindowDirty(w);
+			w->SetDirty();
 			InvalidateWindow(WC_MUSIC_TRACK_SELECTION, 0);
 			StopMusic();
 			SelectSongToPlay();
--- a/src/network/network_gui.cpp	Sun Feb 11 21:20:30 2007 +0000
+++ b/src/network/network_gui.cpp	Sun Feb 11 22:57:24 2007 +0000
@@ -405,7 +405,7 @@
 
 			_ng_sorting.order = !!(ld->flags & VL_DESC);
 			_ng_sorting.criteria = ld->sort_type;
-			SetWindowDirty(w);
+			w->SetDirty();
 			break;
 		case 9: { /* Matrix to show networkgames */
 			NetworkGameList *cur_item;
@@ -418,7 +418,7 @@
 			for (; id_v > 0 && cur_item != NULL; id_v--) cur_item = cur_item->next;
 
 			nd->server = cur_item;
-			SetWindowDirty(w);
+			w->SetDirty();
 		} break;
 		case 11: /* Find server automatically */
 			switch (_network_lan_internet) {
@@ -461,7 +461,7 @@
 				break;
 		}
 
-		SetWindowDirty(w);
+		w->SetDirty();
 		break;
 
 	case WE_MOUSELOOP:
@@ -471,7 +471,7 @@
 	case WE_MESSAGE:
 		if (e->we.message.msg != 0) nd->server = NULL;
 		ld->flags |= VL_REBUILD;
-		SetWindowDirty(w);
+		w->SetDirty();
 		break;
 
 	case WE_KEYPRESS:
@@ -665,7 +665,7 @@
 			if (y >= w->vscroll.count) return;
 
 			nd->map = (y == 0) ? NULL : _fios_list + y - 1;
-			SetWindowDirty(w);
+			w->SetDirty();
 			} break;
 		case 7: case 8: /* Connection type */
 			ShowDropDownMenu(w, _connection_types_dropdown, _network_advertise, 8, 0, 0); // do it for widget 8
@@ -694,7 +694,7 @@
 					ttd_strlcpy(_file_to_saveload.name, name, sizeof(_file_to_saveload.name));
 					ttd_strlcpy(_file_to_saveload.title, nd->map->title, sizeof(_file_to_saveload.title));
 
-					DeleteWindow(w);
+					w->Close();
 					SwitchMode(SM_START_SCENARIO);
 				}
 			}
@@ -718,7 +718,7 @@
 			case 16: _network_game_info.server_lang    = e->we.dropdown.index;        break;
 		}
 
-		SetWindowDirty(w);
+		w->SetDirty();
 		break;
 
 	case WE_MOUSELOOP:
@@ -737,7 +737,7 @@
 	case WE_ON_EDIT_TEXT: {
 		ttd_strlcpy(_network_server_password, e->we.edittext.str, lengthof(_network_server_password));
 		_network_game_info.use_password = (_network_server_password[0] != '\0');
-		SetWindowDirty(w);
+		w->SetDirty();
 	} break;
 	}
 }
@@ -928,7 +928,7 @@
 
 			id_v += w->vscroll.pos;
 			nd->company = (id_v >= nd->server->info.companies_on) ? INVALID_PLAYER : NetworkLobbyFindCompanyIndex(id_v);
-			SetWindowDirty(w);
+			w->SetDirty();
 		}	break;
 		case 7: /* Join company */
 			if (nd->company != (byte)-1) {
@@ -951,7 +951,7 @@
 		}	break;
 
 	case WE_MESSAGE:
-		SetWindowDirty(w);
+		w->SetDirty();
 		break;
 	}
 }
@@ -1141,10 +1141,10 @@
 	// If height is changed
 	if (w->height != CLNWND_OFFSET + num + 1) {
 		// XXX - magic unfortunately; (num + 2) has to be one bigger than heigh (num + 1)
-		SetWindowDirty(w);
+		w->SetDirty();
 		w->widget[2].bottom = w->widget[2].top + num + 2;
 		w->height = CLNWND_OFFSET + num + 1;
-		SetWindowDirty(w);
+		w->SetDirty();
 		return false;
 	}
 	return true;
@@ -1224,7 +1224,7 @@
 	h = ClientListPopupHeigth();
 
 	// Allocate the popup
-	w = AllocateWindow(x, y, 150, h + 1, ClientListPopupWndProc, WC_TOOLBAR_MENU, _client_list_popup_widgets);
+	w = Window::Allocate(x, y, 150, h + 1, ClientListPopupWndProc, WC_TOOLBAR_MENU, _client_list_popup_widgets);
 	w->widget[0].bottom = w->widget[0].top + h;
 	w->widget[0].right = w->widget[0].left + 150;
 
@@ -1284,7 +1284,7 @@
 		if (index == -1 || index == WP(w,menu_d).sel_index) return;
 
 		WP(w,menu_d).sel_index = index;
-		SetWindowDirty(w);
+		w->SetDirty();
 	} break;
 
 	}
@@ -1342,7 +1342,7 @@
 		if (e->we.mouseover.pt.y == -1) {
 			_selected_clientlist_y = 0;
 			_selected_clientlist_item = 255;
-			SetWindowDirty(w);
+			w->SetDirty();
 			break;
 		}
 		// It did not change.. no update!
@@ -1357,7 +1357,7 @@
 		}
 
 		// Repaint
-		SetWindowDirty(w);
+		w->SetDirty();
 		break;
 
 	case WE_DESTROY: case WE_CREATE:
@@ -1387,7 +1387,7 @@
 		case NETWORK_GAME_PASSWORD:    caption = STR_NETWORK_NEED_GAME_PASSWORD_CAPTION; break;
 		case NETWORK_COMPANY_PASSWORD: caption = STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION; break;
 	}
-	ShowQueryString(STR_EMPTY, caption, 20, 180, FindWindowById(WC_NETWORK_STATUS_WINDOW, 0), CS_ALPHANUMERAL);
+	ShowQueryString(STR_EMPTY, caption, 20, 180, Window::FindById(WC_NETWORK_STATUS_WINDOW, 0), CS_ALPHANUMERAL);
 }
 
 
@@ -1426,7 +1426,7 @@
 		switch (e->we.click.widget) {
 			case 2: /* Disconnect button */
 				NetworkDisconnect();
-				DeleteWindow(w);
+				w->Close();
 				SwitchMode(SM_MENU);
 				ShowNetworkGameWindow();
 				break;
@@ -1466,7 +1466,7 @@
 	DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0);
 	w = AllocateWindowDesc(&_network_join_status_window_desc);
 	/* Parent the status window to the lobby */
-	if (w != NULL) w->parent = FindWindowById(WC_NETWORK_WINDOW, 0);
+	if (w != NULL) w->parent = Window::FindById(WC_NETWORK_WINDOW, 0);
 }
 
 static void SendChat(const char *buf, DestType type, byte dest)
@@ -1593,7 +1593,7 @@
 			/* Update the textbuffer */
 			UpdateTextBufferSize(&WP(w, querystr_d).text);
 
-			SetWindowDirty(w);
+			w->SetDirty();
 			free(pre_buf);
 			return;
 		}
@@ -1607,7 +1607,7 @@
 		/* Update the textbuffer */
 		UpdateTextBufferSize(&WP(w, querystr_d).text);
 
-		SetWindowDirty(w);
+		w->SetDirty();
 	}
 	free(pre_buf);
 }
@@ -1647,7 +1647,7 @@
 				byte dest = GB(WP(w, querystr_d).caption, 8, 8);
 				SendChat(WP(w, querystr_d).text.buf, type, dest);
 			} /* FALLTHROUGH */
-			case 0: /* Cancel */ DeleteWindow(w); break;
+			case 0: /* Cancel */ w->Close(); break;
 		}
 		break;
 
@@ -1666,7 +1666,7 @@
 				byte dest = GB(WP(w, querystr_d).caption, 8, 8);
 				SendChat(WP(w, querystr_d).text.buf, type, dest);
 			} /* FALLTHROUGH */
-				case 2: /* Escape */ DeleteWindow(w); break;
+				case 2: /* Escape */ w->Close(); break;
 			}
 		}
 		break;
--- a/src/newgrf_gui.cpp	Sun Feb 11 21:20:30 2007 +0000
+++ b/src/newgrf_gui.cpp	Sun Feb 11 22:57:24 2007 +0000
@@ -143,7 +143,7 @@
 
 					for (c = _all_grfs; c != NULL && i > 0; c = c->next, i--);
 					WP(w, newgrf_add_d).sel = c;
-					SetWindowDirty(w);
+					w->SetDirty();
 					break;
 				}
 
@@ -179,7 +179,7 @@
 				case 7: /* Rescan list */
 					WP(w, newgrf_add_d).sel = NULL;
 					ScanNewGRFFiles();
-					SetWindowDirty(w);
+					w->SetDirty();
 					break;
 			}
 			break;
@@ -244,7 +244,7 @@
 	bool disable_all = WP(w, newgrf_d).sel == NULL || !WP(w, newgrf_d).editable;
 
 	SetWindowWidgetDisabledState(w, 3, !WP(w, newgrf_d).editable);
-	SetWindowWidgetsDisabledState(w, disable_all,
+	w->SetWidgetsDisabledState(disable_all,
 		SNGRFS_REMOVE,
 		SNGRFS_MOVE_UP,
 		SNGRFS_MOVE_DOWN,
@@ -291,7 +291,7 @@
 		for (c = *nd->list; c != NULL && i > 0; c = c->next, i--);
 		nd->sel = c;
 
-		SetWindowDirty(w);
+		w->SetDirty();
 	}
 }
 
@@ -380,7 +380,7 @@
 
 					WP(w, newgrf_d).sel = newsel;
 					SetupNewGRFWindow(w);
-					SetWindowDirty(w);
+					w->SetDirty();
 					break;
 				}
 
@@ -396,7 +396,7 @@
 							break;
 						}
 					}
-					SetWindowDirty(w);
+					w->SetDirty();
 					break;
 				}
 
@@ -412,7 +412,7 @@
 							break;
 						}
 					}
-					SetWindowDirty(w);
+					w->SetDirty();
 					break;
 				}
 
@@ -423,7 +423,7 @@
 					for (c = *WP(w, newgrf_d).list; c != NULL && i > 0; c = c->next, i--);
 					WP(w, newgrf_d).sel = c;
 
-					SetWindowDirty(w);
+					w->SetDirty();
 					break;
 				}
 
@@ -460,7 +460,7 @@
 				/* parse_intlist returns -1 on error */
 				if (c->num_params == (byte)-1) c->num_params = 0;
 			}
-			SetWindowDirty(w);
+			w->SetDirty();
 			break;
 
 		case WE_DESTROY:
--- a/src/news_gui.cpp	Sun Feb 11 21:20:30 2007 +0000
+++ b/src/news_gui.cpp	Sun Feb 11 22:57:24 2007 +0000
@@ -114,7 +114,7 @@
 {
 	switch (e->event) {
 	case WE_CREATE: { /* If chatbar is open at creation time, we need to go above it */
-		const Window *w1 = FindWindowById(WC_SEND_NETWORK_MSG, 0);
+		const Window *w1 = Window::FindById(WC_SEND_NETWORK_MSG, 0);
 		w->message.msg = (w1 != NULL) ? w1->height : 0;
 	} break;
 
@@ -179,7 +179,7 @@
 		switch (e->we.click.widget) {
 		case 1: {
 			NewsItem *ni = WP(w, news_d).ni;
-			DeleteWindow(w);
+			w->Close();
 			ni->duration = 0;
 			_forced_news = INVALID_NEWS;
 		} break;
@@ -200,7 +200,7 @@
 		if (e->we.keypress.keycode == WKC_SPACE) {
 			// Don't continue.
 			e->we.keypress.cont = false;
-			DeleteWindow(w);
+			w->Close();
 		}
 		break;
 
@@ -309,9 +309,9 @@
 		ni->date = _date;
 		COPY_OUT_DPARAM(ni->params, 0, lengthof(ni->params));
 
-		w = FindWindowById(WC_MESSAGE_HISTORY, 0);
+		w = Window::FindById(WC_MESSAGE_HISTORY, 0);
 		if (w == NULL) return;
-		SetWindowDirty(w);
+		w->SetDirty();
 		w->vscroll.count = _total_news;
 	}
 }
@@ -457,7 +457,7 @@
 	if (_news_ticker_sound) SndPlayFx(SND_16_MORSE);
 
 	_statusbar_news_item = *ni;
-	w = FindWindowById(WC_STATUS_BAR, 0);
+	w = Window::FindById(WC_STATUS_BAR, 0);
 	if (w != NULL) WP(w, def_d).data_1 = 360;
 }
 
@@ -475,14 +475,14 @@
 
 	// Ticker message
 	// Check if the status bar message is still being displayed?
-	w = FindWindowById(WC_STATUS_BAR, 0);
+	w = Window::FindById(WC_STATUS_BAR, 0);
 	if (w != NULL && WP(w, const def_d).data_1 > -1280) return false;
 
 	// Newspaper message, decrement duration counter
 	if (ni->duration != 0) ni->duration--;
 
 	// neither newsticker nor newspaper are running
-	return (ni->duration == 0 || FindWindowById(WC_NEWS_WINDOW, 0) == NULL);
+	return (ni->duration == 0 || Window::FindById(WC_NEWS_WINDOW, 0) == NULL);
 }
 
 static void MoveToNextItem(void)
@@ -502,11 +502,11 @@
 
 		switch (GetNewsDisplayValue(ni->type)) {
 		case 0: { /* Off - show nothing only a small reminder in the status bar */
-			Window *w = FindWindowById(WC_STATUS_BAR, 0);
+			Window *w = Window::FindById(WC_STATUS_BAR, 0);
 
 			if (w != NULL) {
 				WP(w, def_d).data_2 = 91;
-				SetWindowDirty(w);
+				w->SetDirty();
 			}
 			break;
 		}
@@ -558,7 +558,7 @@
 	if (_forced_news == INVALID_NEWS) {
 		/* Not forced any news yet, show the current one, unless a news window is
 		 * open (which can only be the current one), then show the previous item */
-		const Window *w = FindWindowById(WC_NEWS_WINDOW, 0);
+		const Window *w = Window::FindById(WC_NEWS_WINDOW, 0);
 		ShowNewsMessage((w == NULL || (_current_news == _oldest_news)) ? _current_news : decreaseIndex(_current_news));
 	} else if (_forced_news == _oldest_news) {
 		/* We have reached the oldest news, start anew with the latest */
@@ -707,7 +707,7 @@
 		w->resize.height = w->height - 12 * 6; // minimum of 4 items in the list, each item 12 high
 		w->resize.step_width = 1;
 		w->resize.width = 200; // can't make window any smaller than 200 pixel
-		SetWindowDirty(w);
+		w->SetDirty();
 	}
 }
 
@@ -776,7 +776,7 @@
 
 				WP(w, def_d).data_1 |= (1 << element);
 				w->flags4 |= 5 << WF_TIMEOUT_SHL; // XXX - setup unclick (fake widget)
-				SetWindowDirty(w);
+				w->SetDirty();
 			}
 			break;
 		case 23: case 24: /* Dropdown menu for all settings */
@@ -795,7 +795,7 @@
 
 				SetMessageButtonStates(w, val, element);
 				SetNewsDisplayValue(element, val);
-				SetWindowDirty(w);
+				w->SetDirty();
 			}
 		} break;
 		} break;
@@ -809,13 +809,13 @@
 			SB(_news_display_opt, i*2, 2, e->we.dropdown.index);
 			SetMessageButtonStates(w, e->we.dropdown.index, i);
 		}
-		SetWindowDirty(w);
+		w->SetDirty();
 		break;
 		}
 
 	case WE_TIMEOUT: /* XXX - Hack to animate 'fake' buttons */
 		WP(w, def_d).data_1 = 0;
-		SetWindowDirty(w);
+		w->SetDirty();
 		break;
 	}
 }
@@ -912,7 +912,7 @@
 			 * We also need an update of the current, forced and visible (open window)
 			 * news's as this shifting could change the items they were pointing to */
 			if (_total_news != 0) {
-				w = FindWindowById(WC_NEWS_WINDOW, 0);
+				w = Window::FindById(WC_NEWS_WINDOW, 0);
 				NewsID visible_news = (w != NULL) ? (NewsID)(WP(w, news_d).ni - _news_items) : INVALID_NEWS;
 
 				for (NewsID i = n;; i = decreaseIndex(i)) {
@@ -932,9 +932,9 @@
 			/*DEBUG(misc, 0, "-cur %3d, old %2d, lat %3d, for %3d, tot %2d",
 			  _current_news, _oldest_news, _latest_news, _forced_news, _total_news);*/
 
-			w = FindWindowById(WC_MESSAGE_HISTORY, 0);
+			w = Window::FindById(WC_MESSAGE_HISTORY, 0);
 			if (w != NULL) {
-				SetWindowDirty(w);
+				w->SetDirty();
 				w->vscroll.count = _total_news;
 			}
 		}
--- a/src/openttd.cpp	Sun Feb 11 21:20:30 2007 +0000
+++ b/src/openttd.cpp	Sun Feb 11 22:57:24 2007 +0000
@@ -969,7 +969,7 @@
 static void ScrollMainViewport(int x, int y)
 {
 	if (_game_mode != GM_MENU) {
-		Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
+		Window *w = Window::FindById(WC_MAIN_WINDOW, 0);
 		assert(w);
 
 		WP(w,vp_d).scrollpos_x += x << w->viewport->zoom;
@@ -1073,7 +1073,7 @@
 
 void BeforeSaveGame(void)
 {
-	const Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
+	const Window *w = Window::FindById(WC_MAIN_WINDOW, 0);
 
 	if (w != NULL) {
 		_saved_scrollpos_x = WP(w, const vp_d).scrollpos_x;
@@ -1261,7 +1261,7 @@
 	ResetWindowSystem();
 	SetupColorsAndInitialWindow();
 
-	w = FindWindowById(WC_MAIN_WINDOW, 0);
+	w = Window::FindById(WC_MAIN_WINDOW, 0);
 
 	WP(w,vp_d).scrollpos_x = _saved_scrollpos_x;
 	WP(w,vp_d).scrollpos_y = _saved_scrollpos_y;
@@ -1804,3 +1804,4 @@
 HalSoundDriver *_sound_driver;
 HalVideoDriver *_video_driver;
 
+
--- a/src/order_gui.cpp	Sun Feb 11 21:20:30 2007 +0000
+++ b/src/order_gui.cpp	Sun Feb 11 22:57:24 2007 +0000
@@ -475,7 +475,7 @@
 
 			if (sel == WP(w,order_d).sel) sel = -1;
 			WP(w,order_d).sel = sel;
-			SetWindowDirty(w);
+			w->SetDirty();
 		}	break;
 
 		case ORDER_WIDGET_SKIP:
--- a/src/player_gui.cpp	Sun Feb 11 21:20:30 2007 +0000
+++ b/src/player_gui.cpp	Sun Feb 11 22:57:24 2007 +0000
@@ -172,7 +172,7 @@
 			byte mode = (byte)WP(w,def_d).data_1;
 			bool stickied = !!(w->flags4 & WF_STICKY);
 			PlayerID player = (PlayerID)w->window_number;
-			DeleteWindow(w);
+			w->Close();
 			DoShowPlayerFinances(player, !HASBIT(mode, 0), stickied);
 		} break;
 
@@ -432,7 +432,7 @@
 					} else {
 						WP(w, livery_d).sel = 1 << j;
 					}
-					SetWindowDirty(w);
+					w->SetDirty();
 					break;
 				}
 			}
@@ -518,21 +518,21 @@
 
 	case WE_CLICK:
 		switch (e->we.click.widget) {
-		case 3: DeleteWindow(w); break;
+		case 3: w->Close(); break;
 		case 4: /* ok click */
 			DoCommandP(0, 0, WP(w,facesel_d).face, NULL, CMD_SET_PLAYER_FACE);
-			DeleteWindow(w);
+			w->Close();
 			break;
 		case 5: /* male click */
 		case 6: /* female click */
 			RaiseWindowWidget(w, WP(w, facesel_d).gender + 5);
 			WP(w, facesel_d).gender = e->we.click.widget - 5;
 			LowerWindowWidget(w, WP(w, facesel_d).gender + 5);
-			SetWindowDirty(w);
+			w->SetDirty();
 			break;
 		case 7:
 			WP(w,facesel_d).face = (WP(w,facesel_d).gender << 31) + GB(InteractiveRandom(), 0, 31);
-			SetWindowDirty(w);
+			w->SetDirty();
 			break;
 		}
 		break;
@@ -822,18 +822,18 @@
 
 		case WE_MOUSELOOP:
 			/* redraw the window every now and then */
-			if ((++w->vscroll.pos & 0x1F) == 0) SetWindowDirty(w);
+			if ((++w->vscroll.pos & 0x1F) == 0) w->SetDirty();
 			break;
 
 		case WE_PLACE_OBJ:
 			if (DoCommandP(e->we.place.tile, 0, 0, NULL, CMD_BUILD_COMPANY_HQ | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_7071_CAN_T_BUILD_COMPANY_HEADQUARTERS)))
 				ResetObjectToPlace();
 				w->widget[PCW_WIDGET_BUILD_VIEW_HQ].type = WWT_PUSHTXTBTN; // this button can now behave as a normal push button
-				RaiseWindowButtons(w);
+				w->RaiseButtons();
 			break;
 
 		case WE_ABORT_PLACE_OBJ:
-			RaiseWindowButtons(w);
+			w->RaiseButtons();
 			break;
 
 		case WE_DESTROY:
@@ -908,7 +908,7 @@
 	case WE_CLICK:
 		switch (e->we.click.widget) {
 		case 3:
-			DeleteWindow(w);
+			w->Close();
 			break;
 		case 4: {
 			DoCommandP(0, w->window_number, 0, NULL, CMD_BUY_COMPANY | CMD_MSG(STR_7060_CAN_T_BUY_COMPANY));
@@ -995,7 +995,7 @@
 		}
 	} break;
 	case WE_CLICK: /* Close the window (and show the highscore window) */
-		DeleteWindow(w);
+		w->Close();
 		break;
 	case WE_DESTROY: /* Show the highscore window when this one is closed */
 		if (!_networking) DoCommandP(0, 0, 0, NULL, CMD_PAUSE); // unpause
@@ -1035,7 +1035,7 @@
 	} break;
 
 	case WE_CLICK: /* Onclick to close window, and in destroy event handle the rest */
-		DeleteWindow(w);
+		w->Close();
 		break;
 
 	case WE_DESTROY: /* Get back all the hidden windows */
--- a/src/rail_gui.cpp	Sun Feb 11 21:20:30 2007 +0000
+++ b/src/rail_gui.cpp	Sun Feb 11 22:57:24 2007 +0000
@@ -320,7 +320,7 @@
 static void BuildRailClick_Remove(Window *w)
 {
 	if (IsWindowWidgetDisabled(w, RTW_REMOVE)) return;
-	SetWindowDirty(w);
+	w->SetDirty();
 	SndPlayFx(SND_15_BEEP);
 
 	ToggleWidgetLoweredState(w, RTW_REMOVE);
@@ -524,13 +524,13 @@
 		break;
 
 	case WE_ABORT_PLACE_OBJ:
-		RaiseWindowButtons(w);
+		w->RaiseButtons();
 		DisableWindowWidget(w, RTW_REMOVE);
 		InvalidateWidget(w, RTW_REMOVE);
 
-		w = FindWindowById(WC_BUILD_STATION, 0);
+		w = Window::FindById(WC_BUILD_STATION, 0);
 		if (w != NULL) WP(w,def_d).close = true;
-		w = FindWindowById(WC_BUILD_DEPOT, 0);
+		w = Window::FindById(WC_BUILD_DEPOT, 0);
 		if (w != NULL) WP(w,def_d).close = true;
 		break;
 
@@ -612,7 +612,7 @@
 	if (!ValParamRailtype(railtype)) return;
 
 	// don't recreate the window if we're clicking on a button and the window exists.
-	if (button < 0 || !(w = FindWindowById(WC_BUILD_TOOLBAR, 0)) || w->wndproc != BuildRailToolbWndProc) {
+	if (button < 0 || !(w = Window::FindById(WC_BUILD_TOOLBAR, 0)) || w->wndproc != BuildRailToolbWndProc) {
 		DeleteWindowById(WC_BUILD_TOOLBAR, 0);
 		_cur_railtype = railtype;
 		w = AllocateWindowDesc(&_build_rail_desc);
@@ -787,7 +787,7 @@
 			_railstation.orientation = e->we.click.widget - 3;
 			LowerWindowWidget(w, _railstation.orientation + 3);
 			SndPlayFx(SND_15_BEEP);
-			SetWindowDirty(w);
+			w->SetDirty();
 			break;
 
 		case 5:
@@ -804,7 +804,7 @@
 			LowerWindowWidget(w, _railstation.platlength + 11);
 			LowerWindowWidget(w, _railstation.numtracks + 4);
 			SndPlayFx(SND_15_BEEP);
-			SetWindowDirty(w);
+			w->SetDirty();
 			break;
 
 		case 12:
@@ -821,7 +821,7 @@
 			LowerWindowWidget(w, _railstation.platlength + 11);
 			LowerWindowWidget(w, _railstation.numtracks + 4);
 			SndPlayFx(SND_15_BEEP);
-			SetWindowDirty(w);
+			w->SetDirty();
 			break;
 
 		case 19:
@@ -830,7 +830,7 @@
 			SetWindowWidgetLoweredState(w, _railstation.numtracks + 4, !_railstation.dragdrop);
 			SetWindowWidgetLoweredState(w, _railstation.platlength + 11, !_railstation.dragdrop);
 			SndPlayFx(SND_15_BEEP);
-			SetWindowDirty(w);
+			w->SetDirty();
 			break;
 
 		case 20:
@@ -839,7 +839,7 @@
 			SetWindowWidgetLoweredState(w, 20, !_station_show_coverage);
 			SetWindowWidgetLoweredState(w, 21, _station_show_coverage);
 			SndPlayFx(SND_15_BEEP);
-			SetWindowDirty(w);
+			w->SetDirty();
 			break;
 
 		case 22:
@@ -866,7 +866,7 @@
 			CheckSelectedSize(w, statspec);
 
 			SndPlayFx(SND_15_BEEP);
-			SetWindowDirty(w);
+			w->SetDirty();
 			break;
 		}
 		}
@@ -885,12 +885,12 @@
 		}
 
 		SndPlayFx(SND_15_BEEP);
-		SetWindowDirty(w);
+		w->SetDirty();
 		break;
 
 	case WE_MOUSELOOP:
 		if (WP(w,def_d).close) {
-			DeleteWindow(w);
+			w->Close();
 			return;
 		}
 		CheckRedrawStationCoverage(w);
@@ -1027,13 +1027,13 @@
 				_build_depot_direction = (DiagDirection)(e->we.click.widget - 3);
 				LowerWindowWidget(w, _build_depot_direction + 3);
 				SndPlayFx(SND_15_BEEP);
-				SetWindowDirty(w);
+				w->SetDirty();
 				break;
 		}
 		break;
 
 	case WE_MOUSELOOP:
-		if (WP(w,def_d).close) DeleteWindow(w);
+		if (WP(w,def_d).close) w->Close();
 		return;
 
 	case WE_DESTROY:
@@ -1107,7 +1107,7 @@
 
 			_cur_waypoint_type = type;
 			SndPlayFx(SND_15_BEEP);
-			SetWindowDirty(w);
+			w->SetDirty();
 			break;
 		}
 		}
@@ -1115,7 +1115,7 @@
 	}
 
 	case WE_MOUSELOOP:
-		if (WP(w,def_d).close) DeleteWindow(w);
+		if (WP(w,def_d).close) w->Close();
 		break;
 
 	case WE_DESTROY:
@@ -1169,13 +1169,14 @@
 	if (disable && _last_built_railtype == RAILTYPE_ELECTRIC) {
 		Window *w;
 		_last_built_railtype = _cur_railtype = RAILTYPE_RAIL;
-		w = FindWindowById(WC_BUILD_TOOLBAR, 0);
+		w = Window::FindById(WC_BUILD_TOOLBAR, 0);
 		if (w != NULL && w->wndproc == BuildRailToolbWndProc) {
 			SetupRailToolbar(_cur_railtype, w);
-			SetWindowDirty(w);
+			w->SetDirty();
 		}
 	}
 	MarkWholeScreenDirty();
 }
 
 
+
--- a/src/road_gui.cpp	Sun Feb 11 21:20:30 2007 +0000
+++ b/src/road_gui.cpp	Sun Feb 11 22:57:24 2007 +0000
@@ -170,7 +170,7 @@
 static void BuildRoadClick_Remove(Window *w)
 {
 	if (IsWindowWidgetDisabled(w, RTW_REMOVE)) return;
-	SetWindowDirty(w);
+	w->SetDirty();
 	SndPlayFx(SND_15_BEEP);
 	ToggleWidgetLoweredState(w, RTW_REMOVE);
 	SetSelectionRed(IsWindowWidgetLowered(w, RTW_REMOVE));
@@ -228,15 +228,15 @@
 		break;
 
 	case WE_ABORT_PLACE_OBJ:
-		RaiseWindowButtons(w);
+		w->RaiseButtons();
 		DisableWindowWidget(w, RTW_REMOVE);
 		InvalidateWidget(w, RTW_REMOVE);
 
-		w = FindWindowById(WC_BUS_STATION, 0);
+		w = Window::FindById(WC_BUS_STATION, 0);
 		if (w != NULL) WP(w,def_d).close = true;
-		w = FindWindowById(WC_TRUCK_STATION, 0);
+		w = Window::FindById(WC_TRUCK_STATION, 0);
 		if (w != NULL) WP(w,def_d).close = true;
-		w = FindWindowById(WC_BUILD_DEPOT, 0);
+		w = Window::FindById(WC_BUILD_DEPOT, 0);
 		if (w != NULL) WP(w,def_d).close = true;
 		break;
 
@@ -384,13 +384,13 @@
 			_road_depot_orientation = (DiagDirection)(e->we.click.widget - 3);
 			LowerWindowWidget(w, _road_depot_orientation + 3);
 			SndPlayFx(SND_15_BEEP);
-			SetWindowDirty(w);
+			w->SetDirty();
 			break;
 		}
 	}	break;
 
 	case WE_MOUSELOOP:
-		if (WP(w,def_d).close) DeleteWindow(w);
+		if (WP(w,def_d).close) w->Close();
 		break;
 
 	case WE_DESTROY:
@@ -465,21 +465,21 @@
 			_road_station_picker_orientation = (DiagDirection)(e->we.click.widget - 3);
 			LowerWindowWidget(w, _road_station_picker_orientation + 3);
 			SndPlayFx(SND_15_BEEP);
-			SetWindowDirty(w);
+			w->SetDirty();
 			break;
 		case 7: case 8:
 			RaiseWindowWidget(w, _station_show_coverage + 7);
 			_station_show_coverage = (e->we.click.widget != 7);
 			LowerWindowWidget(w, _station_show_coverage + 7);
 			SndPlayFx(SND_15_BEEP);
-			SetWindowDirty(w);
+			w->SetDirty();
 			break;
 		}
 	} break;
 
 	case WE_MOUSELOOP: {
 		if (WP(w,def_d).close) {
-			DeleteWindow(w);
+			w->Close();
 			return;
 		}
 
--- a/src/roadveh_gui.cpp	Sun Feb 11 21:20:30 2007 +0000
+++ b/src/roadveh_gui.cpp	Sun Feb 11 22:57:24 2007 +0000
@@ -300,7 +300,7 @@
 				SetWindowWidgetHiddenState(w,  8, rv_stopped);  // force turn around
 				SetWindowWidgetHiddenState(w, 11, !rv_stopped); // clone
 				SetWindowWidgetHiddenState(w, 12, !rv_stopped); // refit
-				SetWindowDirty(w);
+				w->SetDirty();
 			}
 		}
 	}
--- a/src/settings_gui.cpp	Sun Feb 11 21:20:30 2007 +0000
+++ b/src/settings_gui.cpp	Sun Feb 11 22:57:24 2007 +0000
@@ -155,7 +155,7 @@
 		case 28: /* Click fullscreen on/off */
 			SetWindowWidgetLoweredState(w, 28, !_fullscreen);
 			ToggleFullScreen(!_fullscreen); // toggle full-screen on/off
-			SetWindowDirty(w);
+			w->SetDirty();
 			return;
 		case 30: case 31: /* Setup screenshot format dropdown */
 			ShowDropDownMenu(w, BuildDynamicDropdown(SPECSTR_SCREENSHOT_START, _num_screenshot_formats), _cur_screenshot_format, 31, 0, 0);
@@ -197,7 +197,7 @@
 			break;
 		case 17: /* Autosave options */
 			_opt.autosave = _opt_newgame.autosave = e->we.dropdown.index;
-			SetWindowDirty(w);
+			w->SetDirty();
 			break;
 		case 24: /* Change interface language */
 			ReadLanguagePack(e->we.dropdown.index);
@@ -205,11 +205,11 @@
 			break;
 		case 27: /* Change resolution */
 			if (e->we.dropdown.index < _num_resolutions && ChangeResInGame(_resolutions[e->we.dropdown.index][0],_resolutions[e->we.dropdown.index][1]))
-				SetWindowDirty(w);
+				w->SetDirty();
 			break;
 		case 31: /* Change screenshot format */
 			SetScreenshotFormat(e->we.dropdown.index);
-			SetWindowDirty(w);
+			w->SetDirty();
 			break;
 		}
 		break;
@@ -481,14 +481,14 @@
 			// save value in temporary variable
 			((int*)&_opt_mod_temp.diff)[btn] = val;
 			SetDifficultyLevel(3, &_opt_mod_temp); // set difficulty level to custom
-			SetWindowDirty(w);
+			w->SetDirty();
 		}	break;
 		case 3: case 4: case 5: case 6: /* Easy / Medium / Hard / Custom */
 			// temporarily change difficulty level
 			RaiseWindowWidget(w, _opt_mod_temp.diff_level + 3);
 			SetDifficultyLevel(e->we.click.widget - 3, &_opt_mod_temp);
 			LowerWindowWidget(w, _opt_mod_temp.diff_level + 3);
-			SetWindowDirty(w);
+			w->SetDirty();
 			break;
 		case 7: /* Highscore Table */
 			ShowHighscoreTable(_opt_mod_temp.diff_level, -1);
@@ -502,7 +502,7 @@
 					DoCommandP(0, btn, val, NULL, CMD_CHANGE_DIFFICULTY_LEVEL);
 			}
 			DoCommandP(0, UINT_MAX, _opt_mod_temp.diff_level, NULL, CMD_CHANGE_DIFFICULTY_LEVEL);
-			DeleteWindow(w);
+			w->Close();
 			// If we are in the editor, we should reload the economy.
 			//  This way when you load a game, the max loan and interest rate
 			//  are loaded correctly.
@@ -511,7 +511,7 @@
 			break;
 		}
 		case 11: /* Cancel button - close window, abandon changes */
-			DeleteWindow(w);
+			w->Close();
 			break;
 	} break;
 
@@ -519,7 +519,7 @@
 		if (_difficulty_timeout != 0 && !--_difficulty_timeout) {
 			_difficulty_click_a = 0;
 			_difficulty_click_b = 0;
-			SetWindowDirty(w);
+			w->SetDirty();
 		}
 		break;
 	}
@@ -838,7 +838,7 @@
 
 				if (value != oldvalue) {
 					SetPatchValue(page->entries[btn].index, patches_ptr, value);
-					SetWindowDirty(w);
+					w->SetDirty();
 				}
 			} else {
 				/* only open editbox for types that its sensible for */
@@ -859,14 +859,14 @@
 			WP(w, def_d).data_1 = e->we.click.widget - 4;
 			LowerWindowWidget(w, WP(w, def_d).data_1 + 4);
 			DeleteWindowById(WC_QUERY_STRING, 0);
-			SetWindowDirty(w);
+			w->SetDirty();
 			break;
 		}
 		break;
 
 	case WE_TIMEOUT:
 		WP(w,def_d).data_2 = 0;
-		SetWindowDirty(w);
+		w->SetDirty();
 		break;
 
 	case WE_ON_EDIT_TEXT: {
@@ -879,7 +879,7 @@
 			if (sd->desc.flags & SGF_CURRENCY) value /= _currency->rate;
 
 			SetPatchValue(pe->index, patches_ptr, value);
-			SetWindowDirty(w);
+			w->SetDirty();
 		}
 		break;
 	}
@@ -1069,7 +1069,7 @@
 			}
 
 			w->flags4 |= 5 << WF_TIMEOUT_SHL;
-			SetWindowDirty(w);
+			w->SetDirty();
 			break;
 		}
 
@@ -1108,7 +1108,7 @@
 
 		case WE_TIMEOUT:
 			WP(w,def_d).data_1 = 0;
-			SetWindowDirty(w);
+			w->SetDirty();
 			break;
 
 		case WE_DESTROY:
--- a/src/ship_gui.cpp	Sun Feb 11 21:20:30 2007 +0000
+++ b/src/ship_gui.cpp	Sun Feb 11 22:57:24 2007 +0000
@@ -302,7 +302,7 @@
 			if (ship_stopped != IsWindowWidgetHidden(w, 7) || ship_stopped == IsWindowWidgetHidden(w, 11)) {
 				SetWindowWidgetHiddenState(w,  7, ship_stopped);  // send to depot
 				SetWindowWidgetHiddenState(w, 11, !ship_stopped); // clone
-				SetWindowDirty(w);
+				w->SetDirty();
 			}
 		}
 	}
--- a/src/smallmap_gui.cpp	Sun Feb 11 21:20:30 2007 +0000
+++ b/src/smallmap_gui.cpp	Sun Feb 11 22:57:24 2007 +0000
@@ -762,7 +762,7 @@
 		Point pt;
 
 		// Find main viewport.
-		vp = FindWindowById(WC_MAIN_WINDOW,0)->viewport;
+		vp = Window::FindById(WC_MAIN_WINDOW,0)->viewport;
 
 		pt = RemapCoords(WP(w, smallmap_d).scroll_x, WP(w, smallmap_d).scroll_y, 0);
 
@@ -789,13 +789,13 @@
 {
 	int x, y;
 	ViewPort *vp;
-	vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport;
+	vp = Window::FindById(WC_MAIN_WINDOW, 0)->viewport;
 
 	x  = ((vp->virtual_width  - (w->widget[4].right  - w->widget[4].left) * TILE_SIZE) / 2 + vp->virtual_left) / 4;
 	y  = ((vp->virtual_height - (w->widget[4].bottom - w->widget[4].top ) * TILE_SIZE) / 2 + vp->virtual_top ) / 2 - TILE_SIZE * 2;
 	WP(w, smallmap_d).scroll_x = (y - x) & ~0xF;
 	WP(w, smallmap_d).scroll_y = (x + y) & ~0xF;
-	SetWindowDirty(w);
+	w->SetDirty();
 }
 
 static void SmallMapWindowProc(Window *w, WindowEvent *e)
@@ -840,7 +840,7 @@
 		case WE_CLICK:
 			switch (e->we.click.widget) {
 				case 4: { // Map window
-					Window *w2 = FindWindowById(WC_MAIN_WINDOW, 0);
+					Window *w2 = Window::FindById(WC_MAIN_WINDOW, 0);
 					Point pt;
 
 					/*
@@ -857,7 +857,7 @@
 					WP(w2, vp_d).scrollpos_x = pt.x + ((_cursor.pos.x - w->left + 2) << 4) - (w2->viewport->virtual_width >> 1);
 					WP(w2, vp_d).scrollpos_y = pt.y + ((_cursor.pos.y - w->top - 16) << 4) - (w2->viewport->virtual_height >> 1);
 
-					SetWindowDirty(w);
+					w->SetDirty();
 				} break;
 
 				case 5:  // Show land contours
@@ -870,14 +870,14 @@
 					_smallmap_type = e->we.click.widget - 5;
 					LowerWindowWidget(w, _smallmap_type + 5);
 
-					SetWindowDirty(w);
+					w->SetDirty();
 					SndPlayFx(SND_15_BEEP);
 					break;
 
 				case 11: // Center the smallmap again
 					SmallMapCenterOnCurrentPos(w);
 
-					SetWindowDirty(w);
+					w->SetDirty();
 					SndPlayFx(SND_15_BEEP);
 					break;
 
@@ -885,7 +885,7 @@
 					ToggleWidgetLoweredState(w, 12);
 					_smallmap_show_towns = IsWindowWidgetLowered(w, 12);
 
-					SetWindowDirty(w);
+					w->SetDirty();
 					SndPlayFx(SND_15_BEEP);
 					break;
 				}
@@ -902,7 +902,7 @@
 
 		case WE_MOUSELOOP:
 			/* update the window every now and then */
-			if ((++w->vscroll.pos & 0x1F) == 0) SetWindowDirty(w);
+			if ((++w->vscroll.pos & 0x1F) == 0) w->SetDirty();
 			break;
 
 		case WE_SCROLL: {
@@ -963,7 +963,7 @@
 			WP(w, smallmap_d).scroll_y = y;
 			WP(w, smallmap_d).subscroll = sub;
 
-			SetWindowDirty(w);
+			w->SetDirty();
 		} break;
 	}
 }
@@ -1029,7 +1029,7 @@
 			case 6: DoZoomInOutWindow(ZOOM_OUT, w); break;
 
 		case 7: { /* location button (move main view to same spot as this view) 'Paste Location' */
-			Window *w2 = FindWindowById(WC_MAIN_WINDOW, 0);
+			Window *w2 = Window::FindById(WC_MAIN_WINDOW, 0);
 			int x = WP(w, vp_d).scrollpos_x; // Where is the main looking at
 			int y = WP(w, vp_d).scrollpos_y;
 
@@ -1039,7 +1039,7 @@
 		} break;
 
 		case 8: { /* inverse location button (move this view to same spot as main view) 'Copy Location' */
-			const Window *w2 = FindWindowById(WC_MAIN_WINDOW, 0);
+			const Window *w2 = Window::FindById(WC_MAIN_WINDOW, 0);
 			int x = WP(w2, const vp_d).scrollpos_x;
 			int y = WP(w2, const vp_d).scrollpos_y;
 
@@ -1095,13 +1095,13 @@
 	int i = 0;
 
 	// find next free window number for extra viewport
-	while (FindWindowById(WC_EXTRA_VIEW_PORT, i) != NULL) i++;
+	while (Window::FindById(WC_EXTRA_VIEW_PORT, i) != NULL) i++;
 
 	w = AllocateWindowDescFront(&_extra_view_port_desc, i);
 	if (w != NULL) {
 		int x, y;
 		// the main window with the main view
-		v = FindWindowById(WC_MAIN_WINDOW, 0);
+		v = Window::FindById(WC_MAIN_WINDOW, 0);
 		// New viewport start ats (zero,zero)
 		AssignWindowViewport(w, 3, 17, 294, 214, 0 , 0);
 
--- a/src/sound.cpp	Sun Feb 11 21:20:30 2007 +0000
+++ b/src/sound.cpp	Sun Feb 11 22:57:24 2007 +0000
@@ -193,12 +193,12 @@
 
 static void SndPlayScreenCoordFx(SoundFx sound, int x, int y)
 {
-	Window* const *wz;
 
 	if (msf.effect_vol == 0) return;
 
-	FOR_ALL_WINDOWS(wz) {
-		const ViewPort *vp = (*wz)->viewport;
+	Window *w;
+	FOR_ALL_WINDOWS(w) {
+		const ViewPort *vp = w->viewport;
 
 		if (vp != NULL &&
 				IS_INSIDE_1D(x, vp->virtual_left, vp->virtual_width) &&
--- a/src/station_gui.cpp	Sun Feb 11 21:20:30 2007 +0000
+++ b/src/station_gui.cpp	Sun Feb 11 22:57:24 2007 +0000
@@ -171,26 +171,24 @@
 
 void RebuildStationLists(void)
 {
-	Window* const *wz;
+	Window *w;
 
-	FOR_ALL_WINDOWS(wz) {
-		Window *w = *wz;
+	FOR_ALL_WINDOWS(w) {
 		if (w->window_class == WC_STATION_LIST) {
 			WP(w, plstations_d).flags |= SL_REBUILD;
-			SetWindowDirty(w);
+			w->SetDirty();
 		}
 	}
 }
 
 void ResortStationLists(void)
 {
-	Window* const *wz;
+	Window *w;
 
-	FOR_ALL_WINDOWS(wz) {
-		Window *w = *wz;
+	FOR_ALL_WINDOWS(w) {
 		if (w->window_class == WC_STATION_LIST) {
 			WP(w, plstations_d).flags |= SL_RESORT;
-			SetWindowDirty(w);
+			w->SetDirty();
 		}
 	}
 }
@@ -409,7 +407,7 @@
 			}
 			SetWindowWidgetLoweredState(w, STATIONLIST_WIDGET_FACILALL, facilities == (FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK));
 			sl->flags |= SL_REBUILD;
-			SetWindowDirty(w);
+			w->SetDirty();
 		break;
 
 		case STATIONLIST_WIDGET_FACILALL: {
@@ -421,7 +419,7 @@
 
 			facilities = FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK;
 			sl->flags |= SL_REBUILD;
-			SetWindowDirty(w);
+			w->SetDirty();
 			break;
 		}
 		case STATIONLIST_WIDGET_CARGOALL: {
@@ -434,7 +432,7 @@
 
 			cargo_filter = CARGO_ALL_SELECTED;
 			sl->flags |= SL_REBUILD;
-			SetWindowDirty(w);
+			w->SetDirty();
 			break;
 		}
 		case STATIONLIST_WIDGET_SORTBY: /*flip sorting method asc/desc*/
@@ -443,7 +441,7 @@
 			sl->flags |= SL_RESORT;
 			w->flags4 |= 5 << WF_TIMEOUT_SHL;
 			LowerWindowWidget(w, STATIONLIST_WIDGET_SORTBY);
-			SetWindowDirty(w);
+			w->SetDirty();
 		break;
 
 		case STATIONLIST_WIDGET_SORTCRITERIA:
@@ -466,7 +464,7 @@
 				}
 				sl->flags |= SL_REBUILD;
 				SetWindowWidgetLoweredState(w, STATIONLIST_WIDGET_CARGOALL, cargo_filter == CARGO_ALL_SELECTED);
-				SetWindowDirty(w);
+				w->SetDirty();
 			}
 		}
 	} break;
@@ -478,7 +476,7 @@
 			station_sort.criteria = sl->sort_type;
 			sl->flags |= SL_RESORT;
 		}
-		SetWindowDirty(w);
+		w->SetDirty();
 		break;
 
 	case WE_TICK:
@@ -486,13 +484,13 @@
 			DEBUG(misc, 3, "Periodic rebuild station list player %d", owner);
 			sl->resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS;
 			sl->flags |= SL_REBUILD;
-			SetWindowDirty(w);
+			w->SetDirty();
 		}
 		break;
 
 	case WE_TIMEOUT:
 		RaiseWindowWidget(w, STATIONLIST_WIDGET_SORTBY);
-		SetWindowDirty(w);
+		w->SetDirty();
 		break;
 
 	case WE_RESIZE:
@@ -741,7 +739,7 @@
 			break;
 
 		case 8:
-			SetWindowDirty(w);
+			w->SetDirty();
 
 			/* toggle height/widget set */
 			if (IsWindowOfPrototype(w, _station_view_expanded_widgets)) {
@@ -752,7 +750,7 @@
 				w->height = 210;
 			}
 
-			SetWindowDirty(w);
+			w->SetDirty();
 			break;
 
 		case 9: {
--- a/src/terraform_gui.cpp	Sun Feb 11 21:20:30 2007 +0000
+++ b/src/terraform_gui.cpp	Sun Feb 11 22:57:24 2007 +0000
@@ -248,7 +248,7 @@
 		break;
 
 	case WE_ABORT_PLACE_OBJ:
-		RaiseWindowButtons(w);
+		w->RaiseButtons();
 		break;
 	}
 }
--- a/src/town_gui.cpp	Sun Feb 11 21:20:30 2007 +0000
+++ b/src/town_gui.cpp	Sun Feb 11 22:57:24 2007 +0000
@@ -192,7 +192,7 @@
 			y = GetNthSetBit(GetMaskOfTownActions(NULL, _local_player, t), y + w->vscroll.pos - 1);
 			if (y >= 0) {
 				WP(w,def_d).data_1 = y;
-				SetWindowDirty(w);
+				w->SetDirty();
 			}
 			break;
 		}
@@ -205,7 +205,7 @@
 		break;
 
 	case WE_4:
-		SetWindowDirty(w);
+		w->SetDirty();
 		break;
 	}
 }
@@ -466,13 +466,13 @@
 		case 3: { /* Sort by Name ascending/descending */
 			_town_sort_order = (_town_sort_order == 0) ? 1 : 0;
 			_town_sort_dirty = true;
-			SetWindowDirty(w);
+			w->SetDirty();
 		} break;
 
 		case 4: { /* Sort by Population ascending/descending */
 			_town_sort_order = (_town_sort_order == 2) ? 3 : 2;
 			_town_sort_dirty = true;
-			SetWindowDirty(w);
+			w->SetDirty();
 		} break;
 
 		case 5: { /* Click on Town Matrix */
@@ -495,7 +495,7 @@
 		break;
 
 	case WE_4:
-		SetWindowDirty(w);
+		w->SetDirty();
 		break;
 
 	case WE_RESIZE:
--- a/src/train_gui.cpp	Sun Feb 11 21:20:30 2007 +0000
+++ b/src/train_gui.cpp	Sun Feb 11 22:57:24 2007 +0000
@@ -296,7 +296,7 @@
 			SetWindowWidgetHiddenState(w,  9, train_stopped);  // reverse direction
 			SetWindowWidgetHiddenState(w, 12, !train_stopped); // refit
 			SetWindowWidgetHiddenState(w, 13, !train_stopped); // clone
-			SetWindowDirty(w);
+			w->SetDirty();
 		}
 		break;
 	}
@@ -546,7 +546,7 @@
 			EnableWindowWidget(w, 12);
 			EnableWindowWidget(w, e->we.click.widget);
 			WP(w,traindetails_d).tab = e->we.click.widget - 9;
-			SetWindowDirty(w);
+			w->SetDirty();
 			break;
 		}
 	} break;
--- a/src/vehicle_gui.cpp	Sun Feb 11 21:20:30 2007 +0000
+++ b/src/vehicle_gui.cpp	Sun Feb 11 22:57:24 2007 +0000
@@ -91,18 +91,16 @@
 
 void RebuildVehicleLists(void)
 {
-	Window* const *wz;
+	Window *w;
 
-	FOR_ALL_WINDOWS(wz) {
-		Window *w = *wz;
-
+	FOR_ALL_WINDOWS(w) {
 		switch (w->window_class) {
 			case WC_TRAINS_LIST:
 			case WC_ROADVEH_LIST:
 			case WC_SHIPS_LIST:
 			case WC_AIRCRAFT_LIST:
 				WP(w, vehiclelist_d).l.flags |= VL_REBUILD;
-				SetWindowDirty(w);
+				w->SetDirty();
 				break;
 
 			default: break;
@@ -112,10 +110,9 @@
 
 void ResortVehicleLists(void)
 {
-	Window* const *wz;
+	Window *w;
 
-	FOR_ALL_WINDOWS(wz) {
-		Window *w = *wz;
+	FOR_ALL_WINDOWS(w) {
 
 		switch (w->window_class) {
 			case WC_TRAINS_LIST:
@@ -123,7 +120,7 @@
 			case WC_SHIPS_LIST:
 			case WC_AIRCRAFT_LIST:
 				WP(w, vehiclelist_d).l.flags |= VL_RESORT;
-				SetWindowDirty(w);
+				w->SetDirty();
 				break;
 
 			default: break;
@@ -370,7 +367,7 @@
 					int y = e->we.click.pt.y - w->widget[3].top;
 					if (y >= 0) {
 						WP(w,refit_d).sel = (y / (int)w->resize.step_height) + w->vscroll.pos;
-						SetWindowDirty(w);
+						w->SetDirty();
 					}
 				} break;
 				case 6: // refit button
@@ -386,9 +383,9 @@
 								case VEH_Ship:     command = CMD_REFIT_SHIP         | CMD_MSG(STR_9841_CAN_T_REFIT_SHIP);     break;
 								case VEH_Aircraft: command = CMD_REFIT_AIRCRAFT     | CMD_MSG(STR_A042_CAN_T_REFIT_AIRCRAFT); break;
 							}
-							if (DoCommandP(v->tile, v->index, WP(w,refit_d).cargo->cargo | WP(w,refit_d).cargo->subtype << 8, NULL, command)) DeleteWindow(w);
+							if (DoCommandP(v->tile, v->index, WP(w,refit_d).cargo->cargo | WP(w,refit_d).cargo->subtype << 8, NULL, command)) w->Close();
 						} else {
-							if (DoCommandP(v->tile, v->index, WP(w,refit_d).cargo->cargo | WP(w,refit_d).cargo->subtype << 8 | WP(w, refit_d).order << 16, NULL, CMD_ORDER_REFIT)) DeleteWindow(w);
+							if (DoCommandP(v->tile, v->index, WP(w,refit_d).cargo->cargo | WP(w,refit_d).cargo->subtype << 8 | WP(w, refit_d).order << 16, NULL, CMD_ORDER_REFIT)) w->Close();
 						}
 					}
 					break;
@@ -724,28 +721,28 @@
 {
 	Window *w;
 
-	w = FindWindowById(WC_VEHICLE_VIEW, from_v->index);
+	w = Window::FindById(WC_VEHICLE_VIEW, from_v->index);
 	if (w != NULL) {
 		w->window_number = to_v->index;
 		WP(w, vp_d).follow_vehicle = to_v->index;
-		SetWindowDirty(w);
+		w->SetDirty();
 
-		w = FindWindowById(WC_VEHICLE_ORDERS, from_v->index);
+		w = Window::FindById(WC_VEHICLE_ORDERS, from_v->index);
 		if (w != NULL) {
 			w->window_number = to_v->index;
-			SetWindowDirty(w);
+			w->SetDirty();
 		}
 
-		w = FindWindowById(WC_VEHICLE_REFIT, from_v->index);
+		w = Window::FindById(WC_VEHICLE_REFIT, from_v->index);
 		if (w != NULL) {
 			w->window_number = to_v->index;
-			SetWindowDirty(w);
+			w->SetDirty();
 		}
 
-		w = FindWindowById(WC_VEHICLE_DETAILS, from_v->index);
+		w = Window::FindById(WC_VEHICLE_DETAILS, from_v->index);
 		if (w != NULL) {
 			w->window_number = to_v->index;
-			SetWindowDirty(w);
+			w->SetDirty();
 		}
 	}
 }
@@ -821,7 +818,7 @@
 		HideWindowWidget(w, VLW_WIDGET_OTHER_PLAYER_FILLER);
 		SetWindowWidgetDisabledState(w, VLW_WIDGET_AVAILABLE_VEHICLES, window_type != VLW_STANDARD);
 	} else {
-		SetWindowWidgetsHiddenState(w, true,
+		w->SetWidgetsHiddenState(true,
 			VLW_WIDGET_AVAILABLE_VEHICLES,
 			VLW_WIDGET_MANAGE_VEHICLES,
 			VLW_WIDGET_MANAGE_VEHICLES_DROPDOWN,
@@ -1006,7 +1003,7 @@
 		default: NOT_REACHED(); break;
 	}
 
-	SetWindowWidgetsDisabledState(w, vl->l.list_length == 0,
+	w->SetWidgetsDisabledState(vl->l.list_length == 0,
 		VLW_WIDGET_MANAGE_VEHICLES,
 		VLW_WIDGET_MANAGE_VEHICLES_DROPDOWN,
 		VLW_WIDGET_STOP_ALL,
@@ -1085,7 +1082,7 @@
 					vl->l.flags |= VL_RESORT;
 
 					vl->_sorting->order = !!(vl->l.flags & VL_DESC);
-					SetWindowDirty(w);
+					w->SetDirty();
 					break;
 				case VLW_WIDGET_SORT_BY_TEXT: case VLW_WIDGET_SORT_BY_PULLDOWN:/* Select sorting criteria dropdown menu */
 					ShowDropDownMenu(w, _vehicle_sort_listing, vl->l.sort_type, VLW_WIDGET_SORT_BY_PULLDOWN, 0, 0);
@@ -1179,7 +1176,7 @@
 					break;
 				default: NOT_REACHED();
 			}
-			SetWindowDirty(w);
+			w->SetDirty();
 			break;
 
 		case WE_DESTROY:
@@ -1194,7 +1191,7 @@
 				DEBUG(misc, 3, "Periodic resort %d list player %d at station %d", vl->vehicle_type, owner, station);
 				vl->l.resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS;
 				vl->l.flags |= VL_RESORT;
-				SetWindowDirty(w);
+				w->SetDirty();
 			}
 			break;
 
--- a/src/viewport.cpp	Sun Feb 11 21:20:30 2007 +0000
+++ b/src/viewport.cpp	Sun Feb 11 22:57:24 2007 +0000
@@ -186,11 +186,12 @@
 
 static Point _vp_move_offs;
 
-static void DoSetViewportPosition(Window* const *wz, int left, int top, int width, int height)
+static void DoSetViewportPosition(WindowList::Iterator vit, int left, int top, int width, int height)
 {
-
-	for (; wz != _last_z_window; wz++) {
-		const Window *w = *wz;
+	//Window *w = (*wit).w;
+
+	for (WindowList::Iterator wit = vit; wit != Window::s_list.m_list.end(); wit++) {
+		const Window *w = (*wit).w;
 
 		if (left + width > w->left &&
 				w->left + w->width > left &&
@@ -198,26 +199,26 @@
 				w->top + w->height > top) {
 
 			if (left < w->left) {
-				DoSetViewportPosition(wz, left, top, w->left - left, height);
-				DoSetViewportPosition(wz, left + (w->left - left), top, width - (w->left - left), height);
+				DoSetViewportPosition(wit, left, top, w->left - left, height);
+				DoSetViewportPosition(wit, left + (w->left - left), top, width - (w->left - left), height);
 				return;
 			}
 
 			if (left + width > w->left + w->width) {
-				DoSetViewportPosition(wz, left, top, (w->left + w->width - left), height);
-				DoSetViewportPosition(wz, left + (w->left + w->width - left), top, width - (w->left + w->width - left) , height);
+				DoSetViewportPosition(wit, left, top, (w->left + w->width - left), height);
+				DoSetViewportPosition(wit, left + (w->left + w->width - left), top, width - (w->left + w->width - left) , height);
 				return;
 			}
 
 			if (top < w->top) {
-				DoSetViewportPosition(wz, left, top, width, (w->top - top));
-				DoSetViewportPosition(wz, left, top + (w->top - top), width, height - (w->top - top));
+				DoSetViewportPosition(wit, left, top, width, (w->top - top));
+				DoSetViewportPosition(wit, left, top + (w->top - top), width, height - (w->top - top));
 				return;
 			}
 
 			if (top + height > w->top + w->height) {
-				DoSetViewportPosition(wz, left, top, width, (w->top + w->height - top));
-				DoSetViewportPosition(wz, left, top + (w->top + w->height - top), width , height - (w->top + w->height - top));
+				DoSetViewportPosition(wit, left, top, width, (w->top + w->height - top));
+				DoSetViewportPosition(wit, left, top + (w->top + w->height - top), width , height - (w->top + w->height - top));
 				return;
 			}
 
@@ -300,7 +301,8 @@
 		i = top + height - _screen.height;
 		if (i >= 0) height -= i;
 
-		if (height > 0) DoSetViewportPosition(FindWindowZPosition(w) + 1, left, top, width, height);
+		WindowList::Iterator it = Window::s_list.Find(w);
+		if (height > 0) DoSetViewportPosition(++it, left, top, width, height);
 	}
 }
 
@@ -1807,7 +1809,7 @@
 bool ScrollMainWindowTo(int x, int y)
 {
 	Window *w;
-	bool res = ScrollWindowTo(x, y, FindWindowById(WC_MAIN_WINDOW, 0));
+	bool res = ScrollWindowTo(x, y, Window::FindById(WC_MAIN_WINDOW, 0));
 
 	/* If a user scrolls to a tile (via what way what so ever) and already is on
 	 *  that tile (e.g.: pressed twice), move the smallmap to that location,
@@ -1815,7 +1817,7 @@
 
 	if (res) return res;
 
-	w = FindWindowById(WC_SMALLMAP, 0);
+	w = Window::FindById(WC_SMALLMAP, 0);
 	if (w == NULL) return res;
 
 	SmallMapCenterOnCurrentPos(w);
@@ -2394,7 +2396,7 @@
 	e.we.place.userdata = _thd.userdata;
 
 	// stop drag mode if the window has been closed
-	w = FindWindowById(_thd.window_class,_thd.window_number);
+	w = Window::FindById(_thd.window_class,_thd.window_number);
 	if (w == NULL) {
 		ResetObjectToPlace();
 		return false;
@@ -2448,7 +2450,7 @@
 	// undo clicking on button
 	if (_thd.place_mode != 0) {
 		_thd.place_mode = 0;
-		w = FindWindowById(_thd.window_class, _thd.window_number);
+		w = Window::FindById(_thd.window_class, _thd.window_number);
 		if (w != NULL) CallWindowEventNP(w, WE_ABORT_PLACE_OBJ);
 	}
 
--- a/src/widget.cpp	Sun Feb 11 21:20:30 2007 +0000
+++ b/src/widget.cpp	Sun Feb 11 22:57:24 2007 +0000
@@ -121,7 +121,7 @@
 		}
 	}
 
-	SetWindowDirty(w);
+	w->SetDirty();
 }
 
 /** Returns the index for the widget located at the given position
@@ -550,14 +550,14 @@
 			if (item >= 0) {
 				WP(w,dropdown_d).click_delay = 4;
 				WP(w,dropdown_d).selected_index = item;
-				SetWindowDirty(w);
+				w->SetDirty();
 			}
 		} break;
 
 		case WE_MOUSELOOP: {
-			Window *w2 = FindWindowById(WP(w,dropdown_d).parent_wnd_class, WP(w,dropdown_d).parent_wnd_num);
+			Window *w2 = Window::FindById(WP(w,dropdown_d).parent_wnd_class, WP(w,dropdown_d).parent_wnd_num);
 			if (w2 == NULL) {
-				DeleteWindow(w);
+				w->Close();
 				return;
 			}
 
@@ -567,7 +567,7 @@
 				e.we.dropdown.button = WP(w,dropdown_d).parent_button;
 				e.we.dropdown.index  = WP(w,dropdown_d).selected_index;
 				w2->wndproc(w2, &e);
-				DeleteWindow(w);
+				w->Close();
 				return;
 			}
 
@@ -583,12 +583,12 @@
 				}
 
 				WP(w,dropdown_d).selected_index = item;
-				SetWindowDirty(w);
+				w->SetDirty();
 			}
 		} break;
 
 		case WE_DESTROY: {
-			Window *w2 = FindWindowById(WP(w,dropdown_d).parent_wnd_class, WP(w,dropdown_d).parent_wnd_num);
+			Window *w2 = Window::FindById(WP(w,dropdown_d).parent_wnd_class, WP(w,dropdown_d).parent_wnd_num);
 			if (w2 != NULL) {
 				RaiseWindowWidget(w2, WP(w,dropdown_d).parent_button);
 				InvalidateWidget(w2, WP(w,dropdown_d).parent_button);
@@ -633,12 +633,12 @@
 	top = w->top + wi->bottom + 2;
 	height = i * 10 + 4;
 
-	w3 = FindWindowById(WC_STATUS_BAR, 0);
+	w3 = Window::FindById(WC_STATUS_BAR, 0);
 	screen_bottom = w3 == NULL ? _screen.height : w3->top;
 
 	/* Check if the dropdown will fully fit below the widget */
 	if (top + height >= screen_bottom) {
-		w3 = FindWindowById(WC_MAIN_TOOLBAR, 0);
+		w3 = Window::FindById(WC_MAIN_TOOLBAR, 0);
 		screen_top = w3 == NULL ? 0 : w3->top + w3->height;
 
 		/* If not, check if it will fit above the widget */
@@ -653,7 +653,7 @@
 		}
 	}
 
-	w2 = AllocateWindow(
+	w2 = Window::Allocate(
 		w->left + wi[-1].left + 1,
 		top,
 		wi->right - wi[-1].left + 1,
--- a/src/window.cpp	Sun Feb 11 21:20:30 2007 +0000
+++ b/src/window.cpp	Sun Feb 11 22:57:24 2007 +0000
@@ -19,74 +19,594 @@
 // delta between mouse cursor and upper left corner of dragged window
 static Point _drag_delta;
 
-static Window _windows[25];
-Window *_z_windows[lengthof(_windows)];
-Window **_last_z_window; ///< always points to the next free space in the z-array
+/*static*/ WindowList Window::s_list;
 
-void CDECL SetWindowWidgetsDisabledState(Window *w, bool disab_stat, int widgets, ...)
+//static Window _windows[25];
+//Window *_z_windows[lengthof(_windows)];
+//Window **_last_z_window; ///< always points to the next free space in the z-array
+
+int32 CountedObject::AddRef()
+{
+	return ++m_ref_cnt;
+}
+
+int32 CountedObject::Release()
+{
+	int32 res = --m_ref_cnt;
+	assert(res >= 0);
+	if (res == 0) {
+		FinalRelease();
+		delete this;
+	}
+	return res;
+}
+
+void WindowList::Add(Window *w)
+{
+	/* we will add the new window before first vital window or at the end */
+	Iterator it = w->IsVital() ? m_list.end() : FindFirstVitalWindow();
+	/* it should be now at the proper position where new window should be added */
+	m_list.insert(it, w);
+}
+
+void WindowList::Remove(Window *w)
+{
+	Iterator it = Find(w);
+	if (it != m_list.end()) m_list.erase(it);
+}
+
+WindowList::Iterator WindowList::Find(Window *w)
+{
+	struct Match {
+		Window *m_w;
+		bool EnumProc(Iterator it)
+		{
+			return (*it).w == m_w;
+		}
+	} match = {w};
+
+	Iterator it = EnumT(match);
+	if (it == m_list.end()) {
+		DEBUG(misc, 3, "Window (cls %d, number %d) is not open, probably removed by recursive calls",
+			w->window_class, w->window_number);
+	}
+	return it;
+}
+
+WindowList::Iterator WindowList::FindFirstVitalWindow()
+{
+	struct MatchNonVital {
+		bool EnumProc(Iterator it)
+		{
+			return !(*it).w->IsVital();
+		}
+	} match;
+
+	Iterator it = ReverseEnumT(match);
+	/* we have stopped on last non-vital window. Move one step forward to locate first vital window. */
+	if (it != m_list.end()) ++it;
+	return it;
+}
+
+WindowList::Iterator WindowList::FindByClass(WindowClass cls)
+{
+	struct MatchCls {
+		WindowClass  m_cls;
+		bool EnumProc(Iterator it)
+		{
+			Window *w = (*it).w;
+			return w->window_class == m_cls;
+		}
+	} match = {cls};
+
+	Iterator it = EnumT(match);
+	return it;
+}
+
+WindowList::Iterator WindowList::FindById(WindowClass cls, WindowNumber num)
+{
+	struct MatchClsAndId {
+		WindowClass  m_cls;
+		WindowNumber m_num;
+		bool EnumProc(Iterator it)
+		{
+			Window *w = (*it).w;
+			return w->window_class == m_cls && w->window_number == m_num;
+		}
+	} match = {cls, num};
+
+	Iterator it = EnumT(match);
+	return it;
+}
+
+/* Open a new window.
+* This function is called from AllocateWindow() or AllocateWindowDesc()
+* See descriptions for those functions for usage
+* See AllocateWindow() for description of arguments.
+* Only addition here is window_number, which is the window_number being assigned to the new window
+*/
+Window::Window(
+							 int x, int y, int w, int h,
+							 WindowProc *proc, WindowClass cls, const Widget *widget, int wnd_number)
+{
+	//Window *w = FindFreeWindow();
+
+	///* We have run out of windows, close one and use that as the place for our new one */
+	//if (w == NULL) {
+	//	w = FindDeletableWindow();
+	//	if (w == NULL) w = ForceFindDeletableWindow();
+	//	w->Close();
+	//}
+
+	// Set up window properties
+	//memset(w, 0, sizeof(*w));
+	ZeroInit();
+
+	window_class = cls;
+	flags4 = WF_WHITE_BORDER_MASK; // just opened windows have a white border
+	caption_color = 0xFF;
+	left = x;
+	top = y;
+	width = w;
+	height = h;
+	wndproc = proc;
+	AssignWidgetToWindow(this, widget);
+	resize.width = width;
+	resize.height = height;
+	resize.step_width = 1;
+	resize.step_height = 1;
+	window_number = wnd_number;
+
+	//{
+	//	Window **wz = _last_z_window;
+
+	//	/* Hacky way of specifying always-on-top windows. These windows are
+	//	 * always above other windows because they are moved below them.
+	//	 * status-bar is above news-window because it has been created earlier.
+	//	 * Also, as the chat-window is excluded from this, it will always be
+	//	 * the last window, thus always on top.
+	//	 * XXX - Yes, ugly, probably needs something like w->always_on_top flag
+	//	 * to implement correctly, but even then you need some kind of distinction
+	//	 * between on-top of chat/news and status windows, because these conflict */
+	//	if (wz != _z_windows && w->window_class != WC_SEND_NETWORK_MSG) {
+	//		if (FindWindowById(WC_MAIN_TOOLBAR, 0)     != NULL) wz--;
+	//		if (FindWindowById(WC_STATUS_BAR, 0)       != NULL) wz--;
+	//		if (FindWindowById(WC_NEWS_WINDOW, 0)      != NULL) wz--;
+	//		if (FindWindowById(WC_SEND_NETWORK_MSG, 0) != NULL) wz--;
+
+	//		assert(wz >= _z_windows);
+	//		if (wz != _last_z_window) memmove(wz + 1, wz, (byte*)_last_z_window - (byte*)wz);
+	//	}
+
+	//	*wz = w;
+	//	_last_z_window++;
+	//}
+
+	/* add our new window into z-order list */
+	Window::s_list.Add(this);
+
+	SetDirty();
+	CallWindowEventNP(this, WE_CREATE);
+
+	//return w;
+}
+
+/** Find the Window whose parent pointer points to this window
+* @parent w Window to find child of
+* @return return a Window pointer that is the child of w, or NULL otherwise */
+Window* Window::FindChild() const
+{
+	Window *v;
+	FOR_ALL_WINDOWS(v) {
+		if (v->parent == this) return v;
+	}
+
+	return NULL;
+}
+
+void Window::SetDirty() const
+{
+	if (this == NULL) return;
+	SetDirtyBlocks(left, top, left + width, top + height);
+}
+
+/*virtual*/ void Window::FinalRelease()
+{
+	/* Delete any children a window might have in a head-recursive manner */
+	Window *v = FindChild();
+	if (v != NULL) v->Close();
+
+	if (_thd.place_mode != VHM_NONE &&
+		_thd.window_class == window_class &&
+		_thd.window_number == window_number) {
+			ResetObjectToPlace();
+	}
+
+	CallWindowEventNP(this, WE_DESTROY);
+	if (viewport != NULL) DeleteWindowViewport(this);
+
+	SetDirty();
+	free(widget);
+	widget = NULL;
+	widget_count = 0;
+	parent = NULL;
+}
+
+/*virtual*/ void Window::Close()
+{
+	s_list.Remove(this);
+}
+
+/*virtual*/ bool Window::IsVital()
+{
+	WindowClass wc = window_class;
+	return (wc == WC_MAIN_TOOLBAR || wc == WC_STATUS_BAR || wc == WC_NEWS_WINDOW || wc == WC_SEND_NETWORK_MSG);
+}
+
+/**
+* Open a new window. If there is no space for a new window, close an open
+* window. Try to avoid stickied windows, but if there is no else, close one of
+* those as well. Then make sure all created windows are below some always-on-top
+* ones. Finally set all variables and call the WE_CREATE event
+* @param x offset in pixels from the left of the screen
+* @param y offset in pixels from the top of the screen
+* @param width width in pixels of the window
+* @param height height in pixels of the window
+* @param *proc @see WindowProc function to call when any messages/updates happen to the window
+* @param cls @see WindowClass class of the window, used for identification and grouping
+* @param *widget @see Widget pointer to the window layout and various elements
+* @return @see Window pointer of the newly created window
+*/
+/*static*/ Window* Window::Allocate(
+																		int x, int y, int width, int height,
+																		WindowProc *proc, WindowClass cls, const Widget *widget)
+{
+	return new Window(x, y, width, height, proc, cls, widget, 0);
+}
+
+/*static*/ Window* Window::Get(WindowList::Iterator it)
+{
+	return (it != s_list.m_list.end()) ? (*it).w : NULL;
+}
+
+/*static*/ Window* Window::FindById(WindowClass cls, WindowNumber num)
+{
+	return Get(s_list.FindById(cls, num));
+}
+
+/*static*/ void Window::SetDirtyById(WindowClass cls, WindowNumber num)
+{
+	Window *w = FindById(cls, num);
+	if (w != NULL) w->SetDirty();
+}
+
+void CDECL Window::SetWidgetsDisabledState(bool disab_stat, int widgets, ...)
 {
 	va_list wdg_list;
 
 	va_start(wdg_list, widgets);
 
 	while (widgets != WIDGET_LIST_END) {
-		SetWindowWidgetDisabledState(w, widgets, disab_stat);
-		widgets = va_arg(wdg_list, int);
-	}
-
-	va_end(wdg_list);
-}
-
-void CDECL SetWindowWidgetsHiddenState(Window *w, bool hidden_stat, int widgets, ...)
-{
-	va_list wdg_list;
-
-	va_start(wdg_list, widgets);
-
-	while (widgets != WIDGET_LIST_END) {
-		SetWindowWidgetHiddenState(w, widgets, hidden_stat);
+		SetWindowWidgetDisabledState(this, widgets, disab_stat);
 		widgets = va_arg(wdg_list, int);
 	}
 
 	va_end(wdg_list);
 }
 
-void CDECL SetWindowWidgetsLoweredState(Window *w, bool lowered_stat, int widgets, ...)
+void CDECL Window::SetWidgetsHiddenState(bool hidden_stat, int widgets, ...)
 {
 	va_list wdg_list;
 
 	va_start(wdg_list, widgets);
 
 	while (widgets != WIDGET_LIST_END) {
-		SetWindowWidgetLoweredState(w, widgets, lowered_stat);
+		SetWindowWidgetHiddenState(this, widgets, hidden_stat);
 		widgets = va_arg(wdg_list, int);
 	}
 
 	va_end(wdg_list);
 }
 
-void RaiseWindowButtons(Window *w)
+void CDECL Window::SetWidgetsLoweredState(bool lowered_stat, int widgets, ...)
+{
+	va_list wdg_list;
+
+	va_start(wdg_list, widgets);
+
+	while (widgets != WIDGET_LIST_END) {
+		SetWindowWidgetLoweredState(this, widgets, lowered_stat);
+		widgets = va_arg(wdg_list, int);
+	}
+
+	va_end(wdg_list);
+}
+
+void Window::RaiseButtons()
 {
 	uint i;
 
-	for (i = 0; i < w->widget_count; i++) {
-		if (IsWindowWidgetLowered(w, i)) {
-			RaiseWindowWidget(w, i);
-			InvalidateWidget(w, i);
+	for (i = 0; i < widget_count; i++) {
+		if (IsWindowWidgetLowered(this, i)) {
+			RaiseWindowWidget(this, i);
+			InvalidateWidget(this, i);
 		}
 	}
 }
 
-void HandleButtonClick(Window *w, byte widget)
+void Window::HandleButtonClick(byte widget)
 {
-	LowerWindowWidget(w, widget);
-	w->flags4 |= 5 << WF_TIMEOUT_SHL;
-	InvalidateWidget(w, widget);
+	LowerWindowWidget(this, widget);
+	this->flags4 |= 5 << WF_TIMEOUT_SHL;
+	InvalidateWidget(this, widget);
+}
+
+/** On clicking on a window, make it the frontmost window of all. However
+* there are certain windows that always need to be on-top; these include
+* - Toolbar, Statusbar (always on)
+* - New window, Chatbar (only if open)
+* The window is marked dirty for a repaint if the window is actually moved
+* @param w window that is put into the foreground
+* @return pointer to the window, the same as the input pointer
+*/
+void Window::BringToFront()
+{
+	WindowPtr wp = this;
+	WindowList::Iterator it = Window::s_list.Find(this);
+	Window::s_list.Remove(this);
+	Window::s_list.Add(this);
+
+	SetDirty();
+}
+
+/** Find a window and make it the top-window on the screen. The window
+* gets a white border for a brief period of time to visualize its
+* "activation"
+* @return a pointer to the window thus activated */
+/*static*/ Window* Window::BringToFrontById(WindowClass cls, WindowNumber num)
+{
+	Window *w = FindById(cls, num);
+	if (w != NULL) {
+		w->flags4 |= WF_WHITE_BORDER_MASK;
+		w->BringToFront();
+	}
+	return w;
+}
+
+static bool _dragging_window;
+
+void Window::StartDrag()
+{
+	flags4 |= WF_DRAGGING;
+	_dragging_window = true;
+
+	_drag_delta.x = left - _cursor.pos.x;
+	_drag_delta.y = top  - _cursor.pos.y;
+
+	BringToFront();
+	DeleteWindowById(WC_DROPDOWN_MENU, 0);
+}
+
+bool Window::ContinueDrag()
+{
+	const Widget *t = &widget[1]; // the title bar ... ugh
+	const Window *v;
+	int x;
+	int y;
+	int nx;
+	int ny;
+
+	// Stop the dragging if the left mouse button was released
+	if (!_left_button_down) {
+		flags4 &= ~WF_DRAGGING;
+		_dragging_window = false;
+		return false;
+	}
+
+	SetDirty();
+
+	x = _cursor.pos.x + _drag_delta.x;
+	y = _cursor.pos.y + _drag_delta.y;
+	nx = x;
+	ny = y;
+
+	if (_patches.window_snap_radius != 0) {
+		Window *v;
+
+		int hsnap = _patches.window_snap_radius;
+		int vsnap = _patches.window_snap_radius;
+		int delta;
+
+		FOR_ALL_WINDOWS(v) {
+			if (v == this) continue; // Don't snap at yourself
+
+			if (y + height > v->top && y < v->top + v->height) {
+				// Your left border <-> other right border
+				delta = abs(v->left + v->width - x);
+				if (delta <= hsnap) {
+					nx = v->left + v->width;
+					hsnap = delta;
+				}
+
+				// Your right border <-> other left border
+				delta = abs(v->left - x - width);
+				if (delta <= hsnap) {
+					nx = v->left - width;
+					hsnap = delta;
+				}
+			}
+
+			if (top + height >= v->top && top <= v->top + v->height) {
+				// Your left border <-> other left border
+				delta = abs(v->left - x);
+				if (delta <= hsnap) {
+					nx = v->left;
+					hsnap = delta;
+				}
+
+				// Your right border <-> other right border
+				delta = abs(v->left + v->width - x - width);
+				if (delta <= hsnap) {
+					nx = v->left + v->width - width;
+					hsnap = delta;
+				}
+			}
+
+			if (x + width > v->left && x < v->left + v->width) {
+				// Your top border <-> other bottom border
+				delta = abs(v->top + v->height - y);
+				if (delta <= vsnap) {
+					ny = v->top + v->height;
+					vsnap = delta;
+				}
+
+				// Your bottom border <-> other top border
+				delta = abs(v->top - y - height);
+				if (delta <= vsnap) {
+					ny = v->top - height;
+					vsnap = delta;
+				}
+			}
+
+			if (left + width >= v->left && left <= v->left + v->width) {
+				// Your top border <-> other top border
+				delta = abs(v->top - y);
+				if (delta <= vsnap) {
+					ny = v->top;
+					vsnap = delta;
+				}
+
+				// Your bottom border <-> other bottom border
+				delta = abs(v->top + v->height - y - height);
+				if (delta <= vsnap) {
+					ny = v->top + v->height - height;
+					vsnap = delta;
+				}
+			}
+		}
+	}
+
+	// Make sure the window doesn't leave the screen
+	// 13 is the height of the title bar
+	nx = clamp(nx, 13 - t->right, _screen.width - 13 - t->left);
+	ny = clamp(ny, 0, _screen.height - 13);
+
+	// Make sure the title bar isn't hidden by behind the main tool bar
+	v = Window::FindById(WC_MAIN_TOOLBAR, 0);
+	if (v != NULL) {
+		int v_bottom = v->top + v->height;
+		int v_right = v->left + v->width;
+		if (ny + t->top >= v->top && ny + t->top < v_bottom) {
+			if ((v->left < 13 && nx + t->left < v->left) ||
+				(v_right > _screen.width - 13 && nx + t->right > v_right)) {
+					ny = v_bottom;
+			} else {
+				if (nx + t->left > v->left - 13 &&
+					nx + t->right < v_right + 13) {
+						if (top >= v_bottom) {
+							ny = v_bottom;
+						} else if (left < nx) {
+							nx = v->left - 13 - t->left;
+						} else {
+							nx = v_right + 13 - t->right;
+						}
+				}
+			}
+		}
+	}
+
+	if (viewport != NULL) {
+		viewport->left += nx - left;
+		viewport->top  += ny - top;
+	}
+	left = nx;
+	top  = ny;
+
+	SetDirty();
+	return false;
+}
+
+void Window::StartSizing()
+{
+	flags4 |= WF_SIZING;
+	_dragging_window = true;
+
+	_drag_delta.x = _cursor.pos.x;
+	_drag_delta.y = _cursor.pos.y;
+
+	BringToFront();
+	DeleteWindowById(WC_DROPDOWN_MENU, 0);
+}
+
+bool Window::ContinueSizing()
+{
+	WindowEvent e;
+	int x, y;
+
+	/* Stop the sizing if the left mouse button was released */
+	if (!_left_button_down) {
+		flags4 &= ~WF_SIZING;
+		SetDirty();
+		_dragging_window = false;
+		return false;
+	}
+
+	x = _cursor.pos.x - _drag_delta.x;
+	y = _cursor.pos.y - _drag_delta.y;
+
+	/* X and Y has to go by step.. calculate it.
+	* The cast to int is necessary else x/y are implicitly casted to
+	* unsigned int, which won't work. */
+	if (resize.step_width > 1) x -= x % (int)resize.step_width;
+
+	if (resize.step_height > 1) y -= y % (int)resize.step_height;
+
+	/* Check if we don't go below the minimum set size */
+	if ((int)width + x < (int)resize.width)
+		x = resize.width - width;
+	if ((int)height + y < (int)resize.height)
+		y = resize.height - height;
+
+	/* Window already on size */
+	if (x == 0 && y == 0) return false;
+
+	/* Now find the new cursor pos.. this is NOT _cursor, because
+	we move in steps. */
+	_drag_delta.x += x;
+	_drag_delta.y += y;
+
+	/* ResizeWindow sets both pre- and after-size to dirty for redrawal */
+	ResizeWindow(this, x, y);
+
+	e.event = WE_RESIZE;
+	e.we.sizing.size.x = x + width;
+	e.we.sizing.size.y = y + height;
+	e.we.sizing.diff.x = x;
+	e.we.sizing.diff.y = y;
+	wndproc(this, &e);
+	return false;
+
+}
+
+/*static*/ bool Window::HandleWindowDragging(void)
+{
+	// Get out immediately if no window is being dragged at all.
+	if (!_dragging_window) return true;
+
+	// Otherwise find the window...
+	Window *w;
+	FOR_ALL_WINDOWS(w) {
+		if (w->flags4 & WF_DRAGGING) {
+			return w->ContinueDrag();
+		} else if (w->flags4 & WF_SIZING) {
+			return w->ContinueSizing();
+		}
+	}
+	_dragging_window = false;
+	return false;
 }
 
 
-static void StartWindowDrag(Window *w);
-static void StartWindowSizing(Window *w);
 
 static void DispatchLeftClickEvent(Window *w, int x, int y)
 {
@@ -112,7 +632,7 @@
 				case WWT_PANEL   | WWB_PUSHBUTTON: /* WWT_PUSHBTN */
 				case WWT_IMGBTN  | WWB_PUSHBUTTON: /* WWT_PUSHIMGBTN */
 				case WWT_TEXTBTN | WWB_PUSHBUTTON: /* WWT_PUSHTXTBTN */
-					HandleButtonClick(w, e.we.click.widget);
+					w->HandleButtonClick(e.we.click.widget);
 					break;
 			}
 		} else if (wi->type == WWT_SCROLLBAR || wi->type == WWT_SCROLL2BAR || wi->type == WWT_HSCROLLBAR) {
@@ -121,18 +641,18 @@
 
 		if (w->desc_flags & WDF_STD_BTN) {
 			if (e.we.click.widget == 0) { /* 'X' */
-				DeleteWindow(w);
+				w->Close();
 				return;
 			}
 
 			if (e.we.click.widget == 1) { /* 'Title bar' */
-				StartWindowDrag(w);
+				w->StartDrag();
 				return;
 			}
 		}
 
 		if (w->desc_flags & WDF_RESIZABLE && wi->type == WWT_RESIZEBOX) {
-			StartWindowSizing(w);
+			w->StartSizing();
 			InvalidateWidget(w, e.we.click.widget);
 			return;
 		}
@@ -196,64 +716,63 @@
 			int pos = clamp(sb->pos + wheel, 0, sb->count - sb->cap);
 			if (pos != sb->pos) {
 				sb->pos = pos;
-				SetWindowDirty(w);
+				w->SetDirty();
 			}
 		}
 	}
 }
 
-static void DrawOverlappedWindow(Window* const *wz, int left, int top, int right, int bottom);
+static void DrawOverlappedWindow(WindowList::Iterator it, int left, int top, int right, int bottom);
 
 void DrawOverlappedWindowForAll(int left, int top, int right, int bottom)
 {
-	Window* const *wz;
 	DrawPixelInfo bk;
 	_cur_dpi = &bk;
 
-	FOR_ALL_WINDOWS(wz) {
-		const Window *w = *wz;
+	const Window *w;
+	FOR_ALL_WINDOWS(w) {
 		if (right > w->left &&
 				bottom > w->top &&
 				left < w->left + w->width &&
 				top < w->top + w->height) {
-			DrawOverlappedWindow(wz, left, top, right, bottom);
+			DrawOverlappedWindow(it, left, top, right, bottom);
 		}
 	}
 }
 
-static void DrawOverlappedWindow(Window* const *wz, int left, int top, int right, int bottom)
+static void DrawOverlappedWindow(WindowList::Iterator wit, int left, int top, int right, int bottom)
 {
-	Window* const *vz = wz;
-	int x;
+	Window *w = (*wit).w;
 
-	while (++vz != _last_z_window) {
-		const Window *v = *vz;
+	for (WindowList::Iterator vit = wit; ++vit != Window::s_list.m_list.end(); ) {
+		const Window *v = (*vit).w;
+		int x;
 
 		if (right > v->left &&
 				bottom > v->top &&
 				left < v->left + v->width &&
 				top < v->top + v->height) {
 			if (left < (x=v->left)) {
-				DrawOverlappedWindow(wz, left, top, x, bottom);
-				DrawOverlappedWindow(wz, x, top, right, bottom);
+				DrawOverlappedWindow(wit, left, top, x, bottom);
+				DrawOverlappedWindow(wit, x, top, right, bottom);
 				return;
 			}
 
 			if (right > (x=v->left + v->width)) {
-				DrawOverlappedWindow(wz, left, top, x, bottom);
-				DrawOverlappedWindow(wz, x, top, right, bottom);
+				DrawOverlappedWindow(wit, left, top, x, bottom);
+				DrawOverlappedWindow(wit, x, top, right, bottom);
 				return;
 			}
 
 			if (top < (x=v->top)) {
-				DrawOverlappedWindow(wz, left, top, right, x);
-				DrawOverlappedWindow(wz, left, x, right, bottom);
+				DrawOverlappedWindow(wit, left, top, right, x);
+				DrawOverlappedWindow(wit, left, x, right, bottom);
 				return;
 			}
 
 			if (bottom > (x=v->top + v->height)) {
-				DrawOverlappedWindow(wz, left, top, right, x);
-				DrawOverlappedWindow(wz, left, x, right, bottom);
+				DrawOverlappedWindow(wit, left, top, right, x);
+				DrawOverlappedWindow(wit, left, x, right, bottom);
 				return;
 			}
 
@@ -265,12 +784,12 @@
 		DrawPixelInfo *dp = _cur_dpi;
 		dp->width = right - left;
 		dp->height = bottom - top;
-		dp->left = left - (*wz)->left;
-		dp->top = top - (*wz)->top;
+		dp->left = left - w->left;
+		dp->top = top - w->top;
 		dp->pitch = _screen.pitch;
 		dp->dst_ptr = _screen.dst_ptr + top * _screen.pitch + left;
 		dp->zoom = 0;
-		CallWindowEventNP(*wz, WE_PAINT);
+		CallWindowEventNP(w, WE_PAINT);
 	}
 }
 
@@ -282,104 +801,48 @@
 	w->wndproc(w, &e);
 }
 
-void SetWindowDirty(const Window *w)
-{
-	if (w == NULL) return;
-	SetDirtyBlocks(w->left, w->top, w->left + w->width, w->top + w->height);
-}
-
-/** Find the Window whose parent pointer points to this window
- * @parent w Window to find child of
- * @return return a Window pointer that is the child of w, or NULL otherwise */
-static Window *FindChildWindow(const Window *w)
-{
-	Window* const *wz;
-
-	FOR_ALL_WINDOWS(wz) {
-		Window *v = *wz;
-		if (v->parent == w) return v;
-	}
-
-	return NULL;
-}
-
 /** Find the z-value of a window. A window must already be open
  * or the behaviour is undefined but function should never fail */
-Window **FindWindowZPosition(const Window *w)
-{
-	Window **wz;
-
-	for (wz = _z_windows; wz != _last_z_window; wz++) {
-		if (*wz == w) return wz;
-	}
-
-	DEBUG(misc, 3, "Window (cls %d, number %d) is not open, probably removed by recursive calls",
-		w->window_class, w->window_number);
-	return NULL;
-}
-
-void DeleteWindow(Window *w)
-{
-	Window *v;
-	Window **wz;
-	if (w == NULL) return;
-
-	/* Delete any children a window might have in a head-recursive manner */
-	v = FindChildWindow(w);
-	if (v != NULL) DeleteWindow(v);
+//WindowList::Iterator FindWindowZPosition(const Window *w)
+//{
+//	Window *wz;
+//	FOR_ALL_WINDOWS(wz) {
+//		if (wz == w) return it;
+//	}
+//
+//	DEBUG(misc, 3, "Window (cls %d, number %d) is not open, probably removed by recursive calls",
+//		w->window_class, w->window_number);
+//	return Window::s_list.m_list.end();
+//}
 
-	if (_thd.place_mode != VHM_NONE &&
-			_thd.window_class == w->window_class &&
-			_thd.window_number == w->window_number) {
-		ResetObjectToPlace();
-	}
-
-	CallWindowEventNP(w, WE_DESTROY);
-	if (w->viewport != NULL) DeleteWindowViewport(w);
-
-	SetWindowDirty(w);
-	free(w->widget);
-	w->widget = NULL;
-	w->widget_count = 0;
-	w->parent = NULL;
-
-	/* Find the window in the z-array, and effectively remove it
-	 * by moving all windows after it one to the left */
-	wz = FindWindowZPosition(w);
-	if (wz == NULL) return;
-	memmove(wz, wz + 1, (byte*)_last_z_window - (byte*)wz);
-	_last_z_window--;
-}
-
-Window *FindWindowById(WindowClass cls, WindowNumber number)
-{
-	Window* const *wz;
-
-	FOR_ALL_WINDOWS(wz) {
-		Window *w = *wz;
-		if (w->window_class == cls && w->window_number == number) return w;
-	}
-
-	return NULL;
-}
+//Window *FindWindowById(WindowClass cls, WindowNumber number)
+//{
+//	Window *w;
+//
+//	FOR_ALL_WINDOWS(w) {
+//		if (w->window_class == cls && w->window_number == number) return w;
+//	}
+//
+//	return NULL;
+//}
 
 void DeleteWindowById(WindowClass cls, WindowNumber number)
 {
-	DeleteWindow(FindWindowById(cls, number));
+	Window *w = Window::FindById(cls, number);
+	if (w != NULL) w->Close();
 }
 
 void DeleteWindowByClass(WindowClass cls)
 {
-	Window* const *wz;
 
 restart_search:
 	/* When we find the window to delete, we need to restart the search
 	 * as deleting this window could cascade in deleting (many) others
 	 * anywhere in the z-array */
-	FOR_ALL_WINDOWS(wz) {
-		Window *w = *wz;
+	Window *w;
+	FOR_ALL_WINDOWS(w) {
 		if (w->window_class == cls) {
-			DeleteWindow(w);
+			w->Close();
 			goto restart_search;
 		}
 	}
@@ -391,16 +854,15 @@
  * @param id PlayerID player identifier */
 void DeletePlayerWindows(PlayerID id)
 {
-	Window* const *wz;
 
 restart_search:
 	/* When we find the window to delete, we need to restart the search
 	 * as deleting this window could cascade in deleting (many) others
 	 * anywhere in the z-array */
-	FOR_ALL_WINDOWS(wz) {
-		Window *w = *wz;
+	Window *w;
+	FOR_ALL_WINDOWS(w) {
 		if (w->caption_color == id) {
-			DeleteWindow(w);
+			w->Close();
 			goto restart_search;
 		}
 	}
@@ -416,10 +878,9 @@
  * @param new_player PlayerID of the new owner of the window */
 void ChangeWindowOwner(PlayerID old_player, PlayerID new_player)
 {
-	Window* const *wz;
+	Window *w;
 
-	FOR_ALL_WINDOWS(wz) {
-		Window *w = *wz;
+	FOR_ALL_WINDOWS(w) {
 
 		if (w->caption_color != old_player)      continue;
 		if (w->window_class == WC_PLAYER_COLOR)  continue;
@@ -436,60 +897,6 @@
 	}
 }
 
-static void BringWindowToFront(const Window *w);
-
-/** Find a window and make it the top-window on the screen. The window
- * gets a white border for a brief period of time to visualize its
- * "activation"
- * @return a pointer to the window thus activated */
-Window *BringWindowToFrontById(WindowClass cls, WindowNumber number)
-{
-	Window *w = FindWindowById(cls, number);
-
-	if (w != NULL) {
-		w->flags4 |= WF_WHITE_BORDER_MASK;
-		BringWindowToFront(w);
-		SetWindowDirty(w);
-	}
-
-	return w;
-}
-
-static inline bool IsVitalWindow(const Window *w)
-{
-	WindowClass wc = w->window_class;
-	return (wc == WC_MAIN_TOOLBAR || wc == WC_STATUS_BAR || wc == WC_NEWS_WINDOW || wc == WC_SEND_NETWORK_MSG);
-}
-
-/** On clicking on a window, make it the frontmost window of all. However
- * there are certain windows that always need to be on-top; these include
- * - Toolbar, Statusbar (always on)
- * - New window, Chatbar (only if open)
- * The window is marked dirty for a repaint if the window is actually moved
- * @param w window that is put into the foreground
- * @return pointer to the window, the same as the input pointer
- */
-static void BringWindowToFront(const Window *w)
-{
-	Window *tempz;
-	Window **wz = FindWindowZPosition(w);
-	Window **vz = _last_z_window;
-
-	/* Bring the window just below the vital windows */
-	do {
-		if (--vz < _z_windows) return;
-	} while (IsVitalWindow(*vz));
-
-	if (wz == vz) return; // window is already in the right position
-	assert(wz < vz);
-
-	tempz = *wz;
-	memmove(wz, wz + 1, (byte*)vz - (byte*)wz);
-	*vz = tempz;
-
-	SetWindowDirty(w);
-}
-
 /** We have run out of windows, so find a suitable candidate for replacement.
  * Keep all important windows intact. These are
  * - Main window (gamefield), Toolbar, Statusbar (always on)
@@ -497,18 +904,21 @@
  * - Any sticked windows since we wanted to keep these
  * @return w pointer to the window that is going to be deleted
  */
-static Window *FindDeletableWindow(void)
-{
-	Window* const *wz;
-
-	FOR_ALL_WINDOWS(wz) {
-		Window *w = *wz;
-		if (w->window_class != WC_MAIN_WINDOW && !IsVitalWindow(w) && !(w->flags4 & WF_STICKY)) {
-			return w;
-		}
-	}
-	return NULL;
-}
+//static Window *FindDeletableWindow(void)
+//{
+//	Window *w;
+//	FOR_ALL_WINDOWS(w) {
+//		if (w->window_class != WC_MAIN_WINDOW && !IsVitalWindow(w) && !(w->flags4 & WF_STICKY)) {
+//			return w;
+//		}
+//	}
+//	FOR_ALL_WINDOWS(w) {
+//		if (w->window_class != WC_MAIN_WINDOW && !IsVitalWindow(w)) {
+//			return w;
+//		}
+//	}
+//	return NULL;
+//}
 
 /** A window must be freed, and all are marked as important windows. Ease the
  * restriction a bit by allowing to delete sticky windows. Keep important/vital
@@ -517,16 +927,16 @@
  * @see FindDeletableWindow()
  * @return w Pointer to the window that is being deleted
  */
-static Window *ForceFindDeletableWindow(void)
-{
-	Window* const *wz;
-
-	for (wz = _z_windows;; wz++) {
-		Window *w = *wz;
-		assert(wz < _last_z_window);
-		if (w->window_class != WC_MAIN_WINDOW && !IsVitalWindow(w)) return w;
-	}
-}
+//static Window *ForceFindDeletableWindow(void)
+//{
+//	Window* const *wz;
+//
+//	for (wz = _z_windows;; wz++) {
+//		Window *w = *wz;
+//		assert(wz < _last_z_window);
+//		if (w->window_class != WC_MAIN_WINDOW && !IsVitalWindow(w)) return w;
+//	}
+//}
 
 bool IsWindowOfPrototype(const Window *w, const Widget *widget)
 {
@@ -553,115 +963,28 @@
 	}
 }
 
-static Window *FindFreeWindow(void)
-{
-	Window *w;
-
-	for (w = _windows; w < endof(_windows); w++) {
-		Window* const *wz;
-		bool window_in_use = false;
-
-		FOR_ALL_WINDOWS(wz) {
-			if (*wz == w) {
-				window_in_use = true;
-				break;
-			}
-		}
-
-		if (!window_in_use) return w;
-	}
-
-	assert(_last_z_window == endof(_z_windows));
-	return NULL;
-}
-
-/* Open a new window.
- * This function is called from AllocateWindow() or AllocateWindowDesc()
- * See descriptions for those functions for usage
- * See AllocateWindow() for description of arguments.
- * Only addition here is window_number, which is the window_number being assigned to the new window
- */
-static Window *LocalAllocateWindow(
-							int x, int y, int width, int height,
-							WindowProc *proc, WindowClass cls, const Widget *widget, int window_number)
-{
-	Window *w = FindFreeWindow();
-
-	/* We have run out of windows, close one and use that as the place for our new one */
-	if (w == NULL) {
-		w = FindDeletableWindow();
-		if (w == NULL) w = ForceFindDeletableWindow();
-		DeleteWindow(w);
-	}
+//static Window *FindFreeWindow(void)
+//{
+//	Window *w;
+//
+//	for (w = _windows; w < endof(_windows); w++) {
+//		Window* const *wz;
+//		bool window_in_use = false;
+//
+//		FOR_ALL_WINDOWS(wz) {
+//			if (*wz == w) {
+//				window_in_use = true;
+//				break;
+//			}
+//		}
+//
+//		if (!window_in_use) return w;
+//	}
+//
+//	assert(_last_z_window == endof(_z_windows));
+//	return NULL;
+//}
 
-	// Set up window properties
-	memset(w, 0, sizeof(*w));
-	w->window_class = cls;
-	w->flags4 = WF_WHITE_BORDER_MASK; // just opened windows have a white border
-	w->caption_color = 0xFF;
-	w->left = x;
-	w->top = y;
-	w->width = width;
-	w->height = height;
-	w->wndproc = proc;
-	AssignWidgetToWindow(w, widget);
-	w->resize.width = width;
-	w->resize.height = height;
-	w->resize.step_width = 1;
-	w->resize.step_height = 1;
-	w->window_number = window_number;
-
-	{
-		Window **wz = _last_z_window;
-
-		/* Hacky way of specifying always-on-top windows. These windows are
-		 * always above other windows because they are moved below them.
-		 * status-bar is above news-window because it has been created earlier.
-		 * Also, as the chat-window is excluded from this, it will always be
-		 * the last window, thus always on top.
-		 * XXX - Yes, ugly, probably needs something like w->always_on_top flag
-		 * to implement correctly, but even then you need some kind of distinction
-		 * between on-top of chat/news and status windows, because these conflict */
-		if (wz != _z_windows && w->window_class != WC_SEND_NETWORK_MSG) {
-			if (FindWindowById(WC_MAIN_TOOLBAR, 0)     != NULL) wz--;
-			if (FindWindowById(WC_STATUS_BAR, 0)       != NULL) wz--;
-			if (FindWindowById(WC_NEWS_WINDOW, 0)      != NULL) wz--;
-			if (FindWindowById(WC_SEND_NETWORK_MSG, 0) != NULL) wz--;
-
-			assert(wz >= _z_windows);
-			if (wz != _last_z_window) memmove(wz + 1, wz, (byte*)_last_z_window - (byte*)wz);
-		}
-
-		*wz = w;
-		_last_z_window++;
-	}
-
-	SetWindowDirty(w);
-	CallWindowEventNP(w, WE_CREATE);
-
-	return w;
-}
-
-/**
- * Open a new window. If there is no space for a new window, close an open
- * window. Try to avoid stickied windows, but if there is no else, close one of
- * those as well. Then make sure all created windows are below some always-on-top
- * ones. Finally set all variables and call the WE_CREATE event
- * @param x offset in pixels from the left of the screen
- * @param y offset in pixels from the top of the screen
- * @param width width in pixels of the window
- * @param height height in pixels of the window
- * @param *proc @see WindowProc function to call when any messages/updates happen to the window
- * @param cls @see WindowClass class of the window, used for identification and grouping
- * @param *widget @see Widget pointer to the window layout and various elements
- * @return @see Window pointer of the newly created window
- */
-Window *AllocateWindow(
-							int x, int y, int width, int height,
-							WindowProc *proc, WindowClass cls, const Widget *widget)
-{
-	return LocalAllocateWindow(x, y, width, height, proc, cls, widget, 0);
-}
 
 typedef struct SizeRect {
 	int left,top,width,height;
@@ -673,7 +996,6 @@
 static bool IsGoodAutoPlace1(int left, int top)
 {
 	int right,bottom;
-	Window* const *wz;
 
 	_awap_r.left= left;
 	_awap_r.top = top;
@@ -684,8 +1006,8 @@
 		return false;
 
 	// Make sure it is not obscured by any window.
-	FOR_ALL_WINDOWS(wz) {
-		const Window *w = *wz;
+	Window *w;
+	FOR_ALL_WINDOWS(w) {
 		if (w->window_class == WC_MAIN_WINDOW) continue;
 
 		if (right > w->left &&
@@ -702,7 +1024,6 @@
 static bool IsGoodAutoPlace2(int left, int top)
 {
 	int width,height;
-	Window* const *wz;
 
 	_awap_r.left= left;
 	_awap_r.top = top;
@@ -713,8 +1034,8 @@
 	if (top < 22 || top > _screen.height - (height>>2)) return false;
 
 	// Make sure it is not obscured by any window.
-	FOR_ALL_WINDOWS(wz) {
-		const Window *w = *wz;
+	Window *w;
+	FOR_ALL_WINDOWS(w) {
 		if (w->window_class == WC_MAIN_WINDOW) continue;
 
 		if (left + width > w->left &&
@@ -730,7 +1051,6 @@
 
 static Point GetAutoPlacePosition(int width, int height)
 {
-	Window* const *wz;
 	Point pt;
 
 	_awap_r.width = width;
@@ -738,8 +1058,8 @@
 
 	if (IsGoodAutoPlace1(0, 24)) goto ok_pos;
 
-	FOR_ALL_WINDOWS(wz) {
-		const Window *w = *wz;
+	Window *w;
+	FOR_ALL_WINDOWS(w) {
 		if (w->window_class == WC_MAIN_WINDOW) continue;
 
 		if (IsGoodAutoPlace1(w->left+w->width+2,w->top)) goto ok_pos;
@@ -752,8 +1072,7 @@
 		if (IsGoodAutoPlace1(w->left+w->width-width,w->top-   height-2)) goto ok_pos;
 	}
 
-	FOR_ALL_WINDOWS(wz) {
-		const Window *w = *wz;
+	FOR_ALL_WINDOWS(w) {
 		if (w->window_class == WC_MAIN_WINDOW) continue;
 
 		if (IsGoodAutoPlace2(w->left+w->width+2,w->top)) goto ok_pos;
@@ -766,9 +1085,7 @@
 		int left=0,top=24;
 
 restart:;
-		FOR_ALL_WINDOWS(wz) {
-			const Window *w = *wz;
-
+		FOR_ALL_WINDOWS(w) {
 			if (w->left == left && w->top == top) {
 				left += 5;
 				top += 5;
@@ -796,7 +1113,7 @@
 	 * However if it falls too extremely outside window positions, reposition
 	 * it to an automatic place */
 	if (desc->parent_cls != 0 /* WC_MAIN_WINDOW */ &&
-			(w = FindWindowById(desc->parent_cls, window_number)) != NULL &&
+			(w = Window::FindById(desc->parent_cls, window_number)) != NULL &&
 			w->left < _screen.width - 20 && w->left > -60 && w->top < _screen.height - 20) {
 
 		pt.x = w->left + 10;
@@ -807,11 +1124,11 @@
 	} else {
 		switch (desc->left) {
 			case WDP_ALIGN_TBR: { /* Align the right side with the top toolbar */
-				w = FindWindowById(WC_MAIN_TOOLBAR, 0);
+				w = Window::FindById(WC_MAIN_TOOLBAR, 0);
 				pt.x = (w->left + w->width) - desc->width;
 			}	break;
 			case WDP_ALIGN_TBL: /* Align the left side with the top toolbar */
-				pt.x = FindWindowById(WC_MAIN_TOOLBAR, 0)->left;
+				pt.x = Window::FindById(WC_MAIN_TOOLBAR, 0)->left;
 				break;
 			case WDP_AUTO: /* Find a good automatic position for the window */
 				pt = GetAutoPlacePosition(desc->width, desc->height);
@@ -842,7 +1159,7 @@
 	}
 
 allocate_window:
-	w = LocalAllocateWindow(pt.x, pt.y, desc->width, desc->height, desc->proc, desc->cls, desc->widgets, window_number);
+	w = new Window(pt.x, pt.y, desc->width, desc->height, desc->proc, desc->cls, desc->widgets, window_number);
 	w->desc_flags = desc->flags;
 	return w;
 }
@@ -867,7 +1184,7 @@
 {
 	Window *w;
 
-	if (BringWindowToFrontById(desc->cls, window_number)) return NULL;
+	if (Window::BringToFrontById(desc->cls, window_number) != NULL) return NULL;
 	w = LocalAllocateWindowDesc(desc, window_number);
 	return w;
 }
@@ -877,10 +1194,8 @@
  * @return a pointer to the found window if any, NULL otherwise */
 Window *FindWindowFromPt(int x, int y)
 {
-	Window* const *wz;
-
-	for (wz = _last_z_window; wz != _z_windows;) {
-		Window *w = *--wz;
+	Window *w;
+	REVERSED_FOR_ALL_WINDOWS(w) {
 		if (IS_INSIDE_1D(x, w->left, w->width) && IS_INSIDE_1D(y, w->top, w->height)) {
 			return w;
 		}
@@ -893,28 +1208,30 @@
 {
 	IConsoleClose();
 
-	memset(&_windows, 0, sizeof(_windows));
-	_last_z_window = _z_windows;
+	//memset(&_windows, 0, sizeof(_windows));
+	//_last_z_window = _z_windows;
 	InitViewports();
 	_no_scroll = 0;
 }
 
 void UnInitWindowSystem(void)
 {
-	Window **wz;
+	Window::s_list.m_list.clear();
 
-restart_search:
-	/* Delete all windows, reset z-array.
-	 *When we find the window to delete, we need to restart the search
-	 * as deleting this window could cascade in deleting (many) others
-	 * anywhere in the z-array. We call DeleteWindow() so that it can properly
-	 * release own alloc'd memory, which otherwise could result in memleaks */
-	FOR_ALL_WINDOWS(wz) {
-		DeleteWindow(*wz);
-		goto restart_search;
-	}
-
-	assert(_last_z_window == _z_windows);
+//	Window **wz;
+//
+//restart_search:
+//	/* Delete all windows, reset z-array.
+//	 *When we find the window to delete, we need to restart the search
+//	 * as deleting this window could cascade in deleting (many) others
+//	 * anywhere in the z-array. We call DeleteWindow() so that it can properly
+//	 * release own alloc'd memory, which otherwise could result in memleaks */
+//	FOR_ALL_WINDOWS(wz) {
+//		DeleteWindow(*wz);
+//		goto restart_search;
+//	}
+//
+//	assert(_last_z_window == _z_windows);
 }
 
 void ResetWindowSystem(void)
@@ -930,31 +1247,26 @@
 static void DecreaseWindowCounters(void)
 {
 	Window *w;
-	Window* const *wz;
-
-	for (wz = _last_z_window; wz != _z_windows;) {
-		w = *--wz;
+	REVERSED_FOR_ALL_WINDOWS(w) {
 		// Unclick scrollbar buttons if they are pressed.
 		if (w->flags4 & (WF_SCROLL_DOWN | WF_SCROLL_UP)) {
 			w->flags4 &= ~(WF_SCROLL_DOWN | WF_SCROLL_UP);
-			SetWindowDirty(w);
+			w->SetDirty();
 		}
 		CallWindowEventNP(w, WE_MOUSELOOP);
 	}
 
-	for (wz = _last_z_window; wz != _z_windows;) {
-		w = *--wz;
-
+	REVERSED_FOR_ALL_WINDOWS(w) {
 		if (w->flags4&WF_TIMEOUT_MASK && !(--w->flags4&WF_TIMEOUT_MASK)) {
 			CallWindowEventNP(w, WE_TIMEOUT);
-			if (w->desc_flags & WDF_UNCLICK_BUTTONS) RaiseWindowButtons(w);
+			if (w->desc_flags & WDF_UNCLICK_BUTTONS) w->RaiseButtons();
 		}
 	}
 }
 
 Window *GetCallbackWnd(void)
 {
-	return FindWindowById(_thd.window_class, _thd.window_number);
+	return Window::FindById(_thd.window_class, _thd.window_number);
 }
 
 static void HandlePlacePresize(void)
@@ -1008,7 +1320,7 @@
 
 	if (!_popup_menu_active) return true;
 
-	w = FindWindowById(WC_TOOLBAR_MENU, 0);
+	w = Window::FindById(WC_TOOLBAR_MENU, 0);
 	if (w == NULL) {
 		_popup_menu_active = false;
 		return false;
@@ -1030,9 +1342,13 @@
 
 static bool HandleMouseOver(void)
 {
+	static WindowClass  last_cls;
+	static WindowNumber last_num;
+
 	Window *w;
 	WindowEvent e;
-	static Window *last_w = NULL;
+
+	Window *last_w = Window::FindById(last_cls, last_num);
 
 	w = FindWindowFromPt(_cursor.pos.x, _cursor.pos.y);
 
@@ -1043,7 +1359,9 @@
 		e.we.mouseover.pt.y = -1;
 		if (last_w->wndproc) last_w->wndproc(last_w, &e);
 	}
-	last_w = w;
+
+	last_cls = w->window_class;
+	last_num = w->window_number;
 
 	if (w != NULL) {
 		// send an event in client coordinates.
@@ -1074,7 +1392,7 @@
 
 	if (x == 0 && y == 0) return;
 
-	SetWindowDirty(w);
+	w->SetDirty();
 	for (wi = w->widget; wi->type != WWT_LAST; wi++) {
 		/* Isolate the resizing flags */
 		byte rsizeflag = GB(wi->display_flags, 0, 4);
@@ -1107,238 +1425,11 @@
 	if (resize_width)  w->width  += x;
 	if (resize_height) w->height += y;
 
-	SetWindowDirty(w);
+	w->SetDirty();
 }
 
-static bool _dragging_window;
-
-static bool HandleWindowDragging(void)
-{
-	Window* const *wz;
-	// Get out immediately if no window is being dragged at all.
-	if (!_dragging_window) return true;
-
-	// Otherwise find the window...
-	FOR_ALL_WINDOWS(wz) {
-		Window *w = *wz;
-
-		if (w->flags4 & WF_DRAGGING) {
-			const Widget *t = &w->widget[1]; // the title bar ... ugh
-			const Window *v;
-			int x;
-			int y;
-			int nx;
-			int ny;
-
-			// Stop the dragging if the left mouse button was released
-			if (!_left_button_down) {
-				w->flags4 &= ~WF_DRAGGING;
-				break;
-			}
-
-			SetWindowDirty(w);
-
-			x = _cursor.pos.x + _drag_delta.x;
-			y = _cursor.pos.y + _drag_delta.y;
-			nx = x;
-			ny = y;
-
-			if (_patches.window_snap_radius != 0) {
-				Window* const *vz;
-
-				int hsnap = _patches.window_snap_radius;
-				int vsnap = _patches.window_snap_radius;
-				int delta;
-
-				FOR_ALL_WINDOWS(vz) {
-					const Window *v = *vz;
-
-					if (v == w) continue; // Don't snap at yourself
-
-					if (y + w->height > v->top && y < v->top + v->height) {
-						// Your left border <-> other right border
-						delta = abs(v->left + v->width - x);
-						if (delta <= hsnap) {
-							nx = v->left + v->width;
-							hsnap = delta;
-						}
-
-						// Your right border <-> other left border
-						delta = abs(v->left - x - w->width);
-						if (delta <= hsnap) {
-							nx = v->left - w->width;
-							hsnap = delta;
-						}
-					}
-
-					if (w->top + w->height >= v->top && w->top <= v->top + v->height) {
-						// Your left border <-> other left border
-						delta = abs(v->left - x);
-						if (delta <= hsnap) {
-							nx = v->left;
-							hsnap = delta;
-						}
-
-						// Your right border <-> other right border
-						delta = abs(v->left + v->width - x - w->width);
-						if (delta <= hsnap) {
-							nx = v->left + v->width - w->width;
-							hsnap = delta;
-						}
-					}
-
-					if (x + w->width > v->left && x < v->left + v->width) {
-						// Your top border <-> other bottom border
-						delta = abs(v->top + v->height - y);
-						if (delta <= vsnap) {
-							ny = v->top + v->height;
-							vsnap = delta;
-						}
-
-						// Your bottom border <-> other top border
-						delta = abs(v->top - y - w->height);
-						if (delta <= vsnap) {
-							ny = v->top - w->height;
-							vsnap = delta;
-						}
-					}
-
-					if (w->left + w->width >= v->left && w->left <= v->left + v->width) {
-						// Your top border <-> other top border
-						delta = abs(v->top - y);
-						if (delta <= vsnap) {
-							ny = v->top;
-							vsnap = delta;
-						}
-
-						// Your bottom border <-> other bottom border
-						delta = abs(v->top + v->height - y - w->height);
-						if (delta <= vsnap) {
-							ny = v->top + v->height - w->height;
-							vsnap = delta;
-						}
-					}
-				}
-			}
-
-			// Make sure the window doesn't leave the screen
-			// 13 is the height of the title bar
-			nx = clamp(nx, 13 - t->right, _screen.width - 13 - t->left);
-			ny = clamp(ny, 0, _screen.height - 13);
-
-			// Make sure the title bar isn't hidden by behind the main tool bar
-			v = FindWindowById(WC_MAIN_TOOLBAR, 0);
-			if (v != NULL) {
-				int v_bottom = v->top + v->height;
-				int v_right = v->left + v->width;
-				if (ny + t->top >= v->top && ny + t->top < v_bottom) {
-					if ((v->left < 13 && nx + t->left < v->left) ||
-							(v_right > _screen.width - 13 && nx + t->right > v_right)) {
-						ny = v_bottom;
-					} else {
-						if (nx + t->left > v->left - 13 &&
-								nx + t->right < v_right + 13) {
-							if (w->top >= v_bottom) {
-								ny = v_bottom;
-							} else if (w->left < nx) {
-								nx = v->left - 13 - t->left;
-							} else {
-								nx = v_right + 13 - t->right;
-							}
-						}
-					}
-				}
-			}
-
-			if (w->viewport != NULL) {
-				w->viewport->left += nx - w->left;
-				w->viewport->top  += ny - w->top;
-			}
-			w->left = nx;
-			w->top  = ny;
-
-			SetWindowDirty(w);
-			return false;
-		} else if (w->flags4 & WF_SIZING) {
-			WindowEvent e;
-			int x, y;
-
-			/* Stop the sizing if the left mouse button was released */
-			if (!_left_button_down) {
-				w->flags4 &= ~WF_SIZING;
-				SetWindowDirty(w);
-				break;
-			}
-
-			x = _cursor.pos.x - _drag_delta.x;
-			y = _cursor.pos.y - _drag_delta.y;
-
-			/* X and Y has to go by step.. calculate it.
-			 * The cast to int is necessary else x/y are implicitly casted to
-			 * unsigned int, which won't work. */
-			if (w->resize.step_width > 1) x -= x % (int)w->resize.step_width;
-
-			if (w->resize.step_height > 1) y -= y % (int)w->resize.step_height;
-
-			/* Check if we don't go below the minimum set size */
-			if ((int)w->width + x < (int)w->resize.width)
-				x = w->resize.width - w->width;
-			if ((int)w->height + y < (int)w->resize.height)
-				y = w->resize.height - w->height;
-
-			/* Window already on size */
-			if (x == 0 && y == 0) return false;
-
-			/* Now find the new cursor pos.. this is NOT _cursor, because
-			    we move in steps. */
-			_drag_delta.x += x;
-			_drag_delta.y += y;
-
-			/* ResizeWindow sets both pre- and after-size to dirty for redrawal */
-			ResizeWindow(w, x, y);
-
-			e.event = WE_RESIZE;
-			e.we.sizing.size.x = x + w->width;
-			e.we.sizing.size.y = y + w->height;
-			e.we.sizing.diff.x = x;
-			e.we.sizing.diff.y = y;
-			w->wndproc(w, &e);
-			return false;
-		}
-	}
-
-	_dragging_window = false;
-	return false;
-}
-
-static void StartWindowDrag(Window *w)
-{
-	w->flags4 |= WF_DRAGGING;
-	_dragging_window = true;
-
-	_drag_delta.x = w->left - _cursor.pos.x;
-	_drag_delta.y = w->top  - _cursor.pos.y;
-
-	BringWindowToFront(w);
-	DeleteWindowById(WC_DROPDOWN_MENU, 0);
-}
-
-static void StartWindowSizing(Window *w)
-{
-	w->flags4 |= WF_SIZING;
-	_dragging_window = true;
-
-	_drag_delta.x = _cursor.pos.x;
-	_drag_delta.y = _cursor.pos.y;
-
-	BringWindowToFront(w);
-	DeleteWindowById(WC_DROPDOWN_MENU, 0);
-}
-
-
 static bool HandleScrollbarScrolling(void)
 {
-	Window* const *wz;
 	int i;
 	int pos;
 	Scrollbar *sb;
@@ -1347,14 +1438,13 @@
 	if (!_scrolling_scrollbar) return true;
 
 	// Find the scrolling window
-	FOR_ALL_WINDOWS(wz) {
-		Window *w = *wz;
-
+	Window *w;
+	FOR_ALL_WINDOWS(w) {
 		if (w->flags4 & WF_SCROLL_MIDDLE) {
 			// Abort if no button is clicked any more.
 			if (!_left_button_down) {
 				w->flags4 &= ~WF_SCROLL_MIDDLE;
-				SetWindowDirty(w);
+				w->SetDirty();
 				break;
 			}
 
@@ -1373,7 +1463,7 @@
 			pos = min(max(0, i + _scrollbar_start_pos) * sb->count / _scrollbar_size, max(0, sb->count - sb->cap));
 			if (pos != sb->pos) {
 				sb->pos = pos;
-				SetWindowDirty(w);
+				w->SetDirty();
 			}
 			return false;
 		}
@@ -1423,32 +1513,30 @@
  * modal-popup; function returns a false and child window gets a white border
  * @param w Window to bring on-top
  * @return false if the window has an active modal child, true otherwise */
-static bool MaybeBringWindowToFront(const Window *w)
+static bool MaybeBringWindowToFront(Window *w)
 {
 	bool bring_to_front = false;
-	Window* const *wz;
-	Window* const *uz;
 
 	if (w->window_class == WC_MAIN_WINDOW ||
-			IsVitalWindow(w) ||
+			w->IsVital() ||
 			w->window_class == WC_TOOLTIPS ||
 			w->window_class == WC_DROPDOWN_MENU) {
 		return true;
 	}
 
-	wz = FindWindowZPosition(w);
-	for (uz = wz; ++uz != _last_z_window;) {
-		Window *u = *uz;
+	WindowList::Iterator wit = Window::s_list.Find(w);
+	for (WindowList::Iterator it = wit; it != Window::s_list.m_list.end(); it++) {
+		Window *u = (*it).w;
 
 		/* A modal child will prevent the activation of the parent window */
 		if (u->parent == w && (u->desc_flags & WDF_MODAL)) {
 			u->flags4 |= WF_WHITE_BORDER_MASK;
-			SetWindowDirty(u);
+			u->SetDirty();
 			return false;
 		}
 
 		if (u->window_class == WC_MAIN_WINDOW ||
-				IsVitalWindow(u) ||
+				u->IsVital() ||
 				u->window_class == WC_TOOLTIPS ||
 				u->window_class == WC_DROPDOWN_MENU) {
 			continue;
@@ -1465,7 +1553,7 @@
 		bring_to_front = true;
 	}
 
-	if (bring_to_front) BringWindowToFront(w);
+	if (bring_to_front) w->BringToFront();
 	return true;
 }
 
@@ -1496,7 +1584,7 @@
  */
 void SendWindowMessage(WindowClass wnd_class, WindowNumber wnd_num, int msg, int wparam, int lparam)
 {
-	Window *w = FindWindowById(wnd_class, wnd_num);
+	Window *w = Window::FindById(wnd_class, wnd_num);
 	if (w != NULL) SendWindowMessageW(w, msg, wparam, lparam);
 }
 
@@ -1509,10 +1597,10 @@
  */
 void SendWindowMessageClass(WindowClass wnd_class, int msg, int wparam, int lparam)
 {
-	Window* const *wz;
+	Window *w;
 
-	FOR_ALL_WINDOWS(wz) {
-		if ((*wz)->window_class == wnd_class) SendWindowMessageW(*wz, msg, wparam, lparam);
+	FOR_ALL_WINDOWS(w) {
+		if (w->window_class == wnd_class) SendWindowMessageW(w, msg, wparam, lparam);
 	}
 }
 
@@ -1521,7 +1609,6 @@
  * 16 bits the keycode */
 void HandleKeypress(uint32 key)
 {
-	Window* const *wz;
 	WindowEvent e;
 	/* Stores if a window with a textfield for typing is open
 	 * If this is the case, keypress events are only passed to windows with text fields and
@@ -1546,18 +1633,17 @@
 	e.we.keypress.cont = true;
 
 	// check if we have a query string window open before allowing hotkeys
-	if (FindWindowById(WC_QUERY_STRING,       0) != NULL ||
-			FindWindowById(WC_SEND_NETWORK_MSG,   0) != NULL ||
-			FindWindowById(WC_GENERATE_LANDSCAPE, 0) != NULL ||
-			FindWindowById(WC_CONSOLE,            0) != NULL ||
-			FindWindowById(WC_SAVELOAD,           0) != NULL) {
+	if (Window::FindById(WC_QUERY_STRING,       0) != NULL ||
+			Window::FindById(WC_SEND_NETWORK_MSG,   0) != NULL ||
+			Window::FindById(WC_GENERATE_LANDSCAPE, 0) != NULL ||
+			Window::FindById(WC_CONSOLE,            0) != NULL ||
+			Window::FindById(WC_SAVELOAD,           0) != NULL) {
 		query_open = true;
 	}
 
 	// Call the event, start with the uppermost window.
-	for (wz = _last_z_window; wz != _z_windows;) {
-		Window *w = *--wz;
-
+	Window *w;
+	REVERSED_FOR_ALL_WINDOWS(w) {
 		// if a query window is open, only call the event for certain window types
 		if (query_open &&
 				w->window_class != WC_QUERY_STRING &&
@@ -1572,7 +1658,7 @@
 	}
 
 	if (e.we.keypress.cont) {
-		Window *w = FindWindowById(WC_MAIN_TOOLBAR, 0);
+		Window *w = Window::FindById(WC_MAIN_TOOLBAR, 0);
 		// When there is no toolbar w is null, check for that
 		if (w != NULL) w->wndproc(w, &e);
 	}
@@ -1630,13 +1716,13 @@
 	DecreaseWindowCounters();
 	HandlePlacePresize();
 	UpdateTileSelection();
-	if (!VpHandlePlaceSizingDrag())  return;
-	if (!HandleDragDrop())           return;
-	if (!HandlePopupMenu())          return;
-	if (!HandleWindowDragging())     return;
-	if (!HandleScrollbarScrolling()) return;
-	if (!HandleViewportScroll())     return;
-	if (!HandleMouseOver())          return;
+	if (!VpHandlePlaceSizingDrag())      return;
+	if (!HandleDragDrop())               return;
+	if (!HandlePopupMenu())              return;
+	if (!Window::HandleWindowDragging()) return;
+	if (!HandleScrollbarScrolling())     return;
+	if (!HandleViewportScroll())         return;
+	if (!HandleMouseOver())              return;
 
 	x = _cursor.pos.x;
 	y = _cursor.pos.y;
@@ -1744,31 +1830,30 @@
 
 void UpdateWindows(void)
 {
-	Window* const *wz;
 	static int we4_timer = 0;
 	int t = we4_timer + 1;
 
+	Window *w;
 	if (t >= 100) {
-		for (wz = _last_z_window; wz != _z_windows;) {
-			CallWindowEventNP(*--wz, WE_4);
+		REVERSED_FOR_ALL_WINDOWS(w) {
+			CallWindowEventNP(w, WE_4);
 		}
 		t = 0;
 	}
 	we4_timer = t;
 
-	for (wz = _last_z_window; wz != _z_windows;) {
-		Window *w = *--wz;
+	REVERSED_FOR_ALL_WINDOWS(w) {
 		if (w->flags4 & WF_WHITE_BORDER_MASK) {
 			w->flags4 -= WF_WHITE_BORDER_ONE;
 
-			if (!(w->flags4 & WF_WHITE_BORDER_MASK)) SetWindowDirty(w);
+			if (!(w->flags4 & WF_WHITE_BORDER_MASK)) w->SetDirty();
 		}
 	}
 
 	DrawDirtyBlocks();
 
-	FOR_ALL_WINDOWS(wz) {
-		if ((*wz)->viewport != NULL) UpdateViewportPosition(*wz);
+	FOR_ALL_WINDOWS(w) {
+		if (w->viewport != NULL) UpdateViewportPosition(w);
 	}
 	DrawTextMessage();
 	// Redraw mouse cursor in case it was hidden
@@ -1791,11 +1876,10 @@
 
 void InvalidateWindow(WindowClass cls, WindowNumber number)
 {
-	Window* const *wz;
+	Window *w;
 
-	FOR_ALL_WINDOWS(wz) {
-		const Window *w = *wz;
-		if (w->window_class == cls && w->window_number == number) SetWindowDirty(w);
+	FOR_ALL_WINDOWS(w) {
+		if (w->window_class == cls && w->window_number == number) w->SetDirty();
 	}
 }
 
@@ -1811,10 +1895,8 @@
 
 void InvalidateWindowWidget(WindowClass cls, WindowNumber number, byte widget_index)
 {
-	Window* const *wz;
-
-	FOR_ALL_WINDOWS(wz) {
-		const Window *w = *wz;
+	Window *w;
+	FOR_ALL_WINDOWS(w) {
 		if (w->window_class == cls && w->window_number == number) {
 			InvalidateWidget(w, widget_index);
 		}
@@ -1823,57 +1905,51 @@
 
 void InvalidateWindowClasses(WindowClass cls)
 {
-	Window* const *wz;
-
-	FOR_ALL_WINDOWS(wz) {
-		if ((*wz)->window_class == cls) SetWindowDirty(*wz);
+	Window *w;
+	FOR_ALL_WINDOWS(w) {
+		if (w->window_class == cls) w->SetDirty();
 	}
 }
 
 void InvalidateThisWindowData(Window *w)
 {
 	CallWindowEventNP(w, WE_INVALIDATE_DATA);
-	SetWindowDirty(w);
+	w->SetDirty();
 }
 
 void InvalidateWindowData(WindowClass cls, WindowNumber number)
 {
-	Window* const *wz;
-
-	FOR_ALL_WINDOWS(wz) {
-		Window *w = *wz;
+	Window *w;
+	FOR_ALL_WINDOWS(w) {
 		if (w->window_class == cls && w->window_number == number) InvalidateThisWindowData(w);
 	}
 }
 
 void InvalidateWindowClassesData(WindowClass cls)
 {
-	Window* const *wz;
-
-	FOR_ALL_WINDOWS(wz) {
-		if ((*wz)->window_class == cls) InvalidateThisWindowData(*wz);
+	Window *w;
+	FOR_ALL_WINDOWS(w) {
+		if (w->window_class == cls) InvalidateThisWindowData(w);
 	}
 }
 
 void CallWindowTickEvent(void)
 {
-	Window* const *wz;
-
-	for (wz = _last_z_window; wz != _z_windows;) {
-		CallWindowEventNP(*--wz, WE_TICK);
+	Window *w;
+	REVERSED_FOR_ALL_WINDOWS(w) {
+		CallWindowEventNP(w, WE_TICK);
 	}
 }
 
 void DeleteNonVitalWindows(void)
 {
-	Window* const *wz;
 
 restart_search:
 	/* When we find the window to delete, we need to restart the search
 	 * as deleting this window could cascade in deleting (many) others
 	 * anywhere in the z-array */
-	FOR_ALL_WINDOWS(wz) {
-		Window *w = *wz;
+	Window *w;
+	FOR_ALL_WINDOWS(w) {
 		if (w->window_class != WC_MAIN_WINDOW &&
 				w->window_class != WC_SELECT_GAME &&
 				w->window_class != WC_MAIN_TOOLBAR &&
@@ -1882,7 +1958,7 @@
 				w->window_class != WC_TOOLTIPS &&
 				(w->flags4 & WF_STICKY) == 0) { // do not delete windows which are 'pinned'
 
-			DeleteWindow(w);
+			w->Close();
 			goto restart_search;
 		}
 	}
@@ -1895,8 +1971,6 @@
  * that standard windows (status bar, etc.) are not stickied, so these aren't affected */
 void DeleteAllNonVitalWindows(void)
 {
-	Window* const *wz;
-
 	/* Delete every window except for stickied ones, then sticky ones as well */
 	DeleteNonVitalWindows();
 
@@ -1904,9 +1978,10 @@
 	/* When we find the window to delete, we need to restart the search
 	 * as deleting this window could cascade in deleting (many) others
 	 * anywhere in the z-array */
-	FOR_ALL_WINDOWS(wz) {
-		if ((*wz)->flags4 & WF_STICKY) {
-			DeleteWindow(*wz);
+	Window *w;
+	FOR_ALL_WINDOWS(w) {
+		if (w->flags4 & WF_STICKY) {
+			w->Close();
 			goto restart_search;
 		}
 	}
@@ -1925,7 +2000,7 @@
 	DEBUG(misc, 5, "Repositioning Main Toolbar...");
 
 	if (w == NULL || w->window_class != WC_MAIN_TOOLBAR) {
-		w = FindWindowById(WC_MAIN_TOOLBAR, 0);
+		w = Window::FindById(WC_MAIN_TOOLBAR, 0);
 	}
 
 	switch (_patches.toolbar_pos) {
@@ -1939,10 +2014,8 @@
 
 void RelocateAllWindows(int neww, int newh)
 {
-	Window* const *wz;
-
-	FOR_ALL_WINDOWS(wz) {
-		Window *w = *wz;
+	Window *w;
+	FOR_ALL_WINDOWS(w) {
 		int left, top;
 
 		if (w->window_class == WC_MAIN_WINDOW) {
--- a/src/window.h	Sun Feb 11 21:20:30 2007 +0000
+++ b/src/window.h	Sun Feb 11 22:57:24 2007 +0000
@@ -3,11 +3,13 @@
 #ifndef WINDOW_H
 #define WINDOW_H
 
+#include <list>
 #include "macros.h"
 #include "string.h"
 #include "order.h"
 #include "rail.h"
 #include "airport.h"
+#include "misc/countedptr.hpp"
 
 typedef struct WindowEvent WindowEvent;
 
@@ -246,7 +248,66 @@
 		int lparam;
 } WindowMessage;
 
-struct Window {
+struct CountedObject {
+	int32 m_ref_cnt;
+
+	CountedObject()
+		: m_ref_cnt(0)
+	{}
+
+	virtual ~CountedObject()
+	{};
+
+	virtual int32 AddRef();
+	virtual int32 Release();
+	virtual void FinalRelease() {};
+};
+
+struct Window;
+typedef CCountedPtr<Window> WindowPtr;
+
+struct WindowList {
+	struct Item {
+		WindowPtr w;
+		Item(Window *v = NULL) : w(v) {}
+		Item(const Item &src) : w(src.w) {}
+		~Item()
+		{}
+	};
+	typedef std::list<Item> List;
+	typedef List::iterator Iterator;
+	typedef List::reverse_iterator ReverseIterator;
+
+	List m_list;
+
+	void Add(Window *w);
+	void Remove(Window *w);
+	Iterator Find(Window *w);
+	Iterator FindFirstVitalWindow();
+	Iterator FindByClass(WindowClass cls);
+	Iterator FindById(WindowClass cls, WindowNumber num);
+
+	template <class Tmatch> Iterator EnumT(Tmatch match)
+	{
+		for (Iterator it = m_list.begin(); it != m_list.end(); ++it) {
+			if (match.EnumProc(it)) return it;
+		}
+		return m_list.end();
+	}
+
+	template <class Tmatch> Iterator ReverseEnumT(Tmatch match)
+	{
+		for (Iterator it = m_list.end(); it != m_list.begin(); ) {
+			--it;
+			if (match.EnumProc(it)) return it;
+		}
+		return m_list.end();
+	}
+};
+
+struct Window : public CountedObject {
+	static WindowList s_list;
+
 	uint16 flags4;
 	WindowClass window_class;
 	WindowNumber window_number;
@@ -269,8 +330,100 @@
 	WindowMessage message;
 	Window *parent;
 	byte custom[WINDOW_CUSTOM_SIZE];
+
+	Window(int x, int y, int w, int h, WindowProc *proc, WindowClass cls, const Widget *widget, int wnd_number);
+
+	void ZeroInit()
+	{
+		memset(&flags4, 0, sizeof(*this) - cpp_offsetof(Window, flags4));
+	}
+
+	Window* FindChild() const;
+	void SetDirty() const;
+	void CDECL SetWidgetsDisabledState(bool disab_stat, int widgets, ...);
+	void CDECL SetWidgetsHiddenState(bool hidden_stat, int widgets, ...);
+	void CDECL SetWidgetsLoweredState(bool lowered_stat, int widgets, ...);
+	void RaiseButtons();
+	void HandleButtonClick(byte widget);
+	void BringToFront();
+	static Window* BringToFrontById(WindowClass cls, WindowNumber number);
+	void StartDrag();
+	bool ContinueDrag();
+	void StartSizing();
+	bool ContinueSizing();
+	static bool HandleWindowDragging(void);
+
+	/*virtual*/ void FinalRelease();
+	virtual void Close();
+	virtual bool IsVital();
+
+	static Window* Allocate(int x, int y, int width, int height, WindowProc *proc, WindowClass cls, const Widget *widget);
+	static Window* Get(WindowList::Iterator it);
+	static Window* FindById(WindowClass cls, WindowNumber num);
+	static void SetDirtyById(WindowClass cls, WindowNumber num);
+
+	//int32 AddRef()
+	//{
+	//	const char *name = NULL;
+	//	switch (window_class)
+	//	{
+	//		case WC_MAIN_WINDOW:      name = "mw"; break;
+	//		case WC_SELECT_GAME:      name = "sg"; break;
+	//		case WC_INDUSTRY_VIEW:    name = "iw"; break;
+	//		default: break;
+	//	}
+	//	if (name != NULL) printf("%s+\n", name);
+	//	return CountedObject::AddRef();
+	//}
+
+	//int32 Release()
+	//{
+	//	const char *name = NULL;
+	//	switch (window_class)
+	//	{
+	//		case WC_MAIN_WINDOW:      name = "mw"; break;
+	//		case WC_SELECT_GAME:      name = "sg"; break;
+	//		case WC_INDUSTRY_VIEW:    name = "iw"; break;
+	//		default: break;
+	//	}
+	//	if (name != NULL) printf("%s-\n", name);
+	//	return CountedObject::Release();
+	//}
+
+	template <class Tmatch> struct EnumMatch {
+		Tmatch &m_match;
+		EnumMatch(Tmatch &m)
+			: m_match(m)
+		{}
+		bool EnumProc(WindowList::Iterator it)
+		{
+			return m_match->EnumProc((*it).w);
+		}
+	};
+
+	template <class Tmatch> Window* EnumT(Tmatch m)
+	{
+		WindowList::Iterator it = Window::s_list.EnumT(EnumMatch(m));
+		return (it == Window::s_list.m_list.end()) ? NULL : (*it).w;
+	}
+
+	template <class Tmatch> Window* ReverseEnumT(Tmatch m)
+	{
+		WindowList::Iterator it = Window::s_list.ReverseEnumT(EnumMatch(m));
+		return (it == Window::s_list.m_list.end()) ? NULL : (*it).w;
+	}
+
 };
 
+
+
+#define FOR_ALL_WINDOWS(wz) \
+	for (WindowList::Iterator it = Window::s_list.m_list.begin(); it != Window::s_list.m_list.end() && (wz = (*it).w) != NULL; it++)
+
+#define REVERSED_FOR_ALL_WINDOWS(wz) \
+	for (WindowList::ReverseIterator it = Window::s_list.m_list.rbegin(); it != Window::s_list.m_list.rend() && (wz = (*it).w) != NULL; it++)
+
+
 typedef struct querystr_d {
 	StringID caption;
 	Textbuf text;
@@ -534,27 +687,27 @@
 /* window.c */
 void CallWindowEventNP(Window *w, int event);
 void CallWindowTickEvent(void);
-void SetWindowDirty(const Window *w);
+//void SetWindowDirty(const Window *w);
 void SendWindowMessage(WindowClass wnd_class, WindowNumber wnd_num, int msg, int wparam, int lparam);
 void SendWindowMessageClass(WindowClass wnd_class, int msg, int wparam, int lparam);
 
-Window *FindWindowById(WindowClass cls, WindowNumber number);
-void DeleteWindow(Window *w);
+//Window *FindWindowById(WindowClass cls, WindowNumber number);
+//void DeleteWindow(Window *w);
 void DeletePlayerWindows(PlayerID pi);
 void ChangeWindowOwner(PlayerID old_player, PlayerID new_player);
-Window *BringWindowToFrontById(WindowClass cls, WindowNumber number);
+//Window *BringWindowToFrontById(WindowClass cls, WindowNumber number);
 Window *FindWindowFromPt(int x, int y);
 
 bool IsWindowOfPrototype(const Window *w, const Widget *widget);
 void AssignWidgetToWindow(Window *w, const Widget *widget);
-Window *AllocateWindow(
-							int x,
-							int y,
-							int width,
-							int height,
-							WindowProc *proc,
-							WindowClass cls,
-							const Widget *widget);
+//Window *AllocateWindow(
+//							int x,
+//							int y,
+//							int width,
+//							int height,
+//							WindowProc *proc,
+//							WindowClass cls,
+//							const Widget *widget);
 
 Window *AllocateWindowDesc(const WindowDesc *desc);
 Window *AllocateWindowDescFront(const WindowDesc *desc, int window_number);
@@ -717,12 +870,12 @@
 void InvalidateWidget(const Window *w, byte widget_index);
 void InvalidateThisWindowData(Window *w);
 void InvalidateWindowData(WindowClass cls, WindowNumber number);
-void RaiseWindowButtons(Window *w);
+//void RaiseWindowButtons(Window *w);
 void RelocateAllWindows(int neww, int newh);
 int PositionMainToolbar(Window *w);
-void CDECL SetWindowWidgetsDisabledState(Window *w, bool disab_stat, int widgets, ...);
-void CDECL SetWindowWidgetsHiddenState(Window *w, bool hidden_stat, int widgets, ...);
-void CDECL SetWindowWidgetsLoweredState(Window *w, bool lowered_stat, int widgets, ...);
+//void CDECL SetWindowWidgetsDisabledState(Window *w, bool disab_stat, int widgets, ...);
+//void CDECL SetWindowWidgetsHiddenState(Window *w, bool hidden_stat, int widgets, ...);
+//void CDECL SetWindowWidgetsLoweredState(Window *w, bool lowered_stat, int widgets, ...);
 
 /* misc_gui.c*/
 void GuiShowTooltipsWithArgs(StringID str, uint paramcount, const uint params[]);
@@ -736,19 +889,18 @@
 void DrawWindowWidgets(const Window *w);
 void ShowDropDownMenu(Window *w, const StringID *strings, int selected, int button, uint32 disabled_mask, uint32 hidden_mask);
 
-void HandleButtonClick(Window *w, byte widget);
+//void HandleButtonClick(Window *w, byte widget);
 
 Window *GetCallbackWnd(void);
 void DeleteNonVitalWindows(void);
 void DeleteAllNonVitalWindows(void);
 void HideVitalWindows(void);
 void ShowVitalWindows(void);
-Window **FindWindowZPosition(const Window *w);
+//WindowList::Iterator FindWindowZPosition(const Window *w);
 
 /* window.c */
-extern Window *_z_windows[];
-extern Window **_last_z_window;
-#define FOR_ALL_WINDOWS(wz) for (wz = _z_windows; wz != _last_z_window; wz++)
+//extern Window *_z_windows[];
+//extern Window **_last_z_window;
 
 VARDEF Point _cursorpos_drag_start;