Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лабы / 2 / lab.03.by mice / claw / root

.cpp
Скачиваний:
12
Добавлен:
17.04.2013
Размер:
19.05 Кб
Скачать
/*******************************************************************************
* file:         root.cpp                                                       *
* version:      0.0.2                                                          *
* author:       d-evil [tmd] (mailto:d-evil.tmd@mail.ru)                       *
* description:  not available                                                  *
*******************************************************************************/

#include "root.h"


////////////////////////////////////////////////////////////////////////////////
// ccw_root public definition
ccw_root::ccw_root(): CDialog(IDD_DLG_ROOT) {
	_ch_pipe_mtx = CreateMutex(NULL, 0, NULL);
	for (int i = _CH_PIPE_LEN - 1; 0 <= i; --i) _ch_pipe[i] = '\0';
	_ch_pipe_h = _ch_pipe_t = 0;
	_pause_mtx = CreateMutex(NULL, 0, NULL);
	_graph_paused = false;
	_was_about = false;
}


ccw_root::~ccw_root() {
	CloseHandle(_ch_pipe_mtx);
	CloseHandle(_pause_mtx);
}


int ccw_root::ch_name(const char *const new_name) {
	if (NULL != new_name) {
		CString cap;
		cap.Format("Claw /%s", new_name);
		SetWindowText(cap);
	}

	// servers
	POSITION pos = _servers.GetStartPosition();
	int tmp_key; ccw_server *tmp_srv;
	while (pos != NULL) {
		_servers.GetNextAssoc(pos, tmp_key, tmp_srv);
		if (NULL == new_name) {
			_del_server(tmp_key);
		} else tmp_srv->set_caption(); 
	}

	// clients
	pos = _clients.GetStartPosition();
	ccw_client *tmp_clnt;
	while (pos != NULL) {
		_clients.GetNextAssoc(pos, tmp_key, tmp_clnt);
		if (NULL != new_name) tmp_clnt->set_caption();
		else _del_client(tmp_key);
	}

	if (NULL == new_name) {
		_servers.RemoveAll();
		_clients.RemoveAll();
	}

	return 0;
}


BOOL ccw_root::OnInitDialog() {
	SetIcon(_hicon, TRUE);

	// ShowWindow(SW_MAXIMIZE);
	// SetWindowPos(NULL, 0, 0, 1280, 1024, SWP_NOOWNERZORDER|SWP_NOZORDER);
	if (0 != _run_graph()) {
		MessageBox("Can't init graph" , "Claw error", MB_OK|MB_APPLMODAL|MB_ICONERROR);
		EndDialog(-1);
		return FALSE;
	}

	return TRUE;
}


void ccw_root::OnOK() {
	_char_to_pipe(VK_RETURN);
}


void ccw_root::OnClose() {
	int still_running = 0;

	// servers
	POSITION pos = _servers.GetStartPosition();
	int tmp_key; ccw_server *tmp_srv;
	while (pos != NULL) {
		_servers.GetNextAssoc(pos, tmp_key, tmp_srv);
		tmp_srv->stop();
		if (0 != tmp_srv->wait()) ++still_running;
	}

	// clients
	pos = _clients.GetStartPosition();
	ccw_client *tmp_clnt;
	while (pos != NULL) {
		_clients.GetNextAssoc(pos, tmp_key, tmp_clnt);
		tmp_clnt->stop();
		if (0 != tmp_clnt->wait()) ++still_running;
	}

	if (0 != still_running) {
		PostMessage(WM_CLOSE, 0, 0);
		return;
	}

	// delete all server and clients
	ch_name(NULL);

	_stop_graph();

	EndDialog(0);
}


void ccw_root::OnSysCommand(UINT nID, LPARAM lParam) {
	switch (nID) {
		case SC_MINIMIZE:
			_to_tray();
			_show_all(SW_HIDE);
			// ShowWindow(SW_MINIMIZE);
			break;

		case SC_RESTORE:
			_from_tray();
			ShowWindow(SW_RESTORE);
			_show_all(SW_SHOW);
			// ::SetActiveWindow(GetSafeHwnd());
			::SetForegroundWindow(GetSafeHwnd());
			break;

		default:
			CDialog::OnSysCommand(nID, lParam);
			break;
	}
}


void ccw_root::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) {
	GetKeyboardState((BYTE *)_kbd_state);
	int r = ToAscii(nChar, nFlags, (BYTE *)_kbd_state, (WORD *)_kbd_tr, 0);
	if (1 != r) return;
	_char_to_pipe(_kbd_tr[0]);
}



////////////////////////////////////////////////////////////////////////////////
// ccw_root protected definition
BEGIN_MESSAGE_MAP(ccw_root, CDialog)
	ON_WM_CLOSE()
	ON_WM_KEYDOWN()
	ON_WM_SYSCOMMAND()
	ON_MESSAGE(CL_STR, _on_cl_str)
	ON_MESSAGE(TB_MSG, _on_tb_msg)
	ON_MESSAGE(ccw_server::MSG_ADD_RECVER, _on_add_recver_msg)
	ON_MESSAGE(ccw_client::MSG_DEL_CLIENT, _on_del_client_msg)
	ON_MESSAGE(ccw_server::MSG_DEL_SERVER, _on_del_server_msg)
END_MESSAGE_MAP()


void ccw_root::_to_tray() {
	NOTIFYICONDATA nid;
	nid.cbSize = sizeof(nid);
	nid.hWnd = GetSafeHwnd();
    nid.uID = 0xDEAD;
    nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
    nid.uCallbackMessage = TB_MSG;
    nid.hIcon = _hicon; 
	CString str;
	GetWindowText(str);
	strcpy(nid.szTip, str);
	BOOL res = Shell_NotifyIcon(NIM_ADD, &nid);

	ShowWindow(SW_HIDE);
	long st = GetWindowLong(GetSafeHwnd(), GWL_EXSTYLE);
	st &= ~WS_EX_APPWINDOW;
	st |= WS_EX_TOOLWINDOW;
	SetWindowLong(GetSafeHwnd(), GWL_EXSTYLE, st);
	// ShowWindow(SW_SHOW);
	// ShowWindow(SW_HIDE);

	_pause_graph();
}


void ccw_root::_from_tray() {
	NOTIFYICONDATA nid;
	nid.cbSize = sizeof(nid);
	nid.hWnd = GetSafeHwnd();
    nid.uID = 0xDEAD;
    nid.uFlags = 0; //NIF_MESSAGE | NIF_ICON | NIF_TIP;
    // nid.uCallbackMessage = TB_MSG;
    // nid.hIcon = _hicon; 
	// strcpy(nid.szTip, "Claw shell");
	BOOL res = Shell_NotifyIcon(NIM_DELETE, &nid);

	// ShowWindow(SW_HIDE);
	long st = GetWindowLong(GetSafeHwnd(), GWL_EXSTYLE);
	st |= WS_EX_APPWINDOW;
	st &= ~WS_EX_TOOLWINDOW;
	SetWindowLong(GetSafeHwnd(), GWL_EXSTYLE, st);
	// ShowWindow(SW_SHOWNORMAL);

	_upause_graph();
}


LRESULT ccw_root::_on_tb_msg(WPARAM hz, LPARAM msg) {
	if (WM_LBUTTONUP == msg) {
		PostMessage(WM_SYSCOMMAND, SC_RESTORE, 0);
	}

	return 0;
}


int ccw_root::_char_to_pipe(const int ch) {
	if (WAIT_TIMEOUT == WaitForSingleObject(_ch_pipe_mtx, _SYNH_TIMEOUT)) return -1;

	_char_to_pipe_raw(ch);

	ReleaseMutex(_ch_pipe_mtx);

	return 0;
}


int ccw_root::_char_to_pipe_raw(const int ch) {
	_ch_pipe[_ch_pipe_h++] = ch;
	if (_CH_PIPE_LEN <= _ch_pipe_h) _ch_pipe_h = 0;
	if (_ch_pipe_h == _ch_pipe_t) {
		_ch_pipe_t++;
		if (_CH_PIPE_LEN <= _ch_pipe_t) _ch_pipe_t = 0;
	}

	return 0;
}


int ccw_root::_char_from_pipe(int *const ch) {
	if (WAIT_TIMEOUT == WaitForSingleObject(_ch_pipe_mtx, 0/*_SYNH_TIMEOUT*/)) return -1;

	if (_ch_pipe_h == _ch_pipe_t) {
		ReleaseMutex(_ch_pipe_mtx);
		return -1;
	}
	*ch = _ch_pipe[_ch_pipe_t++];
	if (_CH_PIPE_LEN <= _ch_pipe_t) _ch_pipe_t = 0;

	ReleaseMutex(_ch_pipe_mtx);

	return 0;
}


int ccw_root::_write_console(const char *const str) {
	if (WAIT_TIMEOUT == WaitForSingleObject(_ch_pipe_mtx, _SYNH_TIMEOUT)) return -1;

	_char_to_pipe_raw(1);
	const char *ch = str;
	while ('\0' != *ch) _char_to_pipe_raw(*ch++);
	_char_to_pipe_raw(2);

	ReleaseMutex(_ch_pipe_mtx);

	return 0;
}


int ccw_root::_run_graph() {
	_graph_stoped = false;
	_gthread_h = CreateThread(NULL, 0,
			(LPTHREAD_START_ROUTINE)_graph_proc_helper,
			this, 0, &_gthread_id
	);
	if (NULL == _gthread_h) return -1;
	_graph_mtx = CreateMutex(NULL, 0, NULL);

	return 0;
}


int ccw_root::_init_graph() {
	if (WAIT_TIMEOUT == WaitForSingleObject(_graph_mtx, _SYNH_TIMEOUT)) return -1;

	RECT wnd_rect;
	GetClientRect(&wnd_rect);

	_gx = _MARGINS, _gy = _MARGINS;
	_gw = wnd_rect.right - wnd_rect.left-2*_MARGINS;
	_gh = wnd_rect.bottom - wnd_rect.top-2*_MARGINS;

	_dlg_pcdc = GetDC();
	_dlg_dc = _dlg_pcdc->GetSafeHdc();
	_buf_dc = CreateCompatibleDC(_dlg_dc);
	_txt_dc = CreateCompatibleDC(_dlg_dc);

	BITMAPINFO ibmp;
	ibmp.bmiHeader.biSize = sizeof(ibmp.bmiHeader);
	ibmp.bmiHeader.biWidth = _gw;
	ibmp.bmiHeader.biHeight = _gh;
	ibmp.bmiHeader.biPlanes = 1;
	ibmp.bmiHeader.biBitCount = 32;
	ibmp.bmiHeader.biCompression = BI_RGB;
	ibmp.bmiHeader.biSizeImage = 0;
	ibmp.bmiHeader.biXPelsPerMeter = 0;
	ibmp.bmiHeader.biYPelsPerMeter = 0;
	ibmp.bmiHeader.biClrUsed = 0;
	ibmp.bmiHeader.biClrImportant = 0;

	_buf_bmp = CreateDIBSection(_buf_dc, &ibmp,
		DIB_RGB_COLORS, (void **)&_pxls, NULL, 0);
	SelectObject(_buf_dc, _buf_bmp);

	_txt_bmp = CreateDIBSection(_buf_dc, &ibmp,
		DIB_RGB_COLORS, (void **)&_txls, NULL, 0);
	SelectObject(_txt_dc, _txt_bmp);

	_hpen = CreatePen(PS_SOLID, 1, RGB(0xFF, 0xFF, 0xFF));
	_hbrush = CreateSolidBrush(RGB(0, 0, 0xFF));
	_hfont = CreateFont(_FONT_HEIGTH, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, RUSSIAN_CHARSET,
		OUT_CHARACTER_PRECIS, CLIP_CHARACTER_PRECIS, DEFAULT_QUALITY, FF_DONTCARE, "Courier New");

	SetBkColor(_txt_dc, RGB(0, 0, 0));
	SetTextColor(_txt_dc, RGB(0xFF, 0xFF, 0xFF));

	SelectObject(_txt_dc, _hpen);
	SelectObject(_txt_dc, _hbrush);
	SelectObject(_txt_dc, _hfont);
	SelectObject(_buf_dc, _hpen);
	SelectObject(_buf_dc, _hbrush);
	SelectObject(_buf_dc, _hfont);

	for (int i = 0; i < _gw*_gh; ++i) ((int *)_pxls)[i] = 0;
	//for (int i = 0; i < _wnd_w*_wnd_h; ++i) ((int *)ts)[i] = 0;

	_inv_str = (char *)malloc(_LINES_MX_LEN * sizeof(char));
	_cur_str = (char *)malloc(_LINES_MX_LEN * sizeof(char));
	if (0 != gethostname(_inv_str, _LINES_MX_LEN)) {
		strcpy(_inv_str, "localhost");
	}
	strcat(_inv_str, "# ");
	strcpy(_cur_str, "_");

	return 0;
}


int ccw_root::_close_graph() {
	DeleteDC(_buf_dc);
	DeleteDC(_txt_dc);

	DeleteObject(_buf_bmp);
	DeleteObject(_txt_bmp);

	DeleteObject(_hpen);
	DeleteObject(_hbrush);
	DeleteObject(_hfont);

	ReleaseDC(_dlg_pcdc);

	ReleaseMutex(_graph_mtx);

	free(_inv_str);
	free(_cur_str);

	return 0;
}


int ccw_root::_stop_graph() {
	_graph_stoped = true;
	if (WAIT_TIMEOUT == WaitForSingleObject(_graph_mtx, _SYNH_TIMEOUT)) return -1;
	CloseHandle(_graph_mtx);

	return 0;
}


int ccw_root::_pause_graph() {
	if (WAIT_TIMEOUT == WaitForSingleObject(_pause_mtx, 10000)) return -1;
	_graph_paused = true;

	return 0;
}


int ccw_root::_upause_graph() {
	_graph_paused = false;
	ReleaseMutex(_pause_mtx);

	return 0;
}


int ccw_root::_graph_proc() {
	if (0 != _init_graph()) return -1;

	clock_t rtime1, rtime2;
	rtime1 = rtime2 = clock();
	int sl_need;

	char *lines[_LINES_NUM];
	for (int i = _LINES_NUM - 1; 0 <= i; --i) {
		lines[i] = (char *)malloc(_LINES_MX_LEN * sizeof(char));
		lines[i][0] = '\0';
	}
	strcpy(lines[0], _inv_str);
	int cp = (int)strlen(_inv_str);
	int cp_m;
	strcpy(lines[0] + cp, _cur_str);
	char str4lwc[2] = "x";

	int _gtxt_lc = _gh - _FONT_HEIGTH;
	int mx_lines = _gh / _FONT_HEIGTH;

	int ch;
	POINT mp;
	int rline = _gh;
	int dline = _gh;
	int pnoise = _gh;
	int con_mode = 0;
	int about_stage = 0;
	while (!_graph_stoped) {
		if (_graph_paused) {
			WaitForSingleObject(_pause_mtx, INFINITE);
			ReleaseMutex(_pause_mtx);
		}

		while (0 == _char_from_pipe(&ch)) {
			if (1 == ch) {
				cp_m = 0;
				char *pch = lines[_LINES_NUM - 1];
				for (int i = _LINES_NUM - 1; 1 < i; --i) {
					lines[i] = lines[i-1];
				}
				pch[0] = '\0';
				lines[1] = pch;
				con_mode = 1;
				continue;
			}
			if (2 == ch) {
				con_mode = 0;
				continue;
			}

			if (1 == con_mode) {
				if ('\n' == ch) {
					cp_m = 0;
					char *pch = lines[_LINES_NUM - 1];
					for (int i = _LINES_NUM - 1; 1 < i; --i) {
						lines[i] = lines[i-1];
					}
					pch[0] = '\0';
					lines[1] = pch;
					continue;
				}

				lines[1][cp_m++] = ch;
				lines[1][cp_m] = '\0';
				continue;
			}

			if (VK_RETURN == ch) {
				lines[0][cp] = '\0';
				char *clone = _str_clone_new(lines[0] + strlen(_inv_str));
				PostMessage(CL_STR, (WPARAM)clone, 0);
				char *pch = lines[_LINES_NUM - 1];
				for (int i = _LINES_NUM - 1; 0 < i; --i) {
					lines[i] = lines[i-1];
				}
				strcpy(pch, _inv_str);
				lines[0] = pch;
				cp = (int)strlen(_inv_str);
				strcpy(lines[0] + cp, _cur_str);
				continue;
			}
			if (VK_BACK == ch) {
				if ((int)strlen(_inv_str) < cp) strcpy(lines[0]+(--cp),  _cur_str);
				continue;
			}

			str4lwc[0] = ch;
			// strlwr(str4lwc);
			lines[0][cp++] = ch; // str4lwc[0];
			strcpy(lines[0] + cp, _cur_str);
		}

		GetCursorPos(&mp);
		ScreenToClient(&mp);
		mp.x -= _MARGINS + (RAND_MAX/2 - rand())%4; mp.y -= _MARGINS + (RAND_MAX/2 - rand())%4;
		if (mp.x > 0 && mp.x < _gw && mp.y > 0 && mp.y < _gh) {
			int x = mp.x; int y = mp.y;
			int p = (_gh - y) * _gw;
			for (int i = _gw - 1; 0 <= i; --i) {
				_pxls[i + p].rgbRed += 128;
				_pxls[i + p].rgbGreen += 128;
				_pxls[i + p].rgbBlue += 128;
			}
			for (int i = _gh - 1; 0 <= i; --i) {
				_pxls[i*_gw + x].rgbRed += 128;
				_pxls[i*_gw + x].rgbGreen += 128;
				_pxls[i*_gw + x].rgbBlue += 128;
			}
		}

		if (rline < _gh) {
			int p = rline * _gw;
			for (int i = _gw - 1; 0 <= i; --i) {
				_pxls[i + p].rgbRed += 128;
				_pxls[i + p].rgbGreen += 128;
				_pxls[i + p].rgbBlue += 128;
			}
			rline += (3*RAND_MAX/4 - rand())%20;
			if (0 > rline) rline = _gh + rline;
		} else if (RAND_MAX/10 > rand()) rline = 0;

		/*offset*/

		if (pnoise < _gh) {
			int nc = 16*(-abs(pnoise - _gh/2) + _gh/2);
			for (int i = nc; 0 <= i; --i) {
				int v = rand()%_gw + _gw*(rand()%_gh);
				_pxls[v].rgbRed += 128;
				_pxls[v].rgbGreen += 128;
				_pxls[v].rgbBlue += 128;
			}
			pnoise += 10;
		} else /*if (RAND_MAX/20 > rand())*/ pnoise = rand()%_gh;

		for (int i = _gw*_gh - 1; 0 <= i; --i) {
			((int *)_txls)[i] = 0;
			if (i >= _gw) _pxls[i] = _pxls[i-_gw];
			if (80 <= _pxls[i].rgbBlue) _pxls[i].rgbBlue -= 80*rand()/RAND_MAX; else _pxls[i].rgbBlue = 0;
			if (60 <= _pxls[i].rgbGreen) _pxls[i].rgbGreen -= 60; else _pxls[i].rgbGreen = 0;
			if (60 <= _pxls[i].rgbRed) _pxls[i].rgbRed -= 60*rand()/RAND_MAX; else _pxls[i].rgbRed = 0;
		}

		if (dline < _gh) {
			char *str = "demoscene";
			TextOut(_txt_dc, rand() % _gw, rand() % _gh, str, (int)strlen(str));
			dline += 20;
		} else if (RAND_MAX/200 > rand()) dline = 0;

		for (int i = mx_lines-1; 0 <= i; --i) {
			if (NULL == lines[i]) continue;
			TextOut(_txt_dc, 4, _gtxt_lc - i*_FONT_HEIGTH, lines[i], (int)strlen(lines[i]));
		}

		BitBlt(_buf_dc, 0, 0, _gw, _gh, _txt_dc, 0, 0, SRCPAINT);
		if (RAND_MAX/20 > rand()) {
			for (int i = _gh - 1; 0 <= i; --i) {
				int of = rand() % 10;
				for (int j = _gw - 1; of <= j; --j) _pxls[i*_gw + j] = _pxls[i*_gw + j-of];
			}
		}

		/*if about*/
		static const int ABOUT_MX = 100;
		if (_was_about) {
			int lx = about_stage*_gw/ABOUT_MX;
			int ly = _gh/2;
			for (int u = 1000; 0 <= u; --u) {
				lx -= rand()%5; if (lx < 0) lx = about_stage*_gw/ABOUT_MX-rand()%100;
				if (lx < 0) lx = 0;
				ly += 10 - rand()%20; if (ly >= _gh/2+50 || ly < _gh/2-50) ly = _gh/2;
				int lp = ly * _gw + lx;
				_pxls[lp].rgbRed = 0xFF;//rand()%256;
				_pxls[lp].rgbGreen = 0xFF;//rand()%256;
				_pxls[lp].rgbBlue = 0xFF;//rand()%256;
			}
			about_stage += 10;
			if (about_stage > ABOUT_MX) {
				_was_about = false;
				about_stage = 0;
			}
		}

		BitBlt(_dlg_dc, _gx, _gy, _gw, _gh, _buf_dc, 0, 0, SRCCOPY);
		// HDC dc = ::GetDC((HWND)0x000100AC);
		// BitBlt(dc, _gx, _gy, _gw, _gh, _buf_dc, 0, 0, SRCCOPY);
		// ::ReleaseDC(0, dc);

		rtime2 = clock();
		sl_need = 1000/_NORM_FPS - (rtime2 - rtime1);

		if (sl_need > 0) Sleep(sl_need);
		rtime1 = rtime2;
	}

	for (int i = _LINES_NUM - 1; 0 <= i; --i) free(lines[i]);

	_close_graph();

	return 0;
}


char *ccw_root::_str_clone_new(const char *const str) {
	char *clone = (char *)malloc((strlen(str)+1)*sizeof(char));
	if (NULL == clone) return NULL;
	strcpy(clone, str);

	return clone;
}


void ccw_root::_str_clone_del(char *const str) {
	free(str);
}

LRESULT ccw_root::_on_cl_str(WPARAM pch, LPARAM hz) {
	char *str = (char *)pch;
	char *s = str;
	
	while (' ' >= *s && '\0' != *s) ++s;
	char *f, *p;
	if ('"' == *s) {
		f = ++s;
		while ('"' != *s && '\0' != *s) ++s;
		if ('\0' != *s && '\0' != *(s + 1)) p = s + 1; else p = NULL;
		*s = '\0';
	} else {
		f = s;
		while (' ' != *s && '\0' != *s) ++s;
		if ('\0' != *s && '\0' != *(s + 1)) p = s + 1; else p = NULL;
		*s = '\0';
	}

	if (0 == stricmp("about", f)) {
		_was_about = true;
		_write_console("claw shell by d-evil [tmd]\n    d-evil.tmd@mail.ru || mice@swamp.ru");
	} else if (0 == stricmp("exit", f) || 0 == stricmp("quit", f)) {
		_write_console("terminating...");
		Sleep(400);
		_write_console("closing...");
		PostMessage(WM_CLOSE);
		Sleep(400);
	} else if (0 == stricmp("help", f) || 0 == stricmp("man", f)) {
		_write_console("built-in commands: about, help, man, exit, quit\nnet commands: send, serv");
	} else if (0 == stricmp("name", f)) {
		CString cap;
		if (0 == ch_name(p)) cap.Format("Name set to \"%s\"", p);
		else cap.Format("Can't set name to \"%s\"", p);
		_write_console(cap);
	} else if (0 == stricmp("serv", f)) {
		_add_server();
	} else if (0 == stricmp("send", f)) {
		_add_client();
	} else if (0 < strlen(f)) {
		CString ostr;
		if ((HINSTANCE)32 < ShellExecute(NULL, NULL, f, p, NULL, SW_SHOW)) {
			ostr.Format("%s [%s] - ok", f, p);
		} else ostr.Format("%s - failed", f);
		_write_console(ostr);
	}

	_str_clone_del(str);

	return 0;
}


int ccw_root::_show_all(const int mode) {
	// servers
	POSITION pos = _servers.GetStartPosition();
	int tmp_key; ccw_server *tmp_srv;
	while (pos != NULL) {
		_servers.GetNextAssoc(pos, tmp_key, tmp_srv);
		tmp_srv->ShowWindow(mode);
	}

	// clients
	pos = _clients.GetStartPosition();
	ccw_client *tmp_clnt;
	while (pos != NULL) {
		_clients.GetNextAssoc(pos, tmp_key, tmp_clnt);
		tmp_clnt->ShowWindow(mode);
	}

	return 0;
}


int ccw_root::_add_server() {
	int id = 0;
	ccw_server *serv;
	while (0 != _servers.Lookup(id, serv)) ++id;

	serv = new ccw_server;
	serv->set_claw_id(id);
	_servers.SetAt(id, serv);

	serv->set_icon(_hicon);
	serv->set_parent(this);
	serv->give_life();

	_write_console("server created.");

	return 0;
}


int ccw_root::_del_server(int claw_id) {
	ccw_server *serv;
	if (0 == _servers.Lookup(claw_id, serv)) return -1;

	if (0 != serv->take_life()) return -1;
	_servers.RemoveKey(claw_id);
	delete serv;

	return 0;
}


int ccw_root::_add_client(ccw_client *const clnt2add, const bool give_life) {
	int id = 0;
	ccw_client *clnt;
	while (0 != _clients.Lookup(id, clnt)) ++id;

	if (NULL != clnt2add) {
		clnt = clnt2add;
		clnt->set_claw_id(id);
	} else clnt = ccw_client::mk_client(id);
	_clients.SetAt(id, clnt);

	clnt->set_icon(_hicon);
	clnt->set_parent(this);
	if (give_life) clnt->give_life();

	_write_console("client created.");

	return 0;
}


int ccw_root::_del_client(int claw_id) {
	ccw_client *clnt;
	if (0 == _clients.Lookup(claw_id, clnt)) return -1;

	if (0 != clnt->take_life()) return -1;
	_clients.RemoveKey(claw_id);
	ccw_client::rm_client(clnt);

	return 0;
}


LRESULT ccw_root::_on_add_recver_msg(WPARAM cl, LPARAM hz) {
	ccw_client *clnt = ccw_client::mk_client(0, false);
	if (NULL == clnt) return -1;
	_add_client(clnt);
	*((ccw_client **)cl) = clnt;

	return 0;
}


LRESULT ccw_root::_on_del_client_msg(WPARAM cwid, LPARAM hz) {
	int id = (int)cwid;

	return _del_client(id);
}


LRESULT ccw_root::_on_del_server_msg(WPARAM cwid, LPARAM hz) {
	int id = (int)cwid;

	return _del_server(id);
}

Соседние файлы в папке claw