unrealircd

- supernets unrealircd source & configuration
git clone git://git.acid.vegas/unrealircd.git
Log | Files | Refs | Archive | README | LICENSE

editor.c (24416B)

      1 /************************************************************************
      2  *   IRC - Internet Relay Chat, windows/editor.c
      3  *   Copyright (C) 2004 Dominick Meglio (codemastr)
      4  *   
      5  *   This program is free software; you can redistribute it and/or modify
      6  *   it under the terms of the GNU General Public License as published by
      7  *   the Free Software Foundation; either version 1, or (at your option)
      8  *   any later version.
      9  *
     10  *   This program is distributed in the hope that it will be useful,
     11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13  *   GNU General Public License for more details.
     14  *
     15  *   You should have received a copy of the GNU General Public License
     16  *   along with this program; if not, write to the Free Software
     17  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     18  */
     19 
     20 #include "unrealircd.h"
     21 #include <windowsx.h>
     22 #include <commctrl.h>
     23 #include <richedit.h>
     24 #include <commdlg.h>
     25 #include <stdlib.h>
     26 #include "resource.h"
     27 #include "win.h"
     28 
     29 LRESULT CALLBACK GotoDLG(HWND, UINT, WPARAM, LPARAM);
     30 LRESULT CALLBACK ColorDLG(HWND, UINT, WPARAM, LPARAM);
     31 
     32 HWND hFind;
     33 
     34 /* Draws the statusbar for the editor
     35  * Parameters:
     36  *  hInstance  - The instance to create the statusbar in
     37  *  hwndParent - The parent of the statusbar
     38  *  iId        - The message value used to send messages to the parent
     39  * Returns:
     40  *  The handle to the statusbar
     41  */
     42 HWND DrawStatusbar(HINSTANCE hInstance, HWND hwndParent, UINT iId)
     43 {
     44 	HWND hStatus, hTip;
     45 	TOOLINFO ti;
     46 	RECT clrect;
     47 	hStatus = CreateStatusWindow(WS_CHILD|WS_VISIBLE|SBT_TOOLTIPS, NULL, hwndParent, iId);
     48 	hTip = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, NULL,
     49  		WS_POPUP|TTS_NOPREFIX|TTS_ALWAYSTIP, 0, 0, 0, 0, hwndParent, NULL, hInstance, NULL);
     50 	GetClientRect(hStatus, &clrect);
     51 	ti.cbSize = sizeof(TOOLINFO);
     52 	ti.uFlags = TTF_SUBCLASS;
     53 	ti.hwnd = hStatus;
     54 	ti.uId = 1;
     55 	ti.hinst = hInstance;
     56 	ti.rect = clrect;
     57 	ti.lpszText = "Go To";
     58 	SendMessage(hTip, TTM_ADDTOOL, 0, (LPARAM)&ti);
     59 	return hStatus;
     60 }
     61 
     62 /* Draws the toolbar for the editor
     63  * Parameters:
     64  *  hInstance  - The instance to create the toolbar in
     65  *  hwndParent - The parent of the toolbar
     66  * Returns:
     67  *  The handle to the toolbar
     68  */
     69 HWND DrawToolbar(HINSTANCE hInstance, HWND hwndParent) 
     70 {
     71 	HWND hTool;
     72 	TBADDBITMAP tbBit;
     73 	int newidx;
     74 	TBBUTTON tbButtons[10] = {
     75 		{ STD_FILENEW, IDM_NEW, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0}, 0L, 0},
     76 		{ STD_FILESAVE, IDM_SAVE, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0}, 0L, 0},
     77 		{ 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, {0}, 0L, 0},
     78 		{ STD_CUT, IDM_CUT, 0, TBSTYLE_BUTTON, {0}, 0L, 0},
     79 		{ STD_COPY, IDM_COPY, 0, TBSTYLE_BUTTON, {0}, 0L, 0},
     80 		{ STD_PASTE, IDM_PASTE, 0, TBSTYLE_BUTTON, {0}, 0L, 0},
     81 		{ 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, {0}, 0L, 0},
     82 		{ STD_UNDO, IDM_UNDO, 0, TBSTYLE_BUTTON, {0}, 0L, 0},
     83 		{ STD_REDOW, IDM_REDO, 0, TBSTYLE_BUTTON, {0}, 0L, 0},
     84 		{ 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, {0}, 0L, 0}
     85 	};
     86 		
     87 	TBBUTTON tbAddButtons[7] = {
     88 		{ 0, IDC_BOLD, TBSTATE_ENABLED, TBSTYLE_CHECK, {0}, 0L, 0},
     89 		{ 1, IDC_UNDERLINE, TBSTATE_ENABLED, TBSTYLE_CHECK, {0}, 0L, 0},
     90 		{ 2, IDC_COLOR, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0}, 0L, 0},
     91 		{ 3, IDC_BGCOLOR, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0}, 0L, 0},
     92 		{ 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, {0}, 0L, 0},
     93 		{ 4, IDC_GOTO, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0}, 0L, 0},
     94 		{ STD_FIND, IDC_FIND, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0}, 0L, 0}
     95 	};
     96 	hTool = CreateToolbarEx(hwndParent, WS_VISIBLE|WS_CHILD|TBSTYLE_FLAT|TBSTYLE_TOOLTIPS, 
     97 				IDC_TOOLBAR, 0, HINST_COMMCTRL, IDB_STD_SMALL_COLOR,
     98 				tbButtons, 10, 0, 0, 100, 30, sizeof(TBBUTTON));
     99 	tbBit.hInst = hInstance;
    100 	tbBit.nID = IDB_BITMAP1;
    101 	newidx = SendMessage(hTool, TB_ADDBITMAP, (WPARAM)5, (LPARAM)&tbBit);
    102 	tbAddButtons[0].iBitmap += newidx;
    103 	tbAddButtons[1].iBitmap += newidx;
    104 	tbAddButtons[2].iBitmap += newidx;
    105 	tbAddButtons[3].iBitmap += newidx;
    106 	tbAddButtons[5].iBitmap += newidx;
    107 	SendMessage(hTool, TB_ADDBUTTONS, (WPARAM)7, (LPARAM)&tbAddButtons);
    108 	return hTool;
    109 }
    110 
    111 /* Dialog procedure for the color selection dialog
    112  * Parameters:
    113  *  hDlg    - The dialog handle
    114  *  message - The message received
    115  *  wParam  - The first message parameter
    116  *  lParam  - The second message parameter
    117  * Returns:
    118  *  TRUE if the message was processed, FALSE otherwise
    119  */
    120 LRESULT CALLBACK ColorDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) {
    121 	static HBRUSH hBrushWhite, hBrushBlack, hBrushDarkBlue, hBrushDarkGreen, hBrushRed,
    122 		hBrushDarkRed, hBrushPurple, hBrushOrange, hBrushYellow, hBrushGreen, hBrushVDarkGreen,
    123 		hBrushLightBlue, hBrushBlue, hBrushPink, hBrushDarkGray, hBrushGray;
    124 	static UINT ResultMsg = 0;
    125 
    126 	switch (message) 
    127 	{
    128 		case WM_INITDIALOG:
    129 			hBrushWhite = CreateSolidBrush(RGB(255,255,255));
    130 			hBrushBlack = CreateSolidBrush(RGB(0,0,0));
    131 			hBrushDarkBlue = CreateSolidBrush(RGB(0,0,127));
    132 			hBrushDarkGreen = CreateSolidBrush(RGB(0,147,0));
    133 			hBrushRed = CreateSolidBrush(RGB(255,0,0));
    134 			hBrushDarkRed = CreateSolidBrush(RGB(127,0,0));
    135 			hBrushPurple = CreateSolidBrush(RGB(156,0,156));
    136 			hBrushOrange = CreateSolidBrush(RGB(252,127,0));
    137 			hBrushYellow = CreateSolidBrush(RGB(255,255,0));
    138 			hBrushGreen = CreateSolidBrush(RGB(0,252,0));
    139 			hBrushVDarkGreen = CreateSolidBrush(RGB(0,147,147));
    140 			hBrushLightBlue = CreateSolidBrush(RGB(0,255,255));
    141 			hBrushBlue = CreateSolidBrush(RGB(0,0,252));
    142 			hBrushPink = CreateSolidBrush(RGB(255,0,255));
    143 			hBrushDarkGray = CreateSolidBrush(RGB(127,127,127));
    144 			hBrushGray = CreateSolidBrush(RGB(210,210,210));
    145 			ResultMsg = (UINT)lParam;
    146 			SetFocus(NULL);
    147 			return TRUE;
    148 		case WM_DRAWITEM: 
    149 		{
    150 			LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lParam;
    151 			if (wParam == IDC_WHITE) 
    152 				FillRect(lpdis->hDC, &lpdis->rcItem, hBrushWhite);
    153 			if (wParam == IDC_BLACK)
    154 				FillRect(lpdis->hDC, &lpdis->rcItem, hBrushBlack);
    155 			if (wParam == IDC_DARKBLUE) 
    156 				FillRect(lpdis->hDC, &lpdis->rcItem, hBrushDarkBlue);
    157 			if (wParam == IDC_DARKGREEN) 
    158 				FillRect(lpdis->hDC, &lpdis->rcItem, hBrushDarkGreen);
    159 			if (wParam == IDC_RED)
    160 				FillRect(lpdis->hDC, &lpdis->rcItem, hBrushRed);
    161 			if (wParam == IDC_DARKRED)
    162 				FillRect(lpdis->hDC, &lpdis->rcItem, hBrushDarkRed);
    163 			if (wParam == IDC_PURPLE)
    164 				FillRect(lpdis->hDC, &lpdis->rcItem, hBrushPurple);
    165 			if (wParam == IDC_ORANGE)
    166 				FillRect(lpdis->hDC, &lpdis->rcItem, hBrushOrange);
    167 			if (wParam == IDC_YELLOW)
    168 				FillRect(lpdis->hDC, &lpdis->rcItem, hBrushYellow);
    169 			if (wParam == IDC_GREEN)
    170 				FillRect(lpdis->hDC, &lpdis->rcItem, hBrushGreen);
    171 			if (wParam == IDC_VDARKGREEN)
    172 				FillRect(lpdis->hDC, &lpdis->rcItem, hBrushVDarkGreen);
    173 			if (wParam == IDC_LIGHTBLUE)
    174 				FillRect(lpdis->hDC, &lpdis->rcItem, hBrushLightBlue);
    175 			if (wParam == IDC_BLUE)
    176 				FillRect(lpdis->hDC, &lpdis->rcItem, hBrushBlue);
    177 			if (wParam == IDC_PINK)
    178 				FillRect(lpdis->hDC, &lpdis->rcItem, hBrushPink);
    179 			if (wParam == IDC_DARKGRAY)
    180 				FillRect(lpdis->hDC, &lpdis->rcItem, hBrushDarkGray);
    181 			if (wParam == IDC_GRAY)
    182 				FillRect(lpdis->hDC, &lpdis->rcItem, hBrushGray);
    183 			DrawEdge(lpdis->hDC, &lpdis->rcItem, EDGE_SUNKEN, BF_RECT);
    184 			return TRUE;
    185 		}
    186 		case WM_COMMAND: 
    187 		{
    188 			COLORREF clrref;
    189 			if (LOWORD(wParam) == IDC_WHITE) 
    190 				clrref = RGB(255,255,255);
    191 			else if (LOWORD(wParam) == IDC_BLACK)
    192 				clrref = RGB(0,0,0);
    193 			else if (LOWORD(wParam) == IDC_DARKBLUE)
    194 				clrref = RGB(0,0,127);
    195 			else if (LOWORD(wParam) == IDC_DARKGREEN)
    196 				clrref = RGB(0,147,0);
    197 			else if (LOWORD(wParam) == IDC_RED)
    198 				clrref = RGB(255,0,0);
    199 			else if (LOWORD(wParam) == IDC_DARKRED)
    200 				clrref = RGB(127,0,0);
    201 			else if (LOWORD(wParam) == IDC_PURPLE)
    202 				clrref = RGB(156,0,156);
    203 			else if (LOWORD(wParam) == IDC_ORANGE)
    204 				clrref = RGB(252,127,0);
    205 			else if (LOWORD(wParam) == IDC_YELLOW)
    206 				clrref = RGB(255,255,0);
    207 			else if (LOWORD(wParam) == IDC_GREEN)
    208 				clrref = RGB(0,252,0);
    209 			else if (LOWORD(wParam) == IDC_VDARKGREEN)
    210 				clrref = RGB(0,147,147);
    211 			else if (LOWORD(wParam) == IDC_LIGHTBLUE)
    212 				clrref = RGB(0,255,255);
    213 			else if (LOWORD(wParam) == IDC_BLUE)
    214 				clrref = RGB(0,0,252);
    215 			else if (LOWORD(wParam) == IDC_PINK)
    216 				clrref = RGB(255,0,255);
    217 			else if (LOWORD(wParam) == IDC_DARKGRAY)
    218 				clrref = RGB(127,127,127);
    219 			else if (LOWORD(wParam) == IDC_GRAY)
    220 				clrref = RGB(210,210,210);
    221 			SendMessage(GetParent(hDlg), ResultMsg, (WPARAM)clrref, (LPARAM)hDlg);
    222 			break;
    223 		}
    224 		case WM_CLOSE:
    225 			EndDialog(hDlg, TRUE);
    226 		case WM_DESTROY:
    227 			DeleteObject(hBrushWhite);
    228 			DeleteObject(hBrushBlack);
    229 			DeleteObject(hBrushDarkBlue);
    230 			DeleteObject(hBrushDarkGreen);
    231 			DeleteObject(hBrushRed);
    232 			DeleteObject(hBrushDarkRed);
    233 			DeleteObject(hBrushPurple);
    234 			DeleteObject(hBrushOrange);
    235 			DeleteObject(hBrushYellow);
    236 			DeleteObject(hBrushGreen);
    237 			DeleteObject(hBrushVDarkGreen);
    238 			DeleteObject(hBrushLightBlue);
    239 			DeleteObject(hBrushBlue);
    240 			DeleteObject(hBrushPink);
    241 			DeleteObject(hBrushDarkGray);
    242 			DeleteObject(hBrushGray);
    243 			break;
    244 	}
    245 
    246 	return FALSE;
    247 }
    248 
    249 /* Dialog procedure for the goto dialog
    250  * Parameters:
    251  *  hDlg    - The dialog handle
    252  *  message - The message received
    253  *  wParam  - The first message parameter
    254  *  lParam  - The second message parameter
    255  * Returns:
    256  *  TRUE if the message was processed, FALSE otherwise
    257  */
    258 LRESULT CALLBACK GotoDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) 
    259 {
    260 	if (message == WM_COMMAND) 
    261 	{
    262 		if (LOWORD(wParam) == IDCANCEL)
    263 			EndDialog(hDlg, TRUE);
    264 		else if (LOWORD(wParam) == IDOK) 
    265 		{
    266 			HWND hWnd = GetDlgItem(GetParent(hDlg),IDC_TEXT);
    267 			int line = GetDlgItemInt(hDlg, IDC_GOTO, NULL, FALSE);
    268 			int pos = SendMessage(hWnd, EM_LINEINDEX, (WPARAM)--line, 0);
    269 			SendMessage(hWnd, EM_SETSEL, (WPARAM)pos, (LPARAM)pos);
    270 			SendMessage(hWnd, EM_SCROLLCARET, 0, 0);
    271 			EndDialog(hDlg, TRUE);
    272 		}
    273 	}
    274 	return FALSE;
    275 }
    276 
    277 LRESULT CALLBACK FromFileDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) 
    278 {
    279 	HWND hWnd;
    280 	static FINDREPLACE find;
    281 	static char findbuf[256];
    282 	static unsigned char *file;
    283 	static HWND hTool, hClip, hStatus;
    284 	static RECT rOld;
    285 	CHARFORMAT2 chars;
    286 
    287 	if (message == WM_FINDMSGSTRING)
    288 	{
    289 		FINDREPLACE *fr = (FINDREPLACE *)lParam;
    290 
    291 		if (fr->Flags & FR_FINDNEXT)
    292 		{
    293 			HWND hRich = GetDlgItem(hDlg, IDC_TEXT);
    294 			DWORD flags=0;
    295 			FINDTEXTEX ft;
    296 			CHARRANGE chrg;
    297 
    298 			if (fr->Flags & FR_DOWN)
    299 				flags |= FR_DOWN;
    300 			if (fr->Flags & FR_MATCHCASE)
    301 				flags |= FR_MATCHCASE;
    302 			if (fr->Flags & FR_WHOLEWORD)
    303 				flags |= FR_WHOLEWORD;
    304 			ft.lpstrText = fr->lpstrFindWhat;
    305 			SendMessage(hRich, EM_EXGETSEL, 0, (LPARAM)&chrg);
    306 			if (flags & FR_DOWN)
    307 			{
    308 				ft.chrg.cpMin = chrg.cpMax;
    309 				ft.chrg.cpMax = -1;
    310 			}
    311 			else
    312 			{
    313 				ft.chrg.cpMin = chrg.cpMin;
    314 				ft.chrg.cpMax = -1;
    315 			}
    316 			if (SendMessage(hRich, EM_FINDTEXTEX, flags, (LPARAM)&ft) == -1)
    317 				MessageBox(NULL, "UnrealIRCd has finished searching the document",
    318 					"Find", MB_ICONINFORMATION|MB_OK);
    319 			else
    320 			{
    321 				SendMessage(hRich, EM_EXSETSEL, 0, (LPARAM)&(ft.chrgText));
    322 				SendMessage(hRich, EM_SCROLLCARET, 0, 0);
    323 				SetFocus(hRich);
    324 			}
    325 		}
    326 		return TRUE;
    327 	}
    328 	switch (message) 
    329 	{
    330 		case WM_INITDIALOG: 
    331 		{
    332 			int fd,len;
    333 			char *buffer, *string;
    334 			EDITSTREAM edit;
    335 			StreamIO *stream = safe_alloc(sizeof(StreamIO));
    336 			unsigned char szText[256];
    337 			struct stat sb;
    338 			HWND hWnd = GetDlgItem(hDlg, IDC_TEXT), hTip;
    339 			file = (unsigned char *)lParam;
    340 			if (file)
    341 				wsprintf(szText, "UnrealIRCd Editor - %s", file);
    342 			else 
    343 				strcpy(szText, "UnrealIRCd Editor - New File");
    344 			SetWindowText(hDlg, szText);
    345 			lpfnOldWndProc = (FARPROC)SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)RESubClassFunc);
    346 			hTool = DrawToolbar(hInst, hDlg);
    347 			hStatus = DrawStatusbar(hInst, hDlg, IDC_STATUS);
    348 			SendMessage(hWnd, EM_SETEVENTMASK, 0, (LPARAM)ENM_SELCHANGE);
    349 			chars.cbSize = sizeof(CHARFORMAT2);
    350 			chars.dwMask = CFM_FACE;
    351 			strcpy(chars.szFaceName,"Fixedsys");
    352 			SendMessage(hWnd, EM_SETCHARFORMAT, (WPARAM)SCF_ALL, (LPARAM)&chars);
    353 			if ((fd = open(file, _O_RDONLY|_O_BINARY)) != -1) 
    354 			{
    355 				fstat(fd,&sb);
    356 				/* Only allocate the amount we need */
    357 				buffer = safe_alloc(sb.st_size+1);
    358 				len = read(fd, buffer, sb.st_size);
    359 				buffer[len] = 0;
    360 				len = CountRTFSize(buffer)+1;
    361 				string = safe_alloc(len);
    362 				IRCToRTF(buffer,string);
    363 				RTFBuf = string;
    364 				len--;
    365 				stream->size = &len;
    366 				stream->buffer = &RTFBuf;
    367 				edit.dwCookie = (DWORD_PTR)stream;
    368 				edit.pfnCallback = SplitIt;
    369 				SendMessage(hWnd, EM_EXLIMITTEXT, 0, (LPARAM)0x7FFFFFFF);
    370 				SendMessage(hWnd, EM_STREAMIN, (WPARAM)SF_RTF|SFF_PLAINRTF, (LPARAM)&edit);
    371 				SendMessage(hWnd, EM_SETMODIFY, (WPARAM)FALSE, 0);
    372 				SendMessage(hWnd, EM_EMPTYUNDOBUFFER, 0, 0);
    373 				close(fd);
    374 				RTFBuf = NULL;
    375 				safe_free(buffer);
    376 				safe_free(string);
    377 				safe_free(stream);
    378 				hClip = SetClipboardViewer(hDlg);
    379 				if (SendMessage(hWnd, EM_CANPASTE, 0, 0)) 
    380 					SendMessage(hTool, TB_ENABLEBUTTON, (WPARAM)IDM_PASTE, (LPARAM)MAKELONG(TRUE,0));
    381 				else
    382 					SendMessage(hTool, TB_ENABLEBUTTON, (WPARAM)IDM_PASTE, (LPARAM)MAKELONG(FALSE,0));
    383 				SendMessage(hTool, TB_ENABLEBUTTON, (WPARAM)IDM_UNDO, (LPARAM)MAKELONG(FALSE,0));
    384 				wsprintf(szText, "Line: 1");
    385 				SetWindowText(hStatus, szText);
    386 			}
    387 			return TRUE;
    388 		}
    389 		case WM_WINDOWPOSCHANGING:
    390 		{
    391 			GetClientRect(hDlg, &rOld);
    392 			return FALSE;
    393 		}
    394 		case WM_SIZE:
    395 		{
    396 			DWORD new_width, new_height;
    397 			HWND hRich;
    398 			RECT rOldRich;
    399 			DWORD old_width, old_height;
    400 			DWORD old_rich_width, old_rich_height;
    401 			if (hDlg == hFind)
    402 				return FALSE;
    403 			new_width =  LOWORD(lParam);
    404 			new_height = HIWORD(lParam);
    405 			hRich  = GetDlgItem(hDlg, IDC_TEXT);
    406 			SendMessage(hStatus, WM_SIZE, 0, 0);
    407 			SendMessage(hTool, TB_AUTOSIZE, 0, 0);
    408 			old_width = rOld.right-rOld.left;
    409 			old_height = rOld.bottom-rOld.top;
    410 			new_width = new_width - old_width;
    411 			new_height = new_height - old_height;
    412 			GetWindowRect(hRich, &rOldRich);
    413 			old_rich_width = rOldRich.right-rOldRich.left;
    414 			old_rich_height = rOldRich.bottom-rOldRich.top;
    415 			SetWindowPos(hRich, NULL, 0, 0, old_rich_width+new_width, 
    416 				old_rich_height+new_height,
    417 				SWP_NOMOVE|SWP_NOREPOSITION|SWP_NOZORDER);
    418 			memset(&rOld, 0, sizeof(rOld));
    419 			return TRUE;
    420 		} 
    421 
    422 		case WM_NOTIFY:
    423 			switch (((NMHDR *)lParam)->code) 
    424 			{
    425 				case EN_SELCHANGE: 
    426 				{
    427 					HWND hWnd = GetDlgItem(hDlg, IDC_TEXT);
    428 					DWORD start, end, currline;
    429 					static DWORD prevline = 0;
    430 					unsigned char buffer[512];
    431 					chars.cbSize = sizeof(CHARFORMAT2);
    432 					SendMessage(hWnd, EM_GETCHARFORMAT, (WPARAM)SCF_SELECTION, (LPARAM)&chars);
    433 					if (chars.dwMask & CFM_BOLD && chars.dwEffects & CFE_BOLD)
    434 						SendMessage(hTool, TB_CHECKBUTTON, (WPARAM)IDC_BOLD, (LPARAM)MAKELONG(TRUE,0));
    435 					else
    436 						SendMessage(hTool, TB_CHECKBUTTON, (WPARAM)IDC_BOLD, (LPARAM)MAKELONG(FALSE,0));
    437 					if (chars.dwMask & CFM_UNDERLINE && chars.dwEffects & CFE_UNDERLINE)
    438 						SendMessage(hTool, TB_CHECKBUTTON, (WPARAM)IDC_UNDERLINE, (LPARAM)MAKELONG(TRUE,0));
    439 					else
    440 						SendMessage(hTool, TB_CHECKBUTTON, (WPARAM)IDC_UNDERLINE, (LPARAM)MAKELONG(FALSE,0));
    441 					SendMessage(hWnd, EM_GETSEL,(WPARAM)&start, (LPARAM)&end);
    442 					if (start == end) 
    443 					{
    444 						SendMessage(hTool, TB_ENABLEBUTTON, (WPARAM)IDM_COPY, (LPARAM)MAKELONG(FALSE,0));
    445 						SendMessage(hTool, TB_ENABLEBUTTON, (WPARAM)IDM_CUT, (LPARAM)MAKELONG(FALSE,0));
    446 					}
    447 					else 
    448 					{
    449 						SendMessage(hTool, TB_ENABLEBUTTON, (WPARAM)IDM_COPY, (LPARAM)MAKELONG(TRUE,0));
    450 						SendMessage(hTool, TB_ENABLEBUTTON, (WPARAM)IDM_CUT, (LPARAM)MAKELONG(TRUE,0));
    451 					}
    452 					if (SendMessage(hWnd, EM_CANUNDO, 0, 0)) 
    453 						SendMessage(hTool, TB_ENABLEBUTTON, (WPARAM)IDM_UNDO, (LPARAM)MAKELONG(TRUE,0));
    454 					else
    455 						SendMessage(hTool, TB_ENABLEBUTTON, (WPARAM)IDM_UNDO, (LPARAM)MAKELONG(FALSE,0));
    456 					if (SendMessage(hWnd, EM_CANREDO, 0, 0)) 
    457 						SendMessage(hTool, TB_ENABLEBUTTON, (WPARAM)IDM_REDO, (LPARAM)MAKELONG(TRUE,0));
    458 					else
    459 						SendMessage(hTool, TB_ENABLEBUTTON, (WPARAM)IDM_REDO, (LPARAM)MAKELONG(FALSE,0));
    460 					currline = SendMessage(hWnd, EM_LINEFROMCHAR, (WPARAM)-1, 0);
    461 					currline++;
    462 					if (currline != prevline) 
    463 					{
    464 						wsprintf(buffer, "Line: %d", currline);
    465 						SetWindowText(hStatus, buffer);
    466 						prevline = currline;
    467 					}
    468 				return TRUE;
    469 			}
    470 			case TTN_GETDISPINFO: 
    471 			{
    472 				LPTOOLTIPTEXT lpttt = (LPTOOLTIPTEXT) lParam;
    473 				lpttt->hinst = NULL;
    474 				switch (lpttt->hdr.idFrom) 
    475 				{
    476 					case IDM_NEW:
    477 						strcpy(lpttt->szText, "New");
    478 						break;
    479 					case IDM_SAVE:
    480 						strcpy(lpttt->szText, "Save");
    481 						break;
    482 					case IDM_CUT:
    483 						strcpy(lpttt->szText, "Cut");
    484 						break;
    485 					case IDM_COPY:
    486 						strcpy(lpttt->szText, "Copy");
    487 						break;
    488 					case IDM_PASTE:
    489 						strcpy(lpttt->szText, "Paste");
    490 						break;
    491 					case IDM_UNDO:
    492 						strcpy(lpttt->szText, "Undo");
    493 						break;
    494 					case IDM_REDO:
    495 						strcpy(lpttt->szText, "Redo");
    496 						break;
    497 					case IDC_BOLD:
    498 						strcpy(lpttt->szText, "Bold");
    499 						break;
    500 					case IDC_UNDERLINE:
    501 						strcpy(lpttt->szText, "Underline");
    502 						break;
    503 					case IDC_COLOR:
    504 						strcpy(lpttt->szText, "Text Color");
    505 						break;
    506 					case IDC_BGCOLOR:
    507 						strcpy(lpttt->szText, "Background Color");
    508 						break;
    509 					case IDC_GOTO:
    510 						strcpy(lpttt->szText, "Goto");
    511 						break;
    512 					case IDC_FIND:
    513 						strcpy(lpttt->szText, "Find");
    514 						break;
    515 				}
    516 				return TRUE;
    517 			}
    518 			case NM_DBLCLK:
    519 				DialogBox(hInst, "GOTO", hDlg, (DLGPROC)GotoDLG);
    520 				return (TRUE);
    521 		}
    522 				
    523 				return (TRUE);
    524 		case WM_COMMAND:
    525 			if (LOWORD(wParam) == IDC_BOLD) 
    526 			{
    527 				hWnd = GetDlgItem(hDlg, IDC_TEXT);
    528 				if (SendMessage(hTool, TB_ISBUTTONCHECKED, (WPARAM)IDC_BOLD, (LPARAM)0) != 0) 
    529 				{
    530 					chars.cbSize = sizeof(CHARFORMAT2);
    531 					chars.dwMask = CFM_BOLD;
    532 					chars.dwEffects = CFE_BOLD;
    533 					SendMessage(hWnd, EM_SETCHARFORMAT, (WPARAM)SCF_SELECTION, (LPARAM)&chars);
    534 					SendMessage(hWnd, EM_HIDESELECTION, 0, 0);
    535 					SetFocus(hWnd);
    536 				}
    537 				else 
    538 				{
    539 					chars.cbSize = sizeof(CHARFORMAT2);
    540 					chars.dwMask = CFM_BOLD;
    541 					chars.dwEffects = 0;
    542 					SendMessage(hWnd, EM_SETCHARFORMAT, (WPARAM)SCF_SELECTION, (LPARAM)&chars);
    543 					SendMessage(hWnd, EM_HIDESELECTION, 0, 0);
    544 					SetFocus(hWnd);
    545 				}
    546 				return TRUE;
    547 			}
    548 			else if (LOWORD(wParam) == IDC_UNDERLINE) 
    549 			{
    550 				hWnd = GetDlgItem(hDlg, IDC_TEXT);
    551 				if (SendMessage(hTool, TB_ISBUTTONCHECKED, (WPARAM)IDC_UNDERLINE, (LPARAM)0) != 0) 
    552 				{
    553 					chars.cbSize = sizeof(CHARFORMAT2);
    554 					chars.dwMask = CFM_UNDERLINETYPE;
    555 					chars.bUnderlineType = CFU_UNDERLINE;
    556 					SendMessage(hWnd, EM_SETCHARFORMAT, (WPARAM)SCF_SELECTION, (LPARAM)&chars);
    557 					SendMessage(hWnd, EM_HIDESELECTION, 0, 0);
    558 					SetFocus(hWnd);
    559 				}
    560 				else 
    561 				{
    562 					chars.cbSize = sizeof(CHARFORMAT2);
    563 					chars.dwMask = CFM_UNDERLINETYPE;
    564 					chars.bUnderlineType = CFU_UNDERLINENONE;
    565 					SendMessage(hWnd, EM_SETCHARFORMAT, (WPARAM)SCF_SELECTION, (LPARAM)&chars);
    566 					SendMessage(hWnd, EM_HIDESELECTION, 0, 0);
    567 					SetFocus(hWnd);
    568 				}
    569 				return TRUE;
    570 			}
    571 			if (LOWORD(wParam) == IDC_COLOR) 
    572 			{
    573 				DialogBoxParam(hInst, "Color", hDlg, (DLGPROC)ColorDLG, (LPARAM)WM_USER+10);
    574 				return 0;
    575 			}
    576 			if (LOWORD(wParam) == IDC_BGCOLOR)
    577 			{
    578 				DialogBoxParam(hInst, "Color", hDlg, (DLGPROC)ColorDLG, (LPARAM)WM_USER+11);
    579 				return 0;
    580 			}
    581 			if (LOWORD(wParam) == IDC_GOTO)
    582 			{
    583 				DialogBox(hInst, "GOTO", hDlg, (DLGPROC)GotoDLG);
    584 				return 0;
    585 			}
    586 			if (LOWORD(wParam) == IDC_FIND)
    587 			{
    588 				static FINDREPLACE fr;
    589 				memset(&fr, 0, sizeof(fr));
    590 				fr.lStructSize = sizeof(FINDREPLACE);
    591 				fr.hwndOwner = hDlg;
    592 				fr.lpstrFindWhat = findbuf;
    593 				fr.wFindWhatLen = 255;
    594 				hFind = FindText(&fr);
    595 				return 0;
    596 			}
    597 				
    598 			hWnd = GetDlgItem(hDlg, IDC_TEXT);
    599 			if (LOWORD(wParam) == IDM_COPY) 
    600 			{
    601 				SendMessage(hWnd, WM_COPY, 0, 0);
    602 				return 0;
    603 			}
    604 			if (LOWORD(wParam) == IDM_SELECTALL) 
    605 			{
    606 				SendMessage(hWnd, EM_SETSEL, 0, -1);
    607 				return 0;
    608 			}
    609 			if (LOWORD(wParam) == IDM_PASTE) 
    610 			{
    611 				SendMessage(hWnd, WM_PASTE, 0, 0);
    612 				return 0;
    613 			}
    614 			if (LOWORD(wParam) == IDM_CUT) 
    615 			{
    616 				SendMessage(hWnd, WM_CUT, 0, 0);
    617 				return 0;
    618 			}
    619 			if (LOWORD(wParam) == IDM_UNDO) 
    620 			{
    621 				SendMessage(hWnd, EM_UNDO, 0, 0);
    622 				return 0;
    623 			}
    624 			if (LOWORD(wParam) == IDM_REDO) 
    625 			{
    626 				SendMessage(hWnd, EM_REDO, 0, 0);
    627 				return 0;
    628 			}
    629 			if (LOWORD(wParam) == IDM_DELETE) 
    630 			{
    631 				SendMessage(hWnd, WM_CLEAR, 0, 0);
    632 				return 0;
    633 			}
    634 			if (LOWORD(wParam) == IDM_SAVE) 
    635 			{
    636 				int fd;
    637 				EDITSTREAM edit;
    638 				OPENFILENAME lpopen;
    639 				if (!file) 
    640 				{
    641 					unsigned char path[MAX_PATH];
    642 					path[0] = '\0';
    643 					memset(&lpopen, 0, sizeof(lpopen));
    644 					lpopen.lStructSize = sizeof(OPENFILENAME);
    645 					lpopen.hwndOwner = hDlg;
    646 					lpopen.lpstrFilter = NULL;
    647 					lpopen.lpstrCustomFilter = NULL;
    648 					lpopen.nFilterIndex = 0;
    649 					lpopen.lpstrFile = path;
    650 					lpopen.nMaxFile = MAX_PATH;
    651 					lpopen.lpstrFileTitle = NULL;
    652 					lpopen.lpstrInitialDir = CONFDIR;
    653 					lpopen.lpstrTitle = NULL;
    654 					lpopen.Flags = (OFN_ENABLESIZING|OFN_NONETWORKBUTTON|
    655 							OFN_OVERWRITEPROMPT);
    656 					if (GetSaveFileName(&lpopen))
    657 						file = path;
    658 					else
    659 						break;
    660 				}
    661 				fd = open(file, _O_TRUNC|_O_CREAT|_O_WRONLY|_O_BINARY,_S_IWRITE);
    662 				edit.dwCookie = 0;
    663 				edit.pfnCallback = BufferIt;
    664 				SendMessage(GetDlgItem(hDlg, IDC_TEXT), EM_STREAMOUT, (WPARAM)SF_RTF|SFF_PLAINRTF, (LPARAM)&edit);
    665 				RTFToIRC(fd, RTFBuf, strlen(RTFBuf));
    666 				safe_free(RTFBuf);
    667 				RTFBuf = NULL;
    668 				SendMessage(GetDlgItem(hDlg, IDC_TEXT), EM_SETMODIFY, (WPARAM)FALSE, 0);
    669 	
    670 				return 0;
    671 			}
    672 			if (LOWORD(wParam) == IDM_NEW) 
    673 			{
    674 				unsigned char text[1024];
    675 				BOOL newfile = FALSE;
    676 				int ans;
    677 				if (SendMessage(GetDlgItem(hDlg, IDC_TEXT), EM_GETMODIFY, 0, 0) != 0) 
    678 				{
    679 					sprintf(text, "The text in the %s file has changed.\r\n\r\nDo you want to save the changes?", file ? file : "new");
    680 					ans = MessageBox(hDlg, text, "UnrealIRCd", MB_YESNOCANCEL|MB_ICONWARNING);
    681 					if (ans == IDNO)
    682 						newfile = TRUE;
    683 					if (ans == IDCANCEL)
    684 						return TRUE;
    685 					if (ans == IDYES) 
    686 					{
    687 						SendMessage(hDlg, WM_COMMAND, MAKEWPARAM(IDM_SAVE,0), 0);
    688 						newfile = TRUE;
    689 					}
    690 				}
    691 				else
    692 					newfile = TRUE;
    693 				if (newfile == TRUE) 
    694 				{
    695 					unsigned char szText[256];
    696 					file = NULL;
    697 					strcpy(szText, "UnrealIRCd Editor - New File");
    698 					SetWindowText(hDlg, szText);
    699 					SetWindowText(GetDlgItem(hDlg, IDC_TEXT), NULL);
    700 				}
    701 				break;
    702 			}
    703 			break;
    704 		case WM_USER+10: 
    705 		{
    706 			HWND hWnd = GetDlgItem(hDlg, IDC_TEXT);
    707 			EndDialog((HWND)lParam, TRUE);
    708 			chars.cbSize = sizeof(CHARFORMAT2);
    709 			chars.dwMask = CFM_COLOR;
    710 			chars.crTextColor = (COLORREF)wParam;
    711 			SendMessage(hWnd, EM_SETCHARFORMAT, (WPARAM)SCF_SELECTION, (LPARAM)&chars);
    712 			SendMessage(hWnd, EM_HIDESELECTION, 0, 0);
    713 			SetFocus(hWnd);
    714 			break;
    715 		}
    716 		case WM_USER+11: 
    717 		{
    718 			HWND hWnd = GetDlgItem(hDlg, IDC_TEXT);
    719 			EndDialog((HWND)lParam, TRUE);
    720 			chars.cbSize = sizeof(CHARFORMAT2);
    721 			chars.dwMask = CFM_BACKCOLOR;
    722 			chars.crBackColor = (COLORREF)wParam;
    723 			SendMessage(hWnd, EM_SETCHARFORMAT, (WPARAM)SCF_SELECTION, (LPARAM)&chars);
    724 			SendMessage(hWnd, EM_HIDESELECTION, 0, 0);
    725 			SetFocus(hWnd);
    726 			break;
    727 		}
    728 		case WM_CHANGECBCHAIN:
    729 			if ((HWND)wParam == hClip)
    730 				hClip = (HWND)lParam;
    731 			else
    732 				SendMessage(hClip, WM_CHANGECBCHAIN, wParam, lParam);
    733 			break;
    734 		case WM_DRAWCLIPBOARD:
    735 			if (SendMessage(GetDlgItem(hDlg, IDC_TEXT), EM_CANPASTE, 0, 0)) 
    736 				SendMessage(hTool, TB_ENABLEBUTTON, (WPARAM)IDM_PASTE, (LPARAM)MAKELONG(TRUE,0));
    737 			else
    738 				SendMessage(hTool, TB_ENABLEBUTTON, (WPARAM)IDM_PASTE, (LPARAM)MAKELONG(FALSE,0));
    739 			SendMessage(hClip, WM_DRAWCLIPBOARD, wParam, lParam);
    740 			break;
    741 		case WM_CLOSE: 
    742 		{
    743 			unsigned char text[256];
    744 			int ans;
    745 			if (SendMessage(GetDlgItem(hDlg, IDC_TEXT), EM_GETMODIFY, 0, 0) != 0) 
    746 			{
    747 				sprintf(text, "The text in the %s file has changed.\r\n\r\nDo you want to save the changes?", file ? file : "new");
    748 				ans = MessageBox(hDlg, text, "UnrealIRCd", MB_YESNOCANCEL|MB_ICONWARNING);
    749 				if (ans == IDNO)
    750 					EndDialog(hDlg, TRUE);
    751 				if (ans == IDCANCEL)
    752 					return TRUE;
    753 				if (ans == IDYES) 
    754 				{
    755 					SendMessage(hDlg, WM_COMMAND, MAKEWPARAM(IDM_SAVE,0), 0);
    756 					EndDialog(hDlg, TRUE);
    757 				}
    758 			}
    759 			else
    760 				EndDialog(hDlg, TRUE);
    761 			break;
    762 		}
    763 		case WM_DESTROY:
    764 			ChangeClipboardChain(hDlg, hClip);
    765 			break;
    766 	}
    767 
    768 	return FALSE;
    769 }