Annotation of OpenXM_contrib/gnuplot/win/wtext.c, Revision 1.1.1.2
1.1 maekawa 1: #ifndef lint
1.1.1.2 ! maekawa 2: static char *RCSid = "$Id: wtext.c,v 1.3.2.1 1999/09/21 18:48:28 lhecking Exp $";
1.1 maekawa 3: #endif
4:
5: /* GNUPLOT - win/wtext.c */
1.1.1.2 ! maekawa 6:
1.1 maekawa 7: /*[
8: * Copyright 1992, 1993, 1998 Russell Lang
9: *
10: * Permission to use, copy, and distribute this software and its
11: * documentation for any purpose with or without fee is hereby granted,
12: * provided that the above copyright notice appear in all copies and
13: * that both that copyright notice and this permission notice appear
14: * in supporting documentation.
15: *
16: * Permission to modify the software is granted, but not the right to
17: * distribute the complete modified source code. Modifications are to
18: * be distributed as patches to the released version. Permission to
19: * distribute binaries produced by compiling modified sources is granted,
20: * provided you
21: * 1. distribute the corresponding source modifications from the
22: * released version in the form of a patch file along with the binaries,
23: * 2. add special version identification to distinguish your version
24: * in addition to the base release version number,
25: * 3. provide your name and address as the primary contact for the
26: * support of your modified version, and
27: * 4. retain our contact information in regard to use of the base
28: * software.
29: * Permission to distribute the released version of the source code along
30: * with corresponding source modifications in the form of a patch file is
31: * granted with same provisions 2 through 4 for binary distributions.
32: *
33: * This software is provided "as is" without express or implied warranty
34: * to the extent permitted by applicable law.
35: ]*/
36:
37: /*
38: * AUTHORS
39: *
40: * Russell Lang
41: *
42: * Send your comments or suggestions to
43: * info-gnuplot@dartmouth.edu.
44: * This is a mailing list; to join it send a note to
45: * majordomo@dartmouth.edu.
46: * Send bug reports to
47: * bug-gnuplot@dartmouth.edu.
48: */
49:
50: /* WARNING: Do not write to stdout/stderr with functions not listed
51: in win/wtext.h */
52:
53: #define STRICT
54:
55: #include <string.h> /* use only far items */
56: #include <stdlib.h>
57: #include <ctype.h>
58: #include <dos.h>
59: #ifndef __MSC__
60: # include <mem.h>
61: #endif
62:
63: #include <windows.h>
64: #include <windowsx.h>
65: #if WINVER >= 0x030a
66: # include <commdlg.h>
67: #endif
68:
69: #include "wgnuplib.h"
70: #include "wresourc.h"
71: #include "wcommon.h"
72:
73: /* font stuff */
74: #define TEXTFONTSIZE 9
75: #define TEXTFONTNAME "Terminal"
76:
77: #ifndef EOF /* HBB 980809: for MinGW32 */
78: #define EOF -1 /* instead of using <stdio.h> */
79: #endif
80: /* limits */
81: #define MAXSTR 256
82: POINT ScreenMinSize = {16,4};
83:
84: LRESULT CALLBACK WINEXPORT WndParentProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
85: LRESULT CALLBACK WINEXPORT WndTextProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
86:
87: void ReadTextIni(LPTW lptw);
88: void LimitMark(LPTW lptw, POINT FAR *lppt);
89:
90: char szNoMemory[] = "out of memory";
91: COLORREF TextColorTable[16] = {
92: RGB(0,0,0), /* black */
93: RGB(0,0,128), /* dark blue */
94: RGB(0,128,0), /* dark green */
95: RGB(0,128,128), /* dark cyan */
96: RGB(128,0,0), /* dark red */
97: RGB(128,0,128), /* dark magenta */
98: RGB(128,128,0), /* dark yellow */
99: RGB(128,128,128), /* dark grey */
100: RGB(192,192,192), /* light grey */
101: RGB(0,0,255), /* blue */
102: RGB(0,255,0), /* green */
103: RGB(0,255,255), /* cyan */
104: RGB(255,0,0), /* red */
105: RGB(255,0,255), /* magenta */
106: RGB(255,255,0), /* yellow */
107: RGB(255,255,255), /* white */
108: };
109: #define NOTEXT 0xF0
110: #define MARKFORE RGB(255,255,255)
111: #define MARKBACK RGB(0,0,128)
112: #define TextFore(attr) TextColorTable[(attr) & 15]
113: #define TextBack(attr) TextColorTable[(attr>>4) & 15]
114:
115:
116: void WDPROC
117: TextMessage(void)
118: {
119: MSG msg;
120:
121: while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
122: {
1.1.1.2 ! maekawa 123: #if 1 /* HBB 19990505: Petzold says we should check this: */
! 124: if (msg.message == WM_QUIT)
! 125: return;
! 126: #endif
1.1 maekawa 127: TranslateMessage(&msg);
128: DispatchMessage(&msg);
129: }
130: return;
131: }
132:
133:
134:
135: void
136: CreateTextClass(LPTW lptw)
137: {
138: WNDCLASS wndclass;
139: #ifdef WIN32
140: hdllInstance = lptw->hInstance; /* not using a DLL */
141: #endif
142: wndclass.style = CS_HREDRAW | CS_VREDRAW;
143: wndclass.lpfnWndProc = WndTextProc;
144: wndclass.cbClsExtra = 0;
145: wndclass.cbWndExtra = 2 * sizeof(void FAR *);
146: wndclass.hInstance = lptw->hInstance;
147: wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
148: wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
149: wndclass.hbrBackground = NULL;
150: lptw->hbrBackground = CreateSolidBrush(lptw->bSysColors ?
151: GetSysColor(COLOR_WINDOW) : RGB(0,0,0));
152: wndclass.lpszMenuName = NULL;
153: wndclass.lpszClassName = szTextClass;
154: RegisterClass(&wndclass);
155:
156: wndclass.style = CS_HREDRAW | CS_VREDRAW;
157: wndclass.lpfnWndProc = WndParentProc;
158: wndclass.cbClsExtra = 0;
159: wndclass.cbWndExtra = 2 * sizeof(void FAR *);
160: wndclass.hInstance = lptw->hInstance;
161: if (lptw->hIcon)
162: wndclass.hIcon = lptw->hIcon;
163: else
164: wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
165: wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
166: wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
167: wndclass.lpszMenuName = NULL;
168: wndclass.lpszClassName = szParentClass;
169: RegisterClass(&wndclass);
170: }
171:
172:
173: /* make text window */
174: int WDPROC
175: TextInit(LPTW lptw)
176: {
177: RECT rect;
178: HMENU sysmenu;
179: HGLOBAL hglobal;
180: char buf[80];
181:
182: ReadTextIni(lptw);
183:
184: if (!lptw->hPrevInstance)
185: CreateTextClass(lptw);
186:
187: if (lptw->KeyBufSize == 0)
188: lptw->KeyBufSize = 256;
189:
190: if (lptw->ScreenSize.x < ScreenMinSize.x)
191: lptw->ScreenSize.x = ScreenMinSize.x;
192: if (lptw->ScreenSize.y < ScreenMinSize.y)
193: lptw->ScreenSize.y = ScreenMinSize.y;
194:
195: lptw->CursorPos.x = lptw->CursorPos.y = 0;
196: lptw->bFocus = FALSE;
197: lptw->bGetCh = FALSE;
198: lptw->CaretHeight = 0;
199: if (!lptw->nCmdShow)
200: lptw->nCmdShow = SW_SHOWNORMAL;
201: if (!lptw->Attr)
202: lptw->Attr = 0xf0; /* black on white */
203:
204: hglobal = GlobalAlloc(GHND, lptw->ScreenSize.x * lptw->ScreenSize.y);
205: lptw->ScreenBuffer = (BYTE FAR *)GlobalLock(hglobal);
206: if (lptw->ScreenBuffer == (BYTE FAR *)NULL) {
207: MessageBox((HWND)NULL,szNoMemory,(LPSTR)NULL, MB_ICONHAND | MB_SYSTEMMODAL);
208: return(1);
209: }
210: _fmemset(lptw->ScreenBuffer, ' ', lptw->ScreenSize.x * lptw->ScreenSize.y);
211: hglobal = GlobalAlloc(GHND, lptw->ScreenSize.x * lptw->ScreenSize.y);
212: lptw->AttrBuffer = (BYTE FAR *)GlobalLock(hglobal);
213: if (lptw->AttrBuffer == (BYTE FAR *)NULL) {
214: MessageBox((HWND)NULL,szNoMemory,(LPSTR)NULL, MB_ICONHAND | MB_SYSTEMMODAL);
215: return(1);
216: }
217: _fmemset(lptw->AttrBuffer, NOTEXT, lptw->ScreenSize.x * lptw->ScreenSize.y);
218: hglobal = GlobalAlloc(LHND, lptw->KeyBufSize);
219: lptw->KeyBuf = (BYTE FAR *)GlobalLock(hglobal);
220: if (lptw->KeyBuf == (BYTE FAR *)NULL) {
221: MessageBox((HWND)NULL,szNoMemory,(LPSTR)NULL, MB_ICONHAND | MB_SYSTEMMODAL);
222: return(1);
223: }
224: lptw->KeyBufIn = lptw->KeyBufOut = lptw->KeyBuf;
225:
226: lptw->hWndParent = CreateWindow(szParentClass, lptw->Title,
227: WS_OVERLAPPEDWINDOW,
228: lptw->Origin.x, lptw->Origin.y,
229: lptw->Size.x, lptw->Size.y,
230: NULL, NULL, lptw->hInstance, lptw);
231: if (lptw->hWndParent == (HWND)NULL) {
232: MessageBox((HWND)NULL,"Couldn't open parent text window",(LPSTR)NULL, MB_ICONHAND | MB_SYSTEMMODAL);
233: return(1);
234: }
235: GetClientRect(lptw->hWndParent, &rect);
236:
237: lptw->hWndText = CreateWindow(szTextClass, lptw->Title,
238: WS_CHILD | WS_VSCROLL | WS_HSCROLL,
239: 0, lptw->ButtonHeight,
240: rect.right, rect.bottom-lptw->ButtonHeight,
241: lptw->hWndParent, NULL, lptw->hInstance, lptw);
242: if (lptw->hWndText == (HWND)NULL) {
243: MessageBox((HWND)NULL,"Couldn't open text window",(LPSTR)NULL, MB_ICONHAND | MB_SYSTEMMODAL);
244: return(1);
245: }
246:
247: lptw->hPopMenu = CreatePopupMenu();
248: AppendMenu(lptw->hPopMenu, MF_STRING, M_COPY_CLIP, "&Copy to Clipboard");
249: AppendMenu(lptw->hPopMenu, MF_STRING, M_PASTE, "&Paste");
250: #if WINVER >= 0x030a
251: AppendMenu(lptw->hPopMenu, MF_STRING, M_CHOOSE_FONT, "Choose &Font...");
252: #endif
253: AppendMenu(lptw->hPopMenu, MF_STRING | (lptw->bSysColors ? MF_CHECKED : MF_UNCHECKED),
254: M_SYSCOLORS, "&System Colors");
255: if (lptw->IniFile != (LPSTR)NULL) {
256: wsprintf(buf,"&Update %s",lptw->IniFile);
257: AppendMenu(lptw->hPopMenu, MF_STRING, M_WRITEINI, (LPSTR)buf);
258: }
259:
260: sysmenu = GetSystemMenu(lptw->hWndParent,0); /* get the sysmenu */
261: AppendMenu(sysmenu, MF_SEPARATOR, 0, NULL);
262: AppendMenu(sysmenu, MF_POPUP, (UINT)lptw->hPopMenu, "&Options");
263: AppendMenu(sysmenu, MF_STRING, M_ABOUT, "&About");
264:
265: if (lptw->lpmw)
266: LoadMacros(lptw);
267:
268: ShowWindow(lptw->hWndText, SW_SHOWNORMAL);
269: BringWindowToTop(lptw->hWndText);
270: SetFocus(lptw->hWndText);
271: TextMessage();
272: return(0);
273: }
274:
275: /* close a text window */
276: void WDPROC
277: TextClose(LPTW lptw)
278: {
279: HGLOBAL hglobal;
280:
281: /* close window */
282: if (lptw->hWndParent)
283: DestroyWindow(lptw->hWndParent);
284: TextMessage();
285:
286: hglobal = (HGLOBAL)GlobalHandle( SELECTOROF(lptw->ScreenBuffer) );
287: if (hglobal) {
288: GlobalUnlock(hglobal);
289: GlobalFree(hglobal);
290: }
291: hglobal = (HGLOBAL)GlobalHandle( SELECTOROF(lptw->AttrBuffer) );
292: if (hglobal) {
293: GlobalUnlock(hglobal);
294: GlobalFree(hglobal);
295: }
296: hglobal = (HGLOBAL)GlobalHandle( SELECTOROF(lptw->KeyBuf) );
297: if (hglobal) {
298: GlobalUnlock(hglobal);
299: GlobalFree(hglobal);
300: }
301:
302: if (lptw->lpmw)
303: CloseMacros(lptw);
304: lptw->hWndParent = (HWND)NULL;
305: }
306:
307: void
308: WriteTextIni(LPTW lptw)
309: {
310: RECT rect;
311: LPSTR file = lptw->IniFile;
312: LPSTR section = lptw->IniSection;
313: char profile[80];
314: int iconic;
315:
316:
317: if ((file == (LPSTR)NULL) || (section == (LPSTR)NULL))
318: return;
319:
320: iconic = IsIconic(lptw->hWndParent);
321: if (iconic)
322: ShowWindow(lptw->hWndParent, SW_SHOWNORMAL);
323: GetWindowRect(lptw->hWndParent,&rect);
324: wsprintf(profile, "%d %d", rect.left, rect.top);
325: WritePrivateProfileString(section, "TextOrigin", profile, file);
326: wsprintf(profile, "%d %d", rect.right-rect.left, rect.bottom-rect.top);
327: WritePrivateProfileString(section, "TextSize", profile, file);
328: wsprintf(profile, "%d", iconic);
329: WritePrivateProfileString(section, "TextMinimized", profile, file);
330: wsprintf(profile, "%s,%d", lptw->fontname, lptw->fontsize);
331: WritePrivateProfileString(section, "TextFont", profile, file);
332: wsprintf(profile, "%d", lptw->bSysColors);
333: WritePrivateProfileString(section, "SysColors", profile, file);
334: if (iconic)
335: ShowWindow(lptw->hWndParent, SW_SHOWMINIMIZED);
336: return;
337: }
338:
339: void
340: ReadTextIni(LPTW lptw)
341: {
342: LPSTR file = lptw->IniFile;
343: LPSTR section = lptw->IniSection;
344: char profile[81];
345: LPSTR p;
346: BOOL bOKINI;
347:
348: bOKINI = (file != (LPSTR)NULL) && (section != (LPSTR)NULL);
349: profile[0] = '\0';
350:
351: if (bOKINI)
352: GetPrivateProfileString(section, "TextOrigin", "", profile, 80, file);
353: if ( (p = GetInt(profile, (LPINT)&lptw->Origin.x)) == NULL)
354: lptw->Origin.x = CW_USEDEFAULT;
355: if ( (p = GetInt(p, (LPINT)&lptw->Origin.y)) == NULL)
356: lptw->Origin.y = CW_USEDEFAULT;
357: if ( (file != (LPSTR)NULL) && (section != (LPSTR)NULL) )
358: GetPrivateProfileString(section, "TextSize", "", profile, 80, file);
359: if ( (p = GetInt(profile, (LPINT)&lptw->Size.x)) == NULL)
360: lptw->Size.x = CW_USEDEFAULT;
361: if ( (p = GetInt(p, (LPINT)&lptw->Size.y)) == NULL)
362: lptw->Size.y = CW_USEDEFAULT;
363:
364: if (bOKINI)
365: GetPrivateProfileString(section, "TextFont", "", profile, 80, file);
366: {
367: char FAR *size;
368: size = _fstrchr(profile,',');
369: if (size) {
370: *size++ = '\0';
371: if ( (p = GetInt(size, &lptw->fontsize)) == NULL)
372: lptw->fontsize = TEXTFONTSIZE;
373: }
374: _fstrcpy(lptw->fontname, profile);
375: if (lptw->fontsize == 0)
376: lptw->fontsize = TEXTFONTSIZE;
377: if (!(*lptw->fontname))
378: _fstrcpy(lptw->fontname,TEXTFONTNAME);
379: }
380:
381: if (bOKINI) {
382: int iconic;
383: GetPrivateProfileString(section, "TextMinimized", "", profile, 80, file);
384: if ((p = GetInt(profile, &iconic)) == NULL)
385: iconic = 0;
386: if (iconic)
387: lptw->nCmdShow = SW_SHOWMINIMIZED;
388: }
389: lptw->bSysColors = FALSE;
390: GetPrivateProfileString(section, "SysColors", "", profile, 80, file);
391: if ((p = GetInt(profile, &lptw->bSysColors)) == NULL)
392: lptw->bSysColors = 0;
393: }
394:
395:
396: /* Bring Cursor into text window */
397: void WDPROC
398: TextToCursor(LPTW lptw)
399: {
400: int nXinc=0;
401: int nYinc=0;
402: int cxCursor;
403: int cyCursor;
404: cyCursor = lptw->CursorPos.y * lptw->CharSize.y;
405: if ( (cyCursor + lptw->CharSize.y > lptw->ScrollPos.y + lptw->ClientSize.y)
406: || (cyCursor < lptw->ScrollPos.y) ) {
407: nYinc = max(0, cyCursor + lptw->CharSize.y - lptw->ClientSize.y) - lptw->ScrollPos.y;
408: nYinc = min(nYinc, lptw->ScrollMax.y - lptw->ScrollPos.y);
409: }
410: cxCursor = lptw->CursorPos.x * lptw->CharSize.x;
411: if ( (cxCursor + lptw->CharSize.x > lptw->ScrollPos.x + lptw->ClientSize.x)
412: || (cxCursor < lptw->ScrollPos.x) ) {
413: nXinc = max(0, cxCursor + lptw->CharSize.x - lptw->ClientSize.x/2) - lptw->ScrollPos.x;
414: nXinc = min(nXinc, lptw->ScrollMax.x - lptw->ScrollPos.x);
415: }
416: if (nYinc || nXinc) {
417: lptw->ScrollPos.y += nYinc;
418: lptw->ScrollPos.x += nXinc;
419: ScrollWindow(lptw->hWndText,-nXinc,-nYinc,NULL,NULL);
420: SetScrollPos(lptw->hWndText,SB_VERT,lptw->ScrollPos.y,TRUE);
421: SetScrollPos(lptw->hWndText,SB_HORZ,lptw->ScrollPos.x,TRUE);
422: UpdateWindow(lptw->hWndText);
423: }
424: }
425:
426: void
427: NewLine(LPTW lptw)
428: {
429: lptw->CursorPos.x = 0;
430: lptw->CursorPos.y++;
431: if (lptw->CursorPos.y >= lptw->ScreenSize.y) {
432: int i = lptw->ScreenSize.x * (lptw->ScreenSize.y - 1);
433: _fmemmove(lptw->ScreenBuffer, lptw->ScreenBuffer+lptw->ScreenSize.x, i);
434: _fmemset(lptw->ScreenBuffer + i, ' ', lptw->ScreenSize.x);
435: _fmemmove(lptw->AttrBuffer, lptw->AttrBuffer+lptw->ScreenSize.x, i);
436: _fmemset(lptw->AttrBuffer + i, NOTEXT, lptw->ScreenSize.x);
437: lptw->CursorPos.y--;
438: ScrollWindow(lptw->hWndText,0,-lptw->CharSize.y,NULL,NULL);
439: lptw->MarkBegin.y--;
440: lptw->MarkEnd.y--;
441: LimitMark(lptw, &lptw->MarkBegin);
442: LimitMark(lptw, &lptw->MarkEnd);
443: UpdateWindow(lptw->hWndText);
444: }
445: if (lptw->CursorFlag)
446: TextToCursor(lptw);
447: TextMessage();
448: }
449:
450: /* Update count characters in window at cursor position */
451: /* Updates cursor position */
452: void
453: UpdateText(LPTW lptw, int count)
454: {
455: HDC hdc;
456: int xpos, ypos;
457: xpos = lptw->CursorPos.x*lptw->CharSize.x - lptw->ScrollPos.x;
458: ypos = lptw->CursorPos.y*lptw->CharSize.y - lptw->ScrollPos.y;
459: hdc = GetDC(lptw->hWndText);
460: if (lptw->bSysColors) {
461: SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
462: SetBkColor(hdc, GetSysColor(COLOR_WINDOW));
463: }
464: else {
465: SetTextColor(hdc, TextFore(lptw->Attr));
466: SetBkColor(hdc, TextBack(lptw->Attr));
467: }
468: SelectObject(hdc, lptw->hfont);
469: TextOut(hdc,xpos,ypos,
470: (LPSTR)(lptw->ScreenBuffer + lptw->CursorPos.y*lptw->ScreenSize.x +
471: lptw->CursorPos.x), count);
472: (void)ReleaseDC(lptw->hWndText,hdc);
473: lptw->CursorPos.x += count;
474: if (lptw->CursorPos.x >= lptw->ScreenSize.x)
475: NewLine(lptw);
476: }
477:
478: int WDPROC
479: TextPutCh(LPTW lptw, BYTE ch)
480: {
481: int pos;
482: switch(ch) {
483: case '\r':
484: lptw->CursorPos.x = 0;
485: if (lptw->CursorFlag)
486: TextToCursor(lptw);
487: break;
488: case '\n':
489: NewLine(lptw);
490: break;
491: case 7:
492: MessageBeep(0xFFFFFFFF);
493: if (lptw->CursorFlag)
494: TextToCursor(lptw);
495: break;
496: case '\t':
497: {
498: int n;
499: for ( n = 8 - (lptw->CursorPos.x % 8); n>0; n-- )
500: TextPutCh(lptw, ' ');
501: }
502: break;
503: case 0x08:
504: case 0x7f:
505: lptw->CursorPos.x--;
506: if (lptw->CursorPos.x < 0) {
507: lptw->CursorPos.x = lptw->ScreenSize.x - 1;
508: lptw->CursorPos.y--;
509: }
510: if (lptw->CursorPos.y < 0)
511: lptw->CursorPos.y = 0;
512: break;
513: default:
514: pos = lptw->CursorPos.y*lptw->ScreenSize.x + lptw->CursorPos.x;
515: lptw->ScreenBuffer[pos] = ch;
516: lptw->AttrBuffer[pos] = lptw->Attr;
517: UpdateText(lptw, 1);
518: }
519: return ch;
520: }
521:
522: void
523: TextPutStr(LPTW lptw, LPSTR str)
524: {
525: BYTE FAR *p, FAR *pa;
526: int count, limit;
527: while (*str) {
528: p = lptw->ScreenBuffer + lptw->CursorPos.y*lptw->ScreenSize.x + lptw->CursorPos.x;
529: pa = lptw->AttrBuffer + lptw->CursorPos.y*lptw->ScreenSize.x + lptw->CursorPos.x;
530: limit = lptw->ScreenSize.x - lptw->CursorPos.x;
531: for (count=0; (count < limit) && *str && (isprint(*str) || *str=='\t'); count++) {
532: if (*str=='\t') {
533: int n;
534: for ( n = 8 - ((lptw->CursorPos.x+count) % 8); (count < limit) & (n>0); n--, count++ ) {
535: *p++ = ' ';
536: *pa++ = lptw->Attr;
537: }
538: str++;
539: count--;
540: }
541: else {
542: *p++ = *str++;
543: *pa++ = lptw->Attr;
544: }
545: }
546: if (count>0) {
547: UpdateText(lptw, count);
548: }
549: if (*str=='\n') {
550: NewLine(lptw);
551: str++;
552: }
553: else if (*str && !isprint(*str) && *str!='\t') {
554: TextPutCh(lptw, *str++);
555: }
556: }
557: }
558:
559:
560: void
561: LimitMark(LPTW lptw, POINT FAR *lppt)
562: {
563: if (lppt->x < 0)
564: lppt->x = 0;
565: if (lppt->y < 0) {
566: lppt->x = 0;
567: lppt->y = 0;
568: }
569: if (lppt->x > lptw->ScreenSize.x)
570: lppt->x = lptw->ScreenSize.x;
571: if (lppt->y >= lptw->ScreenSize.y) {
572: lppt->x = 0;
573: lppt->y = lptw->ScreenSize.y;
574: }
575: }
576:
577: void
578: ClearMark(LPTW lptw, POINT pt)
579: {
580: RECT rect1, rect2, rect3;
581: int tmp;
582: if ((lptw->MarkBegin.x != lptw->MarkEnd.x) ||
583: (lptw->MarkBegin.y != lptw->MarkEnd.y) ) {
584: if (lptw->MarkBegin.x > lptw->MarkEnd.x) {
585: tmp = lptw->MarkBegin.x;
586: lptw->MarkBegin.x = lptw->MarkEnd.x;
587: lptw->MarkEnd.x = tmp;
588: }
589: if (lptw->MarkBegin.y > lptw->MarkEnd.y) {
590: tmp = lptw->MarkBegin.y;
591: lptw->MarkBegin.y = lptw->MarkEnd.y;
592: lptw->MarkEnd.y = tmp;
593: }
594: /* calculate bounding rectangle in character coordinates */
595: if (lptw->MarkBegin.y != lptw->MarkEnd.y) {
596: rect1.left = 0;
597: rect1.right = lptw->ScreenSize.x;
598: }
599: else {
600: rect1.left = lptw->MarkBegin.x;
601: rect1.right = lptw->MarkEnd.x + 1;
602: }
603: rect1.top = lptw->MarkBegin.y;
604: rect1.bottom = lptw->MarkEnd.y + 1;
605: /* now convert to client coordinates */
606: rect1.left = rect1.left * lptw->CharSize.x - lptw->ScrollPos.x;
607: rect1.right = rect1.right * lptw->CharSize.x - lptw->ScrollPos.x;
608: rect1.top = rect1.top * lptw->CharSize.y - lptw->ScrollPos.y;
609: rect1.bottom = rect1.bottom * lptw->CharSize.y - lptw->ScrollPos.y;
610: /* get client rect and calculate intersection */
611: GetClientRect(lptw->hWndText, &rect2);
612: IntersectRect(&rect3, &rect1, &rect2);
613: /* update window if necessary */
614: if (!IsRectEmpty(&rect3)) {
615: InvalidateRect(lptw->hWndText, &rect3, TRUE);
616: }
617: }
618: LimitMark(lptw, &pt);
619: lptw->MarkBegin.x = lptw->MarkEnd.x = pt.x;
620: lptw->MarkBegin.y = lptw->MarkEnd.y = pt.y;
621: UpdateWindow(lptw->hWndText);
622: }
623:
624:
625: /* output a line including attribute changes as needed */
626: void
627: DoLine(LPTW lptw, HDC hdc, int xpos, int ypos, int offset, int count)
628: {
629: BYTE FAR *pa, attr;
630: int idx, num;
631: pa = lptw->AttrBuffer + offset;
632: if ((offset < 0) || (offset >= lptw->ScreenSize.x*lptw->ScreenSize.y))
633: MessageBox((HWND)NULL, "panic", "panic", MB_OK | MB_ICONEXCLAMATION);
634: idx = 0;
635: num = count;
636: while (num > 0) {
637: attr = *pa;
638: while ((num > 0) && (attr == *pa)) {
639: /* skip over bytes with same attribute */
640: num--;
641: pa++;
642: }
643: if (lptw->bSysColors) {
644: SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
645: SetBkColor(hdc, GetSysColor(COLOR_WINDOW));
646: }
647: else {
648: SetTextColor(hdc, TextFore(attr));
649: SetBkColor(hdc, TextBack(attr));
650: }
651: TextOut(hdc,xpos,ypos, (LPSTR)(lptw->ScreenBuffer + offset + idx),
652: count-num-idx);
653: xpos += lptw->CharSize.x * (count-num-idx);
654: idx = count-num;
655: }
656: }
657:
658: void
659: DoMark(LPTW lptw, POINT pt, POINT end, BOOL mark)
660: {
661: int xpos, ypos;
662: HDC hdc;
663: int count;
664: int offset;
665: offset = lptw->ScreenSize.x * pt.y + pt.x;
666: hdc = GetDC(lptw->hWndText);
667: SelectObject(hdc, lptw->hfont);
668: if (lptw->bSysColors) {
669: SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT));
670: SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT));
671: }
672: else {
673: SetTextColor(hdc, MARKFORE);
674: SetBkColor(hdc, MARKBACK);
675: }
676: while (pt.y < end.y) {
677: /* multiple lines */
678: xpos = pt.x*lptw->CharSize.x - lptw->ScrollPos.x;
679: ypos = pt.y*lptw->CharSize.y - lptw->ScrollPos.y;
680: count = lptw->ScreenSize.x - pt.x;
681: if (mark)
682: TextOut(hdc,xpos,ypos, (LPSTR)(lptw->ScreenBuffer + offset), count);
683: else {
684: DoLine(lptw, hdc, xpos, ypos, offset, count);
685: if (lptw->bSysColors) {
686: SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT));
687: SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT));
688: }
689: else {
690: SetTextColor(hdc, MARKFORE);
691: SetBkColor(hdc, MARKBACK);
692: }
693: }
694: offset += count;
695: pt.y++;
696: pt.x=0;
697: }
698: /* partial line */
699: xpos = pt.x*lptw->CharSize.x - lptw->ScrollPos.x;
700: ypos = pt.y*lptw->CharSize.y - lptw->ScrollPos.y;
701: count = end.x - pt.x;
702: if (end.y != lptw->ScreenSize.y) {
703: if (mark)
704: TextOut(hdc,xpos,ypos, (LPSTR)(lptw->ScreenBuffer + offset), count);
705: else
706: DoLine(lptw, hdc, xpos, ypos, offset, count);
707: }
708: (void)ReleaseDC(lptw->hWndText,hdc);
709: }
710:
711: void
712: UpdateMark(LPTW lptw, POINT pt)
713: {
714: int begin, point, end;
715: LimitMark(lptw, &pt);
716: begin = lptw->ScreenSize.x*lptw->MarkBegin.y + lptw->MarkBegin.x;
717: point = lptw->ScreenSize.x*pt.y + pt.x;
718: end = lptw->ScreenSize.x*lptw->MarkEnd.y + lptw->MarkEnd.x;
719:
720: if (begin <= end) {
721: /* forward mark */
722: if (point >= end) {
723: /* extend marked area */
724: DoMark(lptw, lptw->MarkEnd, pt, TRUE);
725: }
726: else if (point >= begin) {
727: /* retract marked area */
728: DoMark(lptw, pt, lptw->MarkEnd, FALSE);
729: }
730: else { /* retract and reverse */
731: DoMark(lptw, lptw->MarkBegin, lptw->MarkEnd, FALSE);
732: DoMark(lptw, pt, lptw->MarkBegin, TRUE);
733: }
734: }
735: else {
736: /* reverse mark */
737: if (point <= end) {
738: /* extend marked area */
739: DoMark(lptw, pt, lptw->MarkEnd, TRUE);
740: }
741: else if (point <= begin) {
742: /* retract marked area */
743: DoMark(lptw, lptw->MarkEnd, pt, FALSE);
744: }
745: else { /* retract and reverse */
746: DoMark(lptw, lptw->MarkEnd, lptw->MarkBegin, FALSE);
747: DoMark(lptw, lptw->MarkBegin, pt, TRUE);
748: }
749: }
750: lptw->MarkEnd.x = pt.x;
751: lptw->MarkEnd.y = pt.y;
752: }
753:
754:
755: #if WINVER >= 0x030a
756: /* Windows 3.1 drag-drop feature */
757: char szFile[80];
758: void
759: DragFunc(LPTW lptw, HDROP hdrop)
760: {
761: int i, cFiles;
762: LPSTR p;
763: if ( (lptw->DragPre==(LPSTR)NULL) || (lptw->DragPost==(LPSTR)NULL) )
764: return;
765: cFiles = DragQueryFile(hdrop, 0xffff, (LPSTR)NULL, 0);
766: for (i=0; i<cFiles; i++) {
767: DragQueryFile(hdrop, i, szFile, 80);
768: for (p=lptw->DragPre; *p; p++)
769: SendMessage(lptw->hWndText,WM_CHAR,*p,1L);
770: for (p=szFile; *p; p++)
771: SendMessage(lptw->hWndText,WM_CHAR,*p,1L);
772: for (p=lptw->DragPost; *p; p++)
773: SendMessage(lptw->hWndText,WM_CHAR,*p,1L);
774: }
775: DragFinish(hdrop);
776: }
777: #endif
778:
779:
780: void
781: TextCopyClip(LPTW lptw)
782: {
783: int size, count;
784: HGLOBAL hGMem;
785: LPSTR cbuf, cp;
786: POINT pt, end;
787: TEXTMETRIC tm;
788: UINT type;
789: HDC hdc;
790:
791: if ((lptw->MarkBegin.x == lptw->MarkEnd.x) &&
792: (lptw->MarkBegin.y == lptw->MarkEnd.y) ) {
793: /* copy user text */
794: return;
795: }
796:
797: size = (lptw->MarkEnd.y - lptw->MarkBegin.y + 1)
798: * (lptw->ScreenSize.x + 2) + 1;
799: hGMem = GlobalAlloc(GMEM_MOVEABLE, (DWORD)size);
800: cbuf = cp = (LPSTR)GlobalLock(hGMem);
801: if (cp == (LPSTR)NULL)
802: return;
803:
804: pt.x = lptw->MarkBegin.x;
805: pt.y = lptw->MarkBegin.y;
806: end.x = lptw->MarkEnd.x;
807: end.y = lptw->MarkEnd.y;
808:
809: while (pt.y < end.y) {
810: /* copy to global buffer */
811: count = lptw->ScreenSize.x - pt.x;
812: _fmemcpy(cp, lptw->ScreenBuffer + lptw->ScreenSize.x*pt.y+pt.x, count);
813: /* remove trailing spaces */
814: for (count=count-1; count>=0; count--) {
815: if (cp[count]!=' ')
816: break;
817: cp[count] = '\0';
818: }
819: cp[++count] = '\r';
820: cp[++count] = '\n';
821: cp[++count] = '\0';
822: cp += count;
823: pt.y++;
824: pt.x=0;
825: }
826: /* partial line */
827: count = end.x - pt.x;
828: if (end.y != lptw->ScreenSize.y) {
829: _fmemcpy(cp, lptw->ScreenBuffer + lptw->ScreenSize.x*pt.y+pt.x, count);
830: cp[count] = '\0';
831: }
832: size = _fstrlen(cbuf) + 1;
833: GlobalUnlock(hGMem);
834: hGMem = GlobalReAlloc(hGMem, (DWORD)size, GMEM_MOVEABLE);
835: /* find out what type to put into clipboard */
836: hdc = GetDC(lptw->hWndText);
837: SelectObject(hdc, lptw->hfont);
838: GetTextMetrics(hdc,(TEXTMETRIC FAR *)&tm);
839: if (tm.tmCharSet == OEM_CHARSET)
840: type = CF_OEMTEXT;
841: else
842: type = CF_TEXT;
843: ReleaseDC(lptw->hWndText, hdc);
844: /* give buffer to clipboard */
845: OpenClipboard(lptw->hWndParent);
846: EmptyClipboard();
847: SetClipboardData(type, hGMem);
848: CloseClipboard();
849: }
850:
851: void
852: TextMakeFont(LPTW lptw)
853: {
854: LOGFONT lf;
855: TEXTMETRIC tm;
856: LPSTR p;
857: HDC hdc;
858:
859: hdc = GetDC(lptw->hWndText);
860: _fmemset(&lf, 0, sizeof(LOGFONT));
861: _fstrncpy(lf.lfFaceName,lptw->fontname,LF_FACESIZE);
862: lf.lfHeight = -MulDiv(lptw->fontsize, GetDeviceCaps(hdc, LOGPIXELSY), 72);
863: lf.lfPitchAndFamily = FIXED_PITCH;
864: lf.lfCharSet = DEFAULT_CHARSET;
865: if ( (p = _fstrstr(lptw->fontname," Italic")) != (LPSTR)NULL ) {
866: lf.lfFaceName[ (unsigned int)(p-lptw->fontname) ] = '\0';
867: lf.lfItalic = TRUE;
868: }
869: if ( (p = _fstrstr(lptw->fontname," Bold")) != (LPSTR)NULL ) {
870: lf.lfFaceName[ (unsigned int)(p-lptw->fontname) ] = '\0';
871: lf.lfWeight = FW_BOLD;
872: }
873: if (lptw->hfont != 0)
874: DeleteObject(lptw->hfont);
875: lptw->hfont = CreateFontIndirect((LOGFONT FAR *)&lf);
876: /* get text size */
877: SelectObject(hdc, lptw->hfont);
878: GetTextMetrics(hdc,(TEXTMETRIC FAR *)&tm);
879: lptw->CharSize.y = tm.tmHeight;
880: lptw->CharSize.x = tm.tmAveCharWidth;
881: lptw->CharAscent = tm.tmAscent;
882: if (lptw->bFocus)
883: CreateCaret(lptw->hWndText, 0, lptw->CharSize.x, 2+lptw->CaretHeight);
884: ReleaseDC(lptw->hWndText, hdc);
885: return;
886: }
887:
888: void
889: TextSelectFont(LPTW lptw) {
890: #if WINVER >= 0x030a
891: LOGFONT lf;
892: CHOOSEFONT cf;
893: HDC hdc;
894: char lpszStyle[LF_FACESIZE];
895: LPSTR p;
896:
897: /* Set all structure fields to zero. */
898: _fmemset(&cf, 0, sizeof(CHOOSEFONT));
899: _fmemset(&lf, 0, sizeof(LOGFONT));
900: cf.lStructSize = sizeof(CHOOSEFONT);
901: cf.hwndOwner = lptw->hWndParent;
902: _fstrncpy(lf.lfFaceName,lptw->fontname,LF_FACESIZE);
903: if ( (p = _fstrstr(lptw->fontname," Bold")) != (LPSTR)NULL ) {
904: _fstrncpy(lpszStyle,p+1,LF_FACESIZE);
905: lf.lfFaceName[ (unsigned int)(p-lptw->fontname) ] = '\0';
906: }
907: else if ( (p = _fstrstr(lptw->fontname," Italic")) != (LPSTR)NULL ) {
908: _fstrncpy(lpszStyle,p+1,LF_FACESIZE);
909: lf.lfFaceName[ (unsigned int)(p-lptw->fontname) ] = '\0';
910: }
911: else
912: _fstrcpy(lpszStyle,"Regular");
913: cf.lpszStyle = lpszStyle;
914: hdc = GetDC(lptw->hWndText);
915: lf.lfHeight = -MulDiv(lptw->fontsize, GetDeviceCaps(hdc, LOGPIXELSY), 72);
916: ReleaseDC(lptw->hWndText, hdc);
917: lf.lfPitchAndFamily = FIXED_PITCH;
918: cf.lpLogFont = &lf;
919: cf.nFontType = SCREEN_FONTTYPE;
920: cf.Flags = CF_SCREENFONTS | CF_FIXEDPITCHONLY | CF_INITTOLOGFONTSTRUCT | CF_USESTYLE;
921: if (ChooseFont(&cf)) {
922: RECT rect;
923: _fstrcpy(lptw->fontname,lf.lfFaceName);
924: lptw->fontsize = cf.iPointSize / 10;
925: if (cf.nFontType & BOLD_FONTTYPE)
926: lstrcat(lptw->fontname," Bold");
927: if (cf.nFontType & ITALIC_FONTTYPE)
928: lstrcat(lptw->fontname," Italic");
929: TextMakeFont(lptw);
930: /* force a window update */
931: GetClientRect(lptw->hWndText, (LPRECT) &rect);
932: SendMessage(lptw->hWndText, WM_SIZE, SIZE_RESTORED,
933: MAKELPARAM(rect.right-rect.left, rect.bottom-rect.top));
934: GetClientRect(lptw->hWndText, (LPRECT) &rect);
935: InvalidateRect(lptw->hWndText, (LPRECT) &rect, 1);
936: UpdateWindow(lptw->hWndText);
937: }
938: #endif
939: }
940:
941:
942: /* parent overlapped window */
943: LRESULT CALLBACK WINEXPORT
944: WndParentProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
945: {
946: HDC hdc;
947: PAINTSTRUCT ps;
948: RECT rect;
949: LPTW lptw;
950:
951: lptw = (LPTW)GetWindowLong(hwnd, 0);
952:
953: switch(message) {
954: case WM_SYSCOMMAND:
955: switch(LOWORD(wParam))
956: {
957: case M_COPY_CLIP:
958: case M_PASTE:
959: case M_CHOOSE_FONT:
960: case M_SYSCOLORS:
961: case M_WRITEINI:
962: case M_ABOUT:
963: SendMessage(lptw->hWndText, WM_COMMAND, wParam, lParam);
964: }
965: break;
966: case WM_SETFOCUS:
967: if (IsWindow(lptw->hWndText)) {
968: SetFocus(lptw->hWndText);
969: return(0);
970: }
971: break;
972: case WM_GETMINMAXINFO:
973: {
974: POINT FAR * MMinfo = (POINT FAR *)lParam;
975: TEXTMETRIC tm;
976: hdc = GetDC(hwnd);
977: SelectObject(hdc, GetStockObject(OEM_FIXED_FONT));
978: GetTextMetrics(hdc,(LPTEXTMETRIC)&tm);
979: ReleaseDC(hwnd,hdc);
980: /* minimum size */
981: MMinfo[3].x = ScreenMinSize.x*tm.tmAveCharWidth
982: + GetSystemMetrics(SM_CXVSCROLL) + 2*GetSystemMetrics(SM_CXFRAME);
983: MMinfo[3].y = ScreenMinSize.y*tm.tmHeight
984: + GetSystemMetrics(SM_CYHSCROLL) + 2*GetSystemMetrics(SM_CYFRAME)
985: + GetSystemMetrics(SM_CYCAPTION);
986: }
987: return(0);
988: case WM_SIZE:
989: SetWindowPos(lptw->hWndText, (HWND)NULL, 0, lptw->ButtonHeight,
990: LOWORD(lParam), HIWORD(lParam)-lptw->ButtonHeight,
991: SWP_NOZORDER | SWP_NOACTIVATE);
992: return(0);
993: case WM_COMMAND:
994: if (IsWindow(lptw->hWndText))
995: SetFocus(lptw->hWndText);
996: SendMessage(lptw->hWndText, message, wParam, lParam); /* pass on menu commands */
997: return(0);
998: case WM_PAINT:
999: {
1000: hdc = BeginPaint(hwnd, &ps);
1001: if (lptw->ButtonHeight) {
1002: HBRUSH hbrush;
1003: GetClientRect(hwnd, &rect);
1004: hbrush = CreateSolidBrush(GetSysColor(COLOR_BTNSHADOW));
1005: rect.bottom = lptw->ButtonHeight-1;
1006: FillRect(hdc, &rect, hbrush);
1007: DeleteObject(hbrush);
1008: SelectObject(hdc, GetStockObject(BLACK_PEN));
1009: MoveTo(hdc, rect.left, lptw->ButtonHeight-1);
1010: LineTo(hdc, rect.right, lptw->ButtonHeight-1);
1011: }
1012: EndPaint(hwnd, &ps);
1013: return 0;
1014: }
1015: #if WINVER >= 0x030a
1016: case WM_DROPFILES:
1017: {
1018: WORD version = LOWORD(GetVersion());
1019: if ((LOBYTE(version)*100 + HIBYTE(version)) >= 310)
1020: DragFunc(lptw, (HDROP)wParam);
1021: }
1022: break;
1023: #endif
1024: case WM_CREATE:
1025: {
1026: RECT crect, wrect;
1027: TEXTMETRIC tm;
1028: lptw = ((CREATESTRUCT FAR *)lParam)->lpCreateParams;
1029: SetWindowLong(hwnd, 0, (LONG)lptw);
1030: lptw->hWndParent = hwnd;
1031: /* get character size */
1032: TextMakeFont(lptw);
1033: hdc = GetDC(hwnd);
1034: SelectObject(hdc, lptw->hfont);
1035: GetTextMetrics(hdc,(LPTEXTMETRIC)&tm);
1036: lptw->CharSize.y = tm.tmHeight;
1037: lptw->CharSize.x = tm.tmAveCharWidth;
1038: lptw->CharAscent = tm.tmAscent;
1039: ReleaseDC(hwnd,hdc);
1040: GetClientRect(hwnd, &crect);
1041: if ( lptw->CharSize.x*lptw->ScreenSize.x < crect.right ) {
1042: /* shrink x size */
1043: GetWindowRect(lptw->hWndParent,&wrect);
1044: MoveWindow(lptw->hWndParent, wrect.left, wrect.top,
1045: wrect.right-wrect.left + (lptw->CharSize.x*lptw->ScreenSize.x - crect.right),
1046: wrect.bottom-wrect.top,
1047: TRUE);
1048: }
1049: if ( lptw->CharSize.y*lptw->ScreenSize.y < crect.bottom ) {
1050: /* shrink y size */
1051: GetWindowRect(lptw->hWndParent,&wrect);
1052: MoveWindow(lptw->hWndParent, wrect.left, wrect.top,
1053: wrect.right-wrect.left,
1054: wrect.bottom-wrect.top + (lptw->CharSize.y*lptw->ScreenSize.y+lptw->ButtonHeight - crect.bottom),
1055: TRUE);
1056: }
1057: }
1058: #if WINVER >= 0x030a
1059: {
1060: WORD version = LOWORD(GetVersion());
1061: if ((LOBYTE(version)*100 + HIBYTE(version)) >= 310)
1062: if ( (lptw->DragPre!=(LPSTR)NULL) && (lptw->DragPost!=(LPSTR)NULL) )
1063: DragAcceptFiles(hwnd, TRUE);
1064: }
1065: #endif
1066: break;
1067: case WM_DESTROY:
1068: #if WINVER >= 0x030a
1069: {
1070: WORD version = LOWORD(GetVersion());
1071: if ((LOBYTE(version)*100 + HIBYTE(version)) >= 310)
1072: DragAcceptFiles(hwnd, FALSE);
1073: }
1074: #endif
1075: DeleteObject(lptw->hfont);
1076: lptw->hfont = 0;
1077: break;
1078: case WM_CLOSE:
1079: if (lptw->shutdown) {
1080: FARPROC lpShutDown = lptw->shutdown;
1081: (*lpShutDown)();
1082: }
1083: break;
1084: }
1085: return DefWindowProc(hwnd, message, wParam, lParam);
1086: }
1087:
1088: /* child text window */
1089: LRESULT CALLBACK WINEXPORT
1090: WndTextProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
1091: {
1092: HDC hdc;
1093: PAINTSTRUCT ps;
1094: RECT rect;
1095: int nYinc, nXinc;
1096: LPTW lptw;
1097:
1098: lptw = (LPTW)GetWindowLong(hwnd, 0);
1099:
1100: switch(message) {
1101: case WM_SETFOCUS:
1102: lptw->bFocus = TRUE;
1103: CreateCaret(hwnd, 0, lptw->CharSize.x, 2+lptw->CaretHeight);
1104: SetCaretPos(lptw->CursorPos.x*lptw->CharSize.x - lptw->ScrollPos.x,
1105: lptw->CursorPos.y*lptw->CharSize.y + lptw->CharAscent
1106: - lptw->CaretHeight - lptw->ScrollPos.y);
1107: if (lptw->bGetCh)
1108: ShowCaret(hwnd);
1109: break;
1110: case WM_KILLFOCUS:
1111: DestroyCaret();
1112: lptw->bFocus = FALSE;
1113: break;
1114: case WM_SIZE:
1115: lptw->ClientSize.y = HIWORD(lParam);
1116: lptw->ClientSize.x = LOWORD(lParam);
1117:
1118: lptw->ScrollMax.y = max(0, lptw->CharSize.y*lptw->ScreenSize.y - lptw->ClientSize.y);
1119: lptw->ScrollPos.y = min(lptw->ScrollPos.y, lptw->ScrollMax.y);
1120:
1121: SetScrollRange(hwnd, SB_VERT, 0, lptw->ScrollMax.y, FALSE);
1122: SetScrollPos(hwnd, SB_VERT, lptw->ScrollPos.y, TRUE);
1123:
1124: lptw->ScrollMax.x = max(0, lptw->CharSize.x*lptw->ScreenSize.x - lptw->ClientSize.x);
1125: lptw->ScrollPos.x = min(lptw->ScrollPos.x, lptw->ScrollMax.x);
1126:
1127: SetScrollRange(hwnd, SB_HORZ, 0, lptw->ScrollMax.x, FALSE);
1128: SetScrollPos(hwnd, SB_HORZ, lptw->ScrollPos.x, TRUE);
1129:
1130: if (lptw->bFocus && lptw->bGetCh) {
1131: SetCaretPos(lptw->CursorPos.x*lptw->CharSize.x - lptw->ScrollPos.x,
1132: lptw->CursorPos.y*lptw->CharSize.y + lptw->CharAscent
1133: - lptw->CaretHeight - lptw->ScrollPos.y);
1134: ShowCaret(hwnd);
1135: }
1136: return(0);
1137: case WM_VSCROLL:
1138: switch(LOWORD(wParam)) {
1139: case SB_TOP:
1140: nYinc = -lptw->ScrollPos.y;
1141: break;
1142: case SB_BOTTOM:
1143: nYinc = lptw->ScrollMax.y - lptw->ScrollPos.y;
1144: break;
1145: case SB_LINEUP:
1146: nYinc = -lptw->CharSize.y;
1147: break;
1148: case SB_LINEDOWN:
1149: nYinc = lptw->CharSize.y;
1150: break;
1151: case SB_PAGEUP:
1152: nYinc = min(-1,-lptw->ClientSize.y);
1153: break;
1154: case SB_PAGEDOWN:
1155: nYinc = max(1,lptw->ClientSize.y);
1156: break;
1157: case SB_THUMBPOSITION:
1158: nYinc = LOWORD(lParam) - lptw->ScrollPos.y;
1159: break;
1160: default:
1161: nYinc = 0;
1162: }
1163: if ( (nYinc = max(-lptw->ScrollPos.y,
1164: min(nYinc, lptw->ScrollMax.y - lptw->ScrollPos.y)))
1165: != 0 ) {
1166: lptw->ScrollPos.y += nYinc;
1167: ScrollWindow(hwnd,0,-nYinc,NULL,NULL);
1168: SetScrollPos(hwnd,SB_VERT,lptw->ScrollPos.y,TRUE);
1169: UpdateWindow(hwnd);
1170: }
1171: return(0);
1172: case WM_HSCROLL:
1173: switch(LOWORD(wParam)) {
1174: case SB_LINEUP:
1175: nXinc = -lptw->CharSize.x;
1176: break;
1177: case SB_LINEDOWN:
1178: nXinc = lptw->CharSize.x;
1179: break;
1180: case SB_PAGEUP:
1181: nXinc = min(-1,-lptw->ClientSize.x);
1182: break;
1183: case SB_PAGEDOWN:
1184: nXinc = max(1,lptw->ClientSize.x);
1185: break;
1186: case SB_THUMBPOSITION:
1187: nXinc = LOWORD(lParam) - lptw->ScrollPos.x;
1188: break;
1189: default:
1190: nXinc = 0;
1191: }
1192: if ( (nXinc = max(-lptw->ScrollPos.x,
1193: min(nXinc, lptw->ScrollMax.x - lptw->ScrollPos.x)))
1194: != 0 ) {
1195: lptw->ScrollPos.x += nXinc;
1196: ScrollWindow(hwnd,-nXinc,0,NULL,NULL);
1197: SetScrollPos(hwnd,SB_HORZ,lptw->ScrollPos.x,TRUE);
1198: UpdateWindow(hwnd);
1199: }
1200: return(0);
1201: case WM_KEYDOWN:
1202: if (GetKeyState(VK_SHIFT) < 0) {
1203: switch(wParam) {
1204: case VK_HOME:
1205: SendMessage(hwnd, WM_VSCROLL, SB_TOP, (LPARAM)0);
1206: break;
1207: case VK_END:
1208: SendMessage(hwnd, WM_VSCROLL, SB_BOTTOM, (LPARAM)0);
1209: break;
1210: case VK_PRIOR:
1211: SendMessage(hwnd, WM_VSCROLL, SB_PAGEUP, (LPARAM)0);
1212: break;
1213: case VK_NEXT:
1214: SendMessage(hwnd, WM_VSCROLL, SB_PAGEDOWN, (LPARAM)0);
1215: break;
1216: case VK_UP:
1217: SendMessage(hwnd, WM_VSCROLL, SB_LINEUP, (LPARAM)0);
1218: break;
1219: case VK_DOWN:
1220: SendMessage(hwnd, WM_VSCROLL, SB_LINEDOWN, (LPARAM)0);
1221: break;
1222: case VK_LEFT:
1223: SendMessage(hwnd, WM_HSCROLL, SB_LINEUP, (LPARAM)0);
1224: break;
1225: case VK_RIGHT:
1226: SendMessage(hwnd, WM_HSCROLL, SB_LINEDOWN, (LPARAM)0);
1227: break;
1228: }
1229: }
1230: else {
1231: switch(wParam) {
1232: case VK_HOME:
1233: case VK_END:
1234: case VK_PRIOR:
1235: case VK_NEXT:
1236: case VK_UP:
1237: case VK_DOWN:
1238: case VK_LEFT:
1239: case VK_RIGHT:
1240: case VK_DELETE:
1241: { /* store key in circular buffer */
1242: long count;
1243: count = lptw->KeyBufIn - lptw->KeyBufOut;
1244: if (count < 0) count += lptw->KeyBufSize;
1245: if (count < lptw->KeyBufSize-2) {
1246: *lptw->KeyBufIn++ = 0;
1247: if (lptw->KeyBufIn - lptw->KeyBuf >= lptw->KeyBufSize)
1248: lptw->KeyBufIn = lptw->KeyBuf; /* wrap around */
1249: *lptw->KeyBufIn++ = HIWORD(lParam) & 0xff;
1250: if (lptw->KeyBufIn - lptw->KeyBuf >= lptw->KeyBufSize)
1251: lptw->KeyBufIn = lptw->KeyBuf; /* wrap around */
1252: }
1253: }
1254: }
1255: }
1256: break;
1257: case WM_RBUTTONDOWN:
1258: {
1259: POINT pt;
1260: pt.x = LOWORD(lParam);
1261: pt.y = HIWORD(lParam);
1262: ClientToScreen(hwnd,&pt);
1263: TrackPopupMenu(lptw->hPopMenu, TPM_LEFTALIGN,
1264: pt.x, pt.y, 0, hwnd, NULL);
1265: }
1266: return(0);
1267: case WM_LBUTTONDOWN:
1268: { /* start marking text */
1269: POINT pt;
1270: pt.x = LOWORD(lParam);
1271: pt.y = HIWORD(lParam);
1272: pt.x = (pt.x + lptw->ScrollPos.x)/lptw->CharSize.x;
1273: pt.y = (pt.y + lptw->ScrollPos.y)/lptw->CharSize.y;
1274: ClearMark(lptw, pt);
1275: }
1276: SetCapture(hwnd); /* track the mouse */
1277: lptw->Marking = TRUE;
1278: break;
1279: case WM_LBUTTONUP:
1280: { /* finish marking text */
1281: /* ensure begin mark is before end mark */
1282: ReleaseCapture();
1283: lptw->Marking = FALSE;
1284: if ((lptw->ScreenSize.x*lptw->MarkBegin.y + lptw->MarkBegin.x) >
1285: (lptw->ScreenSize.x*lptw->MarkEnd.y + lptw->MarkEnd.x)) {
1286: POINT tmp;
1287: tmp.x = lptw->MarkBegin.x;
1288: tmp.y = lptw->MarkBegin.y;
1289: lptw->MarkBegin.x = lptw->MarkEnd.x;
1290: lptw->MarkBegin.y = lptw->MarkEnd.y;
1291: lptw->MarkEnd.x = tmp.x;
1292: lptw->MarkEnd.y = tmp.y;
1293: }
1294: }
1295: break;
1296: case WM_MOUSEMOVE:
1297: if ( (wParam & MK_LBUTTON) && lptw->Marking ) {
1298: RECT rect;
1299: POINT pt;
1300: pt.x = LOWORD(lParam);
1301: pt.y = HIWORD(lParam);
1302: GetClientRect(hwnd, &rect);
1303: if (PtInRect(&rect, pt)) {
1304: pt.x = (pt.x + lptw->ScrollPos.x)/lptw->CharSize.x;
1305: pt.y = (pt.y + lptw->ScrollPos.y)/lptw->CharSize.y;
1306: UpdateMark(lptw, pt);
1307: }
1308: else {
1309: int nXinc;
1310: int nYinc;
1311: do {
1312: nXinc = 0;
1313: nYinc = 0;
1314: if (pt.x > rect.right) {
1315: nXinc = lptw->CharSize.x * 4;
1316: pt.x = (rect.right + lptw->ScrollPos.x)/lptw->CharSize.x + 2;
1317: }
1318: else if (pt.x < rect.left) {
1319: nXinc = -lptw->CharSize.x * 4;
1320: pt.x = (rect.left + lptw->ScrollPos.x)/lptw->CharSize.x - 2;
1321: }
1322: else
1323: pt.x = (pt.x + lptw->ScrollPos.x)/lptw->CharSize.x;
1324: if (pt.y > rect.bottom) {
1325: nYinc = lptw->CharSize.y;
1326: pt.y = (rect.bottom + lptw->ScrollPos.y)/lptw->CharSize.y + 1;
1327: }
1328: else if (pt.y < rect.top) {
1329: nYinc = -lptw->CharSize.y;
1330: pt.y = (rect.top + lptw->ScrollPos.y)/lptw->CharSize.y - 1;
1331: }
1332: else
1333: pt.y = (pt.y + lptw->ScrollPos.y)/lptw->CharSize.y;
1334: LimitMark(lptw, &pt);
1335: nXinc = max(nXinc, -lptw->ScrollPos.x);
1336: nYinc = max(nYinc, -lptw->ScrollPos.y);
1337: nYinc = min(nYinc, lptw->ScrollMax.y - lptw->ScrollPos.y);
1338: nXinc = min(nXinc, lptw->ScrollMax.x - lptw->ScrollPos.x);
1339: if (nYinc || nXinc) {
1340: lptw->ScrollPos.y += nYinc;
1341: lptw->ScrollPos.x += nXinc;
1342: ScrollWindow(lptw->hWndText,-nXinc,-nYinc,NULL,NULL);
1343: SetScrollPos(lptw->hWndText,SB_VERT,lptw->ScrollPos.y,TRUE);
1344: SetScrollPos(lptw->hWndText,SB_HORZ,lptw->ScrollPos.x,TRUE);
1345: UpdateWindow(lptw->hWndText);
1346: }
1347: UpdateMark(lptw, pt);
1348: GetCursorPos(&pt);
1349: ScreenToClient(hwnd, &pt);
1350: }
1351: while( (nYinc || nXinc) && !PtInRect(&rect, pt) &&
1352: (GetAsyncKeyState(VK_LBUTTON) < 0) );
1353: }
1354: }
1355: break;
1356: case WM_CHAR:
1357: { /* store key in circular buffer */
1358: long count;
1359: count = lptw->KeyBufIn - lptw->KeyBufOut;
1360: if (count < 0) count += lptw->KeyBufSize;
1361: if (count < lptw->KeyBufSize-1) {
1362: *lptw->KeyBufIn++ = wParam;
1363: if (lptw->KeyBufIn - lptw->KeyBuf >= lptw->KeyBufSize)
1364: lptw->KeyBufIn = lptw->KeyBuf; /* wrap around */
1365: }
1366: }
1367: return(0);
1368: case WM_COMMAND:
1369: if (LOWORD(wParam) < NUMMENU)
1370: SendMacro(lptw, LOWORD(wParam));
1371: else
1372: switch(LOWORD(wParam))
1373: {
1374: case M_COPY_CLIP:
1375: TextCopyClip(lptw);
1376: return 0;
1377: case M_PASTE:
1378: {
1379: HGLOBAL hGMem;
1380: BYTE FAR *cbuf;
1381: TEXTMETRIC tm;
1382: UINT type;
1383: /* find out what type to get from clipboard */
1384: hdc = GetDC(hwnd);
1385: SelectObject(hdc, lptw->hfont);
1386: GetTextMetrics(hdc,(TEXTMETRIC FAR *)&tm);
1387: if (tm.tmCharSet == OEM_CHARSET)
1388: type = CF_OEMTEXT;
1389: else
1390: type = CF_TEXT;
1391: ReleaseDC(lptw->hWndText, hdc);
1392: /* now get it from clipboard */
1393: OpenClipboard(hwnd);
1394: hGMem = GetClipboardData(type);
1395: if (hGMem) {
1396: cbuf = (BYTE FAR *) GlobalLock(hGMem);
1397: while (*cbuf) {
1398: if (*cbuf != '\n')
1399: SendMessage(lptw->hWndText,WM_CHAR,*cbuf,1L);
1400: cbuf++;
1401: }
1402: GlobalUnlock(hGMem);
1403: }
1404: CloseClipboard();
1405: return 0;
1406: }
1407: case M_CHOOSE_FONT:
1408: TextSelectFont(lptw);
1409: return 0;
1410: case M_SYSCOLORS:
1411: lptw->bSysColors = !lptw->bSysColors;
1412: if (lptw->bSysColors)
1413: CheckMenuItem(lptw->hPopMenu, M_SYSCOLORS, MF_BYCOMMAND | MF_CHECKED);
1414: else
1415: CheckMenuItem(lptw->hPopMenu, M_SYSCOLORS, MF_BYCOMMAND | MF_UNCHECKED);
1416: SendMessage(hwnd, WM_SYSCOLORCHANGE, (WPARAM)0, (LPARAM)0);
1417: InvalidateRect(hwnd, (LPRECT)NULL, 1);
1418: UpdateWindow(hwnd);
1419: return 0;
1420: case M_WRITEINI:
1421: WriteTextIni(lptw);
1422: return 0;
1423: case M_ABOUT:
1424: AboutBox(hwnd,lptw->AboutText);
1425: return 0;
1426: }
1427: return(0);
1428: case WM_SYSCOLORCHANGE:
1429: DeleteObject(lptw->hbrBackground);
1430: lptw->hbrBackground = CreateSolidBrush(lptw->bSysColors ?
1431: GetSysColor(COLOR_WINDOW) : RGB(0,0,0));
1432: return(0);
1433: case WM_ERASEBKGND:
1434: return(1); /* we will erase it ourselves */
1435: case WM_PAINT:
1436: {
1437: POINT source, width, dest;
1438: POINT MarkBegin, MarkEnd;
1439: hdc = BeginPaint(hwnd, &ps);
1440: if (ps.fErase)
1441: FillRect(hdc, &ps.rcPaint, lptw->hbrBackground);
1442: SelectObject(hdc, lptw->hfont);
1443: SetMapMode(hdc, MM_TEXT);
1444: SetBkMode(hdc,OPAQUE);
1445: GetClientRect(hwnd, &rect);
1446: source.x = (rect.left + lptw->ScrollPos.x) / lptw->CharSize.x; /* source */
1447: source.y = (rect.top + lptw->ScrollPos.y) / lptw->CharSize.y;
1448: dest.x = source.x * lptw->CharSize.x - lptw->ScrollPos.x; /* destination */
1449: dest.y = source.y * lptw->CharSize.y - lptw->ScrollPos.y;
1450: width.x = ((rect.right + lptw->ScrollPos.x + lptw->CharSize.x - 1) / lptw->CharSize.x) - source.x; /* width */
1451: width.y = ((rect.bottom + lptw->ScrollPos.y + lptw->CharSize.y - 1) / lptw->CharSize.y) - source.y;
1452: if (source.x < 0)
1453: source.x = 0;
1454: if (source.y < 0)
1455: source.y = 0;
1456: if (source.x+width.x > lptw->ScreenSize.x)
1457: width.x = lptw->ScreenSize.x - source.x;
1458: if (source.y+width.y > lptw->ScreenSize.y)
1459: width.y = lptw->ScreenSize.y - source.y;
1460: /* ensure begin mark is before end mark */
1461: if ((lptw->ScreenSize.x*lptw->MarkBegin.y + lptw->MarkBegin.x) >
1462: (lptw->ScreenSize.x*lptw->MarkEnd.y + lptw->MarkEnd.x)) {
1463: MarkBegin.x = lptw->MarkEnd.x;
1464: MarkBegin.y = lptw->MarkEnd.y;
1465: MarkEnd.x = lptw->MarkBegin.x;
1466: MarkEnd.y = lptw->MarkBegin.y;
1467: }
1468: else {
1469: MarkBegin.x = lptw->MarkBegin.x;
1470: MarkBegin.y = lptw->MarkBegin.y;
1471: MarkEnd.x = lptw->MarkEnd.x;
1472: MarkEnd.y = lptw->MarkEnd.y;
1473: }
1474: /* for each line */
1475: while (width.y>0) {
1476: if ( (source.y >= MarkBegin.y) && (source.y <= MarkEnd.y) ) {
1477: int start, end;
1478: int count, offset;
1479: if (source.y == MarkBegin.y)
1480: start = MarkBegin.x;
1481: else
1482: start = 0;
1483: if (source.y == MarkEnd.y)
1484: end = MarkEnd.x;
1485: else
1486: end = lptw->ScreenSize.x;
1487: /* do stuff before marked text */
1488: offset = 0;
1489: count = start - source.x;
1490: if (count > 0)
1491: DoLine(lptw, hdc, dest.x, dest.y,
1492: source.y*lptw->ScreenSize.x + source.x, count);
1493: /* then the marked text */
1494: offset += count;
1495: count = end - start;
1496: if ((count > 0) && (offset < width.x)){
1497: if (lptw->bSysColors) {
1498: SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT));
1499: SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT));
1500: }
1501: else {
1502: SetTextColor(hdc, MARKFORE);
1503: SetBkColor(hdc, MARKBACK);
1504: }
1505: TextOut(hdc, dest.x + lptw->CharSize.x*offset, dest.y,
1506: (LPSTR)(lptw->ScreenBuffer + source.y*lptw->ScreenSize.x
1507: + source.x + offset), count);
1508: }
1509: /* then stuff after marked text */
1510: offset += count;
1511: count = width.x + source.x - end;
1512: if ((count > 0) && (offset < width.x))
1513: DoLine(lptw, hdc, dest.x + lptw->CharSize.x*offset, dest.y,
1514: source.y*lptw->ScreenSize.x + source.x + offset, count);
1515: }
1516: else {
1517: DoLine(lptw, hdc, dest.x, dest.y,
1518: source.y*lptw->ScreenSize.x + source.x, width.x);
1519: }
1520: dest.y += lptw->CharSize.y;
1521: source.y++;
1522: width.y--;
1523: }
1524: EndPaint(hwnd, &ps);
1525: return 0;
1526: }
1527: case WM_CREATE:
1528: lptw = ((CREATESTRUCT FAR *)lParam)->lpCreateParams;
1529: SetWindowLong(hwnd, 0, (LONG)lptw);
1530: lptw->hWndText = hwnd;
1531: break;
1532: case WM_DESTROY:
1533: DeleteObject(lptw->hbrBackground);
1534: break;
1535: }
1536: return DefWindowProc(hwnd, message, wParam, lParam);
1537: }
1538:
1539:
1540: /* ================================== */
1541: /* replacement stdio routines */
1542:
1543: /* TRUE if key hit, FALSE if no key */
1544: int WDPROC
1545: TextKBHit(LPTW lptw)
1546: {
1547: return (lptw->KeyBufIn != lptw->KeyBufOut);
1548: }
1549:
1550: /* get character from keyboard, no echo */
1551: /* need to add extended codes */
1552: int WDPROC
1553: TextGetCh(LPTW lptw)
1554: {
1555: int ch;
1556: TextToCursor(lptw);
1557: lptw->bGetCh = TRUE;
1558: if (lptw->bFocus) {
1559: SetCaretPos(lptw->CursorPos.x*lptw->CharSize.x - lptw->ScrollPos.x,
1560: lptw->CursorPos.y*lptw->CharSize.y + lptw->CharAscent
1561: - lptw->CaretHeight - lptw->ScrollPos.y);
1562: ShowCaret(lptw->hWndText);
1563: }
1564: while (!TextKBHit(lptw)) { /* CMW: can't use TextMessage here as it does not idle properly */
1565: MSG msg;
1566: GetMessage(&msg, 0, 0, 0);
1567: TranslateMessage(&msg);
1568: DispatchMessage(&msg);
1569: }
1570: ch = *lptw->KeyBufOut++;
1571: if (ch=='\r')
1572: ch = '\n';
1573: if (lptw->KeyBufOut - lptw->KeyBuf >= lptw->KeyBufSize)
1574: lptw->KeyBufOut = lptw->KeyBuf; /* wrap around */
1575: if (lptw->bFocus)
1576: HideCaret(lptw->hWndText);
1577: lptw->bGetCh = FALSE;
1578: return ch;
1579: }
1580:
1581: /* get character from keyboard, with echo */
1582: int WDPROC
1583: TextGetChE(LPTW lptw)
1584: {
1585: int ch;
1586: ch = TextGetCh(lptw);
1587: TextPutCh(lptw, (BYTE)ch);
1588: return ch;
1589: }
1590:
1591: LPSTR WDPROC
1592: TextGetS(LPTW lptw, LPSTR str, unsigned int size)
1593: {
1594: LPSTR next = str;
1595: while (--size>0) {
1596: switch(*next = TextGetChE(lptw)) {
1597: case EOF:
1598: *next = 0;
1599: if (next == str) return (char *)NULL;
1600: return str;
1601: case '\n':
1602: *(next+1) = 0;
1603: return str;
1604: case 0x08:
1605: case 0x7f:
1606: if (next > str)
1607: --next;
1608: break;
1609: default:
1610: ++next;
1611: }
1612: }
1613: *next = 0;
1614: return str;
1615: }
1616:
1617: int WDPROC
1618: TextPutS(LPTW lptw, LPSTR str)
1619: {
1620: TextPutStr(lptw, str);
1621: return str[_fstrlen(str)-1];
1622: }
1623:
1624: /* ================================== */
1625: /* routines added for elvis */
1626:
1627: void WDPROC
1628: TextGotoXY(LPTW lptw, int x, int y)
1629: {
1630: lptw->CursorPos.x = x;
1631: lptw->CursorPos.y = y;
1632: }
1633:
1634: int WDPROC
1635: TextWhereX(LPTW lptw)
1636: {
1637: return lptw->CursorPos.x;
1638: }
1639:
1640: int WDPROC
1641: TextWhereY(LPTW lptw)
1642: {
1643: return lptw->CursorPos.y;
1644: }
1645:
1646: void WDPROC
1647: TextCursorHeight(LPTW lptw, int height)
1648: {
1649: lptw->CaretHeight = height;
1650: if (lptw->bFocus)
1651: CreateCaret(lptw->hWndText, 0, lptw->CharSize.x, 2+lptw->CaretHeight);
1652: }
1653:
1654: void WDPROC
1655: TextClearEOL(LPTW lptw)
1656: {
1657: HDC hdc;
1658: int xpos, ypos;
1659: int from, len;
1660: POINT pt;
1661: pt.x = pt.y = 0;
1662: ClearMark(lptw, pt);
1663: from = lptw->CursorPos.y*lptw->ScreenSize.x + lptw->CursorPos.x;
1664: len = lptw->ScreenSize.x-lptw->CursorPos.x;
1665: _fmemset(lptw->ScreenBuffer + from, ' ', len);
1666: _fmemset(lptw->AttrBuffer + from, NOTEXT, len);
1667: xpos = lptw->CursorPos.x*lptw->CharSize.x - lptw->ScrollPos.x;
1668: ypos = lptw->CursorPos.y*lptw->CharSize.y - lptw->ScrollPos.y;
1669: hdc = GetDC(lptw->hWndText);
1670: if (lptw->bSysColors) {
1671: SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
1672: SetBkColor(hdc, GetSysColor(COLOR_WINDOW));
1673: }
1674: else {
1675: SetTextColor(hdc, TextFore(lptw->Attr));
1676: SetBkColor(hdc, TextBack(lptw->Attr));
1677: }
1678: SelectObject(hdc, (lptw->hfont));
1679: TextOut(hdc,xpos,ypos,
1680: (LPSTR)(lptw->ScreenBuffer + lptw->CursorPos.y*lptw->ScreenSize.x +
1681: lptw->CursorPos.x), lptw->ScreenSize.x-lptw->CursorPos.x);
1682: (void)ReleaseDC(lptw->hWndText,hdc);
1683: }
1684:
1685: void WDPROC
1686: TextClearEOS(LPTW lptw)
1687: {
1688: RECT rect;
1689: int from, len;
1690: POINT pt;
1691: pt.x = pt.y = 0;
1692: ClearMark(lptw, pt);
1693: from = lptw->CursorPos.y*lptw->ScreenSize.x + lptw->CursorPos.x;
1694: len = lptw->ScreenSize.x-lptw->CursorPos.x +
1695: (lptw->ScreenSize.y-lptw->CursorPos.y-1)*lptw->ScreenSize.x;
1696: _fmemset(lptw->ScreenBuffer + from, ' ', len);
1697: _fmemset(lptw->AttrBuffer + from, NOTEXT, len);
1698: GetClientRect(lptw->hWndText, (LPRECT) &rect);
1699: InvalidateRect(lptw->hWndText, (LPRECT) &rect, 1);
1700: UpdateWindow(lptw->hWndText);
1701: }
1702:
1703: void WDPROC
1704: TextInsertLine(LPTW lptw)
1705: {
1706: RECT rect;
1707: int from, to, len;
1708: POINT pt;
1709: pt.x = pt.y = 0;
1710: ClearMark(lptw, pt);
1711: from = lptw->CursorPos.y*lptw->ScreenSize.x,
1712: to = (lptw->CursorPos.y+1)*lptw->ScreenSize.x;
1713: len = (lptw->ScreenSize.y-lptw->CursorPos.y-1)*lptw->ScreenSize.x;
1714: _fmemmove(lptw->ScreenBuffer + to, lptw->ScreenBuffer + from, len);
1715: _fmemmove(lptw->AttrBuffer + to, lptw->AttrBuffer + from, len);
1716: _fmemset(lptw->ScreenBuffer + from, ' ', lptw->ScreenSize.x);
1717: _fmemset(lptw->AttrBuffer + from, NOTEXT, lptw->ScreenSize.x);
1718: GetClientRect(lptw->hWndText, (LPRECT) &rect);
1719: InvalidateRect(lptw->hWndText, (LPRECT) &rect, 1);
1720: UpdateWindow(lptw->hWndText);
1721: if (lptw->CursorFlag)
1722: TextToCursor(lptw);
1723: }
1724:
1725: void WDPROC
1726: TextDeleteLine(LPTW lptw)
1727: {
1728: RECT rect;
1729: int from, to, len;
1730: POINT pt;
1731: pt.x = pt.y = 0;
1732: ClearMark(lptw, pt);
1733: to = lptw->CursorPos.y*lptw->ScreenSize.x,
1734: from = (lptw->CursorPos.y+1)*lptw->ScreenSize.x;
1735: len = (lptw->ScreenSize.y-lptw->CursorPos.y-1)*lptw->ScreenSize.x;
1736: _fmemmove(lptw->ScreenBuffer + to, lptw->ScreenBuffer + from, len);
1737: _fmemmove(lptw->AttrBuffer + to, lptw->AttrBuffer + from, len);
1738: from = lptw->ScreenSize.x*(lptw->ScreenSize.y -1);
1739: _fmemset(lptw->ScreenBuffer + from, ' ', lptw->ScreenSize.x);
1740: _fmemset(lptw->AttrBuffer + from, NOTEXT, lptw->ScreenSize.x);
1741: GetClientRect(lptw->hWndText, (LPRECT) &rect);
1742: InvalidateRect(lptw->hWndText, (LPRECT) &rect, 1);
1743: UpdateWindow(lptw->hWndText);
1744: if (lptw->CursorFlag)
1745: TextToCursor(lptw);
1746: }
1747:
1748: void WDPROC
1749: TextScrollReverse(LPTW lptw)
1750: {
1751: RECT rect;
1752: int len = lptw->ScreenSize.x * (lptw->ScreenSize.y - 1);
1753: _fmemmove(lptw->ScreenBuffer+lptw->ScreenSize.x, lptw->ScreenBuffer, len);
1754: _fmemset(lptw->ScreenBuffer, ' ', lptw->ScreenSize.x);
1755: _fmemmove(lptw->AttrBuffer+lptw->ScreenSize.x, lptw->AttrBuffer, len);
1756: _fmemset(lptw->AttrBuffer, NOTEXT, lptw->ScreenSize.x);
1757: if (lptw->CursorPos.y)
1758: lptw->CursorPos.y--;
1759: ScrollWindow(lptw->hWndText,0,+lptw->CharSize.y,NULL,NULL);
1760: GetClientRect(lptw->hWndText, (LPRECT) &rect);
1761: rect.top = lptw->ScreenSize.y*lptw->CharSize.y;
1762: if (rect.top < rect.bottom)
1763: InvalidateRect(lptw->hWndText, (LPRECT) &rect, 1);
1764: lptw->MarkBegin.y++;
1765: lptw->MarkEnd.y++;
1766: LimitMark(lptw, &lptw->MarkBegin);
1767: LimitMark(lptw, &lptw->MarkEnd);
1768: UpdateWindow(lptw->hWndText);
1769: }
1770:
1771: void WDPROC
1772: TextAttr(LPTW lptw, BYTE attr)
1773: {
1774: lptw->Attr = attr;
1775: }
1776:
1777: /* About Box */
1778: BOOL CALLBACK WINEXPORT
1779: AboutDlgProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam)
1780: {
1781: switch (wMsg) {
1782: case WM_INITDIALOG:
1783: {
1784: char buf[80];
1785: GetWindowText(GetParent(hDlg),buf,80);
1786: SetDlgItemText(hDlg, AB_TEXT1, buf);
1787: SetDlgItemText(hDlg, AB_TEXT2, (LPSTR)lParam);
1788: #ifdef __DLL__
1789: wsprintf(buf,"WGNUPLOT.DLL Version %s",(LPSTR)WGNUPLOTVERSION);
1790: SetDlgItemText(hDlg, AB_TEXT3, buf);
1791: #endif
1792: }
1793: return TRUE;
1794: case WM_DRAWITEM:
1795: {
1796: LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lParam;
1797: #ifdef WIN32
1798: DrawIcon(lpdis->hDC, 0, 0, (HICON)GetClassLong(GetParent(hDlg), GCL_HICON));
1799: #else
1800: DrawIcon(lpdis->hDC, 0, 0, (HICON)GetClassWord(GetParent(hDlg), GCW_HICON));
1801: #endif
1802: }
1803: return FALSE;
1804: case WM_COMMAND:
1805: switch (LOWORD(wParam)) {
1806: case IDCANCEL:
1807: case IDOK:
1808: EndDialog(hDlg, LOWORD(wParam));
1809: return TRUE;
1810: }
1811: break;
1812: }
1813: return FALSE;
1814: }
1815:
1816:
1817: void WDPROC
1818: AboutBox(HWND hwnd, LPSTR str)
1819: {
1820: #ifdef WIN32
1821: DialogBoxParam(hdllInstance,"AboutDlgBox",hwnd,AboutDlgProc,(LPARAM)str);
1822: #else
1823: DLGPROC lpfnAboutDlgProc;
1824: #ifdef __DLL__
1825: lpfnAboutDlgProc = (DLGPROC)GetProcAddress(hdllInstance, "AboutDlgProc");
1826: #else
1827: lpfnAboutDlgProc = (DLGPROC)MakeProcInstance((FARPROC)AboutDlgProc, hdllInstance);
1828: #endif
1829: DialogBoxParam(hdllInstance,"AboutDlgBox",hwnd,lpfnAboutDlgProc,(LPARAM)str);
1830: EnableWindow(hwnd,TRUE);
1831: #ifndef __DLL__
1832: FreeProcInstance((FARPROC)lpfnAboutDlgProc);
1833: #endif
1834: #endif
1835: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>