4 * Copyright David W. Metcalfe, 1994
9 static char Copyright
[] = "Copyright David W. Metcalfe, 1994";
21 /* #define DEBUG_EDIT */
22 /* #undef DEBUG_EDIT */
26 #define NOTIFY_PARENT(hWndCntrl, wNotifyCode) \
27 SendMessage(GetParent(hWndCntrl), WM_COMMAND, \
28 GetDlgCtrlID(hWndCntrl), MAKELPARAM(hWndCntrl, wNotifyCode));
30 #define MAXTEXTLEN 30000 /* maximum text buffer length */
31 #define EDITLEN 1024 /* starting length for multi-line control */
32 #define ENTRYLEN 256 /* starting length for single line control */
33 #define GROWLENGTH 64 /* buffers grow by this much */
35 #define HSCROLLDIM (ClientWidth(wndPtr) / 3)
36 /* "line" dimension for horizontal scroll */
40 int wlines
; /* number of lines of text */
41 int wtop
; /* top line that is displayed */
42 int wleft
; /* left pixel that is displayed */
43 unsigned int textlen
; /* text buffer length */
44 int textwidth
; /* width of longest line in pixels */
45 RECT fmtrc
; /* rectangle in which to format text */
46 int txtht
; /* height of text line in pixels */
47 HANDLE hText
; /* handle to text buffer */
48 HANDLE hCharWidths
; /* widths of chars in font */
49 HANDLE hTextPtrs
; /* list of line offsets */
50 HANDLE hBlankLine
; /* to fill blank lines quickly */
51 int CurrCol
; /* current column */
52 int CurrLine
; /* current line */
53 int WndCol
; /* current window column */
54 int WndRow
; /* current window row */
55 BOOL TextChanged
; /* TRUE if text has changed */
56 BOOL PaintBkgd
; /* paint control background */
57 unsigned int MaxTextLen
; /* maximum text buffer length */
58 int SelBegLine
; /* beginning line of selection */
59 int SelBegCol
; /* beginning column of selection */
60 int SelEndLine
; /* ending line of selection */
61 int SelEndCol
; /* ending column of selection */
62 HFONT hFont
; /* handle of current font (if not default) */
63 HANDLE hDeletedText
; /* handle to deleted txet buffer for undo */
64 int DeletedLength
; /* length of deleted text */
65 int DeletedCurrLine
; /* starting line from which text was deleted */
66 int DeletedCurrCol
; /* starting col from which text was deleted */
67 int NumTabStops
; /* number of tab stops in buffer hTabStops */
68 HANDLE hTabStops
; /* handle of tab stops buffer */
72 #define ClientWidth(wndPtr) \
73 (wndPtr->rectClient.right > wndPtr->rectClient.left ? \
74 wndPtr->rectClient.right - wndPtr->rectClient.left : 0)
75 #define ClientHeight(wndPtr, es) \
76 (wndPtr->rectClient.bottom > wndPtr->rectClient.top ? \
77 (wndPtr->rectClient.bottom - wndPtr->rectClient.top) / es->txtht : 0)
78 #define EditBufLen(wndPtr) (wndPtr->dwStyle & ES_MULTILINE \
80 #define CurrChar (EDIT_TextLine(hwnd, es->CurrLine) + es->CurrCol)
81 #define SelMarked(es) (es->SelBegLine != 0 || es->SelBegCol != 0 || \
82 es->SelEndLine != 0 || es->SelEndCol != 0)
83 #define ROUNDUP(numer, denom) (((numer) % (denom)) \
84 ? ((((numer) + (denom)) / (denom)) * (denom)) \
87 /* macros to access window styles */
88 #define IsAutoVScroll() (wndPtr->dwStyle & ES_AUTOVSCROLL)
89 #define IsAutoHScroll() (wndPtr->dwStyle & ES_AUTOHSCROLL)
90 #define IsMultiLine() (wndPtr->dwStyle & ES_MULTILINE)
91 #define IsVScrollBar() (wndPtr->dwStyle & WS_VSCROLL)
92 #define IsHScrollBar() (wndPtr->dwStyle & WS_HSCROLL)
94 /* internal variables */
95 static BOOL TextMarking
; /* TRUE if text marking in progress */
96 static BOOL ButtonDown
; /* TRUE if left mouse button down */
97 static int ButtonRow
; /* row in text buffer when button pressed */
98 static int ButtonCol
; /* col in text buffer when button pressed */
101 LONG
EditWndProc(HWND hWnd
, WORD uMsg
, WORD wParam
, LONG lParam
);
102 long EDIT_NCCreateMsg(HWND hwnd
, LONG lParam
);
103 long EDIT_CreateMsg(HWND hwnd
, LONG lParam
);
104 void EDIT_ClearTextPointers(HWND hwnd
);
105 void EDIT_BuildTextPointers(HWND hwnd
);
106 void EDIT_ModTextPointers(HWND hwnd
, int lineno
, int var
);
107 void EDIT_PaintMsg(HWND hwnd
);
108 HANDLE
EDIT_GetTextLine(HWND hwnd
, int selection
);
109 char *EDIT_TextLine(HWND hwnd
, int sel
);
110 int EDIT_StrLength(HWND hwnd
, unsigned char *str
, int len
, int pcol
);
111 int EDIT_LineLength(HWND hwnd
, int num
);
112 void EDIT_WriteTextLine(HWND hwnd
, RECT
*rc
, int y
);
113 void EDIT_WriteText(HWND hwnd
, char *lp
, int off
, int len
, int row
,
114 int col
, RECT
*rc
, BOOL blank
, BOOL reverse
);
115 HANDLE
EDIT_GetStr(HWND hwnd
, char *lp
, int off
, int len
, int *diff
);
116 void EDIT_CharMsg(HWND hwnd
, WORD wParam
);
117 void EDIT_KeyTyped(HWND hwnd
, short ch
);
118 int EDIT_CharWidth(HWND hwnd
, short ch
, int pcol
);
119 int EDIT_GetNextTabStop(HWND hwnd
, int pcol
);
120 void EDIT_Forward(HWND hwnd
);
121 void EDIT_Downward(HWND hwnd
);
122 void EDIT_Upward(HWND hwnd
);
123 void EDIT_Backward(HWND hwnd
);
124 void EDIT_End(HWND hwnd
);
125 void EDIT_Home(HWND hwnd
);
126 void EDIT_StickEnd(HWND hwnd
);
127 void EDIT_KeyDownMsg(HWND hwnd
, WORD wParam
);
128 void EDIT_KeyHScroll(HWND hwnd
, WORD opt
);
129 void EDIT_KeyVScrollLine(HWND hwnd
, WORD opt
);
130 void EDIT_KeyVScrollPage(HWND hwnd
, WORD opt
);
131 void EDIT_KeyVScrollDoc(HWND hwnd
, WORD opt
);
132 int EDIT_ComputeVScrollPos(HWND hwnd
);
133 int EDIT_ComputeHScrollPos(HWND hwnd
);
134 void EDIT_DelKey(HWND hwnd
);
135 void EDIT_VScrollMsg(HWND hwnd
, WORD wParam
, LONG lParam
);
136 void EDIT_VScrollLine(HWND hwnd
, WORD opt
);
137 void EDIT_VScrollPage(HWND hwnd
, WORD opt
);
138 void EDIT_HScrollMsg(HWND hwnd
, WORD wParam
, LONG lParam
);
139 void EDIT_SizeMsg(HWND hwnd
, WORD wParam
, LONG lParam
);
140 void EDIT_LButtonDownMsg(HWND hwnd
, WORD wParam
, LONG lParam
);
141 void EDIT_MouseMoveMsg(HWND hwnd
, WORD wParam
, LONG lParam
);
142 int EDIT_PixelToChar(HWND hwnd
, int row
, int *pixel
);
143 LONG
EDIT_SetTextMsg(HWND hwnd
, LONG lParam
);
144 void EDIT_ClearText(HWND hwnd
);
145 void EDIT_SetSelMsg(HWND hwnd
, WORD wParam
, LONG lParam
);
146 void EDIT_GetLineCol(HWND hwnd
, int off
, int *line
, int *col
);
147 void EDIT_DeleteSel(HWND hwnd
);
148 void EDIT_ClearSel(HWND hwnd
);
149 int EDIT_TextLineNumber(HWND hwnd
, char *lp
);
150 void EDIT_SetAnchor(HWND hwnd
, int row
, int col
);
151 void EDIT_ExtendSel(HWND hwnd
, int x
, int y
);
152 void EDIT_WriteSel(HWND hwnd
, int y
, int start
, int end
);
153 void EDIT_StopMarking(HWND hwnd
);
154 LONG
EDIT_GetLineMsg(HWND hwnd
, WORD wParam
, LONG lParam
);
155 LONG
EDIT_GetSelMsg(HWND hwnd
);
156 void EDIT_ReplaceSel(HWND hwnd
, LONG lParam
);
157 void EDIT_InsertText(HWND hwnd
, char *str
, int len
);
158 LONG
EDIT_LineFromCharMsg(HWND hwnd
, WORD wParam
);
159 LONG
EDIT_LineIndexMsg(HWND hwnd
, WORD wParam
);
160 LONG
EDIT_LineLengthMsg(HWND hwnd
, WORD wParam
);
161 void EDIT_SetFont(HWND hwnd
, WORD wParam
, LONG lParam
);
162 void EDIT_SaveDeletedText(HWND hwnd
, char *deltext
, int len
, int line
,
164 void EDIT_ClearDeletedText(HWND hwnd
);
165 LONG
EDIT_UndoMsg(HWND hwnd
);
166 unsigned int EDIT_HeapAlloc(HWND hwnd
, int bytes
);
167 void *EDIT_HeapAddr(HWND hwnd
, unsigned int handle
);
168 unsigned int EDIT_HeapReAlloc(HWND hwnd
, unsigned int handle
, int bytes
);
169 void EDIT_HeapFree(HWND hwnd
, unsigned int handle
);
170 unsigned int EDIT_HeapSize(HWND hwnd
, unsigned int handle
);
171 void EDIT_SetHandleMsg(HWND hwnd
, WORD wParam
);
172 LONG
EDIT_SetTabStopsMsg(HWND hwnd
, WORD wParam
, LONG lParam
);
173 void EDIT_CopyToClipboard(HWND hwnd
);
174 void EDIT_PasteMsg(HWND hwnd
);
175 void swap(int *a
, int *b
);
178 LONG
EditWndProc(HWND hwnd
, WORD uMsg
, WORD wParam
, LONG lParam
)
183 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
185 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
189 lResult
= es
->hDeletedText
;
192 case EM_EMPTYUNDOBUFFER
:
193 EDIT_ClearDeletedText(hwnd
);
197 fprintf(stdnimp
,"edit: EM_FMTLINES message received\n");
204 case EM_GETFIRSTVISIBLELINE
:
214 lResult
= EDIT_GetLineMsg(hwnd
, wParam
, lParam
);
219 case EM_GETLINECOUNT
:
221 lResult
= es
->wlines
;
227 lResult
= es
->TextChanged
;
230 case EM_GETPASSWORDCHAR
:
231 fprintf(stdnimp
,"edit: cannot process EM_GETPASSWORDCHAR message\n");
235 GetWindowRect(hwnd
, (LPRECT
)lParam
);
239 lResult
= EDIT_GetSelMsg(hwnd
);
242 case EM_GETWORDBREAKPROC
:
243 fprintf(stdnimp
,"edit: cannot process EM_GETWORDBREAKPROC message\n");
248 es
->MaxTextLen
= wParam
;
249 else if (IsMultiLine())
250 es
->MaxTextLen
= 65535;
252 es
->MaxTextLen
= 32767;
255 case EM_LINEFROMCHAR
:
256 lResult
= EDIT_LineFromCharMsg(hwnd
, wParam
);
261 lResult
= EDIT_LineIndexMsg(hwnd
, wParam
);
267 lResult
= EDIT_LineLengthMsg(hwnd
, wParam
);
271 fprintf(stdnimp
,"edit: cannot process EM_LINESCROLL message\n");
276 EDIT_ReplaceSel(hwnd
, lParam
);
277 SetCaretPos(es
->WndCol
, es
->WndRow
* es
->txtht
);
282 EDIT_SetHandleMsg(hwnd
, wParam
);
286 es
->TextChanged
= wParam
;
289 case EM_SETPASSWORDCHAR
:
290 fprintf(stdnimp
,"edit: cannot process EM_SETPASSWORDCHAR message\n");
294 fprintf(stdnimp
,"edit: cannot process EM_SETREADONLY message\n");
299 fprintf(stdnimp
,"edit: cannot process EM_SETRECT(NP) message\n");
304 EDIT_SetSelMsg(hwnd
, wParam
, lParam
);
305 SetCaretPos(es
->WndCol
, es
->WndRow
* es
->txtht
);
310 lResult
= EDIT_SetTabStopsMsg(hwnd
, wParam
, lParam
);
313 case EM_SETWORDBREAKPROC
:
314 fprintf(stdnimp
,"edit: cannot process EM_SETWORDBREAKPROC message\n");
319 lResult
= EDIT_UndoMsg(hwnd
);
320 SetCaretPos(es
->WndCol
, es
->WndRow
* es
->txtht
);
325 return DLGC_HASSETSEL
| DLGC_WANTCHARS
| DLGC_WANTARROWS
;
328 EDIT_CharMsg(hwnd
, wParam
);
332 EDIT_CopyToClipboard(hwnd
);
337 lResult
= EDIT_CreateMsg(hwnd
, lParam
);
341 EDIT_CopyToClipboard(hwnd
);
342 EDIT_DeleteSel(hwnd
);
346 EDIT_HeapFree(hwnd
, es
->hTextPtrs
);
347 EDIT_HeapFree(hwnd
, es
->hCharWidths
);
348 EDIT_HeapFree(hwnd
, es
->hText
);
349 EDIT_HeapFree(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
353 InvalidateRect(hwnd
, NULL
, FALSE
);
357 textPtr
= EDIT_HeapAddr(hwnd
, es
->hText
);
358 if ((int)wParam
> (len
= strlen(textPtr
)))
360 strcpy((char *)lParam
, textPtr
);
361 lResult
= (DWORD
)len
;
367 case WM_GETTEXTLENGTH
:
368 textPtr
= EDIT_HeapAddr(hwnd
, es
->hText
);
369 lResult
= (DWORD
)strlen(textPtr
);
373 EDIT_HScrollMsg(hwnd
, wParam
, lParam
);
377 EDIT_KeyDownMsg(hwnd
, wParam
);
382 NOTIFY_PARENT(hwnd
, EN_KILLFOCUS
);
388 EDIT_LButtonDownMsg(hwnd
, wParam
, lParam
);
389 SetCaretPos(es
->WndCol
, es
->WndRow
* es
->txtht
);
396 EDIT_StopMarking(hwnd
);
401 EDIT_MouseMoveMsg(hwnd
, wParam
, lParam
);
402 SetCaretPos(es
->WndCol
, es
->WndRow
* es
->txtht
);
411 lResult
= EDIT_NCCreateMsg(hwnd
, lParam
);
423 CreateCaret(hwnd
, 0, 2, es
->txtht
);
424 SetCaretPos(es
->WndCol
, es
->WndRow
* es
->txtht
);
426 NOTIFY_PARENT(hwnd
, EN_SETFOCUS
);
431 EDIT_SetFont(hwnd
, wParam
, lParam
);
432 SetCaretPos(es
->WndCol
, es
->WndRow
* es
->txtht
);
437 EDIT_SetTextMsg(hwnd
, lParam
);
441 EDIT_SizeMsg(hwnd
, wParam
, lParam
);
446 EDIT_VScrollMsg(hwnd
, wParam
, lParam
);
450 lResult
= DefWindowProc(hwnd
, uMsg
, wParam
, lParam
);
458 /*********************************************************************
459 * WM_NCCREATE message function
462 long EDIT_NCCreateMsg(HWND hwnd
, LONG lParam
)
464 CREATESTRUCT
*createStruct
= (CREATESTRUCT
*)lParam
;
465 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
467 unsigned int *textPtrs
;
470 /* store pointer to local or global heap in window structure so that */
471 /* EDITSTATE structure itself can be stored on local heap */
472 if (HEAP_LocalFindHeap(createStruct
->hInstance
)!=NULL
)
473 (MDESC
**)*(LONG
*)(wndPtr
->wExtra
+ 2) =
474 &HEAP_LocalFindHeap(createStruct
->hInstance
)->free_list
;
477 (MDESC
**)*(LONG
*)(wndPtr
->wExtra
+ 2) =
478 GlobalLock(createStruct
->hInstance
);
479 /* GlobalUnlock(createStruct->hInstance); */
481 /* allocate space for state variable structure */
482 (HANDLE
)(*(wndPtr
->wExtra
)) = EDIT_HeapAlloc(hwnd
, sizeof(EDITSTATE
));
483 es
= (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
484 es
->hTextPtrs
= EDIT_HeapAlloc(hwnd
, sizeof(int));
485 textPtrs
= (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
486 es
->hCharWidths
= EDIT_HeapAlloc(hwnd
, 256 * sizeof(short));
488 /* --- text buffer */
489 es
->MaxTextLen
= MAXTEXTLEN
+ 1;
490 if (!(createStruct
->lpszName
))
492 es
->textlen
= EditBufLen(wndPtr
) + 1;
493 es
->hText
= EDIT_HeapAlloc(hwnd
, EditBufLen(wndPtr
) + 2);
494 text
= EDIT_HeapAddr(hwnd
, es
->hText
);
495 memset(text
, 0, es
->textlen
+ 2);
496 EDIT_ClearTextPointers(hwnd
);
500 if (strlen(createStruct
->lpszName
) < EditBufLen(wndPtr
))
502 es
->textlen
= EditBufLen(wndPtr
) + 1;
503 es
->hText
= EDIT_HeapAlloc(hwnd
, EditBufLen(wndPtr
) + 2);
504 text
= EDIT_HeapAddr(hwnd
, es
->hText
);
505 strcpy(text
, createStruct
->lpszName
);
506 *(text
+ es
->textlen
) = '\0';
510 es
->hText
= EDIT_HeapAlloc(hwnd
,
511 strlen(createStruct
->lpszName
) + 2);
512 text
= EDIT_HeapAddr(hwnd
, es
->hText
);
513 strcpy(text
, createStruct
->lpszName
);
514 es
->textlen
= strlen(createStruct
->lpszName
) + 1;
516 *(text
+ es
->textlen
+ 1) = '\0';
517 EDIT_BuildTextPointers(hwnd
);
520 if ((createStruct
->style
& WS_VSCROLL
) ||
521 (createStruct
->style
& WS_HSCROLL
)) NC_CreateScrollBars(hwnd
);
523 /* ES_AUTOVSCROLL and ES_AUTOHSCROLL are automatically applied if */
524 /* the corresponding WM_* message is set */
525 if (createStruct
->style
& WS_VSCROLL
)
526 wndPtr
->dwStyle
|= ES_AUTOVSCROLL
;
527 if (createStruct
->style
& WS_HSCROLL
)
528 wndPtr
->dwStyle
|= ES_AUTOHSCROLL
;
530 /* remove the WS_CAPTION style if it has been set - this is really a */
531 /* pseudo option made from a combination of WS_BORDER and WS_DLGFRAME */
532 if (wndPtr
->dwStyle
& WS_BORDER
&& wndPtr
->dwStyle
& WS_DLGFRAME
)
533 wndPtr
->dwStyle
^= WS_DLGFRAME
;
539 /*********************************************************************
540 * WM_CREATE message function
543 long EDIT_CreateMsg(HWND hwnd
, LONG lParam
)
546 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
548 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
554 /* initialize state variable structure */
555 /* --- char width array */
557 charWidths
= (short *)EDIT_HeapAddr(hwnd
, es
->hCharWidths
);
558 memset(charWidths
, 0, 256 * sizeof(short));
559 GetCharWidth(hdc
, 0, 255, charWidths
);
561 /* --- other structure variables */
562 GetTextMetrics(hdc
, &tm
);
563 es
->txtht
= tm
.tmHeight
+ tm
.tmExternalLeading
;
565 es
->wtop
= es
->wleft
= 0;
566 es
->CurrCol
= es
->CurrLine
= 0;
567 es
->WndCol
= es
->WndRow
= 0;
568 es
->TextChanged
= FALSE
;
570 es
->SelBegLine
= es
->SelBegCol
= 0;
571 es
->SelEndLine
= es
->SelEndCol
= 0;
573 es
->hDeletedText
= 0;
574 es
->DeletedLength
= 0;
576 es
->hTabStops
= EDIT_HeapAlloc(hwnd
, sizeof(int));
578 /* allocate space for a line full of blanks to speed up */
580 es
->hBlankLine
= EDIT_HeapAlloc(hwnd
, (ClientWidth(wndPtr
) /
581 charWidths
[32]) + 2);
582 text
= EDIT_HeapAddr(hwnd
, es
->hBlankLine
);
583 memset(text
, ' ', (ClientWidth(wndPtr
) / charWidths
[32]) + 2);
585 /* set up text cursor for edit class */
586 CLASS_FindClassByName("EDIT", &classPtr
);
587 classPtr
->wc
.hCursor
= LoadCursor(0, IDC_IBEAM
);
589 /* paint background on first WM_PAINT */
590 es
->PaintBkgd
= TRUE
;
592 ReleaseDC(hwnd
, hdc
);
597 /*********************************************************************
598 * EDIT_ClearTextPointers
600 * Clear and initialize text line pointer array.
603 void EDIT_ClearTextPointers(HWND hwnd
)
605 unsigned int *textPtrs
;
606 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
608 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
610 es
->hTextPtrs
= EDIT_HeapReAlloc(hwnd
, es
->hTextPtrs
, sizeof(int));
611 textPtrs
= (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
616 /*********************************************************************
617 * EDIT_BuildTextPointers
619 * Build array of pointers to text lines.
622 #define INITLINES 100
624 void EDIT_BuildTextPointers(HWND hwnd
)
626 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
628 int incrs
= INITLINES
;
629 unsigned int off
, len
;
631 unsigned int *textPtrs
;
634 es
= (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
635 text
= EDIT_HeapAddr(hwnd
, es
->hText
);
636 textPtrs
= (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
637 charWidths
= (short *)EDIT_HeapAddr(hwnd
, es
->hCharWidths
);
639 es
->textwidth
= es
->wlines
= 0;
642 /* advance through text buffer */
645 /* increase size of text pointer array */
646 if (incrs
== INITLINES
)
649 es
->hTextPtrs
= EDIT_HeapReAlloc(hwnd
, es
->hTextPtrs
,
650 (es
->wlines
+ INITLINES
) * sizeof(int));
651 textPtrs
= (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
653 off
= (unsigned int)(cp
- text
); /* offset of beginning of line */
654 *(textPtrs
+ es
->wlines
) = off
;
659 /* advance through current line */
660 while (*cp
&& *cp
!= '\n')
662 len
+= EDIT_CharWidth(hwnd
, (BYTE
)*cp
, len
);
663 /* width of line in pixels */
666 es
->textwidth
= max(es
->textwidth
, len
);
668 cp
++; /* skip '\n' */
671 off
= (unsigned int)(cp
- text
);
672 *(textPtrs
+ es
->wlines
) = off
;
676 /*********************************************************************
677 * EDIT_ModTextPointers
679 * Modify text pointers from a specified position.
682 void EDIT_ModTextPointers(HWND hwnd
, int lineno
, int var
)
684 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
686 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
687 unsigned int *textPtrs
=
688 (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
690 while (lineno
< es
->wlines
)
691 *(textPtrs
+ lineno
++) += var
;
695 /*********************************************************************
696 * WM_PAINT message function
699 void EDIT_PaintMsg(HWND hwnd
)
705 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
707 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
709 hdc
= BeginPaint(hwnd
, &ps
);
712 dprintf_edit(stddeb
,"WM_PAINT: rc=(%d,%d), (%d,%d)\n", rc
.left
, rc
.top
,
713 rc
.right
, rc
.bottom
);
716 FillWindow(GetParent(hwnd
), hwnd
, hdc
, CTLCOLOR_EDIT
);
718 for (y
= (rc
.top
/ es
->txtht
); y
<= (rc
.bottom
/ es
->txtht
); y
++)
720 if (y
< es
->wlines
- es
->wtop
)
721 EDIT_WriteTextLine(hwnd
, &rc
, y
+ es
->wtop
);
728 /*********************************************************************
731 * Get a copy of the text in the specified line.
734 HANDLE
EDIT_GetTextLine(HWND hwnd
, int selection
)
741 dprintf_edit(stddeb
,"GetTextLine %d\n", selection
);
742 cp
= cp1
= EDIT_TextLine(hwnd
, selection
);
743 /* advance through line */
744 while (*cp
&& *cp
!= '\n')
750 /* store selected line and return handle */
751 hLine
= EDIT_HeapAlloc(hwnd
, len
+ 6);
752 line
= (char *)EDIT_HeapAddr(hwnd
, hLine
);
753 memmove(line
, cp1
, len
);
759 /*********************************************************************
762 * Return a pointer to the text in the specified line.
765 char *EDIT_TextLine(HWND hwnd
, int sel
)
767 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
769 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
770 char *text
= EDIT_HeapAddr(hwnd
, es
->hText
);
771 unsigned int *textPtrs
=
772 (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
774 if(sel
>es
->wlines
)return NULL
;
775 return (text
+ *(textPtrs
+ sel
));
779 /*********************************************************************
782 * Return length of string _str_ of length _len_ characters in pixels.
783 * The current column offset in pixels _pcol_ is required to calculate
784 * the width of a tab.
787 int EDIT_StrLength(HWND hwnd
, unsigned char *str
, int len
, int pcol
)
791 for (i
= 0; i
< len
; i
++)
792 plen
+= EDIT_CharWidth(hwnd
, (BYTE
)(*(str
+ i
)), pcol
+ plen
);
794 dprintf_edit(stddeb
,"EDIT_StrLength: returning %d\n", plen
);
799 /*********************************************************************
802 * Return length of line _num_ in characters.
805 int EDIT_LineLength(HWND hwnd
, int num
)
807 char *cp
= EDIT_TextLine(hwnd
, num
);
811 cp1
= strchr(cp
, '\n');
812 return cp1
? (int)(cp1
- cp
) : strlen(cp
);
816 /*********************************************************************
819 * Write the line of text at offset _y_ in text buffer to a window.
822 void EDIT_WriteTextLine(HWND hwnd
, RECT
*rect
, int y
)
829 int sbl
, sel
, sbc
, sec
;
831 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
833 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
835 /* initialize rectangle if NULL, else copy */
839 GetClientRect(hwnd
, &rc
);
841 dprintf_edit(stddeb
,"WriteTextLine %d\n", y
);
843 /* make sure y is inside the window */
844 if (y
< es
->wtop
|| y
> (es
->wtop
+ ClientHeight(wndPtr
, es
)))
846 dprintf_edit(stddeb
,"EDIT_WriteTextLine: y (%d) is not a displayed line\n", y
);
850 /* make sure rectangle is within window */
851 if (rc
.left
>= ClientWidth(wndPtr
) - 1)
853 dprintf_edit(stddeb
,"EDIT_WriteTextLine: rc.left (%d) is greater than right edge\n",
859 dprintf_edit(stddeb
,"EDIT_WriteTextLine: rc.right (%d) is less than left edge\n",
863 if (y
- es
->wtop
< (rc
.top
/ es
->txtht
) ||
864 y
- es
->wtop
> (rc
.bottom
/ es
->txtht
))
866 dprintf_edit(stddeb
,"EDIT_WriteTextLine: y (%d) is outside window\n", y
);
870 /* get the text and length of line */
871 if ((hLine
= EDIT_GetTextLine(hwnd
, y
)) == 0)
873 lp
= (unsigned char *)EDIT_HeapAddr(hwnd
, hLine
);
874 lnlen
= EDIT_StrLength(hwnd
, lp
, strlen(lp
), 0);
877 /* build the line to display */
878 if (lnlen
< es
->wleft
)
886 lnlen
= lnlen1
- off
;
887 len
= min(lnlen
, rc
.right
- rc
.left
);
892 sbl
= es
->SelBegLine
;
893 sel
= es
->SelEndLine
;
897 /* put lowest marker first */
903 if (sbl
== sel
&& sbc
> sec
)
906 if (y
< sbl
|| y
> sel
)
907 EDIT_WriteText(hwnd
, lp
, off
, len
, y
- es
->wtop
, rc
.left
, &rc
,
909 else if (y
> sbl
&& y
< sel
)
910 EDIT_WriteText(hwnd
, lp
, off
, len
, y
- es
->wtop
, rc
.left
, &rc
,
914 col
= EDIT_StrLength(hwnd
, lp
, sbc
, 0);
915 if (col
> (es
->wleft
+ rc
.left
))
917 len
= min(col
- off
, rc
.right
- off
);
918 EDIT_WriteText(hwnd
, lp
, off
, len
, y
- es
->wtop
,
919 rc
.left
, &rc
, FALSE
, FALSE
);
924 col
= EDIT_StrLength(hwnd
, lp
, sec
, 0);
925 if (col
< (es
->wleft
+ rc
.right
))
927 len
= min(col
- off
, rc
.right
- off
);
928 EDIT_WriteText(hwnd
, lp
, off
, len
, y
- es
->wtop
,
929 off
- es
->wleft
, &rc
, FALSE
, TRUE
);
931 len
= min(lnlen
- off
, rc
.right
- off
);
932 EDIT_WriteText(hwnd
, lp
, off
, len
, y
- es
->wtop
,
933 off
- es
->wleft
, &rc
, TRUE
, FALSE
);
937 len
= min(lnlen
- off
, rc
.right
- off
);
938 EDIT_WriteText(hwnd
, lp
, off
, len
, y
- es
->wtop
,
939 off
- es
->wleft
, &rc
, TRUE
, TRUE
);
944 len
= min(lnlen
- off
, rc
.right
- off
);
945 if (col
< (es
->wleft
+ rc
.right
))
946 EDIT_WriteText(hwnd
, lp
, off
, len
, y
- es
->wtop
,
947 off
- es
->wleft
, &rc
, TRUE
, TRUE
);
952 col
= EDIT_StrLength(hwnd
, lp
, sec
, 0);
953 if (col
< (es
->wleft
+ rc
.right
))
955 len
= min(col
- off
, rc
.right
- off
);
956 EDIT_WriteText(hwnd
, lp
, off
, len
, y
- es
->wtop
,
957 off
- es
->wleft
, &rc
, FALSE
, TRUE
);
959 len
= min(lnlen
- off
, rc
.right
- off
);
960 EDIT_WriteText(hwnd
, lp
, off
, len
, y
- es
->wtop
,
961 off
- es
->wleft
, &rc
, TRUE
, FALSE
);
966 EDIT_WriteText(hwnd
, lp
, off
, len
, y
- es
->wtop
, rc
.left
, &rc
,
969 EDIT_HeapFree(hwnd
, hLine
);
973 /*********************************************************************
976 * Write text to a window
978 * off - offset in text line (in pixels)
979 * len - length from off (in pixels)
980 * row - line in window
981 * col - column in window
982 * rc - rectangle in which to display line
983 * blank - blank remainder of line?
984 * reverse - reverse color of line?
987 void EDIT_WriteText(HWND hwnd
, char *lp
, int off
, int len
, int row
,
988 int col
, RECT
*rc
, BOOL blank
, BOOL reverse
)
992 char *str
, *cp
, *cp1
;
993 int diff
, num_spaces
, tabwidth
, scol
;
995 COLORREF oldTextColor
, oldBkgdColor
;
997 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
999 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1000 short *charWidths
= (short *)EDIT_HeapAddr(hwnd
, es
->hCharWidths
);
1001 char *blanks
= (char *)EDIT_HeapAddr(hwnd
, es
->hBlankLine
);
1003 dprintf_edit(stddeb
,"EDIT_WriteText lp=%s, off=%d, len=%d, row=%d, col=%d, reverse=%d\n", lp
, off
, len
, row
, col
, reverse
);
1006 hStr
= EDIT_GetStr(hwnd
, lp
, off
, len
, &diff
);
1007 str
= (char *)EDIT_HeapAddr(hwnd
, hStr
);
1008 hrgnClip
= CreateRectRgnIndirect(rc
);
1009 SelectClipRgn(hdc
, hrgnClip
);
1012 oldfont
= (HFONT
)SelectObject(hdc
, (HANDLE
)es
->hFont
);
1014 SendMessage(GetParent(hwnd
), WM_CTLCOLOR
, (WORD
)hdc
,
1015 MAKELPARAM(hwnd
, CTLCOLOR_EDIT
));
1019 oldBkgdColor
= GetBkColor(hdc
);
1020 oldTextColor
= GetTextColor(hdc
);
1021 SetBkColor(hdc
, oldTextColor
);
1022 SetTextColor(hdc
, oldBkgdColor
);
1025 if (strlen(blanks
) < (ClientWidth(wndPtr
) / charWidths
[32]) + 2)
1027 es
->hBlankLine
= EDIT_HeapReAlloc(hwnd
, es
->hBlankLine
,
1028 (ClientWidth(wndPtr
) / charWidths
[32]) + 2);
1029 blanks
= EDIT_HeapAddr(hwnd
, es
->hBlankLine
);
1030 memset(blanks
, ' ', (ClientWidth(wndPtr
) / charWidths
[32]) + 2);
1033 if (!(cp
= strchr(str
, VK_TAB
)))
1034 TextOut(hdc
, col
- diff
, row
* es
->txtht
, str
, strlen(str
));
1037 TextOut(hdc
, col
- diff
, row
* es
->txtht
, str
, (int)(cp
- str
));
1038 scol
= EDIT_StrLength(hwnd
, str
, (int)(cp
- str
), 0);
1039 tabwidth
= EDIT_CharWidth(hwnd
, VK_TAB
, scol
);
1040 num_spaces
= tabwidth
/ charWidths
[32] + 1;
1041 TextOut(hdc
, scol
, row
* es
->txtht
, blanks
, num_spaces
);
1045 while ((cp1
= strchr(cp
, VK_TAB
)))
1047 TextOut(hdc
, scol
, row
* es
->txtht
, cp
, (int)(cp1
- cp
));
1048 scol
+= EDIT_StrLength(hwnd
, cp
, (int)(cp1
- cp
), scol
);
1049 tabwidth
= EDIT_CharWidth(hwnd
, VK_TAB
, scol
);
1050 num_spaces
= tabwidth
/ charWidths
[32] + 1;
1051 TextOut(hdc
, scol
, row
* es
->txtht
, blanks
, num_spaces
);
1056 TextOut(hdc
, scol
, row
* es
->txtht
, cp
, strlen(cp
));
1061 SetBkColor(hdc
, oldBkgdColor
);
1062 SetTextColor(hdc
, oldTextColor
);
1065 /* blank out remainder of line if appropriate */
1068 if ((rc
->right
- col
) > len
)
1070 num_spaces
= (rc
->right
- col
- len
) / charWidths
[32];
1071 TextOut(hdc
, col
+ len
, row
* es
->txtht
, blanks
, num_spaces
);
1076 SelectObject(hdc
, (HANDLE
)oldfont
);
1078 EDIT_HeapFree(hwnd
, hStr
);
1079 ReleaseDC(hwnd
, hdc
);
1083 /*********************************************************************
1086 * Return sub-string starting at pixel _off_ of length _len_ pixels.
1087 * If _off_ is part way through a character, the negative offset of
1088 * the beginning of the character is returned in _diff_, else _diff_
1092 HANDLE
EDIT_GetStr(HWND hwnd
, char *lp
, int off
, int len
, int *diff
)
1096 int ch
= 0, i
= 0, j
, s_i
;
1099 dprintf_edit(stddeb
,"EDIT_GetStr %s %d %d\n", lp
, off
, len
);
1104 i
+= EDIT_CharWidth(hwnd
, (BYTE
)(*(lp
+ ch
)), i
);
1108 /* if stepped past _off_, go back a character */
1117 while (i
< len
+ off
)
1119 i
+= EDIT_CharWidth(hwnd
, (BYTE
)(*(lp
+ ch
)), i
);
1123 hStr
= EDIT_HeapAlloc(hwnd
, ch
- ch1
+ 3);
1124 str
= (char *)EDIT_HeapAddr(hwnd
, hStr
);
1125 for (i
= ch1
, j
= 0; i
< ch
; i
++, j
++)
1128 dprintf_edit(stddeb
,"EDIT_GetStr: returning %s\n", str
);
1133 /*********************************************************************
1134 * WM_CHAR message function
1137 void EDIT_CharMsg(HWND hwnd
, WORD wParam
)
1139 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1141 dprintf_edit(stddeb
,"EDIT_CharMsg: wParam=%c\n", (char)wParam
);
1150 EDIT_KeyTyped(hwnd
, wParam
);
1156 EDIT_KeyTyped(hwnd
, wParam
);
1160 if (wParam
>= 20 && wParam
<= 126)
1161 EDIT_KeyTyped(hwnd
, wParam
);
1167 /*********************************************************************
1170 * Process keystrokes that produce displayable characters.
1173 void EDIT_KeyTyped(HWND hwnd
, short ch
)
1175 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1177 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1178 char *text
= EDIT_HeapAddr(hwnd
, es
->hText
);
1179 char *currchar
= CurrChar
;
1181 BOOL FullPaint
= FALSE
;
1183 dprintf_edit(stddeb
,"EDIT_KeyTyped: ch=%c\n", (char)ch
);
1185 /* delete selected text (if any) */
1187 EDIT_DeleteSel(hwnd
);
1189 /* test for typing at end of maximum buffer size */
1190 if (currchar
== text
+ es
->MaxTextLen
)
1192 NOTIFY_PARENT(hwnd
, EN_ERRSPACE
);
1196 if (*currchar
== '\0' && IsMultiLine())
1198 /* insert a newline at end of text */
1200 *(currchar
+ 1) = '\0';
1201 EDIT_BuildTextPointers(hwnd
);
1204 /* insert the typed character */
1205 if (text
[es
->textlen
- 1] != '\0')
1207 /* current text buffer is full */
1208 if (es
->textlen
== es
->MaxTextLen
)
1210 /* text buffer is at maximum size */
1211 NOTIFY_PARENT(hwnd
, EN_ERRSPACE
);
1215 /* increase the text buffer size */
1216 es
->textlen
+= GROWLENGTH
;
1217 /* but not above maximum size */
1218 if (es
->textlen
> es
->MaxTextLen
)
1219 es
->textlen
= es
->MaxTextLen
;
1220 es
->hText
= EDIT_HeapReAlloc(hwnd
, es
->hText
, es
->textlen
+ 2);
1222 NOTIFY_PARENT(hwnd
, EN_ERRSPACE
);
1223 text
= EDIT_HeapAddr(hwnd
, es
->hText
);
1224 text
[es
->textlen
- 1] = '\0';
1225 currchar
= CurrChar
;
1227 /* make space for new character and put char in buffer */
1228 memmove(currchar
+ 1, currchar
, strlen(currchar
) + 1);
1230 EDIT_ModTextPointers(hwnd
, es
->CurrLine
+ 1, 1);
1231 es
->TextChanged
= TRUE
;
1232 NOTIFY_PARENT(hwnd
, EN_UPDATE
);
1234 /* re-adjust textwidth, if necessary, and redraw line */
1236 if (IsMultiLine() && es
->wlines
> 1)
1238 es
->textwidth
= max(es
->textwidth
,
1239 EDIT_StrLength(hwnd
, EDIT_TextLine(hwnd
, es
->CurrLine
),
1240 (int)(EDIT_TextLine(hwnd
, es
->CurrLine
+ 1) -
1241 EDIT_TextLine(hwnd
, es
->CurrLine
)), 0));
1244 es
->textwidth
= max(es
->textwidth
,
1245 EDIT_StrLength(hwnd
, text
, strlen(text
), 0));
1246 EDIT_WriteTextLine(hwnd
, NULL
, es
->wtop
+ es
->WndRow
);
1253 EDIT_BuildTextPointers(hwnd
);
1257 /* invalidate rest of window */
1258 GetClientRect(hwnd
, &rc
);
1260 rc
.top
= es
->WndRow
* es
->txtht
;
1261 InvalidateRect(hwnd
, &rc
, FALSE
);
1263 SetCaretPos(es
->WndCol
, es
->WndRow
* es
->txtht
);
1266 NOTIFY_PARENT(hwnd
, EN_CHANGE
);
1270 /* test end of window */
1271 if (es
->WndCol
>= ClientWidth(wndPtr
) -
1272 EDIT_CharWidth(hwnd
, (BYTE
)ch
, es
->WndCol
+ es
->wleft
))
1274 /* TODO:- Word wrap to be handled here */
1276 /* if (!(currchar == text + es->MaxTextLen - 2)) */
1277 EDIT_KeyHScroll(hwnd
, SB_LINEDOWN
);
1279 es
->WndCol
+= EDIT_CharWidth(hwnd
, (BYTE
)ch
, es
->WndCol
+ es
->wleft
);
1281 SetCaretPos(es
->WndCol
, es
->WndRow
* es
->txtht
);
1283 NOTIFY_PARENT(hwnd
, EN_CHANGE
);
1287 /*********************************************************************
1290 * Return the width of the given character in pixels.
1291 * The current column offset in pixels _pcol_ is required to calculate
1292 * the width of a tab.
1295 int EDIT_CharWidth(HWND hwnd
, short ch
, int pcol
)
1297 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1299 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1300 short *charWidths
= (short *)EDIT_HeapAddr(hwnd
, es
->hCharWidths
);
1303 return (charWidths
[ch
]);
1305 return (EDIT_GetNextTabStop(hwnd
, pcol
) - pcol
);
1309 /*********************************************************************
1310 * EDIT_GetNextTabStop
1312 * Return the next tab stop beyond _pcol_.
1315 int EDIT_GetNextTabStop(HWND hwnd
, int pcol
)
1318 int baseUnitWidth
= LOWORD(GetDialogBaseUnits());
1319 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1321 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1322 unsigned short *tabstops
= EDIT_HeapAddr(hwnd
, es
->hTabStops
);
1324 if (es
->NumTabStops
== 0)
1325 return ROUNDUP(pcol
, 8 * baseUnitWidth
);
1326 else if (es
->NumTabStops
== 1)
1327 return ROUNDUP(pcol
, *tabstops
* baseUnitWidth
/ 4);
1330 for (i
= 0; i
< es
->NumTabStops
; i
++)
1332 if (*(tabstops
+ i
) * baseUnitWidth
/ 4 >= pcol
)
1333 return (*(tabstops
+ i
) * baseUnitWidth
/ 4);
1340 /*********************************************************************
1343 * Cursor right key: move right one character position.
1346 void EDIT_Forward(HWND hwnd
)
1348 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1350 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1352 if (*CurrChar
== '\0')
1355 if (*CurrChar
== '\n')
1358 EDIT_Downward(hwnd
);
1362 es
->WndCol
+= EDIT_CharWidth(hwnd
, (BYTE
)(*CurrChar
), es
->WndCol
+ es
->wleft
);
1364 if (es
->WndCol
>= ClientWidth(wndPtr
))
1365 EDIT_KeyHScroll(hwnd
, SB_LINEDOWN
);
1371 /*********************************************************************
1374 * Cursor down key: move down one line.
1377 void EDIT_Downward(HWND hwnd
)
1379 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1381 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1383 dprintf_edit(stddeb
,"EDIT_Downward: WndRow=%d, wtop=%d, wlines=%d\n",
1384 es
->WndRow
, es
->wtop
, es
->wlines
);
1386 if (IsMultiLine() && (es
->WndRow
+ es
->wtop
+ 1 < es
->wlines
))
1389 if (es
->WndRow
== ClientHeight(wndPtr
, es
) - 1)
1392 EDIT_KeyVScrollLine(hwnd
, SB_LINEDOWN
);
1396 EDIT_StickEnd(hwnd
);
1401 /*********************************************************************
1404 * Cursor up key: move up one line.
1407 void EDIT_Upward(HWND hwnd
)
1409 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1411 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1413 if (IsMultiLine() && es
->CurrLine
!= 0)
1416 if (es
->WndRow
== 0)
1419 EDIT_KeyVScrollLine(hwnd
, SB_LINEUP
);
1423 EDIT_StickEnd(hwnd
);
1428 /*********************************************************************
1431 * Cursor left key: move left one character position.
1434 void EDIT_Backward(HWND hwnd
)
1436 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1438 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1443 if (*CurrChar
== VK_TAB
)
1444 es
->WndCol
-= EDIT_CharWidth(hwnd
, (BYTE
)(*CurrChar
),
1445 EDIT_StrLength(hwnd
,
1446 EDIT_TextLine(hwnd
, es
->CurrLine
),
1449 es
->WndCol
-= EDIT_CharWidth(hwnd
, (BYTE
)(*CurrChar
), 0);
1451 EDIT_KeyHScroll(hwnd
, SB_LINEUP
);
1453 else if (IsMultiLine() && es
->CurrLine
!= 0)
1461 /*********************************************************************
1464 * End key: move to end of line.
1467 void EDIT_End(HWND hwnd
)
1469 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1471 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1473 while (*CurrChar
&& *CurrChar
!= '\n')
1475 es
->WndCol
+= EDIT_CharWidth(hwnd
, (BYTE
)(*CurrChar
), es
->WndCol
+ es
->wleft
);
1479 if (es
->WndCol
>= ClientWidth(wndPtr
))
1481 es
->wleft
= es
->WndCol
- ClientWidth(wndPtr
) + HSCROLLDIM
;
1482 es
->WndCol
-= es
->wleft
;
1483 InvalidateRect(hwnd
, NULL
, FALSE
);
1489 /*********************************************************************
1492 * Home key: move to beginning of line.
1495 void EDIT_Home(HWND hwnd
)
1497 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1499 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1501 es
->CurrCol
= es
->WndCol
= 0;
1505 InvalidateRect(hwnd
, NULL
, FALSE
);
1511 /*********************************************************************
1514 * Stick the cursor to the end of the line.
1517 void EDIT_StickEnd(HWND hwnd
)
1519 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1521 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1522 int len
= EDIT_LineLength(hwnd
, es
->CurrLine
);
1523 char *cp
= EDIT_TextLine(hwnd
, es
->CurrLine
);
1526 es
->CurrCol
= min(len
, es
->CurrCol
);
1527 es
->WndCol
= min(EDIT_StrLength(hwnd
, cp
, len
, 0) - es
->wleft
, es
->WndCol
);
1528 currpel
= EDIT_StrLength(hwnd
, cp
, es
->CurrCol
, 0);
1530 if (es
->wleft
> currpel
)
1532 es
->wleft
= max(0, currpel
- 20);
1533 es
->WndCol
= currpel
- es
->wleft
;
1536 else if (currpel
- es
->wleft
>= ClientWidth(wndPtr
))
1538 es
->wleft
= currpel
- (ClientWidth(wndPtr
) - 5);
1539 es
->WndCol
= currpel
- es
->wleft
;
1545 /*********************************************************************
1546 * WM_KEYDOWN message function
1549 void EDIT_KeyDownMsg(HWND hwnd
, WORD wParam
)
1551 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1553 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1555 dprintf_edit(stddeb
,"EDIT_KeyDownMsg: key=%x\n", wParam
);
1562 EDIT_ClearSel(hwnd
);
1566 EDIT_Backward(hwnd
);
1571 EDIT_ClearSel(hwnd
);
1573 EDIT_Downward(hwnd
);
1580 EDIT_ClearSel(hwnd
);
1586 EDIT_ClearSel(hwnd
);
1587 EDIT_Backward(hwnd
);
1592 EDIT_ClearSel(hwnd
);
1598 EDIT_ClearSel(hwnd
);
1606 EDIT_ClearSel(hwnd
);
1607 EDIT_KeyVScrollPage(hwnd
, SB_PAGEUP
);
1615 EDIT_ClearSel(hwnd
);
1616 EDIT_KeyVScrollPage(hwnd
, SB_PAGEDOWN
);
1622 EDIT_DeleteSel(hwnd
);
1625 if (es
->CurrCol
== 0 && es
->CurrLine
== 0)
1627 EDIT_Backward(hwnd
);
1634 EDIT_DeleteSel(hwnd
);
1640 SetCaretPos(es
->WndCol
, es
->WndRow
* es
->txtht
);
1645 /*********************************************************************
1648 * Scroll text horizontally using cursor keys.
1651 void EDIT_KeyHScroll(HWND hwnd
, WORD opt
)
1654 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1656 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1658 if (opt
== SB_LINEDOWN
)
1660 es
->wleft
+= HSCROLLDIM
;
1661 es
->WndCol
-= HSCROLLDIM
;
1667 if (es
->wleft
- HSCROLLDIM
< 0)
1669 es
->WndCol
+= es
->wleft
;
1674 es
->wleft
-= HSCROLLDIM
;
1675 es
->WndCol
+= HSCROLLDIM
;
1679 InvalidateRect(hwnd
, NULL
, FALSE
);
1684 hscrollpos
= EDIT_ComputeHScrollPos(hwnd
);
1685 SetScrollPos(hwnd
, SB_HORZ
, hscrollpos
, TRUE
);
1690 /*********************************************************************
1691 * EDIT_KeyVScrollLine
1693 * Scroll text vertically by one line using keyboard.
1696 void EDIT_KeyVScrollLine(HWND hwnd
, WORD opt
)
1700 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1702 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1707 if (opt
== SB_LINEDOWN
)
1709 /* move down one line */
1710 if (es
->wtop
+ ClientHeight(wndPtr
, es
) >= es
->wlines
)
1716 /* move up one line */
1722 if (IsWindowVisible(hwnd
))
1724 /* adjust client bottom to nearest whole line */
1725 GetClientRect(hwnd
, &rc
);
1726 rc
.bottom
= (rc
.bottom
/ es
->txtht
) * es
->txtht
;
1728 if (opt
== SB_LINEUP
)
1730 /* move up one line (scroll window down) */
1731 ScrollWindow(hwnd
, 0, es
->txtht
, &rc
, &rc
);
1732 /* write top line */
1733 EDIT_WriteTextLine(hwnd
, NULL
, es
->wtop
);
1738 /* move down one line (scroll window up) */
1739 ScrollWindow(hwnd
, 0, -(es
->txtht
), &rc
, &rc
);
1740 /* write bottom line */
1741 y
= (((rc
.bottom
- rc
.top
) / es
->txtht
) - 1);
1742 EDIT_WriteTextLine(hwnd
, NULL
, es
->wtop
+ y
);
1747 /* reset the vertical scroll bar */
1750 vscrollpos
= EDIT_ComputeVScrollPos(hwnd
);
1751 SetScrollPos(hwnd
, SB_VERT
, vscrollpos
, TRUE
);
1756 /*********************************************************************
1757 * EDIT_KeyVScrollPage
1759 * Scroll text vertically by one page using keyboard.
1762 void EDIT_KeyVScrollPage(HWND hwnd
, WORD opt
)
1765 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1767 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1771 if (opt
== SB_PAGEUP
)
1774 es
->wtop
-= ClientHeight(wndPtr
, es
);
1778 if (es
->wtop
+ ClientHeight(wndPtr
, es
) < es
->wlines
)
1780 es
->wtop
+= ClientHeight(wndPtr
, es
);
1781 if (es
->wtop
> es
->wlines
- ClientHeight(wndPtr
, es
))
1782 es
->wtop
= es
->wlines
- ClientHeight(wndPtr
, es
);
1788 es
->CurrLine
= es
->wtop
+ es
->WndRow
;
1789 EDIT_StickEnd(hwnd
);
1790 InvalidateRect(hwnd
, NULL
, TRUE
);
1793 /* reset the vertical scroll bar */
1796 vscrollpos
= EDIT_ComputeVScrollPos(hwnd
);
1797 SetScrollPos(hwnd
, SB_VERT
, vscrollpos
, TRUE
);
1803 /*********************************************************************
1804 * EDIT_KeyVScrollDoc
1806 * Scroll text to top and bottom of document using keyboard.
1809 void EDIT_KeyVScrollDoc(HWND hwnd
, WORD opt
)
1812 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1814 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1820 es
->wtop
= es
->wleft
= 0;
1821 else if (es
->wtop
+ ClientHeight(wndPtr
, es
) < es
->wlines
)
1823 es
->wtop
= es
->wlines
- ClientHeight(wndPtr
, es
);
1827 es
->CurrLine
= es
->wlines
;
1828 es
->WndRow
= es
->wlines
- es
->wtop
;
1830 InvalidateRect(hwnd
, NULL
, TRUE
);
1833 /* reset the vertical scroll bar */
1836 vscrollpos
= EDIT_ComputeVScrollPos(hwnd
);
1837 SetScrollPos(hwnd
, SB_VERT
, vscrollpos
, TRUE
);
1842 /*********************************************************************
1843 * EDIT_ComputeVScrollPos
1845 * Compute the vertical scroll bar position from the window
1846 * position and text width.
1849 int EDIT_ComputeVScrollPos(HWND hwnd
)
1852 short minpos
, maxpos
;
1853 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1855 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1857 GetScrollRange(hwnd
, SB_VERT
, &minpos
, &maxpos
);
1859 if (es
->wlines
> ClientHeight(wndPtr
, es
))
1860 vscrollpos
= (double)(es
->wtop
) / (double)(es
->wlines
-
1861 ClientHeight(wndPtr
, es
)) * (maxpos
- minpos
);
1863 vscrollpos
= minpos
;
1869 /*********************************************************************
1870 * EDIT_ComputeHScrollPos
1872 * Compute the horizontal scroll bar position from the window
1873 * position and text width.
1876 int EDIT_ComputeHScrollPos(HWND hwnd
)
1879 short minpos
, maxpos
;
1880 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1882 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1884 GetScrollRange(hwnd
, SB_HORZ
, &minpos
, &maxpos
);
1886 if (es
->textwidth
> ClientWidth(wndPtr
))
1887 hscrollpos
= (double)(es
->wleft
) / (double)(es
->textwidth
-
1888 ClientWidth(wndPtr
)) * (maxpos
- minpos
);
1890 hscrollpos
= minpos
;
1896 /*********************************************************************
1899 * Delete character to right of cursor.
1902 void EDIT_DelKey(HWND hwnd
)
1905 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1907 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1908 char *currchar
= CurrChar
;
1909 BOOL repaint
= *currchar
== '\n';
1911 if (IsMultiLine() && *currchar
== '\n' && *(currchar
+ 1) == '\0')
1913 strcpy(currchar
, currchar
+ 1);
1914 NOTIFY_PARENT(hwnd
, EN_UPDATE
);
1918 EDIT_BuildTextPointers(hwnd
);
1919 GetClientRect(hwnd
, &rc
);
1920 rc
.top
= es
->WndRow
* es
->txtht
;
1921 InvalidateRect(hwnd
, &rc
, FALSE
);
1926 EDIT_ModTextPointers(hwnd
, es
->CurrLine
+ 1, -1);
1927 EDIT_WriteTextLine(hwnd
, NULL
, es
->WndRow
+ es
->wtop
);
1930 es
->TextChanged
= TRUE
;
1931 NOTIFY_PARENT(hwnd
, EN_CHANGE
);
1934 /*********************************************************************
1935 * WM_VSCROLL message function
1938 void EDIT_VScrollMsg(HWND hwnd
, WORD wParam
, LONG lParam
)
1940 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1942 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1952 EDIT_VScrollLine(hwnd
, wParam
);
1957 EDIT_VScrollPage(hwnd
, wParam
);
1962 SetCaretPos(es
->WndCol
, es
->WndRow
);
1967 /*********************************************************************
1970 * Scroll text vertically by one line using scrollbars.
1973 void EDIT_VScrollLine(HWND hwnd
, WORD opt
)
1977 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
1979 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
1981 dprintf_edit(stddeb
,"EDIT_VScrollLine: direction=%d\n", opt
);
1983 if (opt
== SB_LINEDOWN
)
1985 /* move down one line */
1986 if (es
->wtop
+ ClientHeight(wndPtr
, es
) >= es
->wlines
)
1992 /* move up one line */
1998 if (IsWindowVisible(hwnd
))
2000 /* adjust client bottom to nearest whole line */
2001 GetClientRect(hwnd
, &rc
);
2002 rc
.bottom
= (rc
.bottom
/ es
->txtht
) * es
->txtht
;
2004 if (opt
== SB_LINEUP
)
2006 /* move up one line (scroll window down) */
2007 ScrollWindow(hwnd
, 0, es
->txtht
, &rc
, &rc
);
2008 /* write top line */
2009 EDIT_WriteTextLine(hwnd
, NULL
, es
->wtop
);
2014 /* move down one line (scroll window up) */
2015 ScrollWindow(hwnd
, 0, -(es
->txtht
), &rc
, &rc
);
2016 /* write bottom line */
2017 y
= ((rc
.bottom
- rc
.top
/ es
->txtht
) - 1);
2018 EDIT_WriteTextLine(hwnd
, NULL
, es
->wtop
+ y
);
2025 /*********************************************************************
2028 * Scroll text vertically by one page using keyboard.
2031 void EDIT_VScrollPage(HWND hwnd
, WORD opt
)
2034 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2036 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2038 if (opt
== SB_PAGEUP
)
2041 es
->wtop
-= ClientHeight(wndPtr
, es
);
2045 if (es
->wtop
+ ClientHeight(wndPtr
, es
) < es
->wlines
)
2047 es
->wtop
+= ClientHeight(wndPtr
, es
);
2048 if (es
->wtop
> es
->wlines
- ClientHeight(wndPtr
, es
))
2049 es
->wtop
= es
->wlines
- ClientHeight(wndPtr
, es
);
2055 InvalidateRect(hwnd
, NULL
, TRUE
);
2058 /* reset the vertical scroll bar */
2061 vscrollpos
= EDIT_ComputeVScrollPos(hwnd
);
2062 SetScrollPos(hwnd
, SB_VERT
, vscrollpos
, TRUE
);
2067 /*********************************************************************
2068 * WM_HSCROLL message function
2071 void EDIT_HScrollMsg(HWND hwnd
, WORD wParam
, LONG lParam
)
2073 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2075 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2083 SetCaretPos(es
->WndCol
, es
->WndRow
* es
->txtht
);
2090 /*********************************************************************
2091 * WM_SIZE message function
2094 void EDIT_SizeMsg(HWND hwnd
, WORD wParam
, LONG lParam
)
2096 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2098 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2100 if (wParam
!= SIZE_MAXIMIZED
&& wParam
!= SIZE_RESTORED
) return;
2102 InvalidateRect(hwnd
, NULL
, TRUE
);
2103 es
->PaintBkgd
= TRUE
;
2108 /*********************************************************************
2109 * WM_LBUTTONDOWN message function
2112 void EDIT_LButtonDownMsg(HWND hwnd
, WORD wParam
, LONG lParam
)
2117 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2119 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2122 EDIT_ClearSel(hwnd
);
2124 es
->WndRow
= HIWORD(lParam
) / es
->txtht
;
2125 if (es
->WndRow
> es
->wlines
- es
->wtop
- 1)
2128 es
->WndRow
= es
->wlines
- es
->wtop
- 1;
2133 es
->CurrLine
= es
->wtop
+ es
->WndRow
;
2135 cp
= EDIT_TextLine(hwnd
, es
->CurrLine
);
2136 len
= EDIT_LineLength(hwnd
, es
->CurrLine
);
2137 es
->WndCol
= LOWORD(lParam
);
2138 if (es
->WndCol
> EDIT_StrLength(hwnd
, cp
, len
, 0) - es
->wleft
|| end
)
2139 es
->WndCol
= EDIT_StrLength(hwnd
, cp
, len
, 0) - es
->wleft
;
2140 es
->CurrCol
= EDIT_PixelToChar(hwnd
, es
->CurrLine
, &(es
->WndCol
));
2143 ButtonRow
= es
->CurrLine
;
2144 ButtonCol
= es
->CurrCol
;
2148 /*********************************************************************
2149 * WM_MOUSEMOVE message function
2152 void EDIT_MouseMoveMsg(HWND hwnd
, WORD wParam
, LONG lParam
)
2154 if (wParam
!= MK_LBUTTON
)
2159 EDIT_SetAnchor(hwnd
, ButtonRow
, ButtonCol
);
2165 EDIT_ExtendSel(hwnd
, LOWORD(lParam
), HIWORD(lParam
));
2169 /*********************************************************************
2172 * Convert a pixel offset in the given row to a character offset,
2173 * adjusting the pixel offset to the nearest whole character if
2177 int EDIT_PixelToChar(HWND hwnd
, int row
, int *pixel
)
2179 int ch
= 0, i
= 0, s_i
;
2182 dprintf_edit(stddeb
,"EDIT_PixelToChar: row=%d, pixel=%d\n", row
, *pixel
);
2184 text
= EDIT_TextLine(hwnd
, row
);
2188 i
+= EDIT_CharWidth(hwnd
, (BYTE
)(*(text
+ ch
)), i
);
2192 /* if stepped past _pixel_, go back a character */
2203 /*********************************************************************
2204 * WM_SETTEXT message function
2207 LONG
EDIT_SetTextMsg(HWND hwnd
, LONG lParam
)
2211 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2213 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2215 if (strlen((char *)lParam
) <= es
->MaxTextLen
)
2217 len
= strlen((char *)lParam
);
2218 EDIT_ClearText(hwnd
);
2220 es
->hText
= EDIT_HeapReAlloc(hwnd
, es
->hText
, len
+ 3);
2221 text
= EDIT_HeapAddr(hwnd
, es
->hText
);
2222 strcpy(text
, (char *)lParam
);
2223 text
[len
+ 1] = '\0';
2224 text
[len
+ 2] = '\0';
2225 EDIT_BuildTextPointers(hwnd
);
2226 InvalidateRect(hwnd
, NULL
, TRUE
);
2227 es
->PaintBkgd
= TRUE
;
2228 es
->TextChanged
= TRUE
;
2236 /*********************************************************************
2239 * Clear text from text buffer.
2242 void EDIT_ClearText(HWND hwnd
)
2244 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2246 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2247 unsigned int blen
= EditBufLen(wndPtr
) + 2;
2250 es
->hText
= EDIT_HeapReAlloc(hwnd
, es
->hText
, blen
);
2251 text
= EDIT_HeapAddr(hwnd
, es
->hText
);
2252 memset(text
, 0, blen
);
2255 es
->CurrLine
= es
->CurrCol
= 0;
2256 es
->WndRow
= es
->WndCol
= 0;
2257 es
->wleft
= es
->wtop
= 0;
2259 es
->TextChanged
= FALSE
;
2260 EDIT_ClearTextPointers(hwnd
);
2264 /*********************************************************************
2265 * EM_SETSEL message function
2268 void EDIT_SetSelMsg(HWND hwnd
, WORD wParam
, LONG lParam
)
2271 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2273 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2275 so
= LOWORD(lParam
);
2276 eo
= HIWORD(lParam
);
2278 if (so
== -1) /* if so == -1, clear selection */
2280 EDIT_ClearSel(hwnd
);
2284 if (so
== eo
) /* if so == eo, set caret only */
2286 EDIT_GetLineCol(hwnd
, so
, &(es
->CurrLine
), &(es
->CurrCol
));
2287 es
->WndRow
= es
->CurrLine
- es
->wtop
;
2291 if (es
->WndRow
< 0 || es
->WndRow
> ClientHeight(wndPtr
, es
))
2293 es
->wtop
= es
->CurrLine
;
2296 es
->WndCol
= EDIT_StrLength(hwnd
,
2297 EDIT_TextLine(hwnd
, es
->CurrLine
),
2298 es
->CurrCol
, 0) - es
->wleft
;
2299 if (es
->WndCol
> ClientWidth(wndPtr
))
2301 es
->wleft
= es
->WndCol
;
2304 else if (es
->WndCol
< 0)
2306 es
->wleft
+= es
->WndCol
;
2311 else /* otherwise set selection */
2316 EDIT_GetLineCol(hwnd
, so
, &(es
->SelBegLine
), &(es
->SelBegCol
));
2317 EDIT_GetLineCol(hwnd
, eo
, &(es
->SelEndLine
), &(es
->SelEndCol
));
2318 es
->CurrLine
= es
->SelEndLine
;
2319 es
->CurrCol
= es
->SelEndCol
;
2320 es
->WndRow
= es
->SelEndLine
- es
->wtop
;
2322 if (!wParam
) /* don't suppress scrolling of text */
2326 es
->wtop
= es
->SelEndLine
;
2329 else if (es
->WndRow
> ClientHeight(wndPtr
, es
))
2331 es
->wtop
+= es
->WndRow
- ClientHeight(wndPtr
, es
);
2332 es
->WndRow
= ClientHeight(wndPtr
, es
);
2334 es
->WndCol
= EDIT_StrLength(hwnd
,
2335 EDIT_TextLine(hwnd
, es
->SelEndLine
),
2336 es
->SelEndCol
, 0) - es
->wleft
;
2337 if (es
->WndCol
> ClientWidth(wndPtr
))
2339 es
->wleft
+= es
->WndCol
- ClientWidth(wndPtr
);
2340 es
->WndCol
= ClientWidth(wndPtr
);
2342 else if (es
->WndCol
< 0)
2344 es
->wleft
+= es
->WndCol
;
2349 InvalidateRect(hwnd
, NULL
, TRUE
);
2355 /*********************************************************************
2358 * Return line and column in text buffer from character offset.
2361 void EDIT_GetLineCol(HWND hwnd
, int off
, int *line
, int *col
)
2365 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2367 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2368 char *text
= EDIT_HeapAddr(hwnd
, es
->hText
);
2369 unsigned int *textPtrs
=
2370 (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
2372 /* check for (0,0) */
2380 if (off
> strlen(text
)) off
= strlen(text
);
2382 for (lineno
= 0; lineno
< es
->wlines
; lineno
++)
2384 cp
= text
+ *(textPtrs
+ lineno
);
2385 if (off
== (int)(cp
- text
))
2391 if (off
< (int)(cp
- text
))
2396 *col
= off
- (int)(cp1
- text
);
2398 if (*(text
+ *col
) == '\0')
2404 /*********************************************************************
2407 * Delete the current selected text (if any)
2410 void EDIT_DeleteSel(HWND hwnd
)
2414 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2416 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2420 bbl
= EDIT_TextLine(hwnd
, es
->SelBegLine
) + es
->SelBegCol
;
2421 bel
= EDIT_TextLine(hwnd
, es
->SelEndLine
) + es
->SelEndCol
;
2422 len
= (int)(bel
- bbl
);
2423 EDIT_SaveDeletedText(hwnd
, bbl
, len
, es
->SelBegLine
, es
->SelBegCol
);
2424 es
->TextChanged
= TRUE
;
2427 es
->CurrLine
= es
->SelBegLine
;
2428 es
->CurrCol
= es
->SelBegCol
;
2429 es
->WndRow
= es
->SelBegLine
- es
->wtop
;
2432 es
->wtop
= es
->SelBegLine
;
2435 es
->WndCol
= EDIT_StrLength(hwnd
, bbl
- es
->SelBegCol
,
2436 es
->SelBegCol
, 0) - es
->wleft
;
2438 EDIT_BuildTextPointers(hwnd
);
2439 es
->PaintBkgd
= TRUE
;
2440 EDIT_ClearSel(hwnd
);
2445 /*********************************************************************
2448 * Clear the current selection.
2451 void EDIT_ClearSel(HWND hwnd
)
2453 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2455 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2457 es
->SelBegLine
= es
->SelBegCol
= 0;
2458 es
->SelEndLine
= es
->SelEndCol
= 0;
2460 InvalidateRect(hwnd
, NULL
, TRUE
);
2465 /*********************************************************************
2466 * EDIT_TextLineNumber
2468 * Return the line number in the text buffer of the supplied
2469 * character pointer.
2472 int EDIT_TextLineNumber(HWND hwnd
, char *lp
)
2476 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2478 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2479 char *text
= EDIT_HeapAddr(hwnd
, es
->hText
);
2480 unsigned int *textPtrs
=
2481 (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
2483 for (lineno
= 0; lineno
< es
->wlines
; lineno
++)
2485 cp
= text
+ *(textPtrs
+ lineno
);
2495 /*********************************************************************
2498 * Set down anchor for text marking.
2501 void EDIT_SetAnchor(HWND hwnd
, int row
, int col
)
2504 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2506 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2510 EDIT_ClearSel(hwnd
);
2511 es
->SelBegLine
= es
->SelEndLine
= row
;
2512 es
->SelBegCol
= es
->SelEndCol
= col
;
2515 InvalidateRect(hwnd
, NULL
, FALSE
);
2521 /*********************************************************************
2524 * Extend selection to the given screen co-ordinates.
2527 void EDIT_ExtendSel(HWND hwnd
, int x
, int y
)
2529 int bbl
, bel
, bbc
, bec
;
2533 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2535 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2537 dprintf_edit(stddeb
,"EDIT_ExtendSel: x=%d, y=%d\n", x
, y
);
2539 bbl
= es
->SelEndLine
;
2540 bbc
= es
->SelEndCol
;
2541 line
= es
->wtop
+ y
/ es
->txtht
;
2542 if (line
> es
->wlines
)
2544 cp
= EDIT_TextLine(hwnd
, line
);
2545 len
= EDIT_LineLength(hwnd
, line
);
2547 es
->WndRow
= y
/ es
->txtht
;
2548 if (es
->WndRow
> es
->wlines
- es
->wtop
- 1)
2551 es
->WndRow
= es
->wlines
- es
->wtop
- 1;
2556 es
->CurrLine
= es
->wtop
+ es
->WndRow
;
2557 es
->SelEndLine
= es
->CurrLine
;
2560 if (es
->WndCol
> EDIT_StrLength(hwnd
, cp
, len
, 0) - es
->wleft
|| end
)
2561 es
->WndCol
= EDIT_StrLength(hwnd
, cp
, len
, 0) - es
->wleft
;
2562 es
->CurrCol
= EDIT_PixelToChar(hwnd
, es
->CurrLine
, &(es
->WndCol
));
2563 es
->SelEndCol
= es
->CurrCol
- 1;
2565 bel
= es
->SelEndLine
;
2566 bec
= es
->SelEndCol
;
2568 /* return if no new characters to mark */
2569 if (bbl
== bel
&& bbc
== bec
)
2572 /* put lowest marker first */
2578 if (bbl
== bel
&& bbc
> bec
)
2581 for (y
= bbl
; y
<= bel
; y
++)
2583 if (y
== bbl
&& y
== bel
)
2584 EDIT_WriteSel(hwnd
, y
, bbc
, bec
);
2586 EDIT_WriteSel(hwnd
, y
, bbc
, -1);
2588 EDIT_WriteSel(hwnd
, y
, 0, bec
);
2590 EDIT_WriteSel(hwnd
, y
, 0, -1);
2595 /*********************************************************************
2598 * Display selection by reversing pixels in selected text.
2599 * If end == -1, selection applies to end of line.
2602 void EDIT_WriteSel(HWND hwnd
, int y
, int start
, int end
)
2608 HBRUSH hbrush
, holdbrush
;
2610 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2612 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2614 dprintf_edit(stddeb
,"EDIT_WriteSel: y=%d start=%d end=%d\n", y
, start
,end
);
2615 GetClientRect(hwnd
, &rc
);
2617 /* make sure y is within the window */
2618 if (y
< es
->wtop
|| y
> (es
->wtop
+ ClientHeight(wndPtr
, es
)))
2621 /* get pointer to text */
2622 cp
= EDIT_TextLine(hwnd
, y
);
2624 /* get length of line if end == -1 */
2626 end
= EDIT_LineLength(hwnd
, y
);
2628 scol
= EDIT_StrLength(hwnd
, cp
, start
, 0);
2629 if (scol
> rc
.right
) return;
2630 if (scol
< rc
.left
) scol
= rc
.left
;
2631 ecol
= EDIT_StrLength(hwnd
, cp
, end
, 0);
2632 if (ecol
< rc
.left
) return;
2633 if (ecol
> rc
.right
) ecol
= rc
.right
;
2636 hbrush
= GetStockObject(BLACK_BRUSH
);
2637 holdbrush
= (HBRUSH
)SelectObject(hdc
, (HANDLE
)hbrush
);
2638 olddm
= SetROP2(hdc
, R2_XORPEN
);
2639 Rectangle(hdc
, scol
, y
* es
->txtht
, ecol
, (y
+ 1) * es
->txtht
);
2640 SetROP2(hdc
, olddm
);
2641 SelectObject(hdc
, (HANDLE
)holdbrush
);
2642 ReleaseDC(hwnd
, hdc
);
2646 /*********************************************************************
2649 * Stop text marking (selection).
2652 void EDIT_StopMarking(HWND hwnd
)
2654 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2656 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2658 TextMarking
= FALSE
;
2659 if (es
->SelBegLine
> es
->SelEndLine
)
2661 swap(&(es
->SelBegLine
), &(es
->SelEndLine
));
2662 swap(&(es
->SelBegCol
), &(es
->SelEndCol
));
2664 if (es
->SelBegLine
== es
->SelEndLine
&& es
->SelBegCol
> es
->SelEndCol
)
2665 swap(&(es
->SelBegCol
), &(es
->SelEndCol
));
2669 /*********************************************************************
2670 * EM_GETLINE message function
2673 LONG
EDIT_GetLineMsg(HWND hwnd
, WORD wParam
, LONG lParam
)
2677 char *buffer
= (char *)lParam
;
2679 cp
= EDIT_TextLine(hwnd
, wParam
);
2680 cp1
= EDIT_TextLine(hwnd
, wParam
+ 1);
2681 len
= min((int)(cp1
- cp
), (WORD
)(*buffer
));
2682 strncpy(buffer
, cp
, len
);
2688 /*********************************************************************
2689 * EM_GETSEL message function
2692 LONG
EDIT_GetSelMsg(HWND hwnd
)
2695 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2697 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2698 unsigned int *textPtrs
=
2699 (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
2701 so
= *(textPtrs
+ es
->SelBegLine
) + es
->SelBegCol
;
2702 eo
= *(textPtrs
+ es
->SelEndLine
) + es
->SelEndCol
;
2704 return MAKELONG(so
, eo
);
2708 /*********************************************************************
2709 * EM_REPLACESEL message function
2712 void EDIT_ReplaceSel(HWND hwnd
, LONG lParam
)
2714 EDIT_DeleteSel(hwnd
);
2715 EDIT_InsertText(hwnd
, (char *)lParam
, strlen((char *)lParam
));
2716 InvalidateRect(hwnd
, NULL
, TRUE
);
2721 /*********************************************************************
2724 * Insert text at current line and column.
2727 void EDIT_InsertText(HWND hwnd
, char *str
, int len
)
2730 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2732 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2733 char *text
= EDIT_HeapAddr(hwnd
, es
->hText
);
2735 plen
= strlen(text
) + len
;
2736 if (plen
+ 1 > es
->textlen
)
2738 es
->hText
= EDIT_HeapReAlloc(hwnd
, es
->hText
, es
->textlen
+ len
);
2739 es
->textlen
= plen
+ 1;
2741 memmove(CurrChar
+ len
, CurrChar
, strlen(CurrChar
) + 1);
2742 memcpy(CurrChar
, str
, len
);
2744 EDIT_BuildTextPointers(hwnd
);
2745 es
->PaintBkgd
= TRUE
;
2746 es
->TextChanged
= TRUE
;
2748 EDIT_GetLineCol(hwnd
, (int)((CurrChar
+ len
) - text
), &(es
->CurrLine
),
2750 es
->WndRow
= es
->CurrLine
- es
->wtop
;
2751 es
->WndCol
= EDIT_StrLength(hwnd
, EDIT_TextLine(hwnd
, es
->CurrLine
),
2752 es
->CurrCol
, 0) - es
->wleft
;
2756 /*********************************************************************
2757 * EM_LINEFROMCHAR message function
2760 LONG
EDIT_LineFromCharMsg(HWND hwnd
, WORD wParam
)
2763 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2765 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2767 if (wParam
== (WORD
)-1)
2768 return (LONG
)(es
->SelBegLine
);
2770 EDIT_GetLineCol(hwnd
, wParam
, &row
, &col
);
2776 /*********************************************************************
2777 * EM_LINEINDEX message function
2780 LONG
EDIT_LineIndexMsg(HWND hwnd
, WORD wParam
)
2782 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2784 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2785 unsigned int *textPtrs
=
2786 (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
2788 if (wParam
== (WORD
)-1)
2789 wParam
= es
->CurrLine
;
2791 return (LONG
)(*(textPtrs
+ wParam
));
2795 /*********************************************************************
2796 * EM_LINELENGTH message function
2799 LONG
EDIT_LineLengthMsg(HWND hwnd
, WORD wParam
)
2802 int sbl
, sbc
, sel
, sec
;
2803 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2805 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2806 unsigned int *textPtrs
=
2807 (unsigned int *)EDIT_HeapAddr(hwnd
, es
->hTextPtrs
);
2809 if (wParam
== (WORD
)-1)
2813 sbl
= es
->SelBegLine
;
2814 sbc
= es
->SelBegCol
;
2815 sel
= es
->SelEndLine
;
2816 sec
= es
->SelEndCol
;
2823 if (sbl
== sel
&& sbc
> sec
)
2828 len
= *(textPtrs
+ sbl
+ 1) - *(textPtrs
+ sbl
) - 1;
2829 return len
- sec
- sbc
;
2832 len
= *(textPtrs
+ sel
+ 1) - *(textPtrs
+ sel
) - sec
- 1;
2835 else /* no selection marked */
2837 len
= *(textPtrs
+ es
->CurrLine
+ 1) -
2838 *(textPtrs
+ es
->CurrLine
) - 1;
2842 else /* line number specified */
2844 EDIT_GetLineCol(hwnd
, wParam
, &row
, &col
);
2845 len
= *(textPtrs
+ row
+ 1) - *(textPtrs
+ row
);
2851 /*********************************************************************
2852 * WM_SETFONT message function
2855 void EDIT_SetFont(HWND hwnd
, WORD wParam
, LONG lParam
)
2860 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2862 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2863 short *charWidths
= (short *)EDIT_HeapAddr(hwnd
, es
->hCharWidths
);
2867 oldfont
= (HFONT
)SelectObject(hdc
, (HANDLE
)es
->hFont
);
2868 GetCharWidth(hdc
, 0, 255, charWidths
);
2869 GetTextMetrics(hdc
, &tm
);
2870 es
->txtht
= tm
.tmHeight
+ tm
.tmExternalLeading
;
2871 SelectObject(hdc
, (HANDLE
)oldfont
);
2872 ReleaseDC(hwnd
, hdc
);
2874 es
->WndRow
= (es
->CurrLine
- es
->wtop
) / es
->txtht
;
2875 es
->WndCol
= EDIT_StrLength(hwnd
, EDIT_TextLine(hwnd
, es
->CurrLine
),
2876 es
->CurrCol
, 0) - es
->wleft
;
2878 InvalidateRect(hwnd
, NULL
, TRUE
);
2879 es
->PaintBkgd
= TRUE
;
2880 if (lParam
) UpdateWindow(hwnd
);
2884 /*********************************************************************
2885 * EDIT_SaveDeletedText
2887 * Save deleted text in deleted text buffer.
2890 void EDIT_SaveDeletedText(HWND hwnd
, char *deltext
, int len
,
2894 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2896 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2898 es
->hDeletedText
= GlobalReAlloc(es
->hDeletedText
, len
, GMEM_MOVEABLE
);
2899 if (!es
->hDeletedText
) return;
2900 text
= (char *)GlobalLock(es
->hDeletedText
);
2901 memcpy(text
, deltext
, len
);
2902 GlobalUnlock(es
->hDeletedText
);
2903 es
->DeletedLength
= len
;
2904 es
->DeletedCurrLine
= line
;
2905 es
->DeletedCurrCol
= col
;
2909 /*********************************************************************
2910 * EDIT_ClearDeletedText
2912 * Clear deleted text buffer.
2915 void EDIT_ClearDeletedText(HWND hwnd
)
2917 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2919 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2921 GlobalFree(es
->hDeletedText
);
2922 es
->hDeletedText
= 0;
2923 es
->DeletedLength
= 0;
2927 /*********************************************************************
2928 * EM_UNDO message function
2931 LONG
EDIT_UndoMsg(HWND hwnd
)
2934 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2936 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
2938 if (es
->hDeletedText
)
2940 text
= (char *)GlobalLock(es
->hDeletedText
);
2941 es
->CurrLine
= es
->DeletedCurrLine
;
2942 es
->CurrCol
= es
->DeletedCurrCol
;
2943 EDIT_InsertText(hwnd
, text
, es
->DeletedLength
);
2944 GlobalUnlock(es
->hDeletedText
);
2945 EDIT_ClearDeletedText(hwnd
);
2947 es
->SelBegLine
= es
->CurrLine
;
2948 es
->SelBegCol
= es
->CurrCol
;
2949 EDIT_GetLineCol(hwnd
, (int)((CurrChar
+ es
->DeletedLength
) - text
),
2950 &(es
->CurrLine
), &(es
->CurrCol
));
2951 es
->WndRow
= es
->CurrLine
- es
->wtop
;
2952 es
->WndCol
= EDIT_StrLength(hwnd
, EDIT_TextLine(hwnd
, es
->CurrLine
),
2953 es
->CurrCol
, 0) - es
->wleft
;
2954 es
->SelEndLine
= es
->CurrLine
;
2955 es
->SelEndCol
= es
->CurrCol
;
2957 InvalidateRect(hwnd
, NULL
, TRUE
);
2966 /*********************************************************************
2969 * Allocate the specified number of bytes on the specified local heap.
2972 unsigned int EDIT_HeapAlloc(HWND hwnd
, int bytes
)
2974 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2976 ret
= ((unsigned int)HEAP_Alloc((MDESC
**)
2977 *(LONG
*)(wndPtr
->wExtra
+ 2),
2978 GMEM_MOVEABLE
, bytes
) & 0xffff);
2980 printf("EDIT_HeapAlloc: Out of heap-memory\n");
2985 /*********************************************************************
2988 * Return the address of the memory pointed to by the handle.
2991 void *EDIT_HeapAddr(HWND hwnd
, unsigned int handle
)
2993 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
2995 return ((void *)((handle
) ? ((handle
) | ((unsigned int)
2996 (*(MDESC
**)*(LONG
*)(wndPtr
->wExtra
+ 2))
2997 & 0xffff0000)) : 0));
3001 /*********************************************************************
3004 * Reallocate the memory pointed to by the handle.
3007 unsigned int EDIT_HeapReAlloc(HWND hwnd
, unsigned int handle
, int bytes
)
3009 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
3011 return ((unsigned int)HEAP_ReAlloc((MDESC
**)
3012 *(LONG
*)(wndPtr
->wExtra
+ 2),
3013 EDIT_HeapAddr(hwnd
, handle
),
3014 bytes
, GMEM_MOVEABLE
) & 0xffff);
3018 /*********************************************************************
3021 * Frees the memory pointed to by the handle.
3024 void EDIT_HeapFree(HWND hwnd
, unsigned int handle
)
3026 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
3028 HEAP_Free((MDESC
**)*(LONG
*)(wndPtr
->wExtra
+ 2),
3029 EDIT_HeapAddr(hwnd
, handle
));
3033 /*********************************************************************
3036 * Return the size of the given object on the local heap.
3039 unsigned int EDIT_HeapSize(HWND hwnd
, unsigned int handle
)
3041 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
3043 return HEAP_LocalSize((MDESC
**)*(LONG
*)(wndPtr
->wExtra
+ 2), handle
);
3047 /*********************************************************************
3048 * EM_SETHANDLE message function
3051 void EDIT_SetHandleMsg(HWND hwnd
, WORD wParam
)
3053 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
3055 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
3060 es
->MaxTextLen
= EDIT_HeapSize(hwnd
, es
->hText
);
3062 es
->wtop
= es
->wleft
= 0;
3063 es
->CurrLine
= es
->CurrCol
= 0;
3064 es
->WndRow
= es
->WndCol
= 0;
3065 es
->TextChanged
= FALSE
;
3067 es
->SelBegLine
= es
->SelBegCol
= 0;
3068 es
->SelEndLine
= es
->SelEndCol
= 0;
3070 es
->PaintBkgd
= TRUE
;
3071 InvalidateRect(hwnd
, NULL
, TRUE
);
3077 /*********************************************************************
3078 * EM_SETTABSTOPS message function
3081 LONG
EDIT_SetTabStopsMsg(HWND hwnd
, WORD wParam
, LONG lParam
)
3083 unsigned short *tabstops
;
3084 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
3086 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
3088 es
->NumTabStops
= wParam
;
3090 es
->hTabStops
= EDIT_HeapReAlloc(hwnd
, es
->hTabStops
, 1);
3091 else if (wParam
== 1)
3093 es
->hTabStops
= EDIT_HeapReAlloc(hwnd
, es
->hTabStops
, 1);
3094 tabstops
= (unsigned short *)EDIT_HeapAddr(hwnd
, es
->hTabStops
);
3095 *tabstops
= (unsigned short)lParam
;
3099 es
->hTabStops
= EDIT_HeapReAlloc(hwnd
, es
->hTabStops
, wParam
);
3100 tabstops
= (unsigned short *)EDIT_HeapAddr(hwnd
, es
->hTabStops
);
3101 memcpy(tabstops
, (unsigned short *)lParam
, wParam
);
3107 /*********************************************************************
3108 * EDIT_CopyToClipboard
3110 * Copy the specified text to the clipboard.
3113 void EDIT_CopyToClipboard(HWND hwnd
)
3119 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
3121 (EDITSTATE
*)EDIT_HeapAddr(hwnd
, (HANDLE
)(*(wndPtr
->wExtra
)));
3123 bbl
= EDIT_TextLine(hwnd
, es
->SelBegLine
) + es
->SelBegCol
;
3124 bel
= EDIT_TextLine(hwnd
, es
->SelEndLine
) + es
->SelEndCol
;
3125 len
= (int)(bel
- bbl
);
3127 hMem
= GlobalAlloc(GHND
, (DWORD
)(len
+ 1));
3128 lpMem
= GlobalLock(hMem
);
3130 for (i
= 0; i
< len
; i
++)
3134 OpenClipboard(hwnd
);
3136 SetClipboardData(CF_TEXT
, hMem
);
3141 /*********************************************************************
3142 * WM_PASTE message function
3145 void EDIT_PasteMsg(HWND hwnd
)
3150 OpenClipboard(hwnd
);
3151 if (!(hClipMem
= GetClipboardData(CF_TEXT
)))
3153 /* no text in clipboard */
3157 lpClipMem
= GlobalLock(hClipMem
);
3158 EDIT_InsertText(hwnd
, lpClipMem
, strlen(lpClipMem
));
3159 GlobalUnlock(hClipMem
);
3161 InvalidateRect(hwnd
, NULL
, TRUE
);
3166 /*********************************************************************
3170 void swap(int *a
, int *b
)