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