Annotation of OpenXM_contrib/gnuplot/win/wtext.c, Revision 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>