2 static char *RCSid() { return RCSid("$Id: wtext.c,v 1.15.2.2 2008/05/29 20:01:25 sfeam Exp $"); }
5 /* GNUPLOT - win/wtext.c */
7 * Copyright 1992, 1993, 1998, 2004 Russell Lang
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.
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,
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
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.
32 * This software is provided "as is" without express or implied warranty
33 * to the extent permitted by applicable law.
42 /* WARNING: Do not write to stdout/stderr with functions not listed
47 #include <string.h> /* use only far items */
56 /* needed for mouse scroll wheel support */
57 #define _WIN32_WINNT 0x0400
71 #define TEXTFONTSIZE 9
72 #define TEXTFONTNAME "Terminal"
74 #ifndef EOF /* HBB 980809: for MinGW32 */
75 #define EOF -1 /* instead of using <stdio.h> */
79 POINT ScreenMinSize = {16,4};
81 LRESULT CALLBACK WINEXPORT WndParentProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
82 LRESULT CALLBACK WINEXPORT WndTextProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
84 void ReadTextIni(LPTW lptw);
85 void LimitMark(LPTW lptw, POINT FAR *lppt);
87 char szNoMemory[] = "out of memory";
88 COLORREF TextColorTable[16] = {
89 RGB(0,0,0), /* black */
90 RGB(0,0,128), /* dark blue */
91 RGB(0,128,0), /* dark green */
92 RGB(0,128,128), /* dark cyan */
93 RGB(128,0,0), /* dark red */
94 RGB(128,0,128), /* dark magenta */
95 RGB(128,128,0), /* dark yellow */
96 RGB(128,128,128), /* dark grey */
97 RGB(192,192,192), /* light grey */
98 RGB(0,0,255), /* blue */
99 RGB(0,255,0), /* green */
100 RGB(0,255,255), /* cyan */
101 RGB(255,0,0), /* red */
102 RGB(255,0,255), /* magenta */
103 RGB(255,255,0), /* yellow */
104 RGB(255,255,255), /* white */
107 #define MARKFORE RGB(255,255,255)
108 #define MARKBACK RGB(0,0,128)
109 #define TextFore(attr) TextColorTable[(attr) & 15]
110 #define TextBack(attr) TextColorTable[(attr>>4) & 15]
118 while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
119 #if 1 /* HBB 19990505: Petzold says we should check this: */
120 if (msg.message == WM_QUIT)
123 TranslateMessage(&msg);
124 DispatchMessage(&msg);
131 CreateTextClass(LPTW lptw)
136 hdllInstance = lptw->hInstance; /* not using a DLL */
138 wndclass.style = CS_HREDRAW | CS_VREDRAW;
139 wndclass.lpfnWndProc = WndTextProc;
140 wndclass.cbClsExtra = 0;
141 wndclass.cbWndExtra = 2 * sizeof(void FAR *);
142 wndclass.hInstance = lptw->hInstance;
143 wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
144 wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
145 wndclass.hbrBackground = NULL;
146 lptw->hbrBackground = CreateSolidBrush(lptw->bSysColors ?
147 GetSysColor(COLOR_WINDOW) : RGB(0,0,0));
148 wndclass.lpszMenuName = NULL;
149 wndclass.lpszClassName = szTextClass;
150 RegisterClass(&wndclass);
152 wndclass.style = CS_HREDRAW | CS_VREDRAW;
153 wndclass.lpfnWndProc = WndParentProc;
154 wndclass.cbClsExtra = 0;
155 wndclass.cbWndExtra = 2 * sizeof(void FAR *);
156 wndclass.hInstance = lptw->hInstance;
158 wndclass.hIcon = lptw->hIcon;
160 wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
161 wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
162 wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
163 wndclass.lpszMenuName = NULL;
164 wndclass.lpszClassName = szParentClass;
165 RegisterClass(&wndclass);
169 /* make text window */
179 if (!lptw->hPrevInstance)
180 CreateTextClass(lptw);
182 if (lptw->KeyBufSize == 0)
183 lptw->KeyBufSize = 256;
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;
190 lptw->CursorPos.x = lptw->CursorPos.y = 0;
191 lptw->bFocus = FALSE;
192 lptw->bGetCh = FALSE;
193 lptw->CaretHeight = 0;
195 lptw->nCmdShow = SW_SHOWNORMAL;
197 lptw->Attr = 0xf0; /* black on white */
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);
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);
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);
219 lptw->KeyBufIn = lptw->KeyBufOut = lptw->KeyBuf;
221 lptw->hWndParent = CreateWindow(szParentClass, lptw->Title,
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);
230 GetClientRect(lptw->hWndParent, &rect);
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);
242 lptw->hPopMenu = CreatePopupMenu();
243 AppendMenu(lptw->hPopMenu, MF_STRING, M_COPY_CLIP, "&Copy to Clipboard\tCtrl-Ins");
244 AppendMenu(lptw->hPopMenu, MF_STRING, M_PASTE, "&Paste\tShift-Ins");
245 AppendMenu(lptw->hPopMenu, MF_SEPARATOR, 0, NULL);
247 AppendMenu(lptw->hPopMenu, MF_STRING, M_CHOOSE_FONT, "Choose &Font...");
249 AppendMenu(lptw->hPopMenu, MF_STRING | (lptw->bSysColors ? MF_CHECKED : MF_UNCHECKED),
250 M_SYSCOLORS, "&System Colors");
251 if (lptw->IniFile != (LPSTR)NULL) {
252 char buf[MAX_PATH+80];
253 wsprintf(buf,"&Update %s", lptw->IniFile);
254 AppendMenu(lptw->hPopMenu, MF_STRING, M_WRITEINI, (LPSTR)buf);
257 sysmenu = GetSystemMenu(lptw->hWndParent,0); /* get the sysmenu */
258 AppendMenu(sysmenu, MF_SEPARATOR, 0, NULL);
259 AppendMenu(sysmenu, MF_POPUP, (UINT)lptw->hPopMenu, "&Options");
260 AppendMenu(sysmenu, MF_STRING, M_ABOUT, "&About");
265 ShowWindow(lptw->hWndText, SW_SHOWNORMAL);
266 BringWindowToTop(lptw->hWndText);
267 SetFocus(lptw->hWndText);
272 /* close a text window */
279 if (lptw->hWndParent)
280 DestroyWindow(lptw->hWndParent);
283 hglobal = (HGLOBAL)GlobalHandle( SELECTOROF(lptw->ScreenBuffer) );
285 GlobalUnlock(hglobal);
288 hglobal = (HGLOBAL)GlobalHandle( SELECTOROF(lptw->AttrBuffer) );
290 GlobalUnlock(hglobal);
293 hglobal = (HGLOBAL)GlobalHandle( SELECTOROF(lptw->KeyBuf) );
295 GlobalUnlock(hglobal);
301 lptw->hWndParent = (HWND)NULL;
305 WriteTextIni(LPTW lptw)
308 LPSTR file = lptw->IniFile;
309 LPSTR section = lptw->IniSection;
314 if ((file == (LPSTR)NULL) || (section == (LPSTR)NULL))
317 iconic = IsIconic(lptw->hWndParent);
319 ShowWindow(lptw->hWndParent, SW_SHOWNORMAL);
320 GetWindowRect(lptw->hWndParent,&rect);
321 wsprintf(profile, "%d %d", rect.left, rect.top);
322 WritePrivateProfileString(section, "TextOrigin", profile, file);
323 wsprintf(profile, "%d %d", rect.right-rect.left, rect.bottom-rect.top);
324 WritePrivateProfileString(section, "TextSize", profile, file);
325 wsprintf(profile, "%d", iconic);
326 WritePrivateProfileString(section, "TextMinimized", profile, file);
327 wsprintf(profile, "%s,%d", lptw->fontname, lptw->fontsize);
328 WritePrivateProfileString(section, "TextFont", profile, file);
329 wsprintf(profile, "%d", lptw->bSysColors);
330 WritePrivateProfileString(section, "SysColors", profile, file);
332 ShowWindow(lptw->hWndParent, SW_SHOWMINIMIZED);
337 ReadTextIni(LPTW lptw)
339 LPSTR file = lptw->IniFile;
340 LPSTR section = lptw->IniSection;
345 bOKINI = (file != (LPSTR)NULL) && (section != (LPSTR)NULL);
349 GetPrivateProfileString(section, "TextOrigin", "", profile, 80, file);
350 if ( (p = GetInt(profile, (LPINT)&lptw->Origin.x)) == NULL)
351 lptw->Origin.x = CW_USEDEFAULT;
352 if ( (p = GetInt(p, (LPINT)&lptw->Origin.y)) == NULL)
353 lptw->Origin.y = CW_USEDEFAULT;
354 if ( (file != (LPSTR)NULL) && (section != (LPSTR)NULL) )
355 GetPrivateProfileString(section, "TextSize", "", profile, 80, file);
356 if ( (p = GetInt(profile, (LPINT)&lptw->Size.x)) == NULL)
357 lptw->Size.x = CW_USEDEFAULT;
358 if ( (p = GetInt(p, (LPINT)&lptw->Size.y)) == NULL)
359 lptw->Size.y = CW_USEDEFAULT;
362 GetPrivateProfileString(section, "TextFont", "", profile, 80, file);
365 size = _fstrchr(profile,',');
368 if ( (p = GetInt(size, &lptw->fontsize)) == NULL)
369 lptw->fontsize = TEXTFONTSIZE;
371 _fstrcpy(lptw->fontname, profile);
372 if (lptw->fontsize == 0)
373 lptw->fontsize = TEXTFONTSIZE;
374 if (!(*lptw->fontname))
375 _fstrcpy(lptw->fontname,TEXTFONTNAME);
380 GetPrivateProfileString(section, "TextMinimized", "", profile, 80, file);
381 if ((p = GetInt(profile, &iconic)) == NULL)
384 lptw->nCmdShow = SW_SHOWMINIMIZED;
386 lptw->bSysColors = FALSE;
387 GetPrivateProfileString(section, "SysColors", "", profile, 80, file);
388 if ((p = GetInt(profile, &lptw->bSysColors)) == NULL)
389 lptw->bSysColors = 0;
393 /* Bring Cursor into text window */
395 TextToCursor(LPTW lptw)
402 cyCursor = lptw->CursorPos.y * lptw->CharSize.y;
403 if ( (cyCursor + lptw->CharSize.y > lptw->ScrollPos.y + lptw->ClientSize.y)
404 || (cyCursor < lptw->ScrollPos.y) ) {
405 nYinc = max(0, cyCursor + lptw->CharSize.y - lptw->ClientSize.y) - lptw->ScrollPos.y;
406 nYinc = min(nYinc, lptw->ScrollMax.y - lptw->ScrollPos.y);
408 cxCursor = lptw->CursorPos.x * lptw->CharSize.x;
409 if ( (cxCursor + lptw->CharSize.x > lptw->ScrollPos.x + lptw->ClientSize.x)
410 || (cxCursor < lptw->ScrollPos.x) ) {
411 nXinc = max(0, cxCursor + lptw->CharSize.x - lptw->ClientSize.x/2) - lptw->ScrollPos.x;
412 nXinc = min(nXinc, lptw->ScrollMax.x - lptw->ScrollPos.x);
414 if (nYinc || nXinc) {
415 lptw->ScrollPos.y += nYinc;
416 lptw->ScrollPos.x += nXinc;
417 ScrollWindow(lptw->hWndText,-nXinc,-nYinc,NULL,NULL);
418 SetScrollPos(lptw->hWndText,SB_VERT,lptw->ScrollPos.y,TRUE);
419 SetScrollPos(lptw->hWndText,SB_HORZ,lptw->ScrollPos.x,TRUE);
420 UpdateWindow(lptw->hWndText);
427 lptw->CursorPos.x = 0;
429 if (lptw->CursorPos.y >= lptw->ScreenSize.y) {
430 int i = lptw->ScreenSize.x * (lptw->ScreenSize.y - 1);
431 _fmemmove(lptw->ScreenBuffer, lptw->ScreenBuffer+lptw->ScreenSize.x, i);
432 _fmemset(lptw->ScreenBuffer + i, ' ', lptw->ScreenSize.x);
433 _fmemmove(lptw->AttrBuffer, lptw->AttrBuffer+lptw->ScreenSize.x, i);
434 _fmemset(lptw->AttrBuffer + i, NOTEXT, lptw->ScreenSize.x);
436 ScrollWindow(lptw->hWndText,0,-lptw->CharSize.y,NULL,NULL);
439 LimitMark(lptw, &lptw->MarkBegin);
440 LimitMark(lptw, &lptw->MarkEnd);
441 UpdateWindow(lptw->hWndText);
443 if (lptw->CursorFlag)
448 /* Update count characters in window at cursor position */
449 /* Updates cursor position */
451 UpdateText(LPTW lptw, int count)
456 xpos = lptw->CursorPos.x*lptw->CharSize.x - lptw->ScrollPos.x;
457 ypos = lptw->CursorPos.y*lptw->CharSize.y - lptw->ScrollPos.y;
458 hdc = GetDC(lptw->hWndText);
459 if (lptw->bSysColors) {
460 SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
461 SetBkColor(hdc, GetSysColor(COLOR_WINDOW));
463 SetTextColor(hdc, TextFore(lptw->Attr));
464 SetBkColor(hdc, TextBack(lptw->Attr));
466 SelectObject(hdc, lptw->hfont);
467 TextOut(hdc,xpos,ypos,
468 (LPSTR)(lptw->ScreenBuffer + lptw->CursorPos.y*lptw->ScreenSize.x +
469 lptw->CursorPos.x), count);
470 ReleaseDC(lptw->hWndText,hdc);
471 lptw->CursorPos.x += count;
472 if (lptw->CursorPos.x >= lptw->ScreenSize.x)
477 TextPutCh(LPTW lptw, BYTE ch)
482 lptw->CursorPos.x = 0;
483 if (lptw->CursorFlag)
490 MessageBeep(0xFFFFFFFF);
491 if (lptw->CursorFlag)
497 for ( n = 8 - (lptw->CursorPos.x % 8); n>0; n-- )
498 TextPutCh(lptw, ' ');
504 if (lptw->CursorPos.x < 0) {
505 lptw->CursorPos.x = lptw->ScreenSize.x - 1;
508 if (lptw->CursorPos.y < 0)
509 lptw->CursorPos.y = 0;
512 pos = lptw->CursorPos.y*lptw->ScreenSize.x + lptw->CursorPos.x;
513 lptw->ScreenBuffer[pos] = ch;
514 lptw->AttrBuffer[pos] = lptw->Attr;
521 TextPutStr(LPTW lptw, LPSTR str)
523 BYTE FAR *p, FAR *pa;
527 p = lptw->ScreenBuffer + lptw->CursorPos.y*lptw->ScreenSize.x + lptw->CursorPos.x;
528 pa = lptw->AttrBuffer + lptw->CursorPos.y*lptw->ScreenSize.x + lptw->CursorPos.x;
529 limit = lptw->ScreenSize.x - lptw->CursorPos.x;
530 for (count=0; (count < limit) && *str && (isprint(*str) || *str=='\t'); count++) {
534 for ( n = 8 - ((lptw->CursorPos.x+count) % 8); (count < limit) & (n>0); n--, count++ ) {
546 UpdateText(lptw, count);
551 } else if (*str && !isprint(*str) && *str!='\t') {
552 TextPutCh(lptw, *str++);
559 LimitMark(LPTW lptw, POINT FAR *lppt)
567 if (lppt->x > lptw->ScreenSize.x)
568 lppt->x = lptw->ScreenSize.x;
569 if (lppt->y >= lptw->ScreenSize.y) {
571 lppt->y = lptw->ScreenSize.y;
576 ClearMark(LPTW lptw, POINT pt)
578 RECT rect1, rect2, rect3;
581 if ((lptw->MarkBegin.x != lptw->MarkEnd.x) ||
582 (lptw->MarkBegin.y != lptw->MarkEnd.y) ) {
583 if (lptw->MarkBegin.x > lptw->MarkEnd.x) {
584 tmp = lptw->MarkBegin.x;
585 lptw->MarkBegin.x = lptw->MarkEnd.x;
586 lptw->MarkEnd.x = tmp;
588 if (lptw->MarkBegin.y > lptw->MarkEnd.y) {
589 tmp = lptw->MarkBegin.y;
590 lptw->MarkBegin.y = lptw->MarkEnd.y;
591 lptw->MarkEnd.y = tmp;
593 /* calculate bounding rectangle in character coordinates */
594 if (lptw->MarkBegin.y != lptw->MarkEnd.y) {
596 rect1.right = lptw->ScreenSize.x;
598 rect1.left = lptw->MarkBegin.x;
599 rect1.right = lptw->MarkEnd.x + 1;
601 rect1.top = lptw->MarkBegin.y;
602 rect1.bottom = lptw->MarkEnd.y + 1;
603 /* now convert to client coordinates */
604 rect1.left = rect1.left * lptw->CharSize.x - lptw->ScrollPos.x;
605 rect1.right = rect1.right * lptw->CharSize.x - lptw->ScrollPos.x;
606 rect1.top = rect1.top * lptw->CharSize.y - lptw->ScrollPos.y;
607 rect1.bottom = rect1.bottom * lptw->CharSize.y - lptw->ScrollPos.y;
608 /* get client rect and calculate intersection */
609 GetClientRect(lptw->hWndText, &rect2);
610 IntersectRect(&rect3, &rect1, &rect2);
611 /* update window if necessary */
612 if (!IsRectEmpty(&rect3)) {
613 InvalidateRect(lptw->hWndText, &rect3, TRUE);
616 LimitMark(lptw, &pt);
617 lptw->MarkBegin.x = lptw->MarkEnd.x = pt.x;
618 lptw->MarkBegin.y = lptw->MarkEnd.y = pt.y;
619 UpdateWindow(lptw->hWndText);
623 /* output a line including attribute changes as needed */
625 DoLine(LPTW lptw, HDC hdc, int xpos, int ypos, int offset, int count)
630 pa = lptw->AttrBuffer + offset;
631 if ((offset < 0) || (offset >= lptw->ScreenSize.x*lptw->ScreenSize.y))
632 MessageBox((HWND)NULL, "panic", "panic", MB_OK | MB_ICONEXCLAMATION);
637 while ((num > 0) && (attr == *pa)) {
638 /* skip over bytes with same attribute */
642 if (lptw->bSysColors) {
643 SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
644 SetBkColor(hdc, GetSysColor(COLOR_WINDOW));
646 SetTextColor(hdc, TextFore(attr));
647 SetBkColor(hdc, TextBack(attr));
649 TextOut(hdc,xpos,ypos, (LPSTR)(lptw->ScreenBuffer + offset + idx),
651 xpos += lptw->CharSize.x * (count-num-idx);
657 DoMark(LPTW lptw, POINT pt, POINT end, BOOL mark)
664 offset = lptw->ScreenSize.x * pt.y + pt.x;
665 hdc = GetDC(lptw->hWndText);
666 SelectObject(hdc, lptw->hfont);
667 if (lptw->bSysColors) {
668 SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT));
669 SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT));
671 SetTextColor(hdc, MARKFORE);
672 SetBkColor(hdc, MARKBACK);
674 while (pt.y < end.y) {
676 xpos = pt.x*lptw->CharSize.x - lptw->ScrollPos.x;
677 ypos = pt.y*lptw->CharSize.y - lptw->ScrollPos.y;
678 count = lptw->ScreenSize.x - pt.x;
680 TextOut(hdc,xpos,ypos, (LPSTR)(lptw->ScreenBuffer + offset), count);
682 DoLine(lptw, hdc, xpos, ypos, offset, count);
683 if (lptw->bSysColors) {
684 SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT));
685 SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT));
687 SetTextColor(hdc, MARKFORE);
688 SetBkColor(hdc, MARKBACK);
696 xpos = pt.x*lptw->CharSize.x - lptw->ScrollPos.x;
697 ypos = pt.y*lptw->CharSize.y - lptw->ScrollPos.y;
698 count = end.x - pt.x;
699 if (end.y != lptw->ScreenSize.y) {
701 TextOut(hdc,xpos,ypos, (LPSTR)(lptw->ScreenBuffer + offset), count);
703 DoLine(lptw, hdc, xpos, ypos, offset, count);
705 ReleaseDC(lptw->hWndText,hdc);
709 UpdateMark(LPTW lptw, POINT pt)
711 int begin, point, end;
713 LimitMark(lptw, &pt);
714 begin = lptw->ScreenSize.x*lptw->MarkBegin.y + lptw->MarkBegin.x;
715 point = lptw->ScreenSize.x*pt.y + pt.x;
716 end = lptw->ScreenSize.x*lptw->MarkEnd.y + lptw->MarkEnd.x;
721 /* extend marked area */
722 DoMark(lptw, lptw->MarkEnd, pt, TRUE);
723 } else if (point >= begin) {
724 /* retract marked area */
725 DoMark(lptw, pt, lptw->MarkEnd, FALSE);
726 } else { /* retract and reverse */
727 DoMark(lptw, lptw->MarkBegin, lptw->MarkEnd, FALSE);
728 DoMark(lptw, pt, lptw->MarkBegin, TRUE);
733 /* extend marked area */
734 DoMark(lptw, pt, lptw->MarkEnd, TRUE);
735 } else if (point <= begin) {
736 /* retract marked area */
737 DoMark(lptw, lptw->MarkEnd, pt, FALSE);
738 } else { /* retract and reverse */
739 DoMark(lptw, lptw->MarkEnd, lptw->MarkBegin, FALSE);
740 DoMark(lptw, lptw->MarkBegin, pt, TRUE);
743 lptw->MarkEnd.x = pt.x;
744 lptw->MarkEnd.y = pt.y;
749 /* Windows 3.1 drag-drop feature */
752 DragFunc(LPTW lptw, HDROP hdrop)
757 if ((lptw->DragPre==(LPSTR)NULL) || (lptw->DragPost==(LPSTR)NULL))
759 cFiles = DragQueryFile(hdrop, (UINT) -1, (LPSTR)NULL, 0);
760 for (i=0; i<cFiles; i++) {
761 char szFile[MAX_PATH];
763 DragQueryFile(hdrop, i, szFile, MAX_PATH);
764 for (p=lptw->DragPre; *p; p++)
765 SendMessage(lptw->hWndText,WM_CHAR,*p,1L);
766 for (p=szFile; *p; p++)
767 SendMessage(lptw->hWndText,WM_CHAR,*p,1L);
768 for (p=lptw->DragPost; *p; p++)
769 SendMessage(lptw->hWndText,WM_CHAR,*p,1L);
777 TextCopyClip(LPTW lptw)
787 if ((lptw->MarkBegin.x == lptw->MarkEnd.x) &&
788 (lptw->MarkBegin.y == lptw->MarkEnd.y) ) {
793 size = (lptw->MarkEnd.y - lptw->MarkBegin.y + 1)
794 * (lptw->ScreenSize.x + 2) + 1;
795 hGMem = GlobalAlloc(GMEM_MOVEABLE, (DWORD)size);
796 cbuf = cp = (LPSTR)GlobalLock(hGMem);
797 if (cp == (LPSTR)NULL)
800 pt.x = lptw->MarkBegin.x;
801 pt.y = lptw->MarkBegin.y;
802 end.x = lptw->MarkEnd.x;
803 end.y = lptw->MarkEnd.y;
805 while (pt.y < end.y) {
806 /* copy to global buffer */
807 count = lptw->ScreenSize.x - pt.x;
809 lptw->ScreenBuffer + lptw->ScreenSize.x * pt.y + pt.x,
811 /* remove trailing spaces */
812 for (count=count-1; count>=0; count--) {
825 count = end.x - pt.x;
826 if (end.y != lptw->ScreenSize.y) {
827 _fmemcpy(cp, lptw->ScreenBuffer + lptw->ScreenSize.x*pt.y+pt.x, count);
830 size = _fstrlen(cbuf) + 1;
832 hGMem = GlobalReAlloc(hGMem, (DWORD)size, GMEM_MOVEABLE);
833 /* find out what type to put into clipboard */
834 hdc = GetDC(lptw->hWndText);
835 SelectObject(hdc, lptw->hfont);
836 GetTextMetrics(hdc,(TEXTMETRIC FAR *)&tm);
837 if (tm.tmCharSet == OEM_CHARSET)
841 ReleaseDC(lptw->hWndText, hdc);
842 /* give buffer to clipboard */
843 OpenClipboard(lptw->hWndParent);
845 SetClipboardData(type, hGMem);
850 TextMakeFont(LPTW lptw)
857 hdc = GetDC(lptw->hWndText);
858 _fmemset(&lf, 0, sizeof(LOGFONT));
859 _fstrncpy(lf.lfFaceName,lptw->fontname,LF_FACESIZE);
860 lf.lfHeight = -MulDiv(lptw->fontsize, GetDeviceCaps(hdc, LOGPIXELSY), 72);
861 lf.lfPitchAndFamily = FIXED_PITCH;
862 lf.lfCharSet = DEFAULT_CHARSET;
863 if ( (p = _fstrstr(lptw->fontname," Italic")) != (LPSTR)NULL ) {
864 lf.lfFaceName[ (unsigned int)(p-lptw->fontname) ] = '\0';
867 if ( (p = _fstrstr(lptw->fontname," Bold")) != (LPSTR)NULL ) {
868 lf.lfFaceName[ (unsigned int)(p-lptw->fontname) ] = '\0';
869 lf.lfWeight = FW_BOLD;
871 if (lptw->hfont != 0)
872 DeleteObject(lptw->hfont);
873 lptw->hfont = CreateFontIndirect((LOGFONT FAR *)&lf);
875 SelectObject(hdc, lptw->hfont);
876 GetTextMetrics(hdc,(TEXTMETRIC FAR *)&tm);
877 lptw->CharSize.y = tm.tmHeight;
878 lptw->CharSize.x = tm.tmAveCharWidth;
879 lptw->CharAscent = tm.tmAscent;
881 CreateCaret(lptw->hWndText, 0, lptw->CharSize.x, 2+lptw->CaretHeight);
882 ReleaseDC(lptw->hWndText, hdc);
887 TextSelectFont(LPTW lptw) {
892 char lpszStyle[LF_FACESIZE];
895 /* Set all structure fields to zero. */
896 _fmemset(&cf, 0, sizeof(CHOOSEFONT));
897 _fmemset(&lf, 0, sizeof(LOGFONT));
898 cf.lStructSize = sizeof(CHOOSEFONT);
899 cf.hwndOwner = lptw->hWndParent;
900 _fstrncpy(lf.lfFaceName,lptw->fontname,LF_FACESIZE);
901 if ( (p = _fstrstr(lptw->fontname," Bold")) != (LPSTR)NULL ) {
902 _fstrncpy(lpszStyle,p+1,LF_FACESIZE);
903 lf.lfFaceName[ (unsigned int)(p-lptw->fontname) ] = '\0';
905 else if ( (p = _fstrstr(lptw->fontname," Italic")) != (LPSTR)NULL ) {
906 _fstrncpy(lpszStyle,p+1,LF_FACESIZE);
907 lf.lfFaceName[ (unsigned int)(p-lptw->fontname) ] = '\0';
909 _fstrcpy(lpszStyle,"Regular");
910 cf.lpszStyle = lpszStyle;
911 hdc = GetDC(lptw->hWndText);
912 lf.lfHeight = -MulDiv(lptw->fontsize, GetDeviceCaps(hdc, LOGPIXELSY), 72);
913 ReleaseDC(lptw->hWndText, hdc);
914 lf.lfPitchAndFamily = FIXED_PITCH;
916 cf.nFontType = SCREEN_FONTTYPE;
917 cf.Flags = CF_SCREENFONTS | CF_FIXEDPITCHONLY | CF_INITTOLOGFONTSTRUCT | CF_USESTYLE;
918 if (ChooseFont(&cf)) {
920 _fstrcpy(lptw->fontname,lf.lfFaceName);
921 lptw->fontsize = cf.iPointSize / 10;
922 if (cf.nFontType & BOLD_FONTTYPE)
923 lstrcat(lptw->fontname," Bold");
924 if (cf.nFontType & ITALIC_FONTTYPE)
925 lstrcat(lptw->fontname," Italic");
927 /* force a window update */
928 GetClientRect(lptw->hWndText, (LPRECT) &rect);
929 SendMessage(lptw->hWndText, WM_SIZE, SIZE_RESTORED,
930 MAKELPARAM(rect.right-rect.left, rect.bottom-rect.top));
931 GetClientRect(lptw->hWndText, (LPRECT) &rect);
932 InvalidateRect(lptw->hWndText, (LPRECT) &rect, 1);
933 UpdateWindow(lptw->hWndText);
939 /* parent overlapped window */
940 LRESULT CALLBACK WINEXPORT
941 WndParentProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
948 lptw = (LPTW)GetWindowLong(hwnd, 0);
952 switch(LOWORD(wParam)) {
959 SendMessage(lptw->hWndText, WM_COMMAND, wParam, lParam);
963 if (IsWindow(lptw->hWndText)) {
964 SetFocus(lptw->hWndText);
968 case WM_GETMINMAXINFO:
970 POINT FAR * MMinfo = (POINT FAR *)lParam;
974 SelectObject(hdc, GetStockObject(OEM_FIXED_FONT));
975 GetTextMetrics(hdc,(LPTEXTMETRIC)&tm);
978 MMinfo[3].x = ScreenMinSize.x*tm.tmAveCharWidth
979 + GetSystemMetrics(SM_CXVSCROLL) + 2*GetSystemMetrics(SM_CXFRAME);
980 MMinfo[3].y = ScreenMinSize.y*tm.tmHeight
981 + GetSystemMetrics(SM_CYHSCROLL) + 2*GetSystemMetrics(SM_CYFRAME)
982 + GetSystemMetrics(SM_CYCAPTION);
986 SetWindowPos(lptw->hWndText, (HWND)NULL, 0, lptw->ButtonHeight,
987 LOWORD(lParam), HIWORD(lParam)-lptw->ButtonHeight,
988 SWP_NOZORDER | SWP_NOACTIVATE);
991 if (IsWindow(lptw->hWndText))
992 SetFocus(lptw->hWndText);
993 SendMessage(lptw->hWndText, message, wParam, lParam); /* pass on menu commands */
996 hdc = BeginPaint(hwnd, &ps);
997 if (lptw->ButtonHeight) {
999 GetClientRect(hwnd, &rect);
1000 hbrush = CreateSolidBrush(GetSysColor(COLOR_BTNSHADOW));
1001 rect.bottom = lptw->ButtonHeight-1;
1002 FillRect(hdc, &rect, hbrush);
1003 DeleteObject(hbrush);
1004 SelectObject(hdc, GetStockObject(BLACK_PEN));
1005 MoveTo(hdc, rect.left, lptw->ButtonHeight-1);
1006 LineTo(hdc, rect.right, lptw->ButtonHeight-1);
1008 EndPaint(hwnd, &ps);
1011 #if WINVER >= 0x030a
1014 WORD version = LOWORD(GetVersion());
1016 if ((LOBYTE(version)*100 + HIBYTE(version)) >= 310)
1017 DragFunc(lptw, (HDROP)wParam);
1027 lptw = ((CREATESTRUCT FAR *)lParam)->lpCreateParams;
1028 SetWindowLong(hwnd, 0, (LONG)lptw);
1029 lptw->hWndParent = hwnd;
1030 /* get character size */
1033 SelectObject(hdc, lptw->hfont);
1034 GetTextMetrics(hdc,(LPTEXTMETRIC)&tm);
1035 lptw->CharSize.y = tm.tmHeight;
1036 lptw->CharSize.x = tm.tmAveCharWidth;
1037 lptw->CharAscent = tm.tmAscent;
1038 ReleaseDC(hwnd,hdc);
1039 GetClientRect(hwnd, &crect);
1040 if ( lptw->CharSize.x*lptw->ScreenSize.x < crect.right ) {
1042 GetWindowRect(lptw->hWndParent,&wrect);
1043 MoveWindow(lptw->hWndParent, wrect.left, wrect.top,
1044 wrect.right-wrect.left + (lptw->CharSize.x*lptw->ScreenSize.x - crect.right),
1045 wrect.bottom-wrect.top,
1048 if ( lptw->CharSize.y*lptw->ScreenSize.y < crect.bottom ) {
1050 GetWindowRect(lptw->hWndParent,&wrect);
1051 MoveWindow(lptw->hWndParent, wrect.left, wrect.top,
1052 wrect.right-wrect.left,
1053 wrect.bottom-wrect.top + (lptw->CharSize.y*lptw->ScreenSize.y+lptw->ButtonHeight - crect.bottom),
1058 #if WINVER >= 0x030a
1060 WORD version = LOWORD(GetVersion());
1062 if ((LOBYTE(version)*100 + HIBYTE(version)) >= 310)
1063 if ( (lptw->DragPre!=(LPSTR)NULL) && (lptw->DragPost!=(LPSTR)NULL) )
1064 DragAcceptFiles(hwnd, TRUE);
1070 #if WINVER >= 0x030a
1072 WORD version = LOWORD(GetVersion());
1074 if ((LOBYTE(version)*100 + HIBYTE(version)) >= 310)
1075 DragAcceptFiles(hwnd, FALSE);
1079 DeleteObject(lptw->hfont);
1084 if (lptw->shutdown) {
1085 FARPROC lpShutDown = lptw->shutdown;
1091 return DefWindowProc(hwnd, message, wParam, lParam);
1095 /* PM 20011218: Reallocate larger keyboard buffer */
1097 ReallocateKeyBuf(LPTW lptw)
1099 int newbufsize = lptw->KeyBufSize + 16*1024; /* new buffer size */
1100 HGLOBAL h_old = (HGLOBAL)GlobalHandle( SELECTOROF(lptw->KeyBuf) );
1101 HGLOBAL h = GlobalAlloc(LHND, newbufsize);
1102 int pos_in = lptw->KeyBufIn - lptw->KeyBuf;
1103 int pos_out = lptw->KeyBufOut - lptw->KeyBuf;
1104 BYTE FAR *NewKeyBuf = (BYTE FAR *)GlobalLock(h);
1106 if (NewKeyBuf == (BYTE FAR *)NULL) {
1107 MessageBox((HWND)NULL, szNoMemory, (LPSTR)NULL,
1108 MB_ICONHAND | MB_SYSTEMMODAL);
1111 if (lptw->KeyBufIn > lptw->KeyBufOut) {
1112 /* | Buf ... Out ... In | */
1113 _fmemcpy(NewKeyBuf, lptw->KeyBufOut,
1114 lptw->KeyBufIn - lptw->KeyBufOut);
1115 lptw->KeyBufIn = NewKeyBuf + (pos_in - pos_out);
1117 /* | Buf ... In ... Out ... | */
1118 _fmemcpy(NewKeyBuf, lptw->KeyBufOut, lptw->KeyBufSize - pos_out );
1119 _fmemcpy(NewKeyBuf, lptw->KeyBuf, pos_in );
1120 lptw->KeyBufIn = NewKeyBuf + (lptw->KeyBufSize - pos_out + pos_in);
1123 GlobalUnlock(h_old);
1126 lptw->KeyBufSize = newbufsize;
1127 lptw->KeyBufOut = lptw->KeyBuf = NewKeyBuf;
1132 /* child text window */
1133 LRESULT CALLBACK WINEXPORT
1134 WndTextProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
1142 lptw = (LPTW)GetWindowLong(hwnd, 0);
1146 lptw->bFocus = TRUE;
1147 CreateCaret(hwnd, 0, lptw->CharSize.x, 2+lptw->CaretHeight);
1148 SetCaretPos(lptw->CursorPos.x*lptw->CharSize.x - lptw->ScrollPos.x,
1149 lptw->CursorPos.y*lptw->CharSize.y + lptw->CharAscent
1150 - lptw->CaretHeight - lptw->ScrollPos.y);
1156 lptw->bFocus = FALSE;
1159 lptw->ClientSize.y = HIWORD(lParam);
1160 lptw->ClientSize.x = LOWORD(lParam);
1162 lptw->ScrollMax.y = max(0, lptw->CharSize.y*lptw->ScreenSize.y - lptw->ClientSize.y);
1163 lptw->ScrollPos.y = min(lptw->ScrollPos.y, lptw->ScrollMax.y);
1165 SetScrollRange(hwnd, SB_VERT, 0, lptw->ScrollMax.y, FALSE);
1166 SetScrollPos(hwnd, SB_VERT, lptw->ScrollPos.y, TRUE);
1168 lptw->ScrollMax.x = max(0, lptw->CharSize.x*lptw->ScreenSize.x - lptw->ClientSize.x);
1169 lptw->ScrollPos.x = min(lptw->ScrollPos.x, lptw->ScrollMax.x);
1171 SetScrollRange(hwnd, SB_HORZ, 0, lptw->ScrollMax.x, FALSE);
1172 SetScrollPos(hwnd, SB_HORZ, lptw->ScrollPos.x, TRUE);
1174 if (lptw->bFocus && lptw->bGetCh) {
1175 SetCaretPos(lptw->CursorPos.x*lptw->CharSize.x - lptw->ScrollPos.x,
1176 lptw->CursorPos.y*lptw->CharSize.y + lptw->CharAscent
1177 - lptw->CaretHeight - lptw->ScrollPos.y);
1182 switch(LOWORD(wParam)) {
1184 nYinc = -lptw->ScrollPos.y;
1187 nYinc = lptw->ScrollMax.y - lptw->ScrollPos.y;
1190 nYinc = -lptw->CharSize.y;
1193 nYinc = lptw->CharSize.y;
1196 nYinc = min(-1,-lptw->ClientSize.y);
1199 nYinc = max(1,lptw->ClientSize.y);
1201 case SB_THUMBPOSITION:
1202 nYinc = HIWORD(wParam) - lptw->ScrollPos.y;
1206 } /* switch(loword(wparam)) */
1208 if ( (nYinc = max(-lptw->ScrollPos.y,
1209 min(nYinc, lptw->ScrollMax.y - lptw->ScrollPos.y)))
1211 lptw->ScrollPos.y += nYinc;
1212 ScrollWindow(hwnd,0,-nYinc,NULL,NULL);
1213 SetScrollPos(hwnd,SB_VERT,lptw->ScrollPos.y,TRUE);
1218 switch(LOWORD(wParam)) {
1220 nXinc = -lptw->CharSize.x;
1223 nXinc = lptw->CharSize.x;
1226 nXinc = min(-1,-lptw->ClientSize.x);
1229 nXinc = max(1,lptw->ClientSize.x);
1231 case SB_THUMBPOSITION:
1232 nXinc = HIWORD(wParam) - lptw->ScrollPos.x;
1236 } /* switch(loword(wparam)) */
1238 if ( (nXinc = max(-lptw->ScrollPos.x,
1239 min(nXinc, lptw->ScrollMax.x - lptw->ScrollPos.x)))
1241 lptw->ScrollPos.x += nXinc;
1242 ScrollWindow(hwnd,-nXinc,0,NULL,NULL);
1243 SetScrollPos(hwnd,SB_HORZ,lptw->ScrollPos.x,TRUE);
1248 if (GetKeyState(VK_SHIFT) < 0) {
1251 SendMessage(hwnd, WM_VSCROLL, SB_TOP, (LPARAM)0);
1254 SendMessage(hwnd, WM_VSCROLL, SB_BOTTOM, (LPARAM)0);
1257 SendMessage(hwnd, WM_VSCROLL, SB_PAGEUP, (LPARAM)0);
1260 SendMessage(hwnd, WM_VSCROLL, SB_PAGEDOWN, (LPARAM)0);
1263 SendMessage(hwnd, WM_VSCROLL, SB_LINEUP, (LPARAM)0);
1266 SendMessage(hwnd, WM_VSCROLL, SB_LINEDOWN, (LPARAM)0);
1269 SendMessage(hwnd, WM_HSCROLL, SB_LINEUP, (LPARAM)0);
1272 SendMessage(hwnd, WM_HSCROLL, SB_LINEDOWN, (LPARAM)0);
1274 } /* switch(wparam) */
1275 } else { /* if(shift) */
1285 case VK_DELETE: { /* store key in circular buffer */
1286 long count = lptw->KeyBufIn - lptw->KeyBufOut;
1289 count += lptw->KeyBufSize;
1290 if (count < lptw->KeyBufSize-2) {
1291 *lptw->KeyBufIn++ = 0;
1292 if (lptw->KeyBufIn - lptw->KeyBuf >= lptw->KeyBufSize)
1293 lptw->KeyBufIn = lptw->KeyBuf; /* wrap around */
1294 *lptw->KeyBufIn++ = HIWORD(lParam) & 0xff;
1295 if (lptw->KeyBufIn - lptw->KeyBuf >= lptw->KeyBufSize)
1296 lptw->KeyBufIn = lptw->KeyBuf; /* wrap around */
1299 } /* switch(wparam) */
1303 if (GetKeyState(VK_SHIFT) < 0) {
1306 /* Shift-Insert: paste clipboard */
1307 SendMessage(lptw->hWndText, WM_COMMAND, M_PASTE, (LPARAM)0);
1311 if (GetKeyState(VK_CONTROL) < 0) {
1314 /* Ctrl-Insert: copy to clipboard */
1315 SendMessage(lptw->hWndText, WM_COMMAND, M_COPY_CLIP, (LPARAM)0);
1318 /* Ctrl-V: paste clipboard */
1319 SendMessage(lptw->hWndText, WM_COMMAND, M_PASTE, (LPARAM)0);
1321 } /* switch(wparam) */
1325 case WM_RBUTTONDOWN:
1329 pt.x = LOWORD(lParam);
1330 pt.y = HIWORD(lParam);
1331 ClientToScreen(hwnd,&pt);
1332 TrackPopupMenu(lptw->hPopMenu, TPM_LEFTALIGN,
1333 pt.x, pt.y, 0, hwnd, NULL);
1336 case WM_LBUTTONDOWN:
1337 { /* start marking text */
1340 pt.x = LOWORD(lParam);
1341 pt.y = HIWORD(lParam);
1342 pt.x = (pt.x + lptw->ScrollPos.x)/lptw->CharSize.x;
1343 pt.y = (pt.y + lptw->ScrollPos.y)/lptw->CharSize.y;
1344 ClearMark(lptw, pt);
1345 SetCapture(hwnd); /* track the mouse */
1346 lptw->Marking = TRUE;
1350 { /* finish marking text */
1351 /* ensure begin mark is before end mark */
1353 lptw->Marking = FALSE;
1354 if ((lptw->ScreenSize.x*lptw->MarkBegin.y + lptw->MarkBegin.x) >
1355 (lptw->ScreenSize.x*lptw->MarkEnd.y + lptw->MarkEnd.x)) {
1357 tmp.x = lptw->MarkBegin.x;
1358 tmp.y = lptw->MarkBegin.y;
1359 lptw->MarkBegin.x = lptw->MarkEnd.x;
1360 lptw->MarkBegin.y = lptw->MarkEnd.y;
1361 lptw->MarkEnd.x = tmp.x;
1362 lptw->MarkEnd.y = tmp.y;
1367 if ((wParam & MK_LBUTTON) && lptw->Marking) {
1371 pt.x = LOWORD(lParam);
1372 pt.y = HIWORD(lParam);
1373 GetClientRect(hwnd, &rect);
1374 if (PtInRect(&rect, pt)) {
1375 pt.x = (pt.x + lptw->ScrollPos.x)/lptw->CharSize.x;
1376 pt.y = (pt.y + lptw->ScrollPos.y)/lptw->CharSize.y;
1377 UpdateMark(lptw, pt);
1384 if (pt.x > rect.right) {
1385 nXinc = lptw->CharSize.x * 4;
1386 pt.x = (rect.right + lptw->ScrollPos.x)
1387 / lptw->CharSize.x + 2;
1388 } else if (pt.x < rect.left) {
1389 nXinc = -lptw->CharSize.x * 4;
1390 pt.x = (rect.left + lptw->ScrollPos.x)
1391 / lptw->CharSize.x - 2;
1393 pt.x = (pt.x + lptw->ScrollPos.x)
1395 if (pt.y > rect.bottom) {
1396 nYinc = lptw->CharSize.y;
1397 pt.y = (rect.bottom + lptw->ScrollPos.y)
1398 / lptw->CharSize.y + 1;
1399 } else if (pt.y < rect.top) {
1400 nYinc = -lptw->CharSize.y;
1401 pt.y = (rect.top + lptw->ScrollPos.y)
1402 / lptw->CharSize.y - 1;
1404 pt.y = (pt.y + lptw->ScrollPos.y)
1407 LimitMark(lptw, &pt);
1408 nXinc = max(nXinc, -lptw->ScrollPos.x);
1409 nYinc = max(nYinc, -lptw->ScrollPos.y);
1410 nYinc = min(nYinc, lptw->ScrollMax.y - lptw->ScrollPos.y);
1411 nXinc = min(nXinc, lptw->ScrollMax.x - lptw->ScrollPos.x);
1412 if (nYinc || nXinc) {
1413 lptw->ScrollPos.y += nYinc;
1414 lptw->ScrollPos.x += nXinc;
1415 ScrollWindow(lptw->hWndText, -nXinc, -nYinc,
1417 SetScrollPos(lptw->hWndText, SB_VERT,
1418 lptw->ScrollPos.y, TRUE);
1419 SetScrollPos(lptw->hWndText, SB_HORZ,
1420 lptw->ScrollPos.x, TRUE);
1421 UpdateWindow(lptw->hWndText);
1423 UpdateMark(lptw, pt);
1425 ScreenToClient(hwnd, &pt);
1427 while((nYinc || nXinc) && !PtInRect(&rect, pt)
1428 && (GetAsyncKeyState(VK_LBUTTON) < 0));
1429 } /* moved inside viewport */
1430 } /* if(dragging) */
1432 #if _WIN32_WINNT >= 0x0400
1433 case WM_MOUSEWHEEL: {
1437 fwKeys = LOWORD(wParam);
1438 zDelta = HIWORD(wParam);
1442 SendMessage(hwnd, WM_VSCROLL, SB_LINEDOWN, (LPARAM)0);
1444 SendMessage(hwnd, WM_VSCROLL, SB_LINEUP, (LPARAM)0);
1448 SendMessage(hwnd, WM_VSCROLL, SB_PAGEDOWN, (LPARAM)0);
1450 SendMessage(hwnd, WM_VSCROLL, SB_PAGEUP, (LPARAM)0);
1454 SendMessage(hwnd, WM_CHAR, 0x0e, (LPARAM)0); // CTRL-N
1456 SendMessage(hwnd, WM_CHAR, 0x10, (LPARAM)0); // CTRL-P
1463 /* store key in circular buffer */
1464 long count = lptw->KeyBufIn - lptw->KeyBufOut;
1467 count += lptw->KeyBufSize;
1468 if (count == lptw->KeyBufSize-1) {
1469 /* PM 20011218: Keyboard buffer is full, thus reallocate
1470 * larger one. (Up to now: forthcoming characters were
1471 * silently ignored.)
1473 if ( ReallocateKeyBuf(lptw) )
1474 return 0; /* not enough memory */
1476 if (count < lptw->KeyBufSize-1) {
1477 *lptw->KeyBufIn++ = wParam;
1478 if (lptw->KeyBufIn - lptw->KeyBuf >= lptw->KeyBufSize)
1479 lptw->KeyBufIn = lptw->KeyBuf; /* wrap around */
1484 if (LOWORD(wParam) < NUMMENU)
1485 SendMacro(lptw, LOWORD(wParam));
1487 switch(LOWORD(wParam)) {
1498 /* find out what type to get from clipboard */
1500 SelectObject(hdc, lptw->hfont);
1501 GetTextMetrics(hdc,(TEXTMETRIC FAR *)&tm);
1502 if (tm.tmCharSet == OEM_CHARSET)
1506 ReleaseDC(lptw->hWndText, hdc);
1507 /* now get it from clipboard */
1508 OpenClipboard(hwnd);
1509 hGMem = GetClipboardData(type);
1511 cbuf = (BYTE FAR *) GlobalLock(hGMem);
1514 SendMessage(lptw->hWndText,WM_CHAR,*cbuf,1L);
1517 GlobalUnlock(hGMem);
1523 TextSelectFont(lptw);
1526 lptw->bSysColors = !lptw->bSysColors;
1527 if (lptw->bSysColors)
1528 CheckMenuItem(lptw->hPopMenu, M_SYSCOLORS, MF_BYCOMMAND | MF_CHECKED);
1530 CheckMenuItem(lptw->hPopMenu, M_SYSCOLORS, MF_BYCOMMAND | MF_UNCHECKED);
1531 SendMessage(hwnd, WM_SYSCOLORCHANGE, (WPARAM)0, (LPARAM)0);
1532 InvalidateRect(hwnd, (LPRECT)NULL, 1);
1539 AboutBox(hwnd,lptw->AboutText);
1541 } /* switch(loword(wparam)) */
1544 case WM_SYSCOLORCHANGE:
1545 DeleteObject(lptw->hbrBackground);
1546 lptw->hbrBackground = CreateSolidBrush(lptw->bSysColors ?
1547 GetSysColor(COLOR_WINDOW) : RGB(0,0,0));
1550 return(1); /* we will erase it ourselves */
1553 POINT source, width, dest;
1554 POINT MarkBegin, MarkEnd;
1556 hdc = BeginPaint(hwnd, &ps);
1558 FillRect(hdc, &ps.rcPaint, lptw->hbrBackground);
1559 SelectObject(hdc, lptw->hfont);
1560 SetMapMode(hdc, MM_TEXT);
1561 SetBkMode(hdc,OPAQUE);
1562 GetClientRect(hwnd, &rect);
1564 source.x = (rect.left + lptw->ScrollPos.x) / lptw->CharSize.x;
1565 source.y = (rect.top + lptw->ScrollPos.y) / lptw->CharSize.y;
1567 dest.x = source.x * lptw->CharSize.x - lptw->ScrollPos.x;
1568 dest.y = source.y * lptw->CharSize.y - lptw->ScrollPos.y;
1569 width.x = ((rect.right + lptw->ScrollPos.x + lptw->CharSize.x - 1)
1570 / lptw->CharSize.x) - source.x;
1571 width.y = ((rect.bottom + lptw->ScrollPos.y + lptw->CharSize.y - 1)
1572 / lptw->CharSize.y) - source.y;
1577 if (source.x+width.x > lptw->ScreenSize.x)
1578 width.x = lptw->ScreenSize.x - source.x;
1579 if (source.y+width.y > lptw->ScreenSize.y)
1580 width.y = lptw->ScreenSize.y - source.y;
1581 /* ensure begin mark is before end mark */
1582 if ((lptw->ScreenSize.x*lptw->MarkBegin.y + lptw->MarkBegin.x) >
1583 (lptw->ScreenSize.x*lptw->MarkEnd.y + lptw->MarkEnd.x)) {
1584 MarkBegin.x = lptw->MarkEnd.x;
1585 MarkBegin.y = lptw->MarkEnd.y;
1586 MarkEnd.x = lptw->MarkBegin.x;
1587 MarkEnd.y = lptw->MarkBegin.y;
1589 MarkBegin.x = lptw->MarkBegin.x;
1590 MarkBegin.y = lptw->MarkBegin.y;
1591 MarkEnd.x = lptw->MarkEnd.x;
1592 MarkEnd.y = lptw->MarkEnd.y;
1597 if ((source.y >= MarkBegin.y) && (source.y <= MarkEnd.y)) {
1601 if (source.y == MarkBegin.y)
1602 start = MarkBegin.x;
1605 if (source.y == MarkEnd.y)
1608 end = lptw->ScreenSize.x;
1609 /* do stuff before marked text */
1611 count = start - source.x;
1613 DoLine(lptw, hdc, dest.x, dest.y,
1614 source.y*lptw->ScreenSize.x + source.x, count);
1615 /* then the marked text */
1617 count = end - start;
1618 if ((count > 0) && (offset < width.x)){
1619 if (lptw->bSysColors) {
1620 SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT));
1621 SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT));
1623 SetTextColor(hdc, MARKFORE);
1624 SetBkColor(hdc, MARKBACK);
1626 TextOut(hdc, dest.x + lptw->CharSize.x*offset, dest.y,
1627 (LPSTR)(lptw->ScreenBuffer
1628 + source.y * lptw->ScreenSize.x
1629 + source.x + offset),
1632 /* then stuff after marked text */
1634 count = width.x + source.x - end;
1635 if ((count > 0) && (offset < width.x))
1636 DoLine(lptw, hdc, dest.x + lptw->CharSize.x*offset, dest.y,
1637 source.y * lptw->ScreenSize.x + source.x + offset,
1640 DoLine(lptw, hdc, dest.x, dest.y,
1641 source.y*lptw->ScreenSize.x + source.x, width.x);
1643 dest.y += lptw->CharSize.y;
1647 EndPaint(hwnd, &ps);
1651 lptw = ((CREATESTRUCT FAR *)lParam)->lpCreateParams;
1652 SetWindowLong(hwnd, 0, (LONG)lptw);
1653 lptw->hWndText = hwnd;
1656 DeleteObject(lptw->hbrBackground);
1658 } /* switch(message) */
1659 return DefWindowProc(hwnd, message, wParam, lParam);
1663 /* ================================== */
1664 /* replacement stdio routines */
1666 /* TRUE if key hit, FALSE if no key */
1668 TextKBHit(LPTW lptw)
1670 return (lptw->KeyBufIn != lptw->KeyBufOut);
1673 /* get character from keyboard, no echo */
1674 /* need to add extended codes */
1676 TextGetCh(LPTW lptw)
1680 lptw->bGetCh = TRUE;
1682 SetCaretPos(lptw->CursorPos.x * lptw->CharSize.x - lptw->ScrollPos.x,
1683 lptw->CursorPos.y * lptw->CharSize.y + lptw->CharAscent
1684 - lptw->CaretHeight - lptw->ScrollPos.y);
1685 ShowCaret(lptw->hWndText);
1687 while (!TextKBHit(lptw)) {
1688 /* CMW: can't use TextMessage here as it does not idle properly */
1690 GetMessage(&msg, 0, 0, 0);
1691 TranslateMessage(&msg);
1692 DispatchMessage(&msg);
1694 ch = *lptw->KeyBufOut++;
1697 if (lptw->KeyBufOut - lptw->KeyBuf >= lptw->KeyBufSize)
1698 lptw->KeyBufOut = lptw->KeyBuf; /* wrap around */
1700 HideCaret(lptw->hWndText);
1701 lptw->bGetCh = FALSE;
1705 /* get character from keyboard, with echo */
1707 TextGetChE(LPTW lptw)
1711 ch = TextGetCh(lptw);
1712 TextPutCh(lptw, (BYTE)ch);
1717 TextGetS(LPTW lptw, LPSTR str, unsigned int size)
1722 switch(*next = TextGetChE(lptw)) {
1726 return (LPSTR) NULL;
1745 TextPutS(LPTW lptw, LPSTR str)
1747 TextPutStr(lptw, str);
1748 return str[_fstrlen(str)-1];
1751 /* ================================== */
1752 /* routines added for elvis */
1755 TextGotoXY(LPTW lptw, int x, int y)
1757 lptw->CursorPos.x = x;
1758 lptw->CursorPos.y = y;
1762 TextWhereX(LPTW lptw)
1764 return lptw->CursorPos.x;
1768 TextWhereY(LPTW lptw)
1770 return lptw->CursorPos.y;
1774 TextCursorHeight(LPTW lptw, int height)
1776 lptw->CaretHeight = height;
1778 CreateCaret(lptw->hWndText, 0, lptw->CharSize.x, 2+lptw->CaretHeight);
1782 TextClearEOL(LPTW lptw)
1790 ClearMark(lptw, pt);
1791 from = lptw->CursorPos.y * lptw->ScreenSize.x + lptw->CursorPos.x;
1792 len = lptw->ScreenSize.x-lptw->CursorPos.x;
1793 _fmemset(lptw->ScreenBuffer + from, ' ', len);
1794 _fmemset(lptw->AttrBuffer + from, NOTEXT, len);
1795 xpos = lptw->CursorPos.x * lptw->CharSize.x - lptw->ScrollPos.x;
1796 ypos = lptw->CursorPos.y * lptw->CharSize.y - lptw->ScrollPos.y;
1797 hdc = GetDC(lptw->hWndText);
1798 if (lptw->bSysColors) {
1799 SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
1800 SetBkColor(hdc, GetSysColor(COLOR_WINDOW));
1802 SetTextColor(hdc, TextFore(lptw->Attr));
1803 SetBkColor(hdc, TextBack(lptw->Attr));
1805 SelectObject(hdc, (lptw->hfont));
1806 TextOut(hdc,xpos,ypos,
1807 (LPSTR)(lptw->ScreenBuffer
1808 + lptw->CursorPos.y * lptw->ScreenSize.x
1809 + lptw->CursorPos.x),
1810 lptw->ScreenSize.x - lptw->CursorPos.x);
1811 ReleaseDC(lptw->hWndText,hdc);
1815 TextClearEOS(LPTW lptw)
1822 ClearMark(lptw, pt);
1823 from = lptw->CursorPos.y*lptw->ScreenSize.x + lptw->CursorPos.x;
1824 len = lptw->ScreenSize.x-lptw->CursorPos.x
1825 + (lptw->ScreenSize.y - lptw->CursorPos.y - 1) * lptw->ScreenSize.x;
1826 _fmemset(lptw->ScreenBuffer + from, ' ', len);
1827 _fmemset(lptw->AttrBuffer + from, NOTEXT, len);
1828 GetClientRect(lptw->hWndText, (LPRECT) &rect);
1829 InvalidateRect(lptw->hWndText, (LPRECT) &rect, 1);
1830 UpdateWindow(lptw->hWndText);
1834 TextInsertLine(LPTW lptw)
1841 ClearMark(lptw, pt);
1842 from = lptw->CursorPos.y * lptw->ScreenSize.x;
1843 to = (lptw->CursorPos.y + 1) * lptw->ScreenSize.x;
1844 len = (lptw->ScreenSize.y - lptw->CursorPos.y - 1) * lptw->ScreenSize.x;
1845 _fmemmove(lptw->ScreenBuffer + to, lptw->ScreenBuffer + from, len);
1846 _fmemmove(lptw->AttrBuffer + to, lptw->AttrBuffer + from, len);
1847 _fmemset(lptw->ScreenBuffer + from, ' ', lptw->ScreenSize.x);
1848 _fmemset(lptw->AttrBuffer + from, NOTEXT, lptw->ScreenSize.x);
1849 GetClientRect(lptw->hWndText, (LPRECT) &rect);
1850 InvalidateRect(lptw->hWndText, (LPRECT) &rect, 1);
1851 UpdateWindow(lptw->hWndText);
1852 if (lptw->CursorFlag)
1857 TextDeleteLine(LPTW lptw)
1864 ClearMark(lptw, pt);
1865 to = lptw->CursorPos.y * lptw->ScreenSize.x;
1866 from = (lptw->CursorPos.y + 1) * lptw->ScreenSize.x;
1867 len = (lptw->ScreenSize.y - lptw->CursorPos.y - 1) * lptw->ScreenSize.x;
1868 _fmemmove(lptw->ScreenBuffer + to, lptw->ScreenBuffer + from, len);
1869 _fmemmove(lptw->AttrBuffer + to, lptw->AttrBuffer + from, len);
1870 from = lptw->ScreenSize.x * (lptw->ScreenSize.y -1);
1871 _fmemset(lptw->ScreenBuffer + from, ' ', lptw->ScreenSize.x);
1872 _fmemset(lptw->AttrBuffer + from, NOTEXT, lptw->ScreenSize.x);
1873 GetClientRect(lptw->hWndText, (LPRECT) &rect);
1874 InvalidateRect(lptw->hWndText, (LPRECT) &rect, 1);
1875 UpdateWindow(lptw->hWndText);
1876 if (lptw->CursorFlag)
1881 TextScrollReverse(LPTW lptw)
1884 int len = lptw->ScreenSize.x * (lptw->ScreenSize.y - 1);
1886 _fmemmove(lptw->ScreenBuffer+lptw->ScreenSize.x, lptw->ScreenBuffer, len);
1887 _fmemset(lptw->ScreenBuffer, ' ', lptw->ScreenSize.x);
1888 _fmemmove(lptw->AttrBuffer+lptw->ScreenSize.x, lptw->AttrBuffer, len);
1889 _fmemset(lptw->AttrBuffer, NOTEXT, lptw->ScreenSize.x);
1890 if (lptw->CursorPos.y)
1891 lptw->CursorPos.y--;
1892 ScrollWindow(lptw->hWndText, 0, lptw->CharSize.y, NULL, NULL);
1893 GetClientRect(lptw->hWndText, (LPRECT) &rect);
1894 rect.top = lptw->ScreenSize.y * lptw->CharSize.y;
1895 if (rect.top < rect.bottom)
1896 InvalidateRect(lptw->hWndText, (LPRECT) &rect, 1);
1897 lptw->MarkBegin.y++;
1899 LimitMark(lptw, &lptw->MarkBegin);
1900 LimitMark(lptw, &lptw->MarkEnd);
1901 UpdateWindow(lptw->hWndText);
1905 TextAttr(LPTW lptw, BYTE attr)
1911 BOOL CALLBACK WINEXPORT
1912 AboutDlgProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam)
1919 GetWindowText(GetParent(hDlg),buf,80);
1920 SetDlgItemText(hDlg, AB_TEXT1, buf);
1921 SetDlgItemText(hDlg, AB_TEXT2, (LPSTR)lParam);
1923 wsprintf(buf,"WGNUPLOT.DLL Version %s",(LPSTR)WGNUPLOTVERSION);
1924 SetDlgItemText(hDlg, AB_TEXT3, buf);
1930 LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lParam;
1932 DrawIcon(lpdis->hDC, 0, 0, (HICON)GetClassLong(GetParent(hDlg), GCL_HICON));
1934 DrawIcon(lpdis->hDC, 0, 0, (HICON)GetClassWord(GetParent(hDlg), GCW_HICON));
1939 switch (LOWORD(wParam)) {
1942 EndDialog(hDlg, LOWORD(wParam));
1946 } /* switch(message) */
1952 AboutBox(HWND hwnd, LPSTR str)
1955 DialogBoxParam(hdllInstance, "AboutDlgBox", hwnd,
1956 AboutDlgProc, (LPARAM)str);
1958 DLGPROC lpfnAboutDlgProc;
1961 lpfnAboutDlgProc = (DLGPROC)GetProcAddress(hdllInstance, "AboutDlgProc");
1963 lpfnAboutDlgProc = (DLGPROC)MakeProcInstance((FARPROC)AboutDlgProc,
1965 # endif /* __DLL__ */
1966 DialogBoxParam(hdllInstance,"AboutDlgBox", hwnd, lpfnAboutDlgProc,
1968 EnableWindow(hwnd,TRUE);
1970 FreeProcInstance((FARPROC)lpfnAboutDlgProc);
1971 # endif /* __DLL__ */